vircam_dark_combine.c

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

Generated on Wed Apr 10 04:01:55 2013 for VIRCAM Pipeline by  doxygen 1.5.1