vircam_dark_combine.c

00001 /* $Id: vircam_dark_combine.c,v 1.70 2012/01/16 12:32:17 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: 2012/01/16 12:32:17 $
00024  * $Revision: 1.70 $
00025  * $Name: vcam-1_3_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     cpl_size          *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 j,jst,jfn,retval,status,live,nx,ny;
00462     cpl_size nlab;
00463     long i;
00464     float exptime;
00465     vir_fits *ff;
00466     cpl_parameter *p;
00467     cpl_propertylist *plist;
00468 
00469     /* Check validity of input frameset */
00470 
00471     if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00472         cpl_msg_error(fctid,"Input framelist NULL or has no input data");
00473         return(-1);
00474     }
00475 
00476     /* Check the files in the frameset */
00477 
00478     if (vircam_frameset_fexists(framelist) != VIR_OK) {
00479         cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00480         return(-1);
00481     }
00482 
00483     /* Initialise some things */
00484 
00485     vircam_dark_combine_init();
00486     we_expect |= MEANDARK;
00487 
00488     /* Get the parameters */
00489 
00490     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.combtype");
00491     vircam_dark_combine_config.combtype = cpl_parameter_get_int(p);
00492     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.scaletype");
00493     vircam_dark_combine_config.scaletype = cpl_parameter_get_int(p);
00494     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.xrej");
00495     vircam_dark_combine_config.xrej = cpl_parameter_get_bool(p);
00496     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.thresh");
00497     vircam_dark_combine_config.thresh = (float)cpl_parameter_get_double(p);
00498     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.ncells");
00499     vircam_dark_combine_config.ncells = cpl_parameter_get_int(p);
00500     p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.extenum");
00501     vircam_dark_combine_config.extenum = cpl_parameter_get_int(p);
00502 
00503     /* Sort out raw from calib frames */
00504 
00505     if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00506         cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00507         vircam_dark_combine_tidy(2);
00508         return(-1);
00509     }
00510 
00511     /* Get a list of the frame labels */ 
00512 
00513     if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00514                                            &nlab)) == NULL) {
00515         cpl_msg_error(fctid,"Cannot labelise the input frames");
00516         vircam_dark_combine_tidy(2);
00517         return(-1);
00518     }
00519 
00520     /* Get the dark frames */
00521 
00522     if ((ps.darklist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00523                                                 VIRCAM_DARK_RAW)) == NULL) {
00524         cpl_msg_error(fctid,"Cannot find dark frames in input frameset");
00525         vircam_dark_combine_tidy(2);
00526         return(-1);
00527     }
00528     ps.ndarks = cpl_frameset_get_size(ps.darklist);
00529 
00530     /* Get the exposure time from the first dark frame in the list */
00531 
00532     fname = cpl_frame_get_filename(cpl_frameset_get_first(ps.darklist));
00533     plist = cpl_propertylist_load(fname,0);
00534     if (vircam_pfits_get_exptime(plist,&exptime) != VIR_OK) {
00535         cpl_msg_warning(fctid,"Unable to get exposure time for %s",fname);
00536         exptime = 1.0;
00537     }
00538     cpl_propertylist_delete(plist);
00539 
00540     /* Check to see if there is a master dark frame */
00541 
00542     if ((ps.master_dark = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00543                                                      VIRCAM_REF_DARK)) == NULL)
00544         cpl_msg_info(fctid,"No master dark found -- no difference image will be formed");
00545     else
00546         we_expect |= DIFFIMG;
00547         
00548     /* Check to see if there is a master bad pixel map. If there isn't one 
00549        then look for a confidence map */
00550 
00551     ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00552 
00553     /* Check to see if there is a channel table */
00554 
00555     if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00556                                                  VIRCAM_CAL_CHANTAB)) == NULL) {
00557         if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00558                                                      VIRCAM_CAL_CHANTAB_INIT)) == NULL)
00559             cpl_msg_info(fctid,"No channel table found -- no difference image stats will be done");
00560     } else if (we_expect & DIFFIMG)
00561         we_expect |= STATS_TAB;
00562 
00563     /* Now, how many image extensions do we want to do? If the extension
00564        number is zero, then we loop for all possible extensions. If it
00565        isn't then we just do the extension specified */
00566 
00567     vircam_exten_range(vircam_dark_combine_config.extenum,
00568                        (const cpl_frame *)cpl_frameset_get_frame(ps.darklist,0),
00569                        &jst,&jfn);
00570     if (jst == -1 || jfn == -1) {
00571         cpl_msg_error(fctid,"Unable to continue");
00572         vircam_dark_combine_tidy(2);
00573         return(-1);
00574     }
00575 
00576     /* Get some space for the good frames */
00577 
00578     ps.good = cpl_malloc(ps.ndarks*sizeof(vir_fits *));
00579 
00580     /* Now loop for all the extension... */
00581 
00582     for (j = jst; j <= jfn; j++) {
00583         status = VIR_OK;
00584         we_get = 0;
00585         isfirst = (j == jst);
00586 
00587         /* Load up the images. If they won't load then signal a major error,
00588            create some dummy products and save them. */
00589 
00590         ps.darks = vircam_fits_load_list(ps.darklist,CPL_TYPE_FLOAT,j);
00591         if (ps.darks == NULL) {
00592             cpl_msg_info(fctid,
00593                          "Extension %" CPL_SIZE_FORMAT " darks wouldn't load",
00594                          (cpl_size)j);
00595             retval = vircam_dark_combine_lastbit(j,framelist,parlist);
00596             if (retval != 0) 
00597                 return(-1);
00598             continue;
00599         }
00600 
00601         /* Are any of these dark frames good? */
00602 
00603         ps.ngood = 0;
00604         for (i = 0; i < ps.ndarks; i++) {
00605             ff = ps.darks[i];
00606             vircam_pfits_get_detlive(vircam_fits_get_ehu(ff),&live);
00607             if (! live) {
00608                 cpl_msg_info(fctid,"Detector flagged dead %s",
00609                              vircam_fits_get_fullname(ff));
00610                 vircam_fits_set_error(ff,VIR_FATAL);
00611             } else {
00612                 ps.good[ps.ngood] = ff;
00613                 ps.ngood += 1;
00614             }
00615         }       
00616 
00617         /* If there are no good images, then signal that we need to 
00618            create some dummy products and move on */
00619 
00620         if (ps.ngood == 0) {
00621             cpl_msg_info(fctid,"All images flagged bad for this extension");
00622             retval = vircam_dark_combine_lastbit(j,framelist,parlist);
00623             if (retval != 0) 
00624                 return(-1);
00625             continue;
00626         }
00627         
00628         /* Load the master mask extension */
00629 
00630         nx = (int)cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
00631         ny = (int)cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
00632         retval = vircam_mask_load(ps.master_mask,j,nx,ny);
00633         if (retval == VIR_FATAL) {
00634             cpl_msg_info(fctid,
00635                          "Unable to load mask image %s[%" CPL_SIZE_FORMAT "]",
00636                          vircam_mask_get_filename(ps.master_mask),(cpl_size)j);
00637             cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00638             vircam_mask_force(ps.master_mask,nx,ny);
00639         }
00640             
00641         /* Call the combine module. If it fails, then signal that
00642            all products will be dummies */
00643 
00644         cpl_msg_info(fctid,"Doing combination for extension %" CPL_SIZE_FORMAT,
00645                      (cpl_size)j);
00646         (void)vircam_imcombine(ps.good,ps.ngood,
00647                                vircam_dark_combine_config.combtype,
00648                                vircam_dark_combine_config.scaletype,
00649                                vircam_dark_combine_config.xrej,
00650                                vircam_dark_combine_config.thresh,
00651                                &(ps.outimage),&(ps.rejmask),
00652                                &(ps.rejplus),&(ps.drs),&status);
00653         if (status == VIR_OK) {
00654             we_get |= MEANDARK;
00655             vircam_dark_combine_hotpix();
00656             vircam_dark_combine_normal(j,exptime);
00657         } 
00658 
00659         /* Create any dummies and save the products */
00660 
00661         retval = vircam_dark_combine_lastbit(j,framelist,parlist);
00662         if (retval != 0) 
00663             return(-1);
00664     }
00665     vircam_dark_combine_tidy(2);
00666     return(0);
00667 }
00668 
00669 
00670 /*---------------------------------------------------------------------------*/
00677 /*---------------------------------------------------------------------------*/
00678 
00679 static int vircam_dark_combine_save(cpl_frameset *framelist, 
00680                                     cpl_parameterlist *parlist) {
00681     cpl_propertylist *plist,*elist,*p,*pafprop;
00682     int status;
00683     const char *fctid = "vircam_dark_combine_save";
00684     const char *outfile = "darkcomb.fits";
00685     const char *outdiff = "darkdiff.fits";
00686     const char *outdimst = "darkdifftab.fits";
00687     const char *outfilepaf = "darkcomb";
00688     const char *outdiffpaf = "darkdiff";
00689     const char *recipeid = "vircam_dark_combine";
00690 
00691     /* If we need to make a PHU then do that now. */
00692 
00693     if (isfirst) {
00694 
00695         /* Create a new product frame object and define some tags */
00696 
00697         product_frame_mean_dark = cpl_frame_new();
00698         cpl_frame_set_filename(product_frame_mean_dark,outfile);
00699         cpl_frame_set_tag(product_frame_mean_dark,VIRCAM_PRO_DARK);
00700         cpl_frame_set_type(product_frame_mean_dark,CPL_FRAME_TYPE_IMAGE);
00701         cpl_frame_set_group(product_frame_mean_dark,CPL_FRAME_GROUP_PRODUCT);
00702         cpl_frame_set_level(product_frame_mean_dark,CPL_FRAME_LEVEL_FINAL);
00703 
00704         /* Base the header on the first image in the input framelist */
00705 
00706         plist = vircam_fits_get_phu(ps.darks[0]);
00707         ps.phupaf = vircam_paf_phu_items(plist);
00708         if (ps.master_dark != NULL) {
00709             cpl_propertylist_update_string(ps.phupaf,"REF_DARK",
00710                                            cpl_frame_get_filename(ps.master_dark));
00711             cpl_propertylist_set_comment(ps.phupaf,"REF_DARK",
00712                                          "Reference dark used");
00713         }
00714         vircam_dfs_set_product_primary_header(plist,product_frame_mean_dark,
00715                                               framelist,parlist,
00716                                               (char *)recipeid,"PRO-1.15",
00717                                               NULL,0);
00718 
00719         /* 'Save' the PHU image */                       
00720 
00721         if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
00722                            CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00723             cpl_msg_error(fctid,"Cannot save product PHU");
00724             cpl_frame_delete(product_frame_mean_dark);
00725             return(-1);
00726         }
00727         cpl_frameset_insert(framelist,product_frame_mean_dark);
00728 
00729         /* Create a new product frame object for the difference image */
00730 
00731         if (we_expect & DIFFIMG) {
00732             product_frame_diffimg = cpl_frame_new();
00733             cpl_frame_set_filename(product_frame_diffimg,outdiff);
00734             cpl_frame_set_tag(product_frame_diffimg,VIRCAM_PRO_DIFFIMG_DARK);
00735             cpl_frame_set_type(product_frame_diffimg,CPL_FRAME_TYPE_IMAGE);
00736             cpl_frame_set_group(product_frame_diffimg,CPL_FRAME_GROUP_PRODUCT);
00737             cpl_frame_set_level(product_frame_diffimg,CPL_FRAME_LEVEL_FINAL);
00738 
00739             /* Base the header on the first image in the input framelist */
00740 
00741             plist = vircam_fits_get_phu(ps.darks[0]);
00742             vircam_dfs_set_product_primary_header(plist,product_frame_diffimg,
00743                                                   framelist,parlist,
00744                                                   (char *)recipeid,
00745                                                   "PRO-1.15",NULL,0);
00746 
00747             /* 'Save' the PHU image */                   
00748 
00749             if (cpl_image_save(NULL,outdiff,CPL_TYPE_UCHAR,plist,
00750                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00751                 cpl_msg_error(fctid,"Cannot save product PHU");
00752                 cpl_frame_delete(product_frame_diffimg);
00753                 return(-1);
00754             }
00755             cpl_frameset_insert(framelist,product_frame_diffimg);
00756         }
00757 
00758         /* Create a new product frame object for the difference image stats 
00759            table */
00760 
00761         if (we_expect & STATS_TAB) {
00762             product_frame_diffimg_stats = cpl_frame_new();
00763             cpl_frame_set_filename(product_frame_diffimg_stats,outdimst);
00764             cpl_frame_set_tag(product_frame_diffimg_stats,
00765                               VIRCAM_PRO_DIFFIMG_DARK_STATS);
00766             cpl_frame_set_type(product_frame_diffimg_stats,
00767                                CPL_FRAME_TYPE_TABLE);
00768             cpl_frame_set_group(product_frame_diffimg_stats,
00769                                 CPL_FRAME_GROUP_PRODUCT);
00770             cpl_frame_set_level(product_frame_diffimg_stats,
00771                                 CPL_FRAME_LEVEL_FINAL);
00772 
00773             /* Base the header on the first image in the input framelist */
00774 
00775             plist = vircam_fits_get_phu(ps.darks[0]);
00776             vircam_dfs_set_product_primary_header(plist,
00777                                                   product_frame_diffimg_stats,
00778                                                   framelist,parlist,
00779                                                   (char *)recipeid,
00780                                                   "PRO-1.15",NULL,0);
00781 
00782             /* Fiddle with the extension header now */
00783 
00784             elist = vircam_fits_get_ehu(ps.darks[0]);
00785             p = cpl_propertylist_duplicate(elist);
00786             vircam_merge_propertylists(p,ps.drs);
00787             if (! (we_get & STATS_TAB))
00788                 vircam_dummy_property(p);
00789             vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
00790                                                 framelist,parlist,
00791                                                 (char *)recipeid,
00792                                                 "PRO-1.15",NULL);
00793             status = VIR_OK;
00794             vircam_removewcs(p,&status);
00795 
00796             /* And finally save the difference image stats table */
00797 
00798             if (cpl_table_save(ps.diffimstats,plist,p,outdimst,
00799                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00800                 cpl_msg_error(fctid,"Cannot save product table extension");
00801                 cpl_frame_delete(product_frame_diffimg_stats);
00802                 cpl_propertylist_delete(p);
00803                 return(-1);
00804             }
00805             cpl_propertylist_delete(p);
00806             cpl_frameset_insert(framelist,product_frame_diffimg_stats);
00807         }
00808     }
00809 
00810     /* Get the extension property list */
00811 
00812     plist = vircam_fits_get_ehu(ps.darks[0]);
00813     cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
00814 
00815     /* Fiddle with the header now */
00816 
00817     vircam_merge_propertylists(plist,ps.drs);
00818     p = cpl_propertylist_duplicate(plist);
00819     if (! (we_get & MEANDARK))
00820         vircam_dummy_property(p);
00821     vircam_dfs_set_product_exten_header(p,product_frame_mean_dark,
00822                                         framelist,parlist,
00823                                         (char *)recipeid,"PRO-1.15",NULL);
00824                 
00825     /* Now save the mean dark image extension */
00826 
00827     cpl_propertylist_update_float(p,"ESO QC DARKMED",
00828                                   vircam_dark_combine_config.darkmed);
00829     cpl_propertylist_set_comment(p,"ESO QC DARKMED",
00830                                  "Median of mean dark frame");
00831     cpl_propertylist_update_float(p,"ESO QC DARKRMS",
00832                                   vircam_dark_combine_config.darkrms);
00833     cpl_propertylist_set_comment(p,"ESO QC DARKRMS",
00834                                  "RMS of mean dark frame");
00835     cpl_propertylist_update_float(p,"ESO QC PARTICLE_RATE",
00836                                   vircam_dark_combine_config.particle_rate);
00837     cpl_propertylist_set_comment(p,"ESO QC PARTICLE_RATE",
00838                                  "[N/(detector*sec)] Particle rate");
00839     cpl_propertylist_update_float(p,"ESO QC STRIPERMS",
00840                                   vircam_dark_combine_config.striperms);
00841     cpl_propertylist_set_comment(p,"ESO QC STRIPERMS","RMS of stripe pattern");
00842     cpl_propertylist_update_int(p,"ESO QC NHOTPIX",
00843                                 vircam_dark_combine_config.nhot);
00844     cpl_propertylist_set_comment(p,"ESO QC NHOTPIX","Number of hot pixels");
00845     cpl_propertylist_update_float(p,"ESO QC HOTFRAC",
00846                                   vircam_dark_combine_config.hotfrac);
00847     cpl_propertylist_set_comment(p,"ESO QC HOTFRAC","Hot pixel fraction");
00848     cpl_propertylist_update_float(p,"ESO QC RON12",
00849                                   vircam_dark_combine_config.ron12);
00850     cpl_propertylist_set_comment(p,"ESO QC RON12",
00851                                  "[ADU] Estimate of readnoise + stripe RMS");
00852     if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,p,
00853                        CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00854         cpl_msg_error(fctid,"Cannot save product image extension");
00855         cpl_propertylist_delete(p);
00856         return(-1);
00857     }
00858 
00859     /* Write out PAF for mean image */
00860 
00861     pafprop = vircam_paf_req_items(p);
00862     vircam_merge_propertylists(pafprop,ps.phupaf);
00863     vircam_paf_append(pafprop,p,"ESO DET NDIT");
00864     vircam_paf_append(pafprop,p,"ESO PRO CATG");
00865     vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
00866     if (vircam_paf_print((char *)outfilepaf,"VIRCAM/vircam_dark_combine",
00867                          "QC file",pafprop) != VIR_OK)
00868         cpl_msg_warning(fctid,"Unable to save PAF for mean dark");
00869     cpl_propertylist_delete(pafprop);
00870     cpl_propertylist_delete(p);
00871 
00872     /* Now save the dark difference image extension */
00873 
00874     if (we_expect & DIFFIMG) {
00875         p = cpl_propertylist_duplicate(plist);
00876         if (! (we_get & DIFFIMG))
00877             vircam_dummy_property(p);;
00878         cpl_propertylist_update_float(p,"ESO QC DARKDIFF_MED",
00879                                       vircam_dark_combine_config.darkdiff_med);
00880         cpl_propertylist_set_comment(p,"ESO QC DARKDIFF_MED",
00881                                      "Median of dark difference image");
00882         cpl_propertylist_update_float(p,"ESO QC DARKDIFF_RMS",
00883                                       vircam_dark_combine_config.darkdiff_rms);
00884         cpl_propertylist_set_comment(p,"ESO QC DARKDIFF_RMS",
00885                                      "RMS of dark difference image");
00886         vircam_dfs_set_product_exten_header(p,product_frame_diffimg,
00887                                             framelist,parlist,
00888                                             (char *)recipeid,
00889                                             "PRO-1.15",NULL);
00890         if (cpl_image_save(ps.diffimg,outdiff,CPL_TYPE_FLOAT,p,
00891                            CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00892             cpl_msg_error(fctid,"Cannot save product image extension");
00893             cpl_propertylist_delete(p);
00894             return(-1);
00895         }
00896         
00897         /* Now write PAF for difference image */
00898 
00899         pafprop = vircam_paf_req_items(p);
00900         vircam_paf_append(pafprop,p,"ESO PRO CATG");
00901         vircam_merge_propertylists(pafprop,ps.phupaf);
00902         if (vircam_paf_print((char *)outdiffpaf,"VIRCAM/vircam_dark_combine",
00903                              "QC file",pafprop) != VIR_OK)
00904             cpl_msg_warning(fctid,"Unable to save PAF for difference image");
00905         cpl_propertylist_delete(pafprop);
00906         cpl_propertylist_delete(p);
00907     }
00908 
00909     /* Now any further difference image stats tables */
00910 
00911     if (! isfirst && (we_expect & STATS_TAB)) {
00912         p = cpl_propertylist_duplicate(plist);
00913         if (! (we_get & STATS_TAB))
00914             vircam_dummy_property(p);
00915         vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
00916                                             framelist,parlist,
00917                                             (char *)recipeid,
00918                                             "PRO-1.15",NULL);
00919         status = VIR_OK;
00920         vircam_removewcs(p,&status);
00921         if (cpl_table_save(ps.diffimstats,NULL,p,outdimst,CPL_IO_EXTEND)
00922                            != CPL_ERROR_NONE) {
00923             cpl_msg_error(fctid,"Cannot save product table extension");
00924             cpl_propertylist_delete(p);
00925             return(-1);
00926         }       
00927         cpl_propertylist_delete(p);
00928     }
00929 
00930     return(0);
00931 }
00932 
00933 /*---------------------------------------------------------------------------*/
00937 /*---------------------------------------------------------------------------*/
00938 
00939 static void vircam_dark_combine_dummy_products(void) {
00940 
00941     /* See if you even need to be here */
00942 
00943     if (we_get == we_expect)
00944         return;
00945 
00946     /* We always expect a mean frame. If we don't have one, then create
00947        a dummy */
00948 
00949     if (! (we_get & MEANDARK)) {
00950         ps.outimage = vircam_dummy_image(ps.darks[0]);
00951 
00952         /* Set up the QC parameters */
00953     
00954         vircam_dark_combine_config.particle_rate = 0.0;
00955         vircam_dark_combine_config.darkmed = 0.0;
00956         vircam_dark_combine_config.darkrms = 0.0;
00957         vircam_dark_combine_config.nhot = 0;
00958         vircam_dark_combine_config.hotfrac = 0.0;
00959         vircam_dark_combine_config.striperms = 0.0;
00960         vircam_dark_combine_config.ron12 = 0.0;
00961     }
00962 
00963     /* Do the difference image */
00964 
00965     if ((we_expect & DIFFIMG) && ! (we_get & DIFFIMG)) {
00966         vircam_dark_combine_config.darkdiff_med = 0.0;
00967         vircam_dark_combine_config.darkdiff_rms = 0.0;
00968         ps.diffimg = vircam_dummy_image(ps.darks[0]);
00969     }
00970 
00971     /* If a difference image stats table is required, then do that now */
00972 
00973     if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
00974         ps.diffimstats = vircam_create_diffimg_stats(0);
00975 
00976     return;
00977 }
00978 
00979 /*---------------------------------------------------------------------------*/
00983 /*---------------------------------------------------------------------------*/
00984 
00985 static void vircam_dark_combine_hotpix(void) {
00986     int i,nx,ny,status,nh,nhot,j;
00987     long npts;
00988     cpl_image *im;
00989     unsigned char *bpm;
00990     float med,mad,lowcut,highcut,*data;
00991     vir_fits *f;
00992 
00993     /* Get some workspace to hold the bad pixel mask */
00994 
00995     im = vircam_fits_get_image(ps.good[0]);
00996     nx = (int)cpl_image_get_size_x(im);
00997     ny = (int)cpl_image_get_size_y(im);
00998     npts = (long)(nx*ny);
00999     bpm = cpl_calloc(npts,sizeof(*bpm));
01000 
01001     /* Create a difference image for each of the good frames and
01002        destripe it. */
01003 
01004     for (i = 0; i < ps.ngood; i++) {
01005         f = vircam_fits_duplicate(ps.good[i]);
01006         im = vircam_fits_get_image(f);
01007         cpl_image_subtract(im,ps.outimage);
01008         status = VIR_OK;
01009         vircam_destripe(f,NULL,&status);
01010         if (i == 0) {
01011             vircam_dark_combine_config.striperms =
01012             cpl_propertylist_get_float(vircam_fits_get_ehu(f),
01013                                        "ESO DRS STRIPERMS");
01014         }
01015         
01016         /* Work out the stats of the difference image. Define a lower and
01017            upper cut. NB: a lower cut is needed since we are doing stats
01018            on a difference image and hot pixels will appear as either 
01019            bright or dark. Dead pixels will probably correct properly and
01020            hence shouldn't be flagged using this procedure. */
01021 
01022         data = cpl_image_get_data_float(im);
01023         vircam_medmad(data,NULL,npts,&med,&mad);
01024         lowcut = med - 1.48*mad*vircam_dark_combine_config.thresh;
01025         highcut = med + 1.48*mad*vircam_dark_combine_config.thresh;
01026         for (j = 0; j < npts; j++) 
01027             if (data[j] > highcut || data[j] < lowcut)
01028                 bpm[j] += 1;
01029 
01030         /* Get rid of temporary image */
01031 
01032         vircam_fits_delete(f);
01033     }
01034 
01035     /* Define a pixel as hot so long as it is discordant on at least half of 
01036        the frames */
01037 
01038     nh = (ps.ngood + 1)/2;
01039     nhot = 0;
01040     for (j = 0; j < npts; j++)
01041         if (bpm[j] >= nh)
01042             nhot++;
01043 
01044     /* Do a difference image of the first two darks and work out the RMS */
01045 
01046     im = cpl_image_subtract_create(vircam_fits_get_image(ps.good[0]),
01047                                    vircam_fits_get_image(ps.good[1]));
01048     data = cpl_image_get_data_float(im);
01049     vircam_medmad(data,bpm,npts,&med,&mad);
01050     mad *= 1.48/CPL_MATH_SQRT2;
01051     vircam_dark_combine_config.ron12 = mad;
01052     cpl_image_delete(im);
01053 
01054     /* Clean up... */
01055 
01056     cpl_free(bpm);
01057         
01058     /* Set QC parameters */
01059 
01060     vircam_dark_combine_config.nhot = nhot;
01061     vircam_dark_combine_config.hotfrac = (float)nhot/(float)npts;
01062 }
01063 
01064 
01065 /*---------------------------------------------------------------------------*/
01071 /*---------------------------------------------------------------------------*/
01072 
01073 static void vircam_dark_combine_normal(int jext, float exptime) {
01074     int nx,ny,ndiff,ncells;
01075     long npi,i;
01076     unsigned char *bpm;
01077     float med,sig,*idata,grms,gdiff;
01078     const char *fctid="vircam_dark_combine_normal";
01079     cpl_table *ctable;
01080     cpl_propertylist *p;
01081 
01082     /* Load up the bad pixel mask */
01083 
01084     nx = (int)cpl_image_get_size_x(ps.outimage);
01085     ny = (int)cpl_image_get_size_y(ps.outimage);
01086     npi = nx*ny;
01087     vircam_dark_combine_config.particle_rate = 0;
01088     bpm = vircam_mask_get_data(ps.master_mask);
01089 
01090     /* Now find out how many 'good' pixels were rejected for
01091        being too high during the combination phase */
01092 
01093     ndiff = 0;
01094     for (i = 0; i < npi; i++)
01095         if ((ps.rejplus)[i] > 0 && bpm[i] == 0)
01096             ndiff += (ps.rejplus)[i];
01097     vircam_dark_combine_config.particle_rate = 
01098         (float)ndiff/(exptime*(float)(ps.ndarks));
01099 
01100     /* Work out the RMS of the mean dark frame */
01101 
01102     idata = cpl_image_get_data(ps.outimage);
01103     vircam_medmad(idata,bpm,npi,&med,&sig);
01104     sig *= 1.48;
01105     vircam_dark_combine_config.darkmed = med;
01106     vircam_dark_combine_config.darkrms = sig;
01107 
01108     /* Load up the master dark */
01109 
01110     if (ps.master_dark != NULL) {
01111         ps.mdimage = vircam_fits_load(ps.master_dark,CPL_TYPE_FLOAT,jext);
01112         if (ps.mdimage == NULL) 
01113             cpl_msg_info(fctid,
01114                          "Master dark extension %" CPL_SIZE_FORMAT " won't load",
01115                          (cpl_size)jext);
01116         else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mdimage))) {
01117             cpl_msg_info(fctid,
01118                          "Master dark extension %" CPL_SIZE_FORMAT " is a dummy!",
01119                          (cpl_size)jext);
01120             freefits(ps.mdimage);
01121         }
01122     } else 
01123         ps.mdimage = NULL;
01124 
01125     /* Load up the channel table */
01126 
01127     if (ps.chantab != NULL) {
01128         ctable = cpl_table_load(cpl_frame_get_filename(ps.chantab),jext,0);
01129         if (ctable == NULL) {
01130             cpl_error_reset();
01131             cpl_msg_info(fctid,
01132                          "Channel table extension %" CPL_SIZE_FORMAT " won't load",
01133                          (cpl_size)jext);
01134         } else if (vircam_chantab_verify(ctable) != VIR_OK) {
01135             cpl_msg_info(fctid,
01136                          "Channel table extension %" CPL_SIZE_FORMAT " has errors",
01137                          (cpl_size)jext);
01138             freetable(ctable);
01139         } else { 
01140             p = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
01141                                       (cpl_size)jext);
01142             if (vircam_is_dummy(p)) {
01143                 cpl_msg_info(fctid,
01144                              "Channel table extensions %" CPL_SIZE_FORMAT " is a dummy",
01145                              (cpl_size)jext);
01146                 freetable(ctable);
01147             }
01148             freepropertylist(p);
01149         }
01150     } else 
01151         ctable = NULL;
01152 
01153     /* Form the difference image. NB: the difference image routine
01154        copes if the input mean image and or the channel tables are
01155        null. Thus if either or both are null because of a failure
01156        to load then the routine will do as much as it can and return
01157        allowing you to fill in the rest with dummy products */
01158 
01159     vircam_dark_combine_config.darkdiff_med = 0.0;
01160     vircam_dark_combine_config.darkdiff_rms = 0.0;
01161     ncells = vircam_dark_combine_config.ncells;
01162     vircam_difference_image(vircam_fits_get_image(ps.mdimage),
01163                             ps.outimage,bpm,ctable,ncells,1,
01164                             &gdiff,&grms,&(ps.diffimg),
01165                             &(ps.diffimstats));
01166     vircam_mask_clear(ps.master_mask);
01167     vircam_dark_combine_config.darkdiff_med = gdiff;
01168     vircam_dark_combine_config.darkdiff_rms = grms;
01169     freetable(ctable);
01170     if (ps.diffimg != NULL)
01171         we_get |= DIFFIMG;
01172     if (ps.diffimstats != NULL)
01173         we_get |= STATS_TAB;
01174     return;
01175 }
01176 
01177 /*---------------------------------------------------------------------------*/
01185 /*---------------------------------------------------------------------------*/
01186 
01187 static int vircam_dark_combine_lastbit(int jext, cpl_frameset *framelist,
01188                                        cpl_parameterlist *parlist) {
01189     int retval;
01190     const char *fctid="vircam_dark_combine_lastbit";
01191 
01192     /* Make whatever dummy products you need */
01193 
01194     vircam_dark_combine_dummy_products();
01195 
01196     /* Save everything */
01197 
01198     cpl_msg_info(fctid,"Saving products for extension %" CPL_SIZE_FORMAT,
01199                  (cpl_size)jext);
01200     retval = vircam_dark_combine_save(framelist,parlist);
01201     if (retval != 0) {
01202         vircam_dark_combine_tidy(2);
01203         return(-1);
01204     }
01205 
01206     /* Free some stuff up */
01207 
01208     vircam_dark_combine_tidy(1);
01209     return(0);
01210 }
01211 
01212 /*---------------------------------------------------------------------------*/
01216 /*---------------------------------------------------------------------------*/
01217 
01218 static void vircam_dark_combine_init(void) {
01219     ps.labels = NULL;
01220     ps.darklist = NULL;
01221     ps.darks = NULL;
01222     ps.ndarks = 0;
01223     ps.good = NULL;
01224     ps.ngood = 0;
01225     ps.master_dark = NULL;
01226     ps.master_mask = NULL;
01227     ps.chantab = NULL;
01228     ps.outimage = NULL;
01229     ps.drs = NULL;
01230     ps.rejmask = NULL;
01231     ps.rejplus = NULL;
01232     ps.mdimage = NULL;
01233     ps.diffimg = NULL;
01234     ps.diffimstats = NULL;
01235     ps.phupaf = NULL;
01236     we_expect = 0;
01237     we_get = 0;
01238 }
01239 
01240 /*---------------------------------------------------------------------------*/
01244 /*---------------------------------------------------------------------------*/
01245 
01246 static void vircam_dark_combine_tidy(int level) {
01247 
01248     freeimage(ps.outimage);
01249     freefitslist(ps.darks,ps.ndarks);
01250     freepropertylist(ps.drs);
01251     freefits(ps.mdimage);
01252     freeimage(ps.diffimg);
01253     freetable(ps.diffimstats);
01254     freespace(ps.rejmask);
01255     freespace(ps.rejplus);
01256     if (level == 1)
01257         return;
01258     freespace(ps.labels);
01259     freeframeset(ps.darklist);
01260     freespace(ps.good);
01261     freeframe(ps.master_dark);
01262     freemask(ps.master_mask);
01263     freeframe(ps.chantab);
01264     freepropertylist(ps.phupaf);
01265 }
01266 
01269 /*
01270 
01271 $Log: vircam_dark_combine.c,v $
01272 Revision 1.70  2012/01/16 12:32:17  jim
01273 A few more changes to fit in with cpl6
01274 
01275 Revision 1.69  2012/01/15 17:40:09  jim
01276 Minor modifications to take into accout the changes in cpl API for v6
01277 
01278 Revision 1.68  2011/05/09 09:58:10  jim
01279 Cosmetic changes to stop compiler warnings
01280 
01281 Revision 1.67  2010/09/10 11:25:39  jim
01282 Removed some unnecessary declarations
01283 
01284 Revision 1.66  2010/09/09 12:14:05  jim
01285 Does a difference image of the first two darks to get an estimate of the
01286 readnoise in ADU. Also estimates stripe RMS from the difference image
01287 
01288 Revision 1.65  2010/03/21 06:48:21  jim
01289 Fixed bug where DATANCOM wasn't being updated in all products
01290 
01291 Revision 1.64  2010/03/09 14:27:40  jim
01292 Now updates ESO PRO DATANCOM to reflect the number of images used
01293 
01294 Revision 1.63  2010/02/05 09:42:22  jim
01295 Fixed call to non-existent cpl routine
01296 
01297 Revision 1.62  2010/01/31 18:52:43  jim
01298 Reference dark image written to paf
01299 
01300 Revision 1.61  2009/09/09 09:50:21  jim
01301 Modified to try and get headers right
01302 
01303 Revision 1.60  2008/12/05 13:28:32  jim
01304 Fixed save routine so that the correct version of PRO CATG is written to the
01305 paf file
01306 
01307 Revision 1.59  2008/10/01 04:59:13  jim
01308 Added call to vircam_frameset_fexists to check input frameset
01309 
01310 Revision 1.58  2008/09/30 11:33:23  jim
01311 Added PRO CATG to pafs
01312 
01313 Revision 1.57  2007/10/19 09:25:09  jim
01314 Fixed problems with missing includes
01315 
01316 Revision 1.56  2007/10/15 12:53:26  jim
01317 Modified for compatibiliity with cpl_4.0
01318 
01319 Revision 1.55  2007/07/18 15:35:41  jim
01320 Added better error handling for missing or corrupt mask extensions
01321 
01322 Revision 1.54  2007/07/09 13:21:37  jim
01323 Modified to use new vircam_exten_range and to fix comment on particle_rate
01324 QC parameter
01325 
01326 Revision 1.53  2007/04/30 09:40:17  jim
01327 Added more stuff to paf files
01328 
01329 Revision 1.52  2007/04/04 10:36:18  jim
01330 Modified to use new dfs tags
01331 
01332 Revision 1.51  2007/03/29 12:19:38  jim
01333 Little changes to improve documentation
01334 
01335 Revision 1.50  2007/03/02 12:37:16  jim
01336 Removed WCS stuff from table headers
01337 
01338 Revision 1.49  2007/03/01 12:41:48  jim
01339 Modified slightly after code checking
01340 
01341 Revision 1.48  2007/02/25 06:26:35  jim
01342 Plugged a few memory leaks
01343 
01344 Revision 1.47  2007/02/19 10:03:02  jim
01345 Fixed small memory leak
01346 
01347 Revision 1.46  2007/02/15 12:17:33  jim
01348 Fixed typo
01349 
01350 Revision 1.45  2007/02/15 11:54:09  jim
01351 Modified to make a distinction between initial channel table and one that
01352 has the proper linearity information
01353 
01354 Revision 1.44  2007/02/15 06:59:37  jim
01355 Added ability to write QC paf files
01356 
01357 Revision 1.43  2007/02/09 14:49:05  jim
01358 Added QC parameter NHOTPIX and HOTFRAC and routine vircam_dark_combine_hotpix
01359 
01360 Revision 1.42  2007/02/07 10:12:39  jim
01361 Removed calls to vircam_ndit_correct as this is now no longer necessary
01362 
01363 Revision 1.41  2007/02/06 13:11:11  jim
01364 Fixed entry for PRO dictionary in cpl_dfs_set_product_header
01365 
01366 Revision 1.40  2007/02/05 14:14:05  jim
01367 Input master frame is now tagged as REFERENCE. QC removed from stats table
01368 headers
01369 
01370 Revision 1.39  2006/12/13 13:14:38  jim
01371 Fixed badly scaled sigma
01372 
01373 Revision 1.38  2006/12/12 11:30:13  jim
01374 Added QC STRIPERMS calculation
01375 
01376 Revision 1.37  2006/11/27 12:13:21  jim
01377 Swapped calls to cpl_propertylist_append to cpl_propertylist_update
01378 
01379 Revision 1.36  2006/09/29 11:19:30  jim
01380 changed aliases on parameter names
01381 
01382 Revision 1.35  2006/09/09 16:49:39  jim
01383 Header comment update
01384 
01385 Revision 1.34  2006/08/27 20:30:02  jim
01386 Major mods to structure of the main processing routine to deal with missing
01387 and dummy frames. Deals better with lower level failures too
01388 
01389 Revision 1.33  2006/06/20 19:07:00  jim
01390 Corrects for ndit != 1
01391 
01392 Revision 1.32  2006/06/15 09:58:57  jim
01393 Minor changes to docs
01394 
01395 Revision 1.31  2006/06/06 13:01:39  jim
01396 Fixed so that the QC parameters go into the correct headers
01397 
01398 Revision 1.30  2006/05/17 14:43:58  jim
01399 Fixed problem in save routine which messed up the PRO CATG keywords
01400 
01401 Revision 1.29  2006/05/16 13:58:47  jim
01402 Fixed memory leaks that occur from not closing images at the end of
01403 the image extension loop
01404 
01405 Revision 1.28  2006/05/04 11:53:14  jim
01406 Fixed the way the _save routine works to be more consistent with the
01407 standard CPL way of doing things
01408 
01409 Revision 1.27  2006/04/27 09:46:01  jim
01410 Modified DFS frame types to conform to new dictionary
01411 
01412 Revision 1.26  2006/04/25 13:45:56  jim
01413 Fixed to adhere to new calling sequence for vircam_dfs routines
01414 
01415 Revision 1.25  2006/04/24 13:46:35  jim
01416 A bit more error trapping in case fits structures can't be loaded
01417 
01418 Revision 1.24  2006/03/22 12:13:51  jim
01419 Modified to use new vircam_mask capability
01420 
01421 Revision 1.23  2006/03/15 10:43:40  jim
01422 Fixed a few things
01423 
01424 Revision 1.22  2006/03/08 14:32:35  jim
01425 Lots of little mods
01426 
01427 Revision 1.21  2006/03/03 14:29:06  jim
01428 Now calls routines with vir_fits.
01429 
01430 Revision 1.19  2006/02/27 14:05:07  jim
01431 Fixed screwup
01432 
01433 Revision 1.18  2006/02/27 13:51:17  jim
01434 new routine
01435 
01436 Revision 1.17  2006/02/22 10:01:38  jim
01437 Modified to use new version of vircam_imcombine
01438 
01439 Revision 1.16  2006/02/18 11:50:43  jim
01440 Modified the way the dfs product keywords are written using the vircam
01441 routines, rather than the cpl routine that doesn't understand image
01442 extensions
01443 
01444 Revision 1.15  2006/01/23 10:35:21  jim
01445 Now allows both BPM or CPM to be used for masking
01446 
01447 Revision 1.14  2005/12/14 22:19:11  jim
01448 fixed docs
01449 
01450 Revision 1.13  2005/12/12 14:16:20  jim
01451 Fixed typo that caused compilation error
01452 
01453 Revision 1.12  2005/12/09 09:47:57  jim
01454 Many changes to add more documentation
01455 
01456 Revision 1.11  2005/12/02 10:45:37  jim
01457 The tags used in the sof are now written to the description string in the
01458 constructor. This is so that if they change in the vircam_dfs.h file, they
01459 aren't then hardcopied into each of the recipes...
01460 
01461 Revision 1.10  2005/12/01 16:25:48  jim
01462 Made the routine a bit more forgiving if certain master calibration files
01463 were missing. Now does as much as it can with the info it has
01464 
01465 Revision 1.9  2005/11/25 09:56:14  jim
01466 Tidied up some more documentation
01467 
01468 Revision 1.8  2005/11/23 14:57:40  jim
01469 A bit of tidying in response to splint messages
01470 
01471 Revision 1.7  2005/11/08 12:47:44  jim
01472 Made garbage collection a little better
01473 
01474 Revision 1.6  2005/11/07 13:14:41  jim
01475 Added better garbage collection and fixed a few bugs
01476 
01477 Revision 1.5  2005/11/03 15:16:28  jim
01478 Lots of changes mainly to strengthen error reporting
01479 
01480 Revision 1.4  2005/10/14 13:22:12  jim
01481 Added lots of QC checking and diagnostics, so it pretty much does what the
01482 docs say it should
01483 
01484 Revision 1.3  2005/09/20 15:07:45  jim
01485 Fixed a few bugs and added a few things
01486 
01487 Revision 1.2  2005/08/09 10:24:37  jim
01488 Replaced dodgy calls to cpl_msg_err with correct cpl_msg_error
01489 
01490 Revision 1.1.1.1  2005/08/05 08:29:09  jim
01491 Initial import
01492 
01493 
01494 */

Generated on 15 Mar 2012 for VIRCAM Pipeline by  doxygen 1.6.1