vircam_twilight_flat_combine.c

00001 /* $Id: vircam_twilight_flat_combine.c,v 1.57 2012/01/16 12:32:18 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2012/01/16 12:32:18 $
00024  * $Revision: 1.57 $
00025  * $Name: vcam-1_3_0 $
00026  */
00027 
00028 /* Includes */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 #include <stdio.h>
00035 #include <cpl.h>
00036 #include <math.h>
00037 
00038 #include "vircam_utils.h"
00039 #include "vircam_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     cpl_size         *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 j,jst,jfn,retval,status,live,nx,ny,ndit,npts;
00504     cpl_size nlab;
00505     long i;
00506     cpl_parameter *p;
00507     vir_fits *ff;
00508     cpl_propertylist *pp;
00509     cpl_image *im1,*im2,*newim,*diffim;
00510     double val1,val2,scl;
00511     float *data,med,mad;
00512     unsigned char *bpm;
00513 
00514     /* Check validity of input frameset */
00515 
00516     if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00517         cpl_msg_error(fctid,"Input framelist NULL or has no input data");
00518         return(-1);
00519     }
00520 
00521     /* Check the files in the frameset */
00522 
00523     if (vircam_frameset_fexists(framelist) != VIR_OK) {
00524         cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00525         return(-1);
00526     }
00527 
00528     /* Initialise some things */
00529 
00530     vircam_twilight_flat_combine_init();
00531     we_expect = MEANTWI + CONFMAP;
00532 
00533     /* Get the parameters */
00534 
00535     p = cpl_parameterlist_find(parlist,"vircam.vircam_twilight_flat_combine.lthr");
00536     vircam_twilight_flat_combine_config.lthr = 
00537         (float)cpl_parameter_get_double(p);
00538     p = cpl_parameterlist_find(parlist,
00539                                "vircam.vircam_twilight_flat_combine.hthr");
00540     vircam_twilight_flat_combine_config.hthr = 
00541         (float)cpl_parameter_get_double(p);
00542     p = cpl_parameterlist_find(parlist,
00543                                "vircam.vircam_twilight_flat_combine.combtype");
00544     vircam_twilight_flat_combine_config.combtype = cpl_parameter_get_int(p);
00545     p = cpl_parameterlist_find(parlist,
00546                                "vircam.vircam_twilight_flat_combine.scaletype");
00547     vircam_twilight_flat_combine_config.scaletype = cpl_parameter_get_int(p);
00548     p = cpl_parameterlist_find(parlist,
00549                                "vircam.vircam_twilight_flat_combine.xrej");
00550     vircam_twilight_flat_combine_config.xrej = cpl_parameter_get_bool(p);
00551     p = cpl_parameterlist_find(parlist,
00552                                "vircam.vircam_twilight_flat_combine.thresh");
00553     vircam_twilight_flat_combine_config.thresh = 
00554         (float)cpl_parameter_get_double(p);
00555     p = cpl_parameterlist_find(parlist,
00556                                "vircam.vircam_twilight_flat_combine.ncells");
00557     vircam_twilight_flat_combine_config.ncells = cpl_parameter_get_int(p);
00558     p = cpl_parameterlist_find(parlist,
00559                                "vircam.vircam_twilight_flat_combine.extenum");
00560     vircam_twilight_flat_combine_config.extenum = cpl_parameter_get_int(p);
00561 
00562     /* Sort out raw from calib frames */
00563 
00564     if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00565         cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00566         vircam_twilight_flat_combine_tidy(2);
00567         return(-1);
00568     }
00569 
00570     /* Get the twilight frames */
00571 
00572     if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00573                                            &nlab)) == NULL) {
00574         cpl_msg_error(fctid,"Cannot labelise the input frames");
00575         vircam_twilight_flat_combine_tidy(2);
00576         return(-1);
00577     }
00578     if ((ps.twilightlist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00579                                                     VIRCAM_TWI_RAW)) == NULL) {
00580         cpl_msg_error(fctid,"Cannot find twilight frames in input frameset");
00581         vircam_twilight_flat_combine_tidy(2);
00582         return(-1);
00583     }
00584     ps.ntwilights = cpl_frameset_get_size(ps.twilightlist);
00585 
00586     /* Check to see if there is a master dark frame */
00587 
00588     if ((ps.master_dark = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00589                                                      VIRCAM_CAL_DARK)) == NULL) {
00590         cpl_msg_error(fctid,"No master dark found");
00591         vircam_twilight_flat_combine_tidy(2);
00592         return(-1);
00593     }
00594         
00595     /* Check to see if there is a master twilight flat frame */
00596 
00597     if ((ps.master_twilight_flat = vircam_frameset_subgroup_1(framelist,
00598          ps.labels,nlab,VIRCAM_REF_TWILIGHT_FLAT)) == NULL)
00599         cpl_msg_info(fctid,"No master twilight flat found -- no ratio image will be formed");
00600     else
00601         we_expect |= RATIMG;
00602         
00603     /* Check to see if there is a master bad pixel map. If there isn't one 
00604        then look for a confidence map */
00605 
00606     ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00607 
00608     /* Check to see if there is a channel table */
00609 
00610     if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00611                                                  VIRCAM_CAL_CHANTAB)) == NULL) {
00612         if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00613                                                      VIRCAM_CAL_CHANTAB_INIT)) == NULL) {
00614             cpl_msg_info(fctid,"No channel table found -- no ratio image stats and no linearisation will be done");
00615         } else {
00616             cpl_msg_info(fctid,"Channel table is labelled INIT -- no linearisation will be done");
00617             if (we_expect & RATIMG)
00618                 we_expect |= STATS_TAB;
00619         }
00620     } else if (we_expect & RATIMG) {
00621         we_expect |= STATS_TAB;
00622     }
00623 
00624     /* Get the number of DITs */
00625 
00626     pp = cpl_propertylist_load(cpl_frame_get_filename(cpl_frameset_get_frame(ps.twilightlist,0)),0);
00627     if (vircam_pfits_get_ndit(pp,&ndit) != VIR_OK) {
00628         cpl_msg_error(fctid,"No value for NDIT available");
00629         freepropertylist(pp);
00630         vircam_twilight_flat_combine_tidy(2);
00631         return(-1);
00632     }
00633     cpl_propertylist_delete(pp);
00634 
00635     /* Now, how many image extensions do we want to do? If the extension
00636        number is zero, then we loop for all possible extensions. If it
00637        isn't then we just do the extension specified */
00638 
00639     vircam_exten_range(vircam_twilight_flat_combine_config.extenum,
00640                        (const cpl_frame *)cpl_frameset_get_frame(ps.twilightlist,0),
00641                        &jst,&jfn);
00642     if (jst == -1 || jfn == -1) {
00643         cpl_msg_error(fctid,"Unable to continue");
00644         vircam_twilight_flat_combine_tidy(2);
00645         return(-1);
00646     }
00647 
00648     /* Get some space for the good frames */
00649 
00650     ps.good = cpl_malloc(ps.ntwilights*sizeof(vir_fits *));
00651 
00652     /* Now loop for all the extension... */
00653 
00654     for (j = jst; j <= jfn; j++) {
00655         status = VIR_OK;
00656         we_get = 0;
00657         isfirst = (j == jst);
00658 
00659         /* Load the images and the master dark. */
00660 
00661         ps.twilights = vircam_fits_load_list(ps.twilightlist,CPL_TYPE_FLOAT,j);
00662         if (ps.twilights == NULL) {
00663             cpl_msg_info(fctid,
00664                          "Extension %" CPL_SIZE_FORMAT " twilights wouldn't load",
00665                          (cpl_size)j);
00666             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00667             if (retval != 0)
00668                 return(-1);
00669             continue;
00670         }
00671 
00672         /* Are any of these twilight flats any good? */
00673         
00674         ps.ngood = 0;
00675         for (i = 0; i < ps.ntwilights; i++) {
00676             ff = ps.twilights[i];
00677             vircam_pfits_get_detlive(vircam_fits_get_ehu(ff),&live);
00678             if (! live) {
00679                 cpl_msg_info(fctid,"Detector flagged dead %s",
00680                              vircam_fits_get_fullname(ff));
00681                 vircam_fits_set_error(ff,VIR_FATAL);
00682             } else {
00683                 ps.good[ps.ngood] = ff;
00684                 ps.ngood += 1;
00685             }
00686         }
00687 
00688         /* If there are no good images, then signal that we need to create 
00689            dummy products and move on */
00690 
00691         if (ps.ngood == 0) {
00692             cpl_msg_info(fctid,"All images flagged bad for this extension");
00693             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00694             if (retval != 0)
00695                 return(-1);
00696             continue;
00697         }
00698 
00699         /* Sort out the images that are either over or under exposed */
00700 
00701         vircam_overexp(ps.good,&(ps.ngood),ndit,
00702                        vircam_twilight_flat_combine_config.lthr,
00703                        vircam_twilight_flat_combine_config.hthr,0,
00704                        &(vircam_twilight_flat_combine_config.minv),
00705                        &(vircam_twilight_flat_combine_config.maxv),
00706                        &(vircam_twilight_flat_combine_config.avev));
00707 
00708         /* Check to see how many are left. If there aren't any, then
00709            signal a major error */
00710 
00711         if (ps.ngood == 0) {
00712             cpl_msg_info(fctid,"All images either under or overexposed");
00713             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00714             if (retval != 0)
00715                 return(-1);
00716             continue;
00717         }
00718 
00719         /* Load up the mask */
00720 
00721         nx = (int)cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
00722         ny = (int)cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
00723         if (vircam_mask_load(ps.master_mask,j,nx,ny) == VIR_FATAL) {
00724             cpl_msg_info(fctid,
00725                          "Unable to load mask image %s[%" CPL_SIZE_FORMAT "]",
00726                          vircam_mask_get_filename(ps.master_mask),
00727                          (cpl_size)j);
00728             cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00729             vircam_mask_force(ps.master_mask,nx,ny);
00730         }
00731 
00732         /* Take the middle two exposures and create a scaled difference image
00733            estimate */
00734 
00735         if (ps.ngood > 1) {
00736             i = ps.ngood/2 - 1;
00737             im1 = vircam_fits_get_image(ps.good[i]);
00738             im2 = vircam_fits_get_image(ps.good[i+1]);
00739             val1 = cpl_image_get_median_window(im1,500,500,1000,1000);
00740             val2 = cpl_image_get_median_window(im2,500,500,1000,1000);
00741             val1 /= (double)ndit;
00742             val2 /= (double)ndit;
00743             scl = val1/val2;
00744             newim = cpl_image_multiply_scalar_create(im2,scl);
00745             diffim = cpl_image_subtract_create(im1,newim);
00746             cpl_image_delete(newim);
00747             data = cpl_image_get_data_float(diffim);
00748             bpm = vircam_mask_get_data(ps.master_mask);
00749             npts = nx*ny;
00750             vircam_medmad(data,bpm,npts,&med,&mad);
00751             mad *= 1.48/CPL_MATH_SQRT2;
00752             vircam_twilight_flat_combine_config.photnoise = mad;
00753             vircam_twilight_flat_combine_config.snratio = 
00754                 val1*sqrt((double)(ps.ngood))/mad;
00755             cpl_image_delete(diffim);
00756         } else {
00757             vircam_twilight_flat_combine_config.photnoise = 0.0;
00758             vircam_twilight_flat_combine_config.snratio = 0.0;
00759         }
00760 
00761         /* Right, we want to dark correct, so we need to load the mean 
00762            dark and make sure it isn't a dummy */
00763 
00764         ps.mdark = vircam_fits_load(ps.master_dark,CPL_TYPE_FLOAT,j);
00765         if (ps.mdark == NULL) {
00766             cpl_msg_info(fctid,
00767                          "Can't load master dark for extension %" CPL_SIZE_FORMAT,
00768                          (cpl_size)j);
00769             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00770             if (retval != 0)
00771                 return(-1);
00772             continue;
00773         } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mdark))) {
00774             cpl_msg_info(fctid,
00775                          "Can't master dark extension %" CPL_SIZE_FORMAT " is a dummy",
00776                          (cpl_size)j);
00777             retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00778             if (retval != 0)
00779                 return(-1);
00780             continue;
00781         }
00782 
00783         /* Loop for each image and dark correct */
00784 
00785         cpl_msg_info(fctid,"Dark correcting extension %" CPL_SIZE_FORMAT,
00786                      (cpl_size)j);
00787         for (i = 0; i < ps.ngood; i++)
00788             vircam_darkcor((ps.good)[i],ps.mdark,1.0,&status);
00789 
00790         /* We need to load the channel table (if it exists) for linearisation
00791            and for the ratio image stats table */
00792 
00793         if (ps.chantab != NULL) {
00794             ps.ctable = vircam_tfits_load(ps.chantab,j);
00795             if (ps.ctable == NULL) {
00796                 cpl_msg_info(fctid,
00797                              "Channel table extension %" CPL_SIZE_FORMAT " won't load",
00798                              (cpl_size)j);
00799             } else if (vircam_chantab_verify(vircam_tfits_get_table(ps.ctable)) != VIR_OK) {
00800                 cpl_msg_info(fctid,
00801                              "Channel table extension %" CPL_SIZE_FORMAT " has errors",
00802                              (cpl_size)j);
00803                 freetfits(ps.ctable);
00804             } else { 
00805                 pp = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
00806                                            (cpl_size)j);
00807                 if (vircam_is_dummy(pp)) {
00808                     cpl_msg_info(fctid,
00809                                  "Channel table extensions %" CPL_SIZE_FORMAT " is a dummy",
00810                                  (cpl_size)j);
00811                     freetfits(ps.ctable);
00812                 }
00813                 freepropertylist(pp);
00814             }
00815         } else 
00816             ps.ctable = NULL;
00817                 
00818         /* Loop for each of the input images and linearise it if there
00819            is a channel table */
00820 
00821         if (ps.ctable != NULL) {
00822             cpl_msg_info(fctid,
00823                          "Linearising extension %" CPL_SIZE_FORMAT,
00824                          (cpl_size)j);
00825             for (i = 0; i < ps.ngood; i++)
00826                 (void)vircam_lincor((ps.good)[i],ps.ctable,1,ndit,&status);
00827         }
00828 
00829         /* Correct for ndit */
00830 
00831         for (i = 0; i < ps.ngood; i++) 
00832             (void)vircam_nditcor((ps.good)[i],ndit,&status);
00833 
00834         /* Call the combine module */
00835 
00836         cpl_msg_info(fctid,
00837                      "Doing combination for extension %" CPL_SIZE_FORMAT,
00838                      (cpl_size)j);
00839         (void)vircam_imcombine(ps.good,ps.ngood,
00840                                vircam_twilight_flat_combine_config.combtype,
00841                                vircam_twilight_flat_combine_config.scaletype,
00842                                vircam_twilight_flat_combine_config.xrej,
00843                                vircam_twilight_flat_combine_config.thresh,
00844                                &(ps.outimage),&(ps.rejmask),&(ps.rejplus),
00845                                &(ps.drs),&status);
00846 
00847         /* If these correction and combination routines failed at any stage
00848            then get out of here */
00849 
00850         if (status == VIR_OK) {
00851             we_get |= MEANTWI;
00852             vircam_twilight_flat_combine_normal(j);
00853         } else {
00854             cpl_msg_info(fctid,"A processing step failed");
00855         }
00856 
00857         /* Create any dummies and save the products */
00858         
00859         retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00860         if (retval != 0)
00861             return(-1);
00862 
00863     }
00864     vircam_twilight_flat_combine_tidy(2);
00865     return(0);
00866 }
00867 
00868 
00869 /*---------------------------------------------------------------------------*/
00876 /*---------------------------------------------------------------------------*/
00877 
00878 static int vircam_twilight_flat_combine_save(cpl_frameset *framelist, 
00879                                              cpl_parameterlist *parlist) {
00880     cpl_propertylist *plist,*elist,*p,*pafprop;
00881     int status;
00882     float val;
00883     const char *fctid = "vircam_twilight_flat_combine_save";
00884     const char *outfile = "twilightcomb.fits";
00885     const char *outdiff = "twilightratio.fits";
00886     const char *outdimst = "twilightratiotab.fits";
00887     const char *outconf = "twilightconf.fits";
00888     const char *outfilepaf = "twilightcomb";
00889     const char *outdiffpaf = "twilightratio";
00890     const char *recipeid = "vircam_twilight_flat_combine";
00891 
00892     /* If we need to make a PHU then do that now based on the first frame
00893        in the input frame list */
00894 
00895     if (isfirst) {
00896 
00897         /* Create a new product frame object and define some tags */
00898 
00899         product_frame_mean_twi = cpl_frame_new();
00900         cpl_frame_set_filename(product_frame_mean_twi,outfile);
00901         cpl_frame_set_tag(product_frame_mean_twi,VIRCAM_PRO_TWILIGHT_FLAT);
00902         cpl_frame_set_type(product_frame_mean_twi,CPL_FRAME_TYPE_IMAGE);
00903         cpl_frame_set_group(product_frame_mean_twi,CPL_FRAME_GROUP_PRODUCT);
00904         cpl_frame_set_level(product_frame_mean_twi,CPL_FRAME_LEVEL_FINAL);
00905 
00906         /* Set up the PHU header */
00907 
00908         plist = vircam_fits_get_phu(ps.twilights[0]);
00909         ps.phupaf = vircam_paf_phu_items(plist);
00910         if (ps.master_twilight_flat != NULL) {
00911             cpl_propertylist_update_string(ps.phupaf,"REF_TWILIGHT",
00912                                            cpl_frame_get_filename(ps.master_twilight_flat));
00913             cpl_propertylist_set_comment(ps.phupaf,"REF_TWILIGHT",
00914                                          "Reference twilight flat used");
00915         }
00916         vircam_dfs_set_product_primary_header(plist,product_frame_mean_twi,
00917                                               framelist,parlist,
00918                                               (char *)recipeid,
00919                                               "PRO-1.15",NULL,0);
00920 
00921         /* 'Save' the PHU image */                       
00922 
00923         if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
00924                            CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00925             cpl_msg_error(fctid,"Cannot save product PHU");
00926             cpl_frame_delete(product_frame_mean_twi);
00927             return(-1);
00928         }
00929         cpl_frameset_insert(framelist,product_frame_mean_twi);
00930 
00931         /* Create a new product frame object and define some tags for the
00932            output confidence map */
00933 
00934         product_frame_conf = cpl_frame_new();
00935         cpl_frame_set_filename(product_frame_conf,outconf);
00936         cpl_frame_set_tag(product_frame_conf,VIRCAM_PRO_CONF);
00937         cpl_frame_set_type(product_frame_conf,CPL_FRAME_TYPE_IMAGE);
00938         cpl_frame_set_group(product_frame_conf,CPL_FRAME_GROUP_PRODUCT);
00939         cpl_frame_set_level(product_frame_conf,CPL_FRAME_LEVEL_FINAL);
00940 
00941         /* Set up the PHU header */
00942 
00943         plist = vircam_fits_get_phu(ps.twilights[0]);
00944         vircam_dfs_set_product_primary_header(plist,product_frame_conf,
00945                                               framelist,parlist,
00946                                               (char *)recipeid,"PRO-1.15",
00947                                               NULL,0);
00948 
00949         /* 'Save' the PHU image */                       
00950 
00951         if (cpl_image_save(NULL,outconf,CPL_TYPE_UCHAR,plist,
00952                            CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00953             cpl_msg_error(fctid,"Cannot save product PHU");
00954             cpl_frame_delete(product_frame_conf);
00955             return(-1);
00956         }
00957         cpl_frameset_insert(framelist,product_frame_conf);
00958 
00959         /* Create a new product frame object for the difference image */
00960 
00961         if (we_expect & RATIMG) {
00962             product_frame_ratioimg = cpl_frame_new();
00963             cpl_frame_set_filename(product_frame_ratioimg,outdiff);
00964             cpl_frame_set_tag(product_frame_ratioimg,
00965                               VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT);
00966             cpl_frame_set_type(product_frame_ratioimg,CPL_FRAME_TYPE_IMAGE);
00967             cpl_frame_set_group(product_frame_ratioimg,
00968                                 CPL_FRAME_GROUP_PRODUCT);
00969             cpl_frame_set_level(product_frame_ratioimg,CPL_FRAME_LEVEL_FINAL);
00970 
00971             /* Set up the PHU header */
00972 
00973             plist = vircam_fits_get_phu(ps.twilights[0]);
00974             vircam_dfs_set_product_primary_header(plist,product_frame_ratioimg,
00975                                                   framelist,parlist,
00976                                                   (char *)recipeid,"PRO-1.15",
00977                                                   NULL,0);
00978 
00979             /* 'Save' the PHU image */                   
00980 
00981             if (cpl_image_save(NULL,outdiff,CPL_TYPE_CHAR,plist,
00982                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00983                 cpl_msg_error(fctid,"Cannot save product PHU");
00984                 cpl_frame_delete(product_frame_ratioimg);
00985                 return(-1);
00986             }
00987             cpl_frameset_insert(framelist,product_frame_ratioimg);
00988         }
00989 
00990         /* Create a new product frame object for the difference image stats 
00991            table */
00992 
00993         if (we_expect & STATS_TAB) {
00994             product_frame_ratioimg_stats = cpl_frame_new();
00995             cpl_frame_set_filename(product_frame_ratioimg_stats,outdimst);
00996             cpl_frame_set_tag(product_frame_ratioimg_stats,
00997                               VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT_STATS);
00998             cpl_frame_set_type(product_frame_ratioimg_stats,
00999                                CPL_FRAME_TYPE_TABLE);
01000             cpl_frame_set_group(product_frame_ratioimg_stats,
01001                                 CPL_FRAME_GROUP_PRODUCT);
01002             cpl_frame_set_level(product_frame_ratioimg_stats,
01003                                 CPL_FRAME_LEVEL_FINAL);
01004 
01005             /* Set up PHU header */
01006 
01007             plist = vircam_fits_get_phu(ps.twilights[0]);
01008             vircam_dfs_set_product_primary_header(plist,
01009                                                   product_frame_ratioimg_stats,
01010                                                   framelist,parlist,
01011                                                   (char *)recipeid,"PRO-1.15",
01012                                                   NULL,0);
01013 
01014             /* Fiddle with the extension header now */
01015 
01016             elist = vircam_fits_get_ehu(ps.twilights[0]);
01017             p = cpl_propertylist_duplicate(elist);
01018             vircam_merge_propertylists(p,ps.drs);
01019             if (! (we_get & STATS_TAB))
01020                 vircam_dummy_property(p);
01021             vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
01022                                                 framelist,parlist,
01023                                                 (char *)recipeid,
01024                                                 "PRO-1.15",NULL);
01025             status = VIR_OK;
01026             vircam_removewcs(p,&status);
01027 
01028             /* And finally the difference image stats table */
01029 
01030             if (cpl_table_save(ps.ratioimstats,plist,p,outdimst,
01031                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
01032                 cpl_msg_error(fctid,"Cannot save product table extension");
01033                 cpl_propertylist_delete(p);
01034                 return(-1);
01035             }
01036             cpl_propertylist_delete(p);
01037             cpl_frameset_insert(framelist,product_frame_ratioimg_stats);
01038         }
01039     }
01040 
01041     /* Get the extension property list */
01042 
01043     plist = vircam_fits_get_ehu(ps.twilights[0]);
01044     vircam_merge_propertylists(plist,ps.drs);
01045     cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
01046 
01047     /* Fiddle with the header now */
01048 
01049     p = cpl_propertylist_duplicate(plist);
01050     if (! (we_get & MEANTWI)) 
01051         vircam_dummy_property(p);
01052     vircam_dfs_set_product_exten_header(p,product_frame_mean_twi,framelist,
01053                                         parlist,(char *)recipeid,
01054                                         "PRO-1.15",NULL);
01055                 
01056     /* Now save the mean twilight flat image extension */
01057 
01058     cpl_propertylist_update_float(p,"ESO QC FLATRMS",
01059                                   vircam_twilight_flat_combine_config.flatrms);
01060     cpl_propertylist_set_comment(p,"ESO QC FLATRMS","RMS of output flat");
01061     cpl_propertylist_update_float(p,"ESO QC FLATMIN",
01062                                   vircam_twilight_flat_combine_config.minv);
01063     cpl_propertylist_set_comment(p,"ESO QC FLATMIN","Ensemble minimum");
01064     cpl_propertylist_update_float(p,"ESO QC FLATMAX",
01065                                   vircam_twilight_flat_combine_config.maxv);
01066     cpl_propertylist_set_comment(p,"ESO QC FLATMAX","Ensemble maximum");
01067     cpl_propertylist_update_float(p,"ESO QC FLATAVG",
01068                                   vircam_twilight_flat_combine_config.avev);
01069     cpl_propertylist_set_comment(p,"ESO QC FLATAVG","Ensemble average");
01070     val = vircam_twilight_flat_combine_config.maxv - 
01071         vircam_twilight_flat_combine_config.minv;
01072     cpl_propertylist_update_float(p,"ESO QC FLATRNG",val);
01073     cpl_propertylist_set_comment(p,"ESO QC FLATRNG","Ensemble range");
01074     cpl_propertylist_update_float(p,"ESO QC TWIPHOT",
01075                                   vircam_twilight_flat_combine_config.photnoise);
01076     cpl_propertylist_set_comment(p,"ESO QC TWIPHOT",
01077                                  "[adu] Estimated photon noise");
01078     cpl_propertylist_update_float(p,"ESO QC TWISNRATIO",
01079                                   vircam_twilight_flat_combine_config.snratio);
01080     cpl_propertylist_set_comment(p,"ESO QC TWISNRATIO","Estimated S/N ratio");
01081     if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,p,
01082                        CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01083         cpl_msg_error(fctid,"Cannot save product image extension");
01084         cpl_propertylist_delete(p);
01085         return(-1);
01086     }
01087 
01088     /* Write out PAF for mean image */
01089 
01090     pafprop = vircam_paf_req_items(p);
01091     vircam_merge_propertylists(pafprop,ps.phupaf);
01092     vircam_paf_append(pafprop,vircam_fits_get_phu(ps.twilights[0]),
01093                       "ESO INS FILT1 NAME");
01094     vircam_paf_append(pafprop,p,"ESO PRO CATG");
01095     vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
01096     vircam_paf_append(pafprop,p,"ESO DET NDIT");
01097     if (vircam_paf_print((char *)outfilepaf,
01098                          "VIRCAM/vircam_twilight_flat_combine",
01099                          "QC file",pafprop) != VIR_OK)
01100         cpl_msg_warning(fctid,"Unable to save PAF for mean twilight");
01101     cpl_propertylist_delete(pafprop);
01102     cpl_propertylist_delete(p);
01103 
01104     /* Now save the twilight ratio image extension */
01105 
01106     if (we_expect & RATIMG) {
01107         p = cpl_propertylist_duplicate(plist);
01108         if (! (we_get & RATIMG))
01109             vircam_dummy_property(p);
01110         cpl_propertylist_update_float(p,"ESO QC FLATRATIO_MED",
01111                                       vircam_twilight_flat_combine_config.flatratio_med);
01112         cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_MED",
01113                                      "Median of ratio map");
01114         cpl_propertylist_update_float(p,"ESO QC FLATRATIO_RMS",
01115                                       vircam_twilight_flat_combine_config.flatratio_rms);
01116         cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_RMS",
01117                                      "RMS of ratio map");
01118         vircam_dfs_set_product_exten_header(p,product_frame_ratioimg,
01119                                             framelist,parlist,(char *)recipeid,
01120                                             "PRO-1.15",NULL);
01121         if (cpl_image_save(ps.ratioimg,outdiff,CPL_TYPE_FLOAT,p,
01122                            CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01123             cpl_propertylist_delete(p);
01124             cpl_msg_error(fctid,"Cannot save product image extension");
01125             return(-1);
01126         }
01127 
01128         /* Write out PAF for difference image */
01129 
01130         pafprop = vircam_paf_req_items(p);
01131         vircam_merge_propertylists(pafprop,ps.phupaf);
01132         vircam_paf_append(pafprop,vircam_fits_get_phu(ps.twilights[0]),
01133                           "ESO INS FILT1 NAME");
01134         vircam_paf_append(pafprop,p,"ESO PRO CATG");
01135         if (vircam_paf_print((char *)outdiffpaf,
01136                              "VIRCAM/vircam_twilight_flat_combine",
01137                              "QC file",pafprop) != VIR_OK)
01138             cpl_msg_warning(fctid,"Unable to save PAF for twilight ratio image");
01139         cpl_propertylist_delete(pafprop);
01140         cpl_propertylist_delete(p);
01141     }
01142 
01143     /* Now any further ratio image stats tables */
01144 
01145     if (! isfirst && (we_expect & STATS_TAB)) {
01146         p = cpl_propertylist_duplicate(plist);
01147         if (! (we_get & STATS_TAB))
01148             vircam_dummy_property(p);
01149         vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
01150                                             framelist,parlist,(char *)recipeid,
01151                                             "PRO-1.15",NULL);
01152         status = VIR_OK;
01153         vircam_removewcs(p,&status);
01154         if (cpl_table_save(ps.ratioimstats,NULL,p,outdimst,CPL_IO_EXTEND)
01155                            != CPL_ERROR_NONE) {
01156             cpl_msg_error(fctid,"Cannot save product table extension");
01157             cpl_propertylist_delete(p);
01158             return(-1);
01159         }       
01160         cpl_propertylist_delete(p);
01161     }
01162 
01163     /* Fiddle with the header now */
01164 
01165     vircam_merge_propertylists(plist,ps.drs2);
01166     p = cpl_propertylist_duplicate(plist);
01167     if (! (we_get & CONFMAP)) 
01168         vircam_dummy_property(p);
01169 
01170     /* Now save the confidence map */
01171 
01172     vircam_dfs_set_product_exten_header(p,product_frame_conf,framelist,
01173                                         parlist,(char *)recipeid,"PRO-1.15",
01174                                         NULL);
01175     if (cpl_image_save(ps.outconf,outconf,CPL_TYPE_SHORT,p,
01176                        CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01177         cpl_msg_error(fctid,"Cannot save product image extension");
01178         cpl_propertylist_delete(p);
01179         return(-1);
01180     }
01181     cpl_propertylist_delete(p);
01182 
01183     /* Get out of here */
01184 
01185     return(0);
01186 }
01187 
01188 /*---------------------------------------------------------------------------*/
01192 /*---------------------------------------------------------------------------*/
01193 
01194 static void vircam_twilight_flat_combine_dummy_products(void) {
01195 
01196     /* See if you even need to be here */
01197 
01198     if (we_get == we_expect)
01199         return;
01200 
01201     /* First an output combined twilight frame */
01202 
01203     if (! (we_get & MEANTWI)) {
01204         ps.outimage = vircam_dummy_image(ps.twilights[0]);
01205         vircam_twilight_flat_combine_config.flatrms = 0.0;
01206     }
01207 
01208     /* Now the confidence map */
01209 
01210     if (! (we_get & CONFMAP)) {
01211         ps.outconf = vircam_dummy_image(ps.twilights[0]);
01212         vircam_twilight_flat_combine_config.flatrms = 0.0;
01213     }
01214 
01215     /* Do a ratio image */
01216 
01217     if ((we_expect & RATIMG) && ! (we_get & RATIMG)) {
01218         vircam_twilight_flat_combine_config.flatratio_med = 0.0;
01219         vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
01220         ps.ratioimg = vircam_dummy_image(ps.twilights[0]);
01221     }
01222 
01223     /* If a ratio image stats table is required, then do that now */
01224    
01225     if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB)) 
01226         ps.ratioimstats = vircam_create_diffimg_stats(0);
01227 
01228     return;
01229 }
01230 
01231 /*---------------------------------------------------------------------------*/
01236 /*---------------------------------------------------------------------------*/
01237 
01238 static void vircam_twilight_flat_combine_normal(int jext) {
01239     int nx,ny,ncells,status;
01240     long i,npi;
01241     unsigned char *bpm;
01242     float *idata,med,sig,gdiff,grms;
01243     const char *fctid="vircam_twilight_flat_combine_normal";
01244 
01245     /* Load up a bad pixel mask */
01246 
01247     nx = (int)cpl_image_get_size_x(ps.outimage);
01248     ny = (int)cpl_image_get_size_y(ps.outimage);
01249     npi = nx*ny;
01250     vircam_mask_load(ps.master_mask,jext,nx,ny);
01251     bpm = vircam_mask_get_data(ps.master_mask);
01252 
01253     /* Create the bad pixel mask */
01254     
01255     status = VIR_OK;
01256     (void)vircam_mkconf(ps.outimage,(char *)"None Available",ps.master_mask,
01257                         &(ps.outconf),&(ps.drs2),&status);
01258     if (status == VIR_OK) 
01259         we_get |= CONFMAP;
01260     else {
01261         cpl_msg_info(fctid,
01262                      "Confidence map creation failed extension %" CPL_SIZE_FORMAT,
01263                      (cpl_size)jext);
01264         status = VIR_OK;
01265     }
01266         
01267     /* Work out the RMS of the mean twilight frame */
01268 
01269     idata = cpl_image_get_data(ps.outimage);
01270     vircam_medsig(idata,bpm,npi,&med,&sig);
01271 
01272     /* Fill in the bad bits... */
01273 
01274     for (i = 0; i < npi; i++)
01275         if (bpm[i])
01276             idata[i] = med;
01277 
01278     /* Divide through by the median */
01279 
01280     cpl_propertylist_update_float(ps.drs,"ESO DRS MEDFLAT",med);
01281     cpl_propertylist_set_comment(ps.drs,"ESO DRS MEDFLAT",
01282                                  "Median value before normalisation");
01283     cpl_image_divide_scalar(ps.outimage,med);
01284     vircam_medmad(idata,bpm,npi,&med,&sig);
01285     sig *= 1.48;
01286     vircam_twilight_flat_combine_config.flatrms = sig;
01287 
01288     /* Load up the master twilight flat */
01289 
01290     if (ps.master_twilight_flat != NULL) {
01291         ps.mfimage = vircam_fits_load(ps.master_twilight_flat,CPL_TYPE_FLOAT,jext);
01292         if (ps.mfimage == NULL) {
01293             cpl_msg_info(fctid,
01294                          "Master twilight extension %" CPL_SIZE_FORMAT " won't load",
01295                          (cpl_size)jext);
01296         } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mfimage))) {
01297             cpl_msg_info(fctid,
01298                          "Master twilight extension %" CPL_SIZE_FORMAT " is a dummy",
01299                          (cpl_size)jext);
01300             freefits(ps.mfimage);
01301         }
01302     } else
01303         ps.mfimage = NULL;
01304 
01305 
01306     /* Create a ratio image. NB: the difference image routine copes if the 
01307        input mean image or the channel tables are null.  Thus if either or
01308        both are null because of a failure to load, then the routine will do
01309        as  much as it can and return, allowing you to fill in the rest with
01310        dummy products */
01311 
01312     vircam_twilight_flat_combine_config.flatratio_med = 0.0;
01313     vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
01314     ncells = vircam_twilight_flat_combine_config.ncells;
01315     vircam_difference_image(vircam_fits_get_image(ps.mfimage),ps.outimage,bpm,
01316                             vircam_tfits_get_table(ps.ctable),ncells,2,
01317                             &gdiff,&grms,&(ps.ratioimg),
01318                             &(ps.ratioimstats));
01319     vircam_mask_clear(ps.master_mask);
01320     vircam_twilight_flat_combine_config.flatratio_med = gdiff;
01321     vircam_twilight_flat_combine_config.flatratio_rms = grms;
01322     if (ps.ratioimg != NULL)
01323         we_get |= RATIMG;
01324     if (ps.ratioimstats != NULL)
01325         we_get |= STATS_TAB;
01326     return;
01327 }
01328 
01329 /*---------------------------------------------------------------------------*/
01337 /*---------------------------------------------------------------------------*/
01338 
01339 
01340 static int vircam_twilight_flat_combine_lastbit(int jext, 
01341                                                 cpl_frameset *framelist,
01342                                                 cpl_parameterlist *parlist) {
01343     int retval;
01344     const char *fctid="vircam_twilight_flat_combine_lastbit";
01345 
01346     /* Make whatever dummy products you need */
01347 
01348     vircam_twilight_flat_combine_dummy_products();
01349 
01350     /* Save everything */
01351 
01352     cpl_msg_info(fctid,
01353                  "Saving products for extension %" CPL_SIZE_FORMAT,
01354                  (cpl_size)jext);
01355     retval = vircam_twilight_flat_combine_save(framelist,parlist);
01356     if (retval != 0) {
01357         vircam_twilight_flat_combine_tidy(2);
01358         return(-1);
01359     }
01360 
01361     /* Free some stuff up */
01362 
01363     vircam_twilight_flat_combine_tidy(1);
01364     return(0);
01365 }
01366 
01367 /*---------------------------------------------------------------------------*/
01371 /*---------------------------------------------------------------------------*/
01372 
01373 static void vircam_twilight_flat_combine_init(void) {
01374     ps.labels = NULL;
01375     ps.twilightlist = NULL;
01376     ps.twilights = NULL;
01377     ps.good = NULL;
01378     ps.master_dark = NULL;
01379     ps.master_twilight_flat = NULL;
01380     ps.master_mask = NULL;
01381     ps.chantab = NULL;
01382     ps.ctable = NULL;
01383     ps.outimage = NULL;
01384     ps.outconf = NULL;
01385     ps.drs = NULL;
01386     ps.drs2 = NULL;
01387     ps.rejmask = NULL;
01388     ps.rejplus = NULL;
01389     ps.mfimage = NULL;
01390     ps.ratioimg = NULL;
01391     ps.ratioimstats = NULL;
01392     ps.phupaf = NULL;
01393 }
01394 
01395 /*---------------------------------------------------------------------------*/
01399 /*---------------------------------------------------------------------------*/
01400 
01401 static void vircam_twilight_flat_combine_tidy(int level) {
01402     freeimage(ps.outimage);
01403     freeimage(ps.outconf);
01404     freefitslist(ps.twilights,ps.ntwilights);
01405     freepropertylist(ps.drs);
01406     freepropertylist(ps.drs2);
01407     freespace(ps.rejmask);
01408     freespace(ps.rejplus);
01409     freefits(ps.mfimage);
01410     freeimage(ps.ratioimg);
01411     freetable(ps.ratioimstats);
01412     freetfits(ps.ctable);
01413     freefits(ps.mdark);
01414     if (level == 1)
01415         return;
01416 
01417     freespace(ps.good);
01418     freespace(ps.labels);
01419     freeframeset(ps.twilightlist);
01420     freeframe(ps.master_dark);
01421     freeframe(ps.master_twilight_flat);
01422     freemask(ps.master_mask);
01423     freeframe(ps.chantab);
01424     freepropertylist(ps.phupaf);
01425 }
01426 
01429 /*
01430 
01431 $Log: vircam_twilight_flat_combine.c,v $
01432 Revision 1.57  2012/01/16 12:32:18  jim
01433 A few more changes to fit in with cpl6
01434 
01435 Revision 1.56  2012/01/15 17:40:09  jim
01436 Minor modifications to take into accout the changes in cpl API for v6
01437 
01438 Revision 1.55  2011/05/09 09:58:10  jim
01439 Cosmetic changes to stop compiler warnings
01440 
01441 Revision 1.54  2010/12/09 13:21:36  jim
01442 Added code to calculate rough photon noise and s/n ratio
01443 
01444 Revision 1.53  2010/03/21 06:48:21  jim
01445 Fixed bug where DATANCOM wasn't being updated in all products
01446 
01447 Revision 1.52  2010/03/09 14:27:40  jim
01448 Now updates ESO PRO DATANCOM to reflect the number of images used
01449 
01450 Revision 1.51  2010/02/05 09:42:22  jim
01451 Fixed call to non-existent cpl routine
01452 
01453 Revision 1.50  2010/01/31 18:53:22  jim
01454 Reference flat included in paf
01455 
01456 Revision 1.49  2009/12/11 06:52:56  jim
01457 Minor mods to documentation
01458 
01459 Revision 1.48  2009/11/18 21:32:40  jim
01460 Modified to write NDIT to the paf
01461 
01462 Revision 1.47  2009/09/21 11:59:37  jim
01463 Modified to use new version of vircam_overexp and to write ensemble stats
01464 to QC headers
01465 
01466 Revision 1.46  2009/09/09 09:50:21  jim
01467 Modified to try and get headers right
01468 
01469 Revision 1.45  2008/12/05 13:28:32  jim
01470 Fixed save routine so that the correct version of PRO CATG is written to the
01471 paf file
01472 
01473 Revision 1.44  2008/11/26 18:33:59  jim
01474 Now fills bad pixels in the output flat with a median value before normalisation
01475 
01476 Revision 1.43  2008/10/01 04:59:13  jim
01477 Added call to vircam_frameset_fexists to check input frameset
01478 
01479 Revision 1.42  2008/09/30 11:33:23  jim
01480 Added PRO CATG to pafs
01481 
01482 Revision 1.41  2008/09/29 11:21:47  jim
01483 Default is to form medians
01484 
01485 Revision 1.40  2007/11/26 09:59:06  jim
01486 Recipe now takes ndit into account when doing linearity correction
01487 
01488 Revision 1.39  2007/10/19 09:25:09  jim
01489 Fixed problems with missing includes
01490 
01491 Revision 1.38  2007/10/15 12:53:26  jim
01492 Modified for compatibiliity with cpl_4.0
01493 
01494 Revision 1.37  2007/07/18 15:35:42  jim
01495 Added better error handling for missing or corrupt mask extensions
01496 
01497 Revision 1.36  2007/07/09 13:21:56  jim
01498 Modified to use new version of vircam_exten_range
01499 
01500 Revision 1.35  2007/06/13 08:11:27  jim
01501 Modified docs to reflect changes in DFS tags
01502 
01503 Revision 1.34  2007/05/08 10:42:33  jim
01504 Added DRS MEDFLAT keyword
01505 
01506 Revision 1.33  2007/04/30 09:40:17  jim
01507 Added more stuff to paf files
01508 
01509 Revision 1.32  2007/04/04 10:36:18  jim
01510 Modified to use new dfs tags
01511 
01512 Revision 1.31  2007/03/29 12:19:39  jim
01513 Little changes to improve documentation
01514 
01515 Revision 1.30  2007/03/02 12:37:16  jim
01516 Removed WCS stuff from table headers
01517 
01518 Revision 1.29  2007/03/01 12:41:49  jim
01519 Modified slightly after code checking
01520 
01521 Revision 1.28  2007/02/25 06:27:41  jim
01522 plugged a few memory leaks
01523 
01524 Revision 1.27  2007/02/15 11:54:09  jim
01525 Modified to make a distinction between initial channel table and one that
01526 has the proper linearity information
01527 
01528 Revision 1.26  2007/02/15 06:59:38  jim
01529 Added ability to write QC paf files
01530 
01531 Revision 1.25  2007/02/07 10:12:40  jim
01532 Removed calls to vircam_ndit_correct as this is now no longer necessary
01533 
01534 Revision 1.24  2007/02/06 13:11:12  jim
01535 Fixed entry for PRO dictionary in cpl_dfs_set_product_header
01536 
01537 Revision 1.23  2007/02/05 14:14:05  jim
01538 Input master frame is now tagged as REFERENCE. QC removed from stats table
01539 headers
01540 
01541 Revision 1.22  2007/01/08 19:09:11  jim
01542 Fixed memory leak
01543 
01544 Revision 1.21  2006/12/13 13:26:09  jim
01545 Fxied bad sigma estimate
01546 
01547 Revision 1.20  2006/11/27 12:15:08  jim
01548 changed calls to cpl_propertylist_append to cpl_propertylist_update
01549 
01550 Revision 1.19  2006/11/10 09:24:49  jim
01551 Fixed bug in save routine where the wrong propertylist was being saved
01552 
01553 Revision 1.18  2006/09/29 11:19:31  jim
01554 changed aliases on parameter names
01555 
01556 Revision 1.17  2006/09/10 20:47:03  jim
01557 Small documentation fix
01558 
01559 Revision 1.16  2006/09/09 16:49:40  jim
01560 Header comment update
01561 
01562 Revision 1.15  2006/08/27 20:30:02  jim
01563 Major mods to structure of the main processing routine to deal with missing
01564 and dummy frames. Deals better with lower level failures too
01565 
01566 Revision 1.14  2006/07/11 14:55:12  jim
01567 Now checks for zeros in the output flat and replaces them
01568 
01569 Revision 1.13  2006/06/20 19:07:01  jim
01570 Corrects for ndit != 1
01571 
01572 Revision 1.12  2006/06/15 09:58:58  jim
01573 Minor changes to docs
01574 
01575 Revision 1.11  2006/06/09 11:26:25  jim
01576 Small changes to keep lint happy
01577 
01578 Revision 1.10  2006/06/06 13:01:40  jim
01579 Fixed so that the QC parameters go into the correct headers
01580 
01581 Revision 1.9  2006/05/26 19:34:18  jim
01582 Fixed recipe to normalise the flats
01583 
01584 Revision 1.8  2006/05/17 14:43:58  jim
01585 Fixed problem in save routine which messed up the PRO CATG keywords
01586 
01587 Revision 1.7  2006/05/16 13:58:47  jim
01588 Fixed memory leaks that occur from not closing images at the end of
01589 the image extension loop
01590 
01591 Revision 1.6  2006/05/09 08:54:40  jim
01592 Fixed _save routine so that the confidence map is saved as a signed 16 bit
01593 integer
01594 
01595 Revision 1.5  2006/05/08 14:54:03  jim
01596 Fixed little bug where the confidence map file name wasn't being declared to
01597 the header correctly
01598 
01599 Revision 1.4  2006/05/08 13:20:23  jim
01600 Fixed bug where the fitslist for the flats got deleted twice
01601 
01602 Revision 1.3  2006/05/04 11:53:15  jim
01603 Fixed the way the _save routine works to be more consistent with the
01604 standard CPL way of doing things
01605 
01606 Revision 1.2  2006/04/27 14:21:26  jim
01607 Renamed undefined tag
01608 
01609 Revision 1.1  2006/04/27 09:44:47  jim
01610 new file
01611 
01612 */

Generated on 15 Mar 2012 for VIRCAM Pipeline by  doxygen 1.6.1