vircam_dark_combine.c

00001 /* $Id: vircam_dark_combine.c,v 1.67 2010/09/10 11:25:39 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2010/09/10 11:25:39 $
00024  * $Revision: 1.67 $
00025  * $Name: v1-1-0 $
00026  */
00027 
00028 /* Includes */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 #include <stdio.h>
00035 #include <cpl.h>
00036 #include <math.h>
00037 
00038 #include "vircam_utils.h"
00039 #include "vircam_pfits.h"
00040 #include "vircam_dfs.h"
00041 #include "vircam_mods.h"
00042 #include "vircam_stats.h"
00043 #include "vircam_fits.h"
00044 #include "vircam_mask.h"
00045 #include "vircam_channel.h"
00046 #include "vircam_dfs.h"
00047 #include "vircam_paf.h"
00048 #include "vircam_wcsutils.h"
00049 
00050 /* Define values for bit mask that flags dummy results */
00051 
00052 #define MEANDARK    1
00053 #define DIFFIMG     2
00054 #define STATS_TAB   4
00055 
00056 /* Function prototypes */
00057 
00058 static int vircam_dark_combine_create(cpl_plugin *) ;
00059 static int vircam_dark_combine_exec(cpl_plugin *) ;
00060 static int vircam_dark_combine_destroy(cpl_plugin *) ;
00061 static int vircam_dark_combine(cpl_parameterlist *, cpl_frameset *) ;
00062 static int vircam_dark_combine_save(cpl_frameset *framelist, 
00063                                     cpl_parameterlist *parlist);
00064 static void vircam_dark_combine_dummy_products(void);
00065 static void vircam_dark_combine_hotpix(void);
00066 static void vircam_dark_combine_normal(int jext, float exptime);
00067 static int vircam_dark_combine_lastbit(int jext, cpl_frameset *framelist,
00068                                        cpl_parameterlist *parlist);
00069 static void vircam_dark_combine_init(void);
00070 static void vircam_dark_combine_tidy(int level);
00071 
00072 /* Static global variables */
00073 
00074 static struct {
00075 
00076     /* Input */
00077 
00078     int         combtype;
00079     int         scaletype;
00080     int         xrej;
00081     float       thresh;
00082     int         ncells;
00083     int         extenum;
00084 
00085     /* Output */
00086 
00087     float       particle_rate;
00088     float       darkmed;
00089     float       darkrms;
00090     float       darkdiff_med;
00091     float       darkdiff_rms;
00092     float       striperms;
00093     int         nhot;
00094     float       hotfrac;
00095     float       ron12;
00096 
00097 } vircam_dark_combine_config;
00098 
00099 
00100 static struct {
00101     int               *labels;
00102     cpl_frameset      *darklist;
00103     vir_fits          **darks;
00104     int               ndarks;
00105     vir_fits          **good;
00106     int               ngood;
00107     cpl_frame         *master_dark;
00108     vir_mask          *master_mask;
00109     cpl_frame         *chantab;
00110     cpl_image         *outimage;
00111     cpl_propertylist  *drs;
00112     unsigned char     *rejmask;
00113     unsigned char     *rejplus;
00114     vir_fits          *mdimage;
00115     cpl_image         *diffimg;
00116     cpl_table         *diffimstats;
00117     cpl_propertylist  *phupaf;
00118 } ps;
00119 
00120 static cpl_frame *product_frame_mean_dark = NULL;
00121 static cpl_frame *product_frame_diffimg = NULL;
00122 static cpl_frame *product_frame_diffimg_stats = NULL;
00123 static int isfirst;
00124 static int we_expect;
00125 static int we_get;
00126 
00127 static char vircam_dark_combine_description[] =
00128 "vircam_dark_combine -- VIRCAM dark combine recipe.\n\n"
00129 "Combine a list of dark frames into a mean dark frame. Optionally compare \n"
00130 "the output frame to a master dark frame\n\n"
00131 "The program accepts the following files in the SOF:\n\n"
00132 "    Tag                   Description\n"
00133 "    -----------------------------------------------------------------------\n"
00134 "    %-21s A list of raw dark images\n"
00135 "    %-21s Optional reference dark frame\n"
00136 "    %-21s Optional master bad pixel map or\n"
00137 "    %-21s Optional master confidence map\n"
00138 "    %-21s Optional channel table or\n"
00139 "    %-21s Optional initial channel table\n"
00140 "If no master dark frame is made available, then no comparison will be done\n"
00141 "This means there will be no output difference image. If a master dark is\n"
00142 "available, but no channel table is, then a difference image will be formed\n"
00143 "but no stats will be written."
00144 "\n";
00145 
00274 /* Function code */
00275 
00276 
00277 /*---------------------------------------------------------------------------*/
00285 /*---------------------------------------------------------------------------*/
00286 
00287 int cpl_plugin_get_info(cpl_pluginlist *list) {
00288     cpl_recipe  *recipe = cpl_calloc(1,sizeof(*recipe));
00289     cpl_plugin  *plugin = &recipe->interface;
00290     char alldesc[SZ_ALLDESC];
00291     (void)snprintf(alldesc,SZ_ALLDESC,vircam_dark_combine_description,
00292                    VIRCAM_DARK_RAW,VIRCAM_REF_DARK,VIRCAM_CAL_BPM,
00293                    VIRCAM_CAL_CONF,VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT);
00294 
00295     cpl_plugin_init(plugin,
00296                     CPL_PLUGIN_API,
00297                     VIRCAM_BINARY_VERSION,
00298                     CPL_PLUGIN_TYPE_RECIPE,
00299                     "vircam_dark_combine",
00300                     "VIRCAM dark combination recipe",
00301                     alldesc,
00302                     "Jim Lewis",
00303                     "jrl@ast.cam.ac.uk",
00304                     vircam_get_license(),
00305                     vircam_dark_combine_create,
00306                     vircam_dark_combine_exec,
00307                     vircam_dark_combine_destroy);
00308 
00309     cpl_pluginlist_append(list,plugin);
00310 
00311     return(0);
00312 }
00313 
00314 /*---------------------------------------------------------------------------*/
00323 /*---------------------------------------------------------------------------*/
00324 
00325 static int vircam_dark_combine_create(cpl_plugin *plugin) {
00326     cpl_recipe      *recipe;
00327     cpl_parameter   *p;
00328 
00329     /* Get the recipe out of the plugin */
00330 
00331     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00332         recipe = (cpl_recipe *)plugin;
00333     else 
00334         return(-1);
00335 
00336     /* Create the parameters list in the cpl_recipe object */
00337 
00338     recipe->parameters = cpl_parameterlist_new();
00339 
00340     /* Fill in the parameters. First the combination type */
00341 
00342     p = cpl_parameter_new_range("vircam.vircam_dark_combine.combtype",
00343                                 CPL_TYPE_INT,
00344                                 "1 == Median,\n 2 == Mean",
00345                                 "vircam.vircam_dark_combine",
00346                                 1,1,2);
00347     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"combtype");
00348     cpl_parameterlist_append(recipe->parameters,p);
00349 
00350     /* The requested scaling */
00351 
00352     p = cpl_parameter_new_range("vircam.vircam_dark_combine.scaletype",
00353                                 CPL_TYPE_INT,
00354                                 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
00355                                 "vircam.vircam_dark_combine",
00356                                 1,0,3);
00357     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scaletype");
00358     cpl_parameterlist_append(recipe->parameters,p);
00359     
00360     /* Extra rejection cycle */
00361 
00362     p = cpl_parameter_new_value("vircam.vircam_dark_combine.xrej",
00363                                 CPL_TYPE_BOOL,
00364                                 "True if using extra rejection cycle",
00365                                 "vircam.vircam_dark_combine",
00366                                 TRUE);
00367     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
00368     cpl_parameterlist_append(recipe->parameters,p);
00369 
00370     /* Rejection threshold */
00371 
00372     p = cpl_parameter_new_value("vircam.vircam_dark_combine.thresh",
00373                                 CPL_TYPE_DOUBLE,
00374                                 "Rejection threshold in sigma above background",
00375                                 "vircam.vircam_dark_combine",5.0);
00376     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
00377     cpl_parameterlist_append(recipe->parameters,p);
00378 
00379     /* How many cells to divide each data channel */
00380 
00381     p = cpl_parameter_new_enum("vircam.vircam_dark_combine.ncells",
00382                                CPL_TYPE_INT,
00383                                "Number of cells for data channel stats",
00384                                "vircam.vircam_dark_combine",8,7,1,2,4,8,
00385                                16,32,64);
00386     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ncells");
00387     cpl_parameterlist_append(recipe->parameters,p);     
00388 
00389     /* Extension number of input frames to use */
00390 
00391     p = cpl_parameter_new_range("vircam.vircam_dark_combine.extenum",
00392                                 CPL_TYPE_INT,
00393                                 "Extension number to be done, 0 == all",
00394                                 "vircam.vircam_dark_combine",
00395                                 1,0,16);
00396     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
00397     cpl_parameterlist_append(recipe->parameters,p);
00398         
00399     /* Get out of here */
00400 
00401     return(0);
00402 }
00403     
00404     
00405 /*---------------------------------------------------------------------------*/
00411 /*---------------------------------------------------------------------------*/
00412 
00413 static int vircam_dark_combine_exec(cpl_plugin *plugin) {
00414     cpl_recipe  *recipe;
00415 
00416     /* Get the recipe out of the plugin */
00417 
00418     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00419         recipe = (cpl_recipe *)plugin;
00420     else 
00421         return(-1);
00422 
00423     return(vircam_dark_combine(recipe->parameters,recipe->frames));
00424 }
00425                                 
00426 /*---------------------------------------------------------------------------*/
00432 /*---------------------------------------------------------------------------*/
00433 
00434 static int vircam_dark_combine_destroy(cpl_plugin *plugin) {
00435     cpl_recipe *recipe ;
00436 
00437     /* Get the recipe out of the plugin */
00438 
00439     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00440         recipe = (cpl_recipe *)plugin;
00441     else 
00442         return(-1);
00443 
00444     cpl_parameterlist_delete(recipe->parameters);
00445     return(0);
00446 }
00447 
00448 /*---------------------------------------------------------------------------*/
00455 /*---------------------------------------------------------------------------*/
00456 
00457 static int vircam_dark_combine(cpl_parameterlist *parlist, 
00458                                cpl_frameset *framelist) {
00459     const char *fctid="vircam_dark_combine";
00460     const char *fname;
00461     int nlab,j,jst,jfn,retval,status,live,nx,ny;
00462     long i;
00463     float exptime;
00464     vir_fits *ff;
00465     cpl_parameter *p;
00466     cpl_propertylist *plist;
00467 
00468     /* Check validity of input frameset */
00469 
00470     if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00471         cpl_msg_error(fctid,"Input framelist NULL or has no input data");
00472         return(-1);
00473     }
00474 
00475     /* Check the files in the frameset */
00476 
00477     if (vircam_frameset_fexists(framelist) != VIR_OK) {
00478         cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00479         return(-1);
00480     }
00481 
00482     /* Initialise some things */
00483 
00484     vircam_dark_combine_init();
00485     we_expect |= MEANDARK;
00486 
00487     /* Get the parameters */
00488 
00489     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.combtype");
00490     vircam_dark_combine_config.combtype = cpl_parameter_get_int(p);
00491     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.scaletype");
00492     vircam_dark_combine_config.scaletype = cpl_parameter_get_int(p);
00493     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.xrej");
00494     vircam_dark_combine_config.xrej = cpl_parameter_get_bool(p);
00495     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.thresh");
00496     vircam_dark_combine_config.thresh = (float)cpl_parameter_get_double(p);
00497     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.ncells");
00498     vircam_dark_combine_config.ncells = cpl_parameter_get_int(p);
00499     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.extenum");
00500     vircam_dark_combine_config.extenum = cpl_parameter_get_int(p);
00501 
00502     /* Sort out raw from calib frames */
00503 
00504     if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00505         cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00506         vircam_dark_combine_tidy(2);
00507         return(-1);
00508     }
00509 
00510     /* Get a list of the frame labels */ 
00511 
00512     if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00513                                            &nlab)) == NULL) {
00514         cpl_msg_error(fctid,"Cannot labelise the input frames");
00515         vircam_dark_combine_tidy(2);
00516         return(-1);
00517     }
00518 
00519     /* Get the dark frames */
00520 
00521     if ((ps.darklist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00522                                                 VIRCAM_DARK_RAW)) == NULL) {
00523         cpl_msg_error(fctid,"Cannot find dark frames in input frameset");
00524         vircam_dark_combine_tidy(2);
00525         return(-1);
00526     }
00527     ps.ndarks = cpl_frameset_get_size(ps.darklist);
00528 
00529     /* Get the exposure time from the first dark frame in the list */
00530 
00531     fname = cpl_frame_get_filename(cpl_frameset_get_first(ps.darklist));
00532     plist = cpl_propertylist_load(fname,0);
00533     if (vircam_pfits_get_exptime(plist,&exptime) != VIR_OK) {
00534         cpl_msg_warning(fctid,"Unable to get exposure time for %s",fname);
00535         exptime = 1.0;
00536     }
00537     cpl_propertylist_delete(plist);
00538 
00539     /* Check to see if there is a master dark frame */
00540 
00541     if ((ps.master_dark = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00542                                                      VIRCAM_REF_DARK)) == NULL)
00543         cpl_msg_info(fctid,"No master dark found -- no difference image will be formed");
00544     else
00545         we_expect |= DIFFIMG;
00546         
00547     /* Check to see if there is a master bad pixel map. If there isn't one 
00548        then look for a confidence map */
00549 
00550     ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00551 
00552     /* Check to see if there is a channel table */
00553 
00554     if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00555                                                  VIRCAM_CAL_CHANTAB)) == NULL) {
00556         if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00557                                                      VIRCAM_CAL_CHANTAB_INIT)) == NULL)
00558             cpl_msg_info(fctid,"No channel table found -- no difference image stats will be done");
00559     } else if (we_expect & DIFFIMG)
00560         we_expect |= STATS_TAB;
00561 
00562     /* Now, how many image extensions do we want to do? If the extension
00563        number is zero, then we loop for all possible extensions. If it
00564        isn't then we just do the extension specified */
00565 
00566     vircam_exten_range(vircam_dark_combine_config.extenum,
00567                        (const cpl_frame *)cpl_frameset_get_frame(ps.darklist,0),
00568                        &jst,&jfn);
00569     if (jst == -1 || jfn == -1) {
00570         cpl_msg_error(fctid,"Unable to continue");
00571         vircam_dark_combine_tidy(2);
00572         return(-1);
00573     }
00574 
00575     /* Get some space for the good frames */
00576 
00577     ps.good = cpl_malloc(ps.ndarks*sizeof(vir_fits *));
00578 
00579     /* Now loop for all the extension... */
00580 
00581     for (j = jst; j <= jfn; j++) {
00582         status = VIR_OK;
00583         we_get = 0;
00584         isfirst = (j == jst);
00585 
00586         /* Load up the images. If they won't load then signal a major error,
00587            create some dummy products and save them. */
00588 
00589         ps.darks = vircam_fits_load_list(ps.darklist,CPL_TYPE_FLOAT,j);
00590         if (ps.darks == NULL) {
00591             cpl_msg_info(fctid,"Extension %d darks wouldn't load",j);
00592             retval = vircam_dark_combine_lastbit(j,framelist,parlist);
00593             if (retval != 0) 
00594                 return(-1);
00595             continue;
00596         }
00597 
00598         /* Are any of these dark frames good? */
00599 
00600         ps.ngood = 0;
00601         for (i = 0; i < ps.ndarks; i++) {
00602             ff = ps.darks[i];
00603             vircam_pfits_get_detlive(vircam_fits_get_ehu(ff),&live);
00604             if (! live) {
00605                 cpl_msg_info(fctid,"Detector flagged dead %s",
00606                              vircam_fits_get_fullname(ff));
00607                 vircam_fits_set_error(ff,VIR_FATAL);
00608             } else {
00609                 ps.good[ps.ngood] = ff;
00610                 ps.ngood += 1;
00611             }
00612         }       
00613 
00614         /* If there are no good images, then signal that we need to 
00615            create some dummy products and move on */
00616 
00617         if (ps.ngood == 0) {
00618             cpl_msg_info(fctid,"All images flagged bad for this extension");
00619             retval = vircam_dark_combine_lastbit(j,framelist,parlist);
00620             if (retval != 0) 
00621                 return(-1);
00622             continue;
00623         }
00624         
00625         /* Load the master mask extension */
00626 
00627         nx = cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
00628         ny = cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
00629         retval = vircam_mask_load(ps.master_mask,j,nx,ny);
00630         if (retval == VIR_FATAL) {
00631             cpl_msg_info(fctid,"Unable to load mask image %s[%d]",
00632                          vircam_mask_get_filename(ps.master_mask),j);
00633             cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00634             vircam_mask_force(ps.master_mask,nx,ny);
00635         }
00636             
00637         /* Call the combine module. If it fails, then signal that
00638            all products will be dummies */
00639 
00640         cpl_msg_info(fctid,"Doing combination for extension %d",j);
00641         (void)vircam_imcombine(ps.good,ps.ngood,
00642                                vircam_dark_combine_config.combtype,
00643                                vircam_dark_combine_config.scaletype,
00644                                vircam_dark_combine_config.xrej,
00645                                vircam_dark_combine_config.thresh,
00646                                &(ps.outimage),&(ps.rejmask),
00647                                &(ps.rejplus),&(ps.drs),&status);
00648         if (status == VIR_OK) {
00649             we_get |= MEANDARK;
00650             vircam_dark_combine_hotpix();
00651             vircam_dark_combine_normal(j,exptime);
00652         } 
00653 
00654         /* Create any dummies and save the products */
00655 
00656         retval = vircam_dark_combine_lastbit(j,framelist,parlist);
00657         if (retval != 0) 
00658             return(-1);
00659     }
00660     vircam_dark_combine_tidy(2);
00661     return(0);
00662 }
00663 
00664 
00665 /*---------------------------------------------------------------------------*/
00672 /*---------------------------------------------------------------------------*/
00673 
00674 static int vircam_dark_combine_save(cpl_frameset *framelist, 
00675                                     cpl_parameterlist *parlist) {
00676     cpl_propertylist *plist,*elist,*p,*pafprop;
00677     int status;
00678     const char *fctid = "vircam_dark_combine_save";
00679     const char *outfile = "darkcomb.fits";
00680     const char *outdiff = "darkdiff.fits";
00681     const char *outdimst = "darkdifftab.fits";
00682     const char *outfilepaf = "darkcomb";
00683     const char *outdiffpaf = "darkdiff";
00684     const char *recipeid = "vircam_dark_combine";
00685 
00686     /* If we need to make a PHU then do that now. */
00687 
00688     if (isfirst) {
00689 
00690         /* Create a new product frame object and define some tags */
00691 
00692         product_frame_mean_dark = cpl_frame_new();
00693         cpl_frame_set_filename(product_frame_mean_dark,outfile);
00694         cpl_frame_set_tag(product_frame_mean_dark,VIRCAM_PRO_DARK);
00695         cpl_frame_set_type(product_frame_mean_dark,CPL_FRAME_TYPE_IMAGE);
00696         cpl_frame_set_group(product_frame_mean_dark,CPL_FRAME_GROUP_PRODUCT);
00697         cpl_frame_set_level(product_frame_mean_dark,CPL_FRAME_LEVEL_FINAL);
00698 
00699         /* Base the header on the first image in the input framelist */
00700 
00701         plist = vircam_fits_get_phu(ps.darks[0]);
00702         ps.phupaf = vircam_paf_phu_items(plist);
00703         if (ps.master_dark != NULL) {
00704             cpl_propertylist_update_string(ps.phupaf,"REF_DARK",
00705                                            cpl_frame_get_filename(ps.master_dark));
00706             cpl_propertylist_set_comment(ps.phupaf,"REF_DARK",
00707                                          "Reference dark used");
00708         }
00709         vircam_dfs_set_product_primary_header(plist,product_frame_mean_dark,
00710                                               framelist,parlist,
00711                                               (char *)recipeid,"PRO-1.15",
00712                                               NULL,0);
00713 
00714         /* 'Save' the PHU image */                       
00715 
00716         if (cpl_image_save(NULL,outfile,CPL_BPP_8_UNSIGNED,plist,
00717                            CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00718             cpl_msg_error(fctid,"Cannot save product PHU");
00719             cpl_frame_delete(product_frame_mean_dark);
00720             return(-1);
00721         }
00722         cpl_frameset_insert(framelist,product_frame_mean_dark);
00723 
00724         /* Create a new product frame object for the difference image */
00725 
00726         if (we_expect & DIFFIMG) {
00727             product_frame_diffimg = cpl_frame_new();
00728             cpl_frame_set_filename(product_frame_diffimg,outdiff);
00729             cpl_frame_set_tag(product_frame_diffimg,VIRCAM_PRO_DIFFIMG_DARK);
00730             cpl_frame_set_type(product_frame_diffimg,CPL_FRAME_TYPE_IMAGE);
00731             cpl_frame_set_group(product_frame_diffimg,CPL_FRAME_GROUP_PRODUCT);
00732             cpl_frame_set_level(product_frame_diffimg,CPL_FRAME_LEVEL_FINAL);
00733 
00734             /* Base the header on the first image in the input framelist */
00735 
00736             plist = vircam_fits_get_phu(ps.darks[0]);
00737             vircam_dfs_set_product_primary_header(plist,product_frame_diffimg,
00738                                                   framelist,parlist,
00739                                                   (char *)recipeid,
00740                                                   "PRO-1.15",NULL,0);
00741 
00742             /* 'Save' the PHU image */                   
00743 
00744             if (cpl_image_save(NULL,outdiff,CPL_BPP_8_UNSIGNED,plist,
00745                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00746                 cpl_msg_error(fctid,"Cannot save product PHU");
00747                 cpl_frame_delete(product_frame_diffimg);
00748                 return(-1);
00749             }
00750             cpl_frameset_insert(framelist,product_frame_diffimg);
00751         }
00752 
00753         /* Create a new product frame object for the difference image stats 
00754            table */
00755 
00756         if (we_expect & STATS_TAB) {
00757             product_frame_diffimg_stats = cpl_frame_new();
00758             cpl_frame_set_filename(product_frame_diffimg_stats,outdimst);
00759             cpl_frame_set_tag(product_frame_diffimg_stats,
00760                               VIRCAM_PRO_DIFFIMG_DARK_STATS);
00761             cpl_frame_set_type(product_frame_diffimg_stats,
00762                                CPL_FRAME_TYPE_TABLE);
00763             cpl_frame_set_group(product_frame_diffimg_stats,
00764                                 CPL_FRAME_GROUP_PRODUCT);
00765             cpl_frame_set_level(product_frame_diffimg_stats,
00766                                 CPL_FRAME_LEVEL_FINAL);
00767 
00768             /* Base the header on the first image in the input framelist */
00769 
00770             plist = vircam_fits_get_phu(ps.darks[0]);
00771             vircam_dfs_set_product_primary_header(plist,
00772                                                   product_frame_diffimg_stats,
00773                                                   framelist,parlist,
00774                                                   (char *)recipeid,
00775                                                   "PRO-1.15",NULL,0);
00776 
00777             /* Fiddle with the extension header now */
00778 
00779             elist = vircam_fits_get_ehu(ps.darks[0]);
00780             p = cpl_propertylist_duplicate(elist);
00781             vircam_merge_propertylists(p,ps.drs);
00782             if (! (we_get & STATS_TAB))
00783                 vircam_dummy_property(p);
00784             vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
00785                                                 framelist,parlist,
00786                                                 (char *)recipeid,
00787                                                 "PRO-1.15",NULL);
00788             status = VIR_OK;
00789             vircam_removewcs(p,&status);
00790 
00791             /* And finally save the difference image stats table */
00792 
00793             if (cpl_table_save(ps.diffimstats,plist,p,outdimst,
00794                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00795                 cpl_msg_error(fctid,"Cannot save product table extension");
00796                 cpl_frame_delete(product_frame_diffimg_stats);
00797                 cpl_propertylist_delete(p);
00798                 return(-1);
00799             }
00800             cpl_propertylist_delete(p);
00801             cpl_frameset_insert(framelist,product_frame_diffimg_stats);
00802         }
00803     }
00804 
00805     /* Get the extension property list */
00806 
00807     plist = vircam_fits_get_ehu(ps.darks[0]);
00808     cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
00809 
00810     /* Fiddle with the header now */
00811 
00812     vircam_merge_propertylists(plist,ps.drs);
00813     p = cpl_propertylist_duplicate(plist);
00814     if (! (we_get & MEANDARK))
00815         vircam_dummy_property(p);
00816     vircam_dfs_set_product_exten_header(p,product_frame_mean_dark,
00817                                         framelist,parlist,
00818                                         (char *)recipeid,"PRO-1.15",NULL);
00819                 
00820     /* Now save the mean dark image extension */
00821 
00822     cpl_propertylist_update_float(p,"ESO QC DARKMED",
00823                                   vircam_dark_combine_config.darkmed);
00824     cpl_propertylist_set_comment(p,"ESO QC DARKMED",
00825                                  "Median of mean dark frame");
00826     cpl_propertylist_update_float(p,"ESO QC DARKRMS",
00827                                   vircam_dark_combine_config.darkrms);
00828     cpl_propertylist_set_comment(p,"ESO QC DARKRMS",
00829                                  "RMS of mean dark frame");
00830     cpl_propertylist_update_float(p,"ESO QC PARTICLE_RATE",
00831                                   vircam_dark_combine_config.particle_rate);
00832     cpl_propertylist_set_comment(p,"ESO QC PARTICLE_RATE",
00833                                  "[N/(detector*sec)] Particle rate");
00834     cpl_propertylist_update_float(p,"ESO QC STRIPERMS",
00835                                   vircam_dark_combine_config.striperms);
00836     cpl_propertylist_set_comment(p,"ESO QC STRIPERMS","RMS of stripe pattern");
00837     cpl_propertylist_update_int(p,"ESO QC NHOTPIX",
00838                                 vircam_dark_combine_config.nhot);
00839     cpl_propertylist_set_comment(p,"ESO QC NHOTPIX","Number of hot pixels");
00840     cpl_propertylist_update_float(p,"ESO QC HOTFRAC",
00841                                   vircam_dark_combine_config.hotfrac);
00842     cpl_propertylist_set_comment(p,"ESO QC HOTFRAC","Hot pixel fraction");
00843     cpl_propertylist_update_float(p,"ESO QC RON12",
00844                                   vircam_dark_combine_config.ron12);
00845     cpl_propertylist_set_comment(p,"ESO QC RON12",
00846                                  "[ADU] Estimate of readnoise + stripe RMS");
00847     if (cpl_image_save(ps.outimage,outfile,CPL_BPP_IEEE_FLOAT,p,
00848                        CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00849         cpl_msg_error(fctid,"Cannot save product image extension");
00850         cpl_propertylist_delete(p);
00851         return(-1);
00852     }
00853 
00854     /* Write out PAF for mean image */
00855 
00856     pafprop = vircam_paf_req_items(p);
00857     vircam_merge_propertylists(pafprop,ps.phupaf);
00858     vircam_paf_append(pafprop,p,"ESO DET NDIT");
00859     vircam_paf_append(pafprop,p,"ESO PRO CATG");
00860     vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
00861     if (vircam_paf_print((char *)outfilepaf,"VIRCAM/vircam_dark_combine",
00862                          "QC file",pafprop) != VIR_OK)
00863         cpl_msg_warning(fctid,"Unable to save PAF for mean dark");
00864     cpl_propertylist_delete(pafprop);
00865     cpl_propertylist_delete(p);
00866 
00867     /* Now save the dark difference image extension */
00868 
00869     if (we_expect & DIFFIMG) {
00870         p = cpl_propertylist_duplicate(plist);
00871         if (! (we_get & DIFFIMG))
00872             vircam_dummy_property(p);;
00873         cpl_propertylist_update_float(p,"ESO QC DARKDIFF_MED",
00874                                       vircam_dark_combine_config.darkdiff_med);
00875         cpl_propertylist_set_comment(p,"ESO QC DARKDIFF_MED",
00876                                      "Median of dark difference image");
00877         cpl_propertylist_update_float(p,"ESO QC DARKDIFF_RMS",
00878                                       vircam_dark_combine_config.darkdiff_rms);
00879         cpl_propertylist_set_comment(p,"ESO QC DARKDIFF_RMS",
00880                                      "RMS of dark difference image");
00881         vircam_dfs_set_product_exten_header(p,product_frame_diffimg,
00882                                             framelist,parlist,
00883                                             (char *)recipeid,
00884                                             "PRO-1.15",NULL);
00885         if (cpl_image_save(ps.diffimg,outdiff,CPL_BPP_IEEE_FLOAT,p,
00886                            CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00887             cpl_msg_error(fctid,"Cannot save product image extension");
00888             cpl_propertylist_delete(p);
00889             return(-1);
00890         }
00891         
00892         /* Now write PAF for difference image */
00893 
00894         pafprop = vircam_paf_req_items(p);
00895         vircam_paf_append(pafprop,p,"ESO PRO CATG");
00896         vircam_merge_propertylists(pafprop,ps.phupaf);
00897         if (vircam_paf_print((char *)outdiffpaf,"VIRCAM/vircam_dark_combine",
00898                              "QC file",pafprop) != VIR_OK)
00899             cpl_msg_warning(fctid,"Unable to save PAF for difference image");
00900         cpl_propertylist_delete(pafprop);
00901         cpl_propertylist_delete(p);
00902     }
00903 
00904     /* Now any further difference image stats tables */
00905 
00906     if (! isfirst && (we_expect & STATS_TAB)) {
00907         p = cpl_propertylist_duplicate(plist);
00908         if (! (we_get & STATS_TAB))
00909             vircam_dummy_property(p);
00910         vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
00911                                             framelist,parlist,
00912                                             (char *)recipeid,
00913                                             "PRO-1.15",NULL);
00914         status = VIR_OK;
00915         vircam_removewcs(p,&status);
00916         if (cpl_table_save(ps.diffimstats,NULL,p,outdimst,CPL_IO_EXTEND)
00917                            != CPL_ERROR_NONE) {
00918             cpl_msg_error(fctid,"Cannot save product table extension");
00919             cpl_propertylist_delete(p);
00920             return(-1);
00921         }       
00922         cpl_propertylist_delete(p);
00923     }
00924 
00925     return(0);
00926 }
00927 
00928 /*---------------------------------------------------------------------------*/
00932 /*---------------------------------------------------------------------------*/
00933 
00934 static void vircam_dark_combine_dummy_products(void) {
00935 
00936     /* See if you even need to be here */
00937 
00938     if (we_get == we_expect)
00939         return;
00940 
00941     /* We always expect a mean frame. If we don't have one, then create
00942        a dummy */
00943 
00944     if (! (we_get & MEANDARK)) {
00945         ps.outimage = vircam_dummy_image(ps.darks[0]);
00946 
00947         /* Set up the QC parameters */
00948     
00949         vircam_dark_combine_config.particle_rate = 0.0;
00950         vircam_dark_combine_config.darkmed = 0.0;
00951         vircam_dark_combine_config.darkrms = 0.0;
00952         vircam_dark_combine_config.nhot = 0;
00953         vircam_dark_combine_config.hotfrac = 0.0;
00954         vircam_dark_combine_config.striperms = 0.0;
00955         vircam_dark_combine_config.ron12 = 0.0;
00956     }
00957 
00958     /* Do the difference image */
00959 
00960     if ((we_expect & DIFFIMG) && ! (we_get & DIFFIMG)) {
00961         vircam_dark_combine_config.darkdiff_med = 0.0;
00962         vircam_dark_combine_config.darkdiff_rms = 0.0;
00963         ps.diffimg = vircam_dummy_image(ps.darks[0]);
00964     }
00965 
00966     /* If a difference image stats table is required, then do that now */
00967 
00968     if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
00969         ps.diffimstats = vircam_create_diffimg_stats(0);
00970 
00971     return;
00972 }
00973 
00974 /*---------------------------------------------------------------------------*/
00978 /*---------------------------------------------------------------------------*/
00979 
00980 static void vircam_dark_combine_hotpix(void) {
00981     int i,nx,ny,status,nh,nhot,j;
00982     long npts;
00983     cpl_image *im;
00984     unsigned char *bpm;
00985     float med,mad,lowcut,highcut,*data;
00986     vir_fits *f;
00987 
00988     /* Get some workspace to hold the bad pixel mask */
00989 
00990     im = vircam_fits_get_image(ps.good[0]);
00991     nx = cpl_image_get_size_x(im);
00992     ny = cpl_image_get_size_y(im);
00993     npts = (long)(nx*ny);
00994     bpm = cpl_calloc(npts,sizeof(*bpm));
00995 
00996     /* Create a difference image for each of the good frames and
00997        destripe it. */
00998 
00999     for (i = 0; i < ps.ngood; i++) {
01000         f = vircam_fits_duplicate(ps.good[i]);
01001         im = vircam_fits_get_image(f);
01002         cpl_image_subtract(im,ps.outimage);
01003         status = VIR_OK;
01004         vircam_destripe(f,NULL,&status);
01005         if (i == 0) {
01006             vircam_dark_combine_config.striperms =
01007             cpl_propertylist_get_float(vircam_fits_get_ehu(f),
01008                                        "ESO DRS STRIPERMS");
01009         }
01010         
01011         /* Work out the stats of the difference image. Define a lower and
01012            upper cut. NB: a lower cut is needed since we are doing stats
01013            on a difference image and hot pixels will appear as either 
01014            bright or dark. Dead pixels will probably correct properly and
01015            hence shouldn't be flagged using this procedure. */
01016 
01017         data = cpl_image_get_data_float(im);
01018         vircam_medmad(data,NULL,npts,&med,&mad);
01019         lowcut = med - 1.48*mad*vircam_dark_combine_config.thresh;
01020         highcut = med + 1.48*mad*vircam_dark_combine_config.thresh;
01021         for (j = 0; j < npts; j++) 
01022             if (data[j] > highcut || data[j] < lowcut)
01023                 bpm[j] += 1;
01024 
01025         /* Get rid of temporary image */
01026 
01027         vircam_fits_delete(f);
01028     }
01029 
01030     /* Define a pixel as hot so long as it is discordant on at least half of 
01031        the frames */
01032 
01033     nh = (ps.ngood + 1)/2;
01034     nhot = 0;
01035     for (j = 0; j < npts; j++)
01036         if (bpm[j] >= nh)
01037             nhot++;
01038 
01039     /* Do a difference image of the first two darks and work out the RMS */
01040 
01041     im = cpl_image_subtract_create(vircam_fits_get_image(ps.good[0]),
01042                                    vircam_fits_get_image(ps.good[1]));
01043     data = cpl_image_get_data_float(im);
01044     vircam_medmad(data,bpm,npts,&med,&mad);
01045     mad *= 1.48/M_SQRT2;
01046     vircam_dark_combine_config.ron12 = mad;
01047     cpl_image_delete(im);
01048 
01049     /* Clean up... */
01050 
01051     cpl_free(bpm);
01052         
01053     /* Set QC parameters */
01054 
01055     vircam_dark_combine_config.nhot = nhot;
01056     vircam_dark_combine_config.hotfrac = (float)nhot/(float)npts;
01057 }
01058 
01059 
01060 /*---------------------------------------------------------------------------*/
01066 /*---------------------------------------------------------------------------*/
01067 
01068 static void vircam_dark_combine_normal(int jext, float exptime) {
01069     int nx,ny,ndiff,ncells;
01070     long npi,i;
01071     unsigned char *bpm;
01072     float med,sig,*idata,grms,gdiff;
01073     const char *fctid="vircam_dark_combine_normal";
01074     cpl_table *ctable;
01075     cpl_propertylist *p;
01076 
01077     /* Load up the bad pixel mask */
01078 
01079     nx = cpl_image_get_size_x(ps.outimage);
01080     ny = cpl_image_get_size_y(ps.outimage);
01081     npi = nx*ny;
01082     vircam_dark_combine_config.particle_rate = 0;
01083     bpm = vircam_mask_get_data(ps.master_mask);
01084 
01085     /* Now find out how many 'good' pixels were rejected for
01086        being too high during the combination phase */
01087 
01088     ndiff = 0;
01089     for (i = 0; i < npi; i++)
01090         if ((ps.rejplus)[i] > 0 && bpm[i] == 0)
01091             ndiff += (ps.rejplus)[i];
01092     vircam_dark_combine_config.particle_rate = 
01093         (float)ndiff/(exptime*(float)(ps.ndarks));
01094 
01095     /* Work out the RMS of the mean dark frame */
01096 
01097     idata = cpl_image_get_data(ps.outimage);
01098     vircam_medmad(idata,bpm,npi,&med,&sig);
01099     sig *= 1.48;
01100     vircam_dark_combine_config.darkmed = med;
01101     vircam_dark_combine_config.darkrms = sig;
01102 
01103     /* Load up the master dark */
01104 
01105     if (ps.master_dark != NULL) {
01106         ps.mdimage = vircam_fits_load(ps.master_dark,CPL_TYPE_FLOAT,jext);
01107         if (ps.mdimage == NULL) 
01108             cpl_msg_info(fctid,"Master dark extension %d won't load",jext);
01109         else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mdimage))) {
01110             cpl_msg_info(fctid,"Master dark extension %d is a dummy!",jext);
01111             freefits(ps.mdimage);
01112         }
01113     } else 
01114         ps.mdimage = NULL;
01115 
01116     /* Load up the channel table */
01117 
01118     if (ps.chantab != NULL) {
01119         ctable = cpl_table_load(cpl_frame_get_filename(ps.chantab),jext,0);
01120         if (ctable == NULL) {
01121             cpl_error_reset();
01122             cpl_msg_info(fctid,"Channel table extension %d won't load",jext);
01123         } else if (vircam_chantab_verify(ctable) != VIR_OK) {
01124             cpl_msg_info(fctid,"Channel table extension %d has errors",jext);
01125             freetable(ctable);
01126         } else { 
01127             p = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),jext);
01128             if (vircam_is_dummy(p)) {
01129                 cpl_msg_info(fctid,"Channel table extensions %d is a dummy",
01130                              jext);
01131                 freetable(ctable);
01132             }
01133             freepropertylist(p);
01134         }
01135     } else 
01136         ctable = NULL;
01137 
01138     /* Form the difference image. NB: the difference image routine
01139        copes if the input mean image and or the channel tables are
01140        null. Thus if either or both are null because of a failure
01141        to load then the routine will do as much as it can and return
01142        allowing you to fill in the rest with dummy products */
01143 
01144     vircam_dark_combine_config.darkdiff_med = 0.0;
01145     vircam_dark_combine_config.darkdiff_rms = 0.0;
01146     ncells = vircam_dark_combine_config.ncells;
01147     vircam_difference_image(vircam_fits_get_image(ps.mdimage),
01148                             ps.outimage,bpm,ctable,ncells,1,
01149                             &gdiff,&grms,&(ps.diffimg),
01150                             &(ps.diffimstats));
01151     vircam_mask_clear(ps.master_mask);
01152     vircam_dark_combine_config.darkdiff_med = gdiff;
01153     vircam_dark_combine_config.darkdiff_rms = grms;
01154     freetable(ctable);
01155     if (ps.diffimg != NULL)
01156         we_get |= DIFFIMG;
01157     if (ps.diffimstats != NULL)
01158         we_get |= STATS_TAB;
01159     return;
01160 }
01161 
01162 /*---------------------------------------------------------------------------*/
01170 /*---------------------------------------------------------------------------*/
01171 
01172 static int vircam_dark_combine_lastbit(int jext, cpl_frameset *framelist,
01173                                        cpl_parameterlist *parlist) {
01174     int retval;
01175     const char *fctid="vircam_dark_combine_lastbit";
01176 
01177     /* Make whatever dummy products you need */
01178 
01179     vircam_dark_combine_dummy_products();
01180 
01181     /* Save everything */
01182 
01183     cpl_msg_info(fctid,"Saving products for extension %d",jext);
01184     retval = vircam_dark_combine_save(framelist,parlist);
01185     if (retval != 0) {
01186         vircam_dark_combine_tidy(2);
01187         return(-1);
01188     }
01189 
01190     /* Free some stuff up */
01191 
01192     vircam_dark_combine_tidy(1);
01193     return(0);
01194 }
01195 
01196 /*---------------------------------------------------------------------------*/
01200 /*---------------------------------------------------------------------------*/
01201 
01202 static void vircam_dark_combine_init(void) {
01203     ps.labels = NULL;
01204     ps.darklist = NULL;
01205     ps.darks = NULL;
01206     ps.ndarks = 0;
01207     ps.good = NULL;
01208     ps.ngood = 0;
01209     ps.master_dark = NULL;
01210     ps.master_mask = NULL;
01211     ps.chantab = NULL;
01212     ps.outimage = NULL;
01213     ps.drs = NULL;
01214     ps.rejmask = NULL;
01215     ps.rejplus = NULL;
01216     ps.mdimage = NULL;
01217     ps.diffimg = NULL;
01218     ps.diffimstats = NULL;
01219     ps.phupaf = NULL;
01220     we_expect = 0;
01221     we_get = 0;
01222 }
01223 
01224 /*---------------------------------------------------------------------------*/
01228 /*---------------------------------------------------------------------------*/
01229 
01230 static void vircam_dark_combine_tidy(int level) {
01231 
01232     freeimage(ps.outimage);
01233     freefitslist(ps.darks,ps.ndarks);
01234     freepropertylist(ps.drs);
01235     freefits(ps.mdimage);
01236     freeimage(ps.diffimg);
01237     freetable(ps.diffimstats);
01238     freespace(ps.rejmask);
01239     freespace(ps.rejplus);
01240     if (level == 1)
01241         return;
01242     freespace(ps.labels);
01243     freeframeset(ps.darklist);
01244     freespace(ps.good);
01245     freeframe(ps.master_dark);
01246     freemask(ps.master_mask);
01247     freeframe(ps.chantab);
01248     freepropertylist(ps.phupaf);
01249 }
01250 
01253 /*
01254 
01255 $Log: vircam_dark_combine.c,v $
01256 Revision 1.67  2010/09/10 11:25:39  jim
01257 Removed some unnecessary declarations
01258 
01259 Revision 1.66  2010/09/09 12:14:05  jim
01260 Does a difference image of the first two darks to get an estimate of the
01261 readnoise in ADU. Also estimates stripe RMS from the difference image
01262 
01263 Revision 1.65  2010/03/21 06:48:21  jim
01264 Fixed bug where DATANCOM wasn't being updated in all products
01265 
01266 Revision 1.64  2010/03/09 14:27:40  jim
01267 Now updates ESO PRO DATANCOM to reflect the number of images used
01268 
01269 Revision 1.63  2010/02/05 09:42:22  jim
01270 Fixed call to non-existent cpl routine
01271 
01272 Revision 1.62  2010/01/31 18:52:43  jim
01273 Reference dark image written to paf
01274 
01275 Revision 1.61  2009/09/09 09:50:21  jim
01276 Modified to try and get headers right
01277 
01278 Revision 1.60  2008/12/05 13:28:32  jim
01279 Fixed save routine so that the correct version of PRO CATG is written to the
01280 paf file
01281 
01282 Revision 1.59  2008/10/01 04:59:13  jim
01283 Added call to vircam_frameset_fexists to check input frameset
01284 
01285 Revision 1.58  2008/09/30 11:33:23  jim
01286 Added PRO CATG to pafs
01287 
01288 Revision 1.57  2007/10/19 09:25:09  jim
01289 Fixed problems with missing includes
01290 
01291 Revision 1.56  2007/10/15 12:53:26  jim
01292 Modified for compatibiliity with cpl_4.0
01293 
01294 Revision 1.55  2007/07/18 15:35:41  jim
01295 Added better error handling for missing or corrupt mask extensions
01296 
01297 Revision 1.54  2007/07/09 13:21:37  jim
01298 Modified to use new vircam_exten_range and to fix comment on particle_rate
01299 QC parameter
01300 
01301 Revision 1.53  2007/04/30 09:40:17  jim
01302 Added more stuff to paf files
01303 
01304 Revision 1.52  2007/04/04 10:36:18  jim
01305 Modified to use new dfs tags
01306 
01307 Revision 1.51  2007/03/29 12:19:38  jim
01308 Little changes to improve documentation
01309 
01310 Revision 1.50  2007/03/02 12:37:16  jim
01311 Removed WCS stuff from table headers
01312 
01313 Revision 1.49  2007/03/01 12:41:48  jim
01314 Modified slightly after code checking
01315 
01316 Revision 1.48  2007/02/25 06:26:35  jim
01317 Plugged a few memory leaks
01318 
01319 Revision 1.47  2007/02/19 10:03:02  jim
01320 Fixed small memory leak
01321 
01322 Revision 1.46  2007/02/15 12:17:33  jim
01323 Fixed typo
01324 
01325 Revision 1.45  2007/02/15 11:54:09  jim
01326 Modified to make a distinction between initial channel table and one that
01327 has the proper linearity information
01328 
01329 Revision 1.44  2007/02/15 06:59:37  jim
01330 Added ability to write QC paf files
01331 
01332 Revision 1.43  2007/02/09 14:49:05  jim
01333 Added QC parameter NHOTPIX and HOTFRAC and routine vircam_dark_combine_hotpix
01334 
01335 Revision 1.42  2007/02/07 10:12:39  jim
01336 Removed calls to vircam_ndit_correct as this is now no longer necessary
01337 
01338 Revision 1.41  2007/02/06 13:11:11  jim
01339 Fixed entry for PRO dictionary in cpl_dfs_set_product_header
01340 
01341 Revision 1.40  2007/02/05 14:14:05  jim
01342 Input master frame is now tagged as REFERENCE. QC removed from stats table
01343 headers
01344 
01345 Revision 1.39  2006/12/13 13:14:38  jim
01346 Fixed badly scaled sigma
01347 
01348 Revision 1.38  2006/12/12 11:30:13  jim
01349 Added QC STRIPERMS calculation
01350 
01351 Revision 1.37  2006/11/27 12:13:21  jim
01352 Swapped calls to cpl_propertylist_append to cpl_propertylist_update
01353 
01354 Revision 1.36  2006/09/29 11:19:30  jim
01355 changed aliases on parameter names
01356 
01357 Revision 1.35  2006/09/09 16:49:39  jim
01358 Header comment update
01359 
01360 Revision 1.34  2006/08/27 20:30:02  jim
01361 Major mods to structure of the main processing routine to deal with missing
01362 and dummy frames. Deals better with lower level failures too
01363 
01364 Revision 1.33  2006/06/20 19:07:00  jim
01365 Corrects for ndit != 1
01366 
01367 Revision 1.32  2006/06/15 09:58:57  jim
01368 Minor changes to docs
01369 
01370 Revision 1.31  2006/06/06 13:01:39  jim
01371 Fixed so that the QC parameters go into the correct headers
01372 
01373 Revision 1.30  2006/05/17 14:43:58  jim
01374 Fixed problem in save routine which messed up the PRO CATG keywords
01375 
01376 Revision 1.29  2006/05/16 13:58:47  jim
01377 Fixed memory leaks that occur from not closing images at the end of
01378 the image extension loop
01379 
01380 Revision 1.28  2006/05/04 11:53:14  jim
01381 Fixed the way the _save routine works to be more consistent with the
01382 standard CPL way of doing things
01383 
01384 Revision 1.27  2006/04/27 09:46:01  jim
01385 Modified DFS frame types to conform to new dictionary
01386 
01387 Revision 1.26  2006/04/25 13:45:56  jim
01388 Fixed to adhere to new calling sequence for vircam_dfs routines
01389 
01390 Revision 1.25  2006/04/24 13:46:35  jim
01391 A bit more error trapping in case fits structures can't be loaded
01392 
01393 Revision 1.24  2006/03/22 12:13:51  jim
01394 Modified to use new vircam_mask capability
01395 
01396 Revision 1.23  2006/03/15 10:43:40  jim
01397 Fixed a few things
01398 
01399 Revision 1.22  2006/03/08 14:32:35  jim
01400 Lots of little mods
01401 
01402 Revision 1.21  2006/03/03 14:29:06  jim
01403 Now calls routines with vir_fits.
01404 
01405 Revision 1.19  2006/02/27 14:05:07  jim
01406 Fixed screwup
01407 
01408 Revision 1.18  2006/02/27 13:51:17  jim
01409 new routine
01410 
01411 Revision 1.17  2006/02/22 10:01:38  jim
01412 Modified to use new version of vircam_imcombine
01413 
01414 Revision 1.16  2006/02/18 11:50:43  jim
01415 Modified the way the dfs product keywords are written using the vircam
01416 routines, rather than the cpl routine that doesn't understand image
01417 extensions
01418 
01419 Revision 1.15  2006/01/23 10:35:21  jim
01420 Now allows both BPM or CPM to be used for masking
01421 
01422 Revision 1.14  2005/12/14 22:19:11  jim
01423 fixed docs
01424 
01425 Revision 1.13  2005/12/12 14:16:20  jim
01426 Fixed typo that caused compilation error
01427 
01428 Revision 1.12  2005/12/09 09:47:57  jim
01429 Many changes to add more documentation
01430 
01431 Revision 1.11  2005/12/02 10:45:37  jim
01432 The tags used in the sof are now written to the description string in the
01433 constructor. This is so that if they change in the vircam_dfs.h file, they
01434 aren't then hardcopied into each of the recipes...
01435 
01436 Revision 1.10  2005/12/01 16:25:48  jim
01437 Made the routine a bit more forgiving if certain master calibration files
01438 were missing. Now does as much as it can with the info it has
01439 
01440 Revision 1.9  2005/11/25 09:56:14  jim
01441 Tidied up some more documentation
01442 
01443 Revision 1.8  2005/11/23 14:57:40  jim
01444 A bit of tidying in response to splint messages
01445 
01446 Revision 1.7  2005/11/08 12:47:44  jim
01447 Made garbage collection a little better
01448 
01449 Revision 1.6  2005/11/07 13:14:41  jim
01450 Added better garbage collection and fixed a few bugs
01451 
01452 Revision 1.5  2005/11/03 15:16:28  jim
01453 Lots of changes mainly to strengthen error reporting
01454 
01455 Revision 1.4  2005/10/14 13:22:12  jim
01456 Added lots of QC checking and diagnostics, so it pretty much does what the
01457 docs say it should
01458 
01459 Revision 1.3  2005/09/20 15:07:45  jim
01460 Fixed a few bugs and added a few things
01461 
01462 Revision 1.2  2005/08/09 10:24:37  jim
01463 Replaced dodgy calls to cpl_msg_err with correct cpl_msg_error
01464 
01465 Revision 1.1.1.1  2005/08/05 08:29:09  jim
01466 Initial import
01467 
01468 
01469 */

Generated on 7 Feb 2011 for VIRCAM Pipeline by  doxygen 1.6.1