vircam_twilight_flat_combine.c

00001 /* $Id: vircam_twilight_flat_combine.c,v 1.54 2010/12/09 13:21:36 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2010/12/09 13:21:36 $
00024  * $Revision: 1.54 $
00025  * $Name: v1-1-0 $
00026  */
00027 
00028 /* Includes */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 #include <stdio.h>
00035 #include <cpl.h>
00036 #include <math.h>
00037 
00038 #include "vircam_utils.h"
00039 #include "vircam_mask.h"
00040 #include "vircam_dfs.h"
00041 #include "vircam_mods.h"
00042 #include "vircam_stats.h"
00043 #include "vircam_fits.h"
00044 #include "vircam_pfits.h"
00045 #include "vircam_channel.h"
00046 #include "vircam_paf.h"
00047 #include "vircam_wcsutils.h"
00048 
00049 /* Define values for bit mask that flags dummy results */
00050 
00051 #define MEANTWI     1
00052 #define CONFMAP     2
00053 #define RATIMG      4
00054 #define STATS_TAB   8
00055 
00056 /* Function prototypes */
00057 
00058 static int vircam_twilight_flat_combine_create(cpl_plugin *) ;
00059 static int vircam_twilight_flat_combine_exec(cpl_plugin *) ;
00060 static int vircam_twilight_flat_combine_destroy(cpl_plugin *) ;
00061 static int vircam_twilight_flat_combine(cpl_parameterlist *, cpl_frameset *) ;
00062 static int vircam_twilight_flat_combine_save(cpl_frameset *framelist, 
00063                                              cpl_parameterlist *parlist);
00064 static void vircam_twilight_flat_combine_dummy_products(void);
00065 static void vircam_twilight_flat_combine_normal(int jext);
00066 static int vircam_twilight_flat_combine_lastbit(int jext, 
00067                                                 cpl_frameset *framelist,
00068                                                 cpl_parameterlist *parlist);
00069 static void vircam_twilight_flat_combine_init(void);
00070 static void vircam_twilight_flat_combine_tidy(int level);
00071 
00072 /* Static global variables */
00073 
00074 static struct {
00075 
00076     /* Input */
00077 
00078     float       lthr;
00079     float       hthr;
00080     int         combtype;
00081     int         scaletype;
00082     int         xrej;
00083     float       thresh;
00084     int         ncells;
00085     int         extenum;
00086 
00087     /* Output */
00088 
00089     float       flatrms;
00090     float       flatratio_med;
00091     float       flatratio_rms;
00092     float       minv;
00093     float       maxv;
00094     float       avev;
00095     float       photnoise;
00096     float       snratio;
00097 
00098 } vircam_twilight_flat_combine_config;
00099 
00100 
00101 static struct {
00102     vir_fits         **good;
00103     int              ngood;
00104     int              *labels;
00105     cpl_frameset     *twilightlist;
00106     cpl_frame        *master_dark;
00107     cpl_frame        *master_twilight_flat;
00108     vir_mask         *master_mask;
00109     cpl_frame        *chantab;
00110 
00111     cpl_image        *outimage;
00112     cpl_image        *outconf;
00113     vir_fits         **twilights;
00114     int              ntwilights;
00115     cpl_propertylist *drs;
00116     cpl_propertylist *drs2;
00117     unsigned char    *rejmask;
00118     unsigned char    *rejplus;
00119     vir_fits         *mfimage;
00120     cpl_image        *ratioimg;
00121     cpl_table        *ratioimstats;
00122     vir_tfits        *ctable;
00123     vir_fits         *mdark;
00124     cpl_propertylist *phupaf;
00125 } ps;
00126 
00127 static int isfirst;
00128 static cpl_frame *product_frame_mean_twi = NULL;
00129 static cpl_frame *product_frame_conf = NULL;
00130 static cpl_frame *product_frame_ratioimg = NULL;
00131 static cpl_frame *product_frame_ratioimg_stats = NULL;
00132 static int we_expect;
00133 static int we_get;
00134 
00135 static char vircam_twilight_flat_combine_description[] =
00136 "vircam_twilight_flat_combine -- VIRCAM twilight flat combine recipe.\n\n"
00137 "Combine a list of twilight flat frames into a mean frame. Optionally\n"
00138 "compare the output frame to a master twilight flat frame\n\n"
00139 "The program accepts the following files in the SOF:\n\n"
00140 "    Tag                   Description\n"
00141 "    -----------------------------------------------------------------------\n"
00142 "    %-21s A list of raw twilight flat images\n"
00143 "    %-21s A master dark frame\n"
00144 "    %-21s Optional reference twilight flat frame\n"
00145 "    %-21s Optional channel table or\n"
00146 "    %-21s Optional initial channel table\n"
00147 "    %-21s Optional master bad pixel map or\n"
00148 "    %-21s Optional master confidence map\n"
00149 "If no reference twilight flat is made available, then no comparison will be\n"
00150 "done. This means there will be no output ratio image. If a master twilight\n"
00151 "is available, but no channel table is, then a ratio image will be formed\n"
00152 "but no stats will be written."
00153 "\n";
00154 
00297 /* Function code */
00298 
00299 /*---------------------------------------------------------------------------*/
00307 /*---------------------------------------------------------------------------*/
00308 
00309 int cpl_plugin_get_info(cpl_pluginlist *list) {
00310     cpl_recipe  *recipe = cpl_calloc(1,sizeof(*recipe));
00311     cpl_plugin  *plugin = &recipe->interface;
00312     char alldesc[SZ_ALLDESC];
00313     (void)snprintf(alldesc,SZ_ALLDESC,vircam_twilight_flat_combine_description,
00314                    VIRCAM_TWI_RAW,VIRCAM_CAL_DARK,VIRCAM_REF_TWILIGHT_FLAT,
00315                    VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT,VIRCAM_CAL_BPM,
00316                    VIRCAM_CAL_CONF);
00317 
00318     cpl_plugin_init(plugin,
00319                     CPL_PLUGIN_API,
00320                     VIRCAM_BINARY_VERSION,
00321                     CPL_PLUGIN_TYPE_RECIPE,
00322                     "vircam_twilight_flat_combine",
00323                     "VIRCAM twilight combination recipe",
00324                     alldesc,
00325                     "Jim Lewis",
00326                     "jrl@ast.cam.ac.uk",
00327                     vircam_get_license(),
00328                     vircam_twilight_flat_combine_create,
00329                     vircam_twilight_flat_combine_exec,
00330                     vircam_twilight_flat_combine_destroy);
00331 
00332     cpl_pluginlist_append(list,plugin);
00333 
00334     return(0);
00335 }
00336 
00337 /*---------------------------------------------------------------------------*/
00346 /*---------------------------------------------------------------------------*/
00347 
00348 static int vircam_twilight_flat_combine_create(cpl_plugin *plugin) {
00349     cpl_recipe      *recipe;
00350     cpl_parameter   *p;
00351 
00352     /* Get the recipe out of the plugin */
00353 
00354     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00355         recipe = (cpl_recipe *)plugin;
00356     else 
00357         return(-1);
00358 
00359     /* Create the parameters list in the cpl_recipe object */
00360 
00361     recipe->parameters = cpl_parameterlist_new();
00362 
00363     /* Lower threshold for rejecting underexposed images */
00364 
00365     p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.lthr",
00366                                 CPL_TYPE_DOUBLE,
00367                                 "Low rejection threshold for underexpsed images",
00368                                 "vircam.vircam_twilight_flat_combine",
00369                                 4000.0);
00370     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"lthr");
00371     cpl_parameterlist_append(recipe->parameters,p);
00372 
00373     /* Upper threshold for rejecting overexposed images */
00374 
00375     p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.hthr",
00376                                 CPL_TYPE_DOUBLE,
00377                                 "High rejection threshold for overexposed images",
00378                                 "vircam.vircam_twilight_flat_combine",
00379                                 12000.0);
00380     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"hthr");
00381     cpl_parameterlist_append(recipe->parameters,p);
00382 
00383     /* Fill in the parameters. First the combination type */
00384 
00385     p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.combtype",
00386                                 CPL_TYPE_INT,
00387                                 "1 == Median,\n 2 == Mean",
00388                                 "vircam.vircam_twilight_flat_combine",
00389                                 1,1,2);
00390     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"combtype");
00391     cpl_parameterlist_append(recipe->parameters,p);
00392 
00393     /* The requested scaling */
00394 
00395     p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.scaletype",
00396                                 CPL_TYPE_INT,
00397                                 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
00398                                 "vircam.vircam_twilight_flat_combine",
00399                                 2,0,3);
00400     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scaletype");
00401     cpl_parameterlist_append(recipe->parameters,p);
00402     
00403     /* Extra rejection cycle */
00404 
00405     p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.xrej",
00406                                 CPL_TYPE_BOOL,
00407                                 "True if using extra rejection cycle",
00408                                 "vircam.vircam_twilight_flat_combine",
00409                                 TRUE);
00410     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
00411     cpl_parameterlist_append(recipe->parameters,p);
00412 
00413     /* Rejection threshold */
00414 
00415     p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.thresh",
00416                                 CPL_TYPE_DOUBLE,
00417                                 "Rejection threshold in sigma above background",
00418                                 "vircam.vircam_twilight_flat_combine",5.0);
00419     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
00420     cpl_parameterlist_append(recipe->parameters,p);
00421 
00422     /* How many cells to divide each data channel */
00423 
00424     p = cpl_parameter_new_enum("vircam.vircam_twilight_flat_combine.ncells",
00425                                CPL_TYPE_INT,
00426                                "Number of cells for data channel stats",
00427                                "vircam.vircam_twilight_flat_combine",8,7,1,2,4,
00428                                8,16,32,64);
00429     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ncells");
00430     cpl_parameterlist_append(recipe->parameters,p);     
00431 
00432     /* Extension number of input frames to use */
00433 
00434     p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.extenum",
00435                                 CPL_TYPE_INT,
00436                                 "Extension number to be done, 0 == all",
00437                                 "vircam.vircam_twilight_flat_combine",
00438                                 1,0,16);
00439     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
00440     cpl_parameterlist_append(recipe->parameters,p);
00441         
00442     /* Get out of here */
00443 
00444     return(0);
00445 }
00446     
00447     
00448 /*---------------------------------------------------------------------------*/
00454 /*---------------------------------------------------------------------------*/
00455 
00456 static int vircam_twilight_flat_combine_exec(cpl_plugin *plugin) {
00457     cpl_recipe  *recipe;
00458 
00459     /* Get the recipe out of the plugin */
00460 
00461     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00462         recipe = (cpl_recipe *)plugin;
00463     else 
00464         return(-1);
00465 
00466     return(vircam_twilight_flat_combine(recipe->parameters,recipe->frames));
00467 }
00468                                 
00469 /*---------------------------------------------------------------------------*/
00475 /*---------------------------------------------------------------------------*/
00476 
00477 static int vircam_twilight_flat_combine_destroy(cpl_plugin *plugin) {
00478     cpl_recipe *recipe ;
00479 
00480     /* Get the recipe out of the plugin */
00481 
00482     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00483         recipe = (cpl_recipe *)plugin;
00484     else 
00485         return(-1);
00486 
00487     cpl_parameterlist_delete(recipe->parameters);
00488     return(0);
00489 }
00490 
00491 /*---------------------------------------------------------------------------*/
00498 /*---------------------------------------------------------------------------*/
00499 
00500 static int vircam_twilight_flat_combine(cpl_parameterlist *parlist, 
00501                                         cpl_frameset *framelist) {
00502     const char *fctid="vircam_twilight_flat_combine";
00503     int nlab,j,jst,jfn,retval,status,live,nx,ny,ndit,npts;
00504     long i;
00505     cpl_parameter *p;
00506     vir_fits *ff;
00507     cpl_propertylist *pp;
00508     cpl_image *im1,*im2,*newim,*diffim;
00509     double val1,val2,scl;
00510     float *data,med,mad;
00511     unsigned char *bpm;
00512 
00513     /* Check validity of input frameset */
00514 
00515     if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00516         cpl_msg_error(fctid,"Input framelist NULL or has no input data\n");
00517         return(-1);
00518     }
00519 
00520     /* Check the files in the frameset */
00521 
00522     if (vircam_frameset_fexists(framelist) != VIR_OK) {
00523         cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00524         return(-1);
00525     }
00526 
00527     /* Initialise some things */
00528 
00529     vircam_twilight_flat_combine_init();
00530     we_expect = MEANTWI + CONFMAP;
00531 
00532     /* Get the parameters */
00533 
00534     p = cpl_parameterlist_find(parlist,"vircam.vircam_twilight_flat_combine.lthr");
00535     vircam_twilight_flat_combine_config.lthr = 
00536         (float)cpl_parameter_get_double(p);
00537     p = cpl_parameterlist_find(parlist,
00538                                "vircam.vircam_twilight_flat_combine.hthr");
00539     vircam_twilight_flat_combine_config.hthr = 
00540         (float)cpl_parameter_get_double(p);
00541     p = cpl_parameterlist_find(parlist,
00542                                "vircam.vircam_twilight_flat_combine.combtype");
00543     vircam_twilight_flat_combine_config.combtype = cpl_parameter_get_int(p);
00544     p = cpl_parameterlist_find(parlist,
00545                                "vircam.vircam_twilight_flat_combine.scaletype");
00546     vircam_twilight_flat_combine_config.scaletype = cpl_parameter_get_int(p);
00547     p = cpl_parameterlist_find(parlist,
00548                                "vircam.vircam_twilight_flat_combine.xrej");
00549     vircam_twilight_flat_combine_config.xrej = cpl_parameter_get_bool(p);
00550     p = cpl_parameterlist_find(parlist,
00551                                "vircam.vircam_twilight_flat_combine.thresh");
00552     vircam_twilight_flat_combine_config.thresh = 
00553         (float)cpl_parameter_get_double(p);
00554     p = cpl_parameterlist_find(parlist,
00555                                "vircam.vircam_twilight_flat_combine.ncells");
00556     vircam_twilight_flat_combine_config.ncells = cpl_parameter_get_int(p);
00557     p = cpl_parameterlist_find(parlist,
00558                                "vircam.vircam_twilight_flat_combine.extenum");
00559     vircam_twilight_flat_combine_config.extenum = cpl_parameter_get_int(p);
00560 
00561     /* Sort out raw from calib frames */
00562 
00563     if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00564         cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00565         vircam_twilight_flat_combine_tidy(2);
00566         return(-1);
00567     }
00568 
00569     /* Get the twilight frames */
00570 
00571     if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00572                                            &nlab)) == NULL) {
00573         cpl_msg_error(fctid,"Cannot labelise the input frames");
00574         vircam_twilight_flat_combine_tidy(2);
00575         return(-1);
00576     }
00577     if ((ps.twilightlist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00578                                                     VIRCAM_TWI_RAW)) == NULL) {
00579         cpl_msg_error(fctid,"Cannot find twilight frames in input frameset");
00580         vircam_twilight_flat_combine_tidy(2);
00581         return(-1);
00582     }
00583     ps.ntwilights = cpl_frameset_get_size(ps.twilightlist);
00584 
00585     /* Check to see if there is a master dark frame */
00586 
00587     if ((ps.master_dark = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00588                                                      VIRCAM_CAL_DARK)) == NULL) {
00589         cpl_msg_error(fctid,"No master dark found");
00590         vircam_twilight_flat_combine_tidy(2);
00591         return(-1);
00592     }
00593         
00594     /* Check to see if there is a master twilight flat frame */
00595 
00596     if ((ps.master_twilight_flat = vircam_frameset_subgroup_1(framelist,
00597          ps.labels,nlab,VIRCAM_REF_TWILIGHT_FLAT)) == NULL)
00598         cpl_msg_info(fctid,"No master twilight flat found -- no ratio image will be formed");
00599     else
00600         we_expect |= RATIMG;
00601         
00602     /* Check to see if there is a master bad pixel map. If there isn't one 
00603        then look for a confidence map */
00604 
00605     ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00606 
00607     /* Check to see if there is a channel table */
00608 
00609     if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00610                                                  VIRCAM_CAL_CHANTAB)) == NULL) {
00611         if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00612                                                      VIRCAM_CAL_CHANTAB_INIT)) == NULL) {
00613             cpl_msg_info(fctid,"No channel table found -- no ratio image stats and no linearisation will be done");
00614         } else {
00615             cpl_msg_info(fctid,"Channel table is labelled INIT -- no linearisation will be done");
00616             if (we_expect & RATIMG)
00617                 we_expect |= STATS_TAB;
00618         }
00619     } else if (we_expect & RATIMG) {
00620         we_expect |= STATS_TAB;
00621     }
00622 
00623     /* Get the number of DITs */
00624 
00625     pp = cpl_propertylist_load(cpl_frame_get_filename(cpl_frameset_get_frame(ps.twilightlist,0)),0);
00626     if (vircam_pfits_get_ndit(pp,&ndit) != VIR_OK) {
00627         cpl_msg_error(fctid,"No value for NDIT available");
00628         freepropertylist(pp);
00629         vircam_twilight_flat_combine_tidy(2);
00630         return(-1);
00631     }
00632     cpl_propertylist_delete(pp);
00633 
00634     /* Now, how many image extensions do we want to do? If the extension
00635        number is zero, then we loop for all possible extensions. If it
00636        isn't then we just do the extension specified */
00637 
00638     vircam_exten_range(vircam_twilight_flat_combine_config.extenum,
00639                        (const cpl_frame *)cpl_frameset_get_frame(ps.twilightlist,0),
00640                        &jst,&jfn);
00641     if (jst == -1 || jfn == -1) {
00642         cpl_msg_error(fctid,"Unable to continue");
00643         vircam_twilight_flat_combine_tidy(2);
00644         return(-1);
00645     }
00646 
00647     /* Get some space for the good frames */
00648 
00649     ps.good = cpl_malloc(ps.ntwilights*sizeof(vir_fits *));
00650 
00651     /* Now loop for all the extension... */
00652 
00653     for (j = jst; j <= jfn; j++) {
00654         status = VIR_OK;
00655         we_get = 0;
00656         isfirst = (j == jst);
00657 
00658         /* Load the images and the master dark. */
00659 
00660         ps.twilights = vircam_fits_load_list(ps.twilightlist,CPL_TYPE_FLOAT,j);
00661         if (ps.twilights == NULL) {
00662             cpl_msg_info(fctid,"Extension %d twilights wouldn't load",j);
00663             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00664             if (retval != 0)
00665                 return(-1);
00666             continue;
00667         }
00668 
00669         /* Are any of these twilight flats any good? */
00670         
00671         ps.ngood = 0;
00672         for (i = 0; i < ps.ntwilights; i++) {
00673             ff = ps.twilights[i];
00674             vircam_pfits_get_detlive(vircam_fits_get_ehu(ff),&live);
00675             if (! live) {
00676                 cpl_msg_info(fctid,"Detector flagged dead %s",
00677                              vircam_fits_get_fullname(ff));
00678                 vircam_fits_set_error(ff,VIR_FATAL);
00679             } else {
00680                 ps.good[ps.ngood] = ff;
00681                 ps.ngood += 1;
00682             }
00683         }
00684 
00685         /* If there are no good images, then signal that we need to create 
00686            dummy products and move on */
00687 
00688         if (ps.ngood == 0) {
00689             cpl_msg_info(fctid,"All images flagged bad for this extension");
00690             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00691             if (retval != 0)
00692                 return(-1);
00693             continue;
00694         }
00695 
00696         /* Sort out the images that are either over or under exposed */
00697 
00698         vircam_overexp(ps.good,&(ps.ngood),ndit,
00699                        vircam_twilight_flat_combine_config.lthr,
00700                        vircam_twilight_flat_combine_config.hthr,0,
00701                        &(vircam_twilight_flat_combine_config.minv),
00702                        &(vircam_twilight_flat_combine_config.maxv),
00703                        &(vircam_twilight_flat_combine_config.avev));
00704 
00705         /* Check to see how many are left. If there aren't any, then
00706            signal a major error */
00707 
00708         if (ps.ngood == 0) {
00709             cpl_msg_info(fctid,"All images either under or overexposed");
00710             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00711             if (retval != 0)
00712                 return(-1);
00713             continue;
00714         }
00715 
00716         /* Load up the mask */
00717 
00718         nx = cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
00719         ny = cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
00720         if (vircam_mask_load(ps.master_mask,j,nx,ny) == VIR_FATAL) {
00721             cpl_msg_info(fctid,"Unable to load mask image %s[%d]",
00722                          vircam_mask_get_filename(ps.master_mask),j);
00723             cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00724             vircam_mask_force(ps.master_mask,nx,ny);
00725         }
00726 
00727         /* Take the middle two exposures and create a scaled difference image
00728            estimate */
00729 
00730         if (ps.ngood > 1) {
00731             i = ps.ngood/2 - 1;
00732             im1 = vircam_fits_get_image(ps.good[i]);
00733             im2 = vircam_fits_get_image(ps.good[i+1]);
00734             val1 = cpl_image_get_median_window(im1,500,500,1000,1000);
00735             val2 = cpl_image_get_median_window(im2,500,500,1000,1000);
00736             val1 /= (double)ndit;
00737             val2 /= (double)ndit;
00738             scl = val1/val2;
00739             newim = cpl_image_multiply_scalar_create(im2,scl);
00740             diffim = cpl_image_subtract_create(im1,newim);
00741             cpl_image_delete(newim);
00742             data = cpl_image_get_data_float(diffim);
00743             bpm = vircam_mask_get_data(ps.master_mask);
00744             npts = nx*ny;
00745             vircam_medmad(data,bpm,npts,&med,&mad);
00746             mad *= 1.48/M_SQRT2;
00747             vircam_twilight_flat_combine_config.photnoise = mad;
00748             vircam_twilight_flat_combine_config.snratio = 
00749                 val1*sqrt((double)(ps.ngood))/mad;
00750             cpl_image_delete(diffim);
00751         } else {
00752             vircam_twilight_flat_combine_config.photnoise = 0.0;
00753             vircam_twilight_flat_combine_config.snratio = 0.0;
00754         }
00755 
00756         /* Right, we want to dark correct, so we need to load the mean 
00757            dark and make sure it isn't a dummy */
00758 
00759         ps.mdark = vircam_fits_load(ps.master_dark,CPL_TYPE_FLOAT,j);
00760         if (ps.mdark == NULL) {
00761             cpl_msg_info(fctid,"Can't load master dark for extension %d",j);
00762             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00763             if (retval != 0)
00764                 return(-1);
00765             continue;
00766         } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mdark))) {
00767             cpl_msg_info(fctid,"Can't master dark extension %d is a dummy",j);
00768             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00769             if (retval != 0)
00770                 return(-1);
00771             continue;
00772         }
00773 
00774         /* Loop for each image and dark correct */
00775 
00776         cpl_msg_info(fctid,"Dark correcting extension %d\n",j);
00777         for (i = 0; i < ps.ngood; i++)
00778             vircam_darkcor((ps.good)[i],ps.mdark,1.0,&status);
00779 
00780         /* We need to load the channel table (if it exists) for linearisation
00781            and for the ratio image stats table */
00782 
00783         if (ps.chantab != NULL) {
00784             ps.ctable = vircam_tfits_load(ps.chantab,j);
00785             if (ps.ctable == NULL) {
00786                 cpl_msg_info(fctid,"Channel table extension %d won't load",j);
00787             } else if (vircam_chantab_verify(vircam_tfits_get_table(ps.ctable)) != VIR_OK) {
00788                 cpl_msg_info(fctid,"Channel table extension %d has errors",j);
00789                 freetfits(ps.ctable);
00790             } else { 
00791                 pp = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
00792                                            j);
00793                 if (vircam_is_dummy(pp)) {
00794                     cpl_msg_info(fctid,
00795                                  "Channel table extensions %d is a dummy",j);
00796                     freetfits(ps.ctable);
00797                 }
00798                 freepropertylist(pp);
00799             }
00800         } else 
00801             ps.ctable = NULL;
00802                 
00803         /* Loop for each of the input images and linearise it if there
00804            is a channel table */
00805 
00806         if (ps.ctable != NULL) {
00807             cpl_msg_info(fctid,"Linearising extension %d\n",j);
00808             for (i = 0; i < ps.ngood; i++)
00809                 (void)vircam_lincor((ps.good)[i],ps.ctable,1,ndit,&status);
00810         }
00811 
00812         /* Correct for ndit */
00813 
00814         for (i = 0; i < ps.ngood; i++) 
00815             (void)vircam_nditcor((ps.good)[i],ndit,&status);
00816 
00817         /* Call the combine module */
00818 
00819         cpl_msg_info(fctid,"Doing combination for extension %d\n",j);
00820         (void)vircam_imcombine(ps.good,ps.ngood,
00821                                vircam_twilight_flat_combine_config.combtype,
00822                                vircam_twilight_flat_combine_config.scaletype,
00823                                vircam_twilight_flat_combine_config.xrej,
00824                                vircam_twilight_flat_combine_config.thresh,
00825                                &(ps.outimage),&(ps.rejmask),&(ps.rejplus),
00826                                &(ps.drs),&status);
00827 
00828         /* If these correction and combination routines failed at any stage
00829            then get out of here */
00830 
00831         if (status == VIR_OK) {
00832             we_get |= MEANTWI;
00833             vircam_twilight_flat_combine_normal(j);
00834         } else {
00835             cpl_msg_info(fctid,"A processing step failed");
00836         }
00837 
00838         /* Create any dummies and save the products */
00839         
00840         retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00841         if (retval != 0)
00842             return(-1);
00843 
00844     }
00845     vircam_twilight_flat_combine_tidy(2);
00846     return(0);
00847 }
00848 
00849 
00850 /*---------------------------------------------------------------------------*/
00857 /*---------------------------------------------------------------------------*/
00858 
00859 static int vircam_twilight_flat_combine_save(cpl_frameset *framelist, 
00860                                              cpl_parameterlist *parlist) {
00861     cpl_propertylist *plist,*elist,*p,*pafprop;
00862     int status;
00863     float val;
00864     const char *fctid = "vircam_twilight_flat_combine_save";
00865     const char *outfile = "twilightcomb.fits";
00866     const char *outdiff = "twilightratio.fits";
00867     const char *outdimst = "twilightratiotab.fits";
00868     const char *outconf = "twilightconf.fits";
00869     const char *outfilepaf = "twilightcomb";
00870     const char *outdiffpaf = "twilightratio";
00871     const char *recipeid = "vircam_twilight_flat_combine";
00872 
00873     /* If we need to make a PHU then do that now based on the first frame
00874        in the input frame list */
00875 
00876     if (isfirst) {
00877 
00878         /* Create a new product frame object and define some tags */
00879 
00880         product_frame_mean_twi = cpl_frame_new();
00881         cpl_frame_set_filename(product_frame_mean_twi,outfile);
00882         cpl_frame_set_tag(product_frame_mean_twi,VIRCAM_PRO_TWILIGHT_FLAT);
00883         cpl_frame_set_type(product_frame_mean_twi,CPL_FRAME_TYPE_IMAGE);
00884         cpl_frame_set_group(product_frame_mean_twi,CPL_FRAME_GROUP_PRODUCT);
00885         cpl_frame_set_level(product_frame_mean_twi,CPL_FRAME_LEVEL_FINAL);
00886 
00887         /* Set up the PHU header */
00888 
00889         plist = vircam_fits_get_phu(ps.twilights[0]);
00890         ps.phupaf = vircam_paf_phu_items(plist);
00891         if (ps.master_twilight_flat != NULL) {
00892             cpl_propertylist_update_string(ps.phupaf,"REF_TWILIGHT",
00893                                            cpl_frame_get_filename(ps.master_twilight_flat));
00894             cpl_propertylist_set_comment(ps.phupaf,"REF_TWILIGHT",
00895                                          "Reference twilight flat used");
00896         }
00897         vircam_dfs_set_product_primary_header(plist,product_frame_mean_twi,
00898                                               framelist,parlist,
00899                                               (char *)recipeid,
00900                                               "PRO-1.15",NULL,0);
00901 
00902         /* 'Save' the PHU image */                       
00903 
00904         if (cpl_image_save(NULL,outfile,CPL_BPP_8_UNSIGNED,plist,
00905                            CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00906             cpl_msg_error(fctid,"Cannot save product PHU");
00907             cpl_frame_delete(product_frame_mean_twi);
00908             return(-1);
00909         }
00910         cpl_frameset_insert(framelist,product_frame_mean_twi);
00911 
00912         /* Create a new product frame object and define some tags for the
00913            output confidence map */
00914 
00915         product_frame_conf = cpl_frame_new();
00916         cpl_frame_set_filename(product_frame_conf,outconf);
00917         cpl_frame_set_tag(product_frame_conf,VIRCAM_PRO_CONF);
00918         cpl_frame_set_type(product_frame_conf,CPL_FRAME_TYPE_IMAGE);
00919         cpl_frame_set_group(product_frame_conf,CPL_FRAME_GROUP_PRODUCT);
00920         cpl_frame_set_level(product_frame_conf,CPL_FRAME_LEVEL_FINAL);
00921 
00922         /* Set up the PHU header */
00923 
00924         plist = vircam_fits_get_phu(ps.twilights[0]);
00925         vircam_dfs_set_product_primary_header(plist,product_frame_conf,
00926                                               framelist,parlist,
00927                                               (char *)recipeid,"PRO-1.15",
00928                                               NULL,0);
00929 
00930         /* 'Save' the PHU image */                       
00931 
00932         if (cpl_image_save(NULL,outconf,CPL_BPP_8_UNSIGNED,plist,
00933                            CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00934             cpl_msg_error(fctid,"Cannot save product PHU");
00935             cpl_frame_delete(product_frame_conf);
00936             return(-1);
00937         }
00938         cpl_frameset_insert(framelist,product_frame_conf);
00939 
00940         /* Create a new product frame object for the difference image */
00941 
00942         if (we_expect & RATIMG) {
00943             product_frame_ratioimg = cpl_frame_new();
00944             cpl_frame_set_filename(product_frame_ratioimg,outdiff);
00945             cpl_frame_set_tag(product_frame_ratioimg,
00946                               VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT);
00947             cpl_frame_set_type(product_frame_ratioimg,CPL_FRAME_TYPE_IMAGE);
00948             cpl_frame_set_group(product_frame_ratioimg,
00949                                 CPL_FRAME_GROUP_PRODUCT);
00950             cpl_frame_set_level(product_frame_ratioimg,CPL_FRAME_LEVEL_FINAL);
00951 
00952             /* Set up the PHU header */
00953 
00954             plist = vircam_fits_get_phu(ps.twilights[0]);
00955             vircam_dfs_set_product_primary_header(plist,product_frame_ratioimg,
00956                                                   framelist,parlist,
00957                                                   (char *)recipeid,"PRO-1.15",
00958                                                   NULL,0);
00959 
00960             /* 'Save' the PHU image */                   
00961 
00962             if (cpl_image_save(NULL,outdiff,CPL_BPP_8_UNSIGNED,plist,
00963                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00964                 cpl_msg_error(fctid,"Cannot save product PHU");
00965                 cpl_frame_delete(product_frame_ratioimg);
00966                 return(-1);
00967             }
00968             cpl_frameset_insert(framelist,product_frame_ratioimg);
00969         }
00970 
00971         /* Create a new product frame object for the difference image stats 
00972            table */
00973 
00974         if (we_expect & STATS_TAB) {
00975             product_frame_ratioimg_stats = cpl_frame_new();
00976             cpl_frame_set_filename(product_frame_ratioimg_stats,outdimst);
00977             cpl_frame_set_tag(product_frame_ratioimg_stats,
00978                               VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT_STATS);
00979             cpl_frame_set_type(product_frame_ratioimg_stats,
00980                                CPL_FRAME_TYPE_TABLE);
00981             cpl_frame_set_group(product_frame_ratioimg_stats,
00982                                 CPL_FRAME_GROUP_PRODUCT);
00983             cpl_frame_set_level(product_frame_ratioimg_stats,
00984                                 CPL_FRAME_LEVEL_FINAL);
00985 
00986             /* Set up PHU header */
00987 
00988             plist = vircam_fits_get_phu(ps.twilights[0]);
00989             vircam_dfs_set_product_primary_header(plist,
00990                                                   product_frame_ratioimg_stats,
00991                                                   framelist,parlist,
00992                                                   (char *)recipeid,"PRO-1.15",
00993                                                   NULL,0);
00994 
00995             /* Fiddle with the extension header now */
00996 
00997             elist = vircam_fits_get_ehu(ps.twilights[0]);
00998             p = cpl_propertylist_duplicate(elist);
00999             vircam_merge_propertylists(p,ps.drs);
01000             if (! (we_get & STATS_TAB))
01001                 vircam_dummy_property(p);
01002             vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
01003                                                 framelist,parlist,
01004                                                 (char *)recipeid,
01005                                                 "PRO-1.15",NULL);
01006             status = VIR_OK;
01007             vircam_removewcs(p,&status);
01008 
01009             /* And finally the difference image stats table */
01010 
01011             if (cpl_table_save(ps.ratioimstats,plist,p,outdimst,
01012                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
01013                 cpl_msg_error(fctid,"Cannot save product table extension");
01014                 cpl_propertylist_delete(p);
01015                 return(-1);
01016             }
01017             cpl_propertylist_delete(p);
01018             cpl_frameset_insert(framelist,product_frame_ratioimg_stats);
01019         }
01020     }
01021 
01022     /* Get the extension property list */
01023 
01024     plist = vircam_fits_get_ehu(ps.twilights[0]);
01025     vircam_merge_propertylists(plist,ps.drs);
01026     cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
01027 
01028     /* Fiddle with the header now */
01029 
01030     p = cpl_propertylist_duplicate(plist);
01031     if (! (we_get & MEANTWI)) 
01032         vircam_dummy_property(p);
01033     vircam_dfs_set_product_exten_header(p,product_frame_mean_twi,framelist,
01034                                         parlist,(char *)recipeid,
01035                                         "PRO-1.15",NULL);
01036                 
01037     /* Now save the mean twilight flat image extension */
01038 
01039     cpl_propertylist_update_float(p,"ESO QC FLATRMS",
01040                                   vircam_twilight_flat_combine_config.flatrms);
01041     cpl_propertylist_set_comment(p,"ESO QC FLATRMS","RMS of output flat");
01042     cpl_propertylist_update_float(p,"ESO QC FLATMIN",
01043                                   vircam_twilight_flat_combine_config.minv);
01044     cpl_propertylist_set_comment(p,"ESO QC FLATMIN","Ensemble minimum");
01045     cpl_propertylist_update_float(p,"ESO QC FLATMAX",
01046                                   vircam_twilight_flat_combine_config.maxv);
01047     cpl_propertylist_set_comment(p,"ESO QC FLATMAX","Ensemble maximum");
01048     cpl_propertylist_update_float(p,"ESO QC FLATAVG",
01049                                   vircam_twilight_flat_combine_config.avev);
01050     cpl_propertylist_set_comment(p,"ESO QC FLATAVG","Ensemble average");
01051     val = vircam_twilight_flat_combine_config.maxv - 
01052         vircam_twilight_flat_combine_config.minv;
01053     cpl_propertylist_update_float(p,"ESO QC FLATRNG",val);
01054     cpl_propertylist_set_comment(p,"ESO QC FLATRNG","Ensemble range");
01055     cpl_propertylist_update_float(p,"ESO QC TWIPHOT",
01056                                   vircam_twilight_flat_combine_config.photnoise);
01057     cpl_propertylist_set_comment(p,"ESO QC TWIPHOT",
01058                                  "[adu] Estimated photon noise");
01059     cpl_propertylist_update_float(p,"ESO QC TWISNRATIO",
01060                                   vircam_twilight_flat_combine_config.snratio);
01061     cpl_propertylist_set_comment(p,"ESO QC TWISNRATIO","Estimated S/N ratio");
01062     if (cpl_image_save(ps.outimage,outfile,CPL_BPP_IEEE_FLOAT,p,
01063                        CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01064         cpl_msg_error(fctid,"Cannot save product image extension");
01065         cpl_propertylist_delete(p);
01066         return(-1);
01067     }
01068 
01069     /* Write out PAF for mean image */
01070 
01071     pafprop = vircam_paf_req_items(p);
01072     vircam_merge_propertylists(pafprop,ps.phupaf);
01073     vircam_paf_append(pafprop,vircam_fits_get_phu(ps.twilights[0]),
01074                       "ESO INS FILT1 NAME");
01075     vircam_paf_append(pafprop,p,"ESO PRO CATG");
01076     vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
01077     vircam_paf_append(pafprop,p,"ESO DET NDIT");
01078     if (vircam_paf_print((char *)outfilepaf,
01079                          "VIRCAM/vircam_twilight_flat_combine",
01080                          "QC file",pafprop) != VIR_OK)
01081         cpl_msg_warning(fctid,"Unable to save PAF for mean twilight");
01082     cpl_propertylist_delete(pafprop);
01083     cpl_propertylist_delete(p);
01084 
01085     /* Now save the twilight ratio image extension */
01086 
01087     if (we_expect & RATIMG) {
01088         p = cpl_propertylist_duplicate(plist);
01089         if (! (we_get & RATIMG))
01090             vircam_dummy_property(p);
01091         cpl_propertylist_update_float(p,"ESO QC FLATRATIO_MED",
01092                                       vircam_twilight_flat_combine_config.flatratio_med);
01093         cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_MED",
01094                                      "Median of ratio map");
01095         cpl_propertylist_update_float(p,"ESO QC FLATRATIO_RMS",
01096                                       vircam_twilight_flat_combine_config.flatratio_rms);
01097         cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_RMS",
01098                                      "RMS of ratio map");
01099         vircam_dfs_set_product_exten_header(p,product_frame_ratioimg,
01100                                             framelist,parlist,(char *)recipeid,
01101                                             "PRO-1.15",NULL);
01102         if (cpl_image_save(ps.ratioimg,outdiff,CPL_BPP_IEEE_FLOAT,p,
01103                            CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01104             cpl_propertylist_delete(p);
01105             cpl_msg_error(fctid,"Cannot save product image extension");
01106             return(-1);
01107         }
01108 
01109         /* Write out PAF for difference image */
01110 
01111         pafprop = vircam_paf_req_items(p);
01112         vircam_merge_propertylists(pafprop,ps.phupaf);
01113         vircam_paf_append(pafprop,vircam_fits_get_phu(ps.twilights[0]),
01114                           "ESO INS FILT1 NAME");
01115         vircam_paf_append(pafprop,p,"ESO PRO CATG");
01116         if (vircam_paf_print((char *)outdiffpaf,
01117                              "VIRCAM/vircam_twilight_flat_combine",
01118                              "QC file",pafprop) != VIR_OK)
01119             cpl_msg_warning(fctid,"Unable to save PAF for twilight ratio image");
01120         cpl_propertylist_delete(pafprop);
01121         cpl_propertylist_delete(p);
01122     }
01123 
01124     /* Now any further ratio image stats tables */
01125 
01126     if (! isfirst && (we_expect & STATS_TAB)) {
01127         p = cpl_propertylist_duplicate(plist);
01128         if (! (we_get & STATS_TAB))
01129             vircam_dummy_property(p);
01130         vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
01131                                             framelist,parlist,(char *)recipeid,
01132                                             "PRO-1.15",NULL);
01133         status = VIR_OK;
01134         vircam_removewcs(p,&status);
01135         if (cpl_table_save(ps.ratioimstats,NULL,p,outdimst,CPL_IO_EXTEND)
01136                            != CPL_ERROR_NONE) {
01137             cpl_msg_error(fctid,"Cannot save product table extension");
01138             cpl_propertylist_delete(p);
01139             return(-1);
01140         }       
01141         cpl_propertylist_delete(p);
01142     }
01143 
01144     /* Fiddle with the header now */
01145 
01146     vircam_merge_propertylists(plist,ps.drs2);
01147     p = cpl_propertylist_duplicate(plist);
01148     if (! (we_get & CONFMAP)) 
01149         vircam_dummy_property(p);
01150 
01151     /* Now save the confidence map */
01152 
01153     vircam_dfs_set_product_exten_header(p,product_frame_conf,framelist,
01154                                         parlist,(char *)recipeid,"PRO-1.15",
01155                                         NULL);
01156     if (cpl_image_save(ps.outconf,outconf,CPL_BPP_16_SIGNED,p,
01157                        CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01158         cpl_msg_error(fctid,"Cannot save product image extension");
01159         cpl_propertylist_delete(p);
01160         return(-1);
01161     }
01162     cpl_propertylist_delete(p);
01163 
01164     /* Get out of here */
01165 
01166     return(0);
01167 }
01168 
01169 /*---------------------------------------------------------------------------*/
01173 /*---------------------------------------------------------------------------*/
01174 
01175 static void vircam_twilight_flat_combine_dummy_products(void) {
01176 
01177     /* See if you even need to be here */
01178 
01179     if (we_get == we_expect)
01180         return;
01181 
01182     /* First an output combined twilight frame */
01183 
01184     if (! (we_get & MEANTWI)) {
01185         ps.outimage = vircam_dummy_image(ps.twilights[0]);
01186         vircam_twilight_flat_combine_config.flatrms = 0.0;
01187     }
01188 
01189     /* Now the confidence map */
01190 
01191     if (! (we_get & CONFMAP)) {
01192         ps.outconf = vircam_dummy_image(ps.twilights[0]);
01193         vircam_twilight_flat_combine_config.flatrms = 0.0;
01194     }
01195 
01196     /* Do a ratio image */
01197 
01198     if ((we_expect & RATIMG) && ! (we_get & RATIMG)) {
01199         vircam_twilight_flat_combine_config.flatratio_med = 0.0;
01200         vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
01201         ps.ratioimg = vircam_dummy_image(ps.twilights[0]);
01202     }
01203 
01204     /* If a ratio image stats table is required, then do that now */
01205    
01206     if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB)) 
01207         ps.ratioimstats = vircam_create_diffimg_stats(0);
01208 
01209     return;
01210 }
01211 
01212 /*---------------------------------------------------------------------------*/
01217 /*---------------------------------------------------------------------------*/
01218 
01219 static void vircam_twilight_flat_combine_normal(int jext) {
01220     int nx,ny,ncells,status;
01221     long i,npi;
01222     unsigned char *bpm;
01223     float *idata,med,sig,gdiff,grms;
01224     const char *fctid="vircam_twilight_flat_combine_normal";
01225 
01226     /* Load up a bad pixel mask */
01227 
01228     nx = cpl_image_get_size_x(ps.outimage);
01229     ny = cpl_image_get_size_y(ps.outimage);
01230     npi = nx*ny;
01231     vircam_mask_load(ps.master_mask,jext,nx,ny);
01232     bpm = vircam_mask_get_data(ps.master_mask);
01233 
01234     /* Create the bad pixel mask */
01235     
01236     status = VIR_OK;
01237     (void)vircam_mkconf(ps.outimage,(char *)"None Available",ps.master_mask,
01238                         &(ps.outconf),&(ps.drs2),&status);
01239     if (status == VIR_OK) 
01240         we_get |= CONFMAP;
01241     else {
01242         cpl_msg_info(fctid,"Confidence map creation failed extension %d",jext);
01243         status = VIR_OK;
01244     }
01245         
01246     /* Work out the RMS of the mean twilight frame */
01247 
01248     idata = cpl_image_get_data(ps.outimage);
01249     vircam_medsig(idata,bpm,npi,&med,&sig);
01250 
01251     /* Fill in the bad bits... */
01252 
01253     for (i = 0; i < npi; i++)
01254         if (bpm[i])
01255             idata[i] = med;
01256 
01257     /* Divide through by the median */
01258 
01259     cpl_propertylist_update_float(ps.drs,"ESO DRS MEDFLAT",med);
01260     cpl_propertylist_set_comment(ps.drs,"ESO DRS MEDFLAT",
01261                                  "Median value before normalisation");
01262     cpl_image_divide_scalar(ps.outimage,med);
01263     vircam_medmad(idata,bpm,npi,&med,&sig);
01264     sig *= 1.48;
01265     vircam_twilight_flat_combine_config.flatrms = sig;
01266 
01267     /* Load up the master twilight flat */
01268 
01269     if (ps.master_twilight_flat != NULL) {
01270         ps.mfimage = vircam_fits_load(ps.master_twilight_flat,CPL_TYPE_FLOAT,jext);
01271         if (ps.mfimage == NULL) {
01272             cpl_msg_info(fctid,"Master twilight extension %d won't load",jext);
01273         } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mfimage))) {
01274             cpl_msg_info(fctid,"Master twilight extension %d is a dummy",jext);
01275             freefits(ps.mfimage);
01276         }
01277     } else
01278         ps.mfimage = NULL;
01279 
01280 
01281     /* Create a ratio image. NB: the difference image routine copes if the 
01282        input mean image or the channel tables are null.  Thus if either or
01283        both are null because of a failure to load, then the routine will do
01284        as  much as it can and return, allowing you to fill in the rest with
01285        dummy products */
01286 
01287     vircam_twilight_flat_combine_config.flatratio_med = 0.0;
01288     vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
01289     ncells = vircam_twilight_flat_combine_config.ncells;
01290     vircam_difference_image(vircam_fits_get_image(ps.mfimage),ps.outimage,bpm,
01291                             vircam_tfits_get_table(ps.ctable),ncells,2,
01292                             &gdiff,&grms,&(ps.ratioimg),
01293                             &(ps.ratioimstats));
01294     vircam_mask_clear(ps.master_mask);
01295     vircam_twilight_flat_combine_config.flatratio_med = gdiff;
01296     vircam_twilight_flat_combine_config.flatratio_rms = grms;
01297     if (ps.ratioimg != NULL)
01298         we_get |= RATIMG;
01299     if (ps.ratioimstats != NULL)
01300         we_get |= STATS_TAB;
01301     return;
01302 }
01303 
01304 /*---------------------------------------------------------------------------*/
01312 /*---------------------------------------------------------------------------*/
01313 
01314 
01315 static int vircam_twilight_flat_combine_lastbit(int jext, 
01316                                                 cpl_frameset *framelist,
01317                                                 cpl_parameterlist *parlist) {
01318     int retval;
01319     const char *fctid="vircam_twilight_flat_combine_lastbit";
01320 
01321     /* Make whatever dummy products you need */
01322 
01323     vircam_twilight_flat_combine_dummy_products();
01324 
01325     /* Save everything */
01326 
01327     cpl_msg_info(fctid,"Saving products for extension %d",jext);
01328     retval = vircam_twilight_flat_combine_save(framelist,parlist);
01329     if (retval != 0) {
01330         vircam_twilight_flat_combine_tidy(2);
01331         return(-1);
01332     }
01333 
01334     /* Free some stuff up */
01335 
01336     vircam_twilight_flat_combine_tidy(1);
01337     return(0);
01338 }
01339 
01340 /*---------------------------------------------------------------------------*/
01344 /*---------------------------------------------------------------------------*/
01345 
01346 static void vircam_twilight_flat_combine_init(void) {
01347     ps.labels = NULL;
01348     ps.twilightlist = NULL;
01349     ps.twilights = NULL;
01350     ps.good = NULL;
01351     ps.master_dark = NULL;
01352     ps.master_twilight_flat = NULL;
01353     ps.master_mask = NULL;
01354     ps.chantab = NULL;
01355     ps.ctable = NULL;
01356     ps.outimage = NULL;
01357     ps.outconf = NULL;
01358     ps.drs = NULL;
01359     ps.drs2 = NULL;
01360     ps.rejmask = NULL;
01361     ps.rejplus = NULL;
01362     ps.mfimage = NULL;
01363     ps.ratioimg = NULL;
01364     ps.ratioimstats = NULL;
01365     ps.phupaf = NULL;
01366 }
01367 
01368 /*---------------------------------------------------------------------------*/
01372 /*---------------------------------------------------------------------------*/
01373 
01374 static void vircam_twilight_flat_combine_tidy(int level) {
01375     freeimage(ps.outimage);
01376     freeimage(ps.outconf);
01377     freefitslist(ps.twilights,ps.ntwilights);
01378     freepropertylist(ps.drs);
01379     freepropertylist(ps.drs2);
01380     freespace(ps.rejmask);
01381     freespace(ps.rejplus);
01382     freefits(ps.mfimage);
01383     freeimage(ps.ratioimg);
01384     freetable(ps.ratioimstats);
01385     freetfits(ps.ctable);
01386     freefits(ps.mdark);
01387     if (level == 1)
01388         return;
01389 
01390     freespace(ps.good);
01391     freespace(ps.labels);
01392     freeframeset(ps.twilightlist);
01393     freeframe(ps.master_dark);
01394     freeframe(ps.master_twilight_flat);
01395     freemask(ps.master_mask);
01396     freeframe(ps.chantab);
01397     freepropertylist(ps.phupaf);
01398 }
01399 
01402 /*
01403 
01404 $Log: vircam_twilight_flat_combine.c,v $
01405 Revision 1.54  2010/12/09 13:21:36  jim
01406 Added code to calculate rough photon noise and s/n ratio
01407 
01408 Revision 1.53  2010/03/21 06:48:21  jim
01409 Fixed bug where DATANCOM wasn't being updated in all products
01410 
01411 Revision 1.52  2010/03/09 14:27:40  jim
01412 Now updates ESO PRO DATANCOM to reflect the number of images used
01413 
01414 Revision 1.51  2010/02/05 09:42:22  jim
01415 Fixed call to non-existent cpl routine
01416 
01417 Revision 1.50  2010/01/31 18:53:22  jim
01418 Reference flat included in paf
01419 
01420 Revision 1.49  2009/12/11 06:52:56  jim
01421 Minor mods to documentation
01422 
01423 Revision 1.48  2009/11/18 21:32:40  jim
01424 Modified to write NDIT to the paf
01425 
01426 Revision 1.47  2009/09/21 11:59:37  jim
01427 Modified to use new version of vircam_overexp and to write ensemble stats
01428 to QC headers
01429 
01430 Revision 1.46  2009/09/09 09:50:21  jim
01431 Modified to try and get headers right
01432 
01433 Revision 1.45  2008/12/05 13:28:32  jim
01434 Fixed save routine so that the correct version of PRO CATG is written to the
01435 paf file
01436 
01437 Revision 1.44  2008/11/26 18:33:59  jim
01438 Now fills bad pixels in the output flat with a median value before normalisation
01439 
01440 Revision 1.43  2008/10/01 04:59:13  jim
01441 Added call to vircam_frameset_fexists to check input frameset
01442 
01443 Revision 1.42  2008/09/30 11:33:23  jim
01444 Added PRO CATG to pafs
01445 
01446 Revision 1.41  2008/09/29 11:21:47  jim
01447 Default is to form medians
01448 
01449 Revision 1.40  2007/11/26 09:59:06  jim
01450 Recipe now takes ndit into account when doing linearity correction
01451 
01452 Revision 1.39  2007/10/19 09:25:09  jim
01453 Fixed problems with missing includes
01454 
01455 Revision 1.38  2007/10/15 12:53:26  jim
01456 Modified for compatibiliity with cpl_4.0
01457 
01458 Revision 1.37  2007/07/18 15:35:42  jim
01459 Added better error handling for missing or corrupt mask extensions
01460 
01461 Revision 1.36  2007/07/09 13:21:56  jim
01462 Modified to use new version of vircam_exten_range
01463 
01464 Revision 1.35  2007/06/13 08:11:27  jim
01465 Modified docs to reflect changes in DFS tags
01466 
01467 Revision 1.34  2007/05/08 10:42:33  jim
01468 Added DRS MEDFLAT keyword
01469 
01470 Revision 1.33  2007/04/30 09:40:17  jim
01471 Added more stuff to paf files
01472 
01473 Revision 1.32  2007/04/04 10:36:18  jim
01474 Modified to use new dfs tags
01475 
01476 Revision 1.31  2007/03/29 12:19:39  jim
01477 Little changes to improve documentation
01478 
01479 Revision 1.30  2007/03/02 12:37:16  jim
01480 Removed WCS stuff from table headers
01481 
01482 Revision 1.29  2007/03/01 12:41:49  jim
01483 Modified slightly after code checking
01484 
01485 Revision 1.28  2007/02/25 06:27:41  jim
01486 plugged a few memory leaks
01487 
01488 Revision 1.27  2007/02/15 11:54:09  jim
01489 Modified to make a distinction between initial channel table and one that
01490 has the proper linearity information
01491 
01492 Revision 1.26  2007/02/15 06:59:38  jim
01493 Added ability to write QC paf files
01494 
01495 Revision 1.25  2007/02/07 10:12:40  jim
01496 Removed calls to vircam_ndit_correct as this is now no longer necessary
01497 
01498 Revision 1.24  2007/02/06 13:11:12  jim
01499 Fixed entry for PRO dictionary in cpl_dfs_set_product_header
01500 
01501 Revision 1.23  2007/02/05 14:14:05  jim
01502 Input master frame is now tagged as REFERENCE. QC removed from stats table
01503 headers
01504 
01505 Revision 1.22  2007/01/08 19:09:11  jim
01506 Fixed memory leak
01507 
01508 Revision 1.21  2006/12/13 13:26:09  jim
01509 Fxied bad sigma estimate
01510 
01511 Revision 1.20  2006/11/27 12:15:08  jim
01512 changed calls to cpl_propertylist_append to cpl_propertylist_update
01513 
01514 Revision 1.19  2006/11/10 09:24:49  jim
01515 Fixed bug in save routine where the wrong propertylist was being saved
01516 
01517 Revision 1.18  2006/09/29 11:19:31  jim
01518 changed aliases on parameter names
01519 
01520 Revision 1.17  2006/09/10 20:47:03  jim
01521 Small documentation fix
01522 
01523 Revision 1.16  2006/09/09 16:49:40  jim
01524 Header comment update
01525 
01526 Revision 1.15  2006/08/27 20:30:02  jim
01527 Major mods to structure of the main processing routine to deal with missing
01528 and dummy frames. Deals better with lower level failures too
01529 
01530 Revision 1.14  2006/07/11 14:55:12  jim
01531 Now checks for zeros in the output flat and replaces them
01532 
01533 Revision 1.13  2006/06/20 19:07:01  jim
01534 Corrects for ndit != 1
01535 
01536 Revision 1.12  2006/06/15 09:58:58  jim
01537 Minor changes to docs
01538 
01539 Revision 1.11  2006/06/09 11:26:25  jim
01540 Small changes to keep lint happy
01541 
01542 Revision 1.10  2006/06/06 13:01:40  jim
01543 Fixed so that the QC parameters go into the correct headers
01544 
01545 Revision 1.9  2006/05/26 19:34:18  jim
01546 Fixed recipe to normalise the flats
01547 
01548 Revision 1.8  2006/05/17 14:43:58  jim
01549 Fixed problem in save routine which messed up the PRO CATG keywords
01550 
01551 Revision 1.7  2006/05/16 13:58:47  jim
01552 Fixed memory leaks that occur from not closing images at the end of
01553 the image extension loop
01554 
01555 Revision 1.6  2006/05/09 08:54:40  jim
01556 Fixed _save routine so that the confidence map is saved as a signed 16 bit
01557 integer
01558 
01559 Revision 1.5  2006/05/08 14:54:03  jim
01560 Fixed little bug where the confidence map file name wasn't being declared to
01561 the header correctly
01562 
01563 Revision 1.4  2006/05/08 13:20:23  jim
01564 Fixed bug where the fitslist for the flats got deleted twice
01565 
01566 Revision 1.3  2006/05/04 11:53:15  jim
01567 Fixed the way the _save routine works to be more consistent with the
01568 standard CPL way of doing things
01569 
01570 Revision 1.2  2006/04/27 14:21:26  jim
01571 Renamed undefined tag
01572 
01573 Revision 1.1  2006/04/27 09:44:47  jim
01574 new file
01575 
01576 */

Generated on 7 Feb 2011 for VIRCAM Pipeline by  doxygen 1.6.1