hawki_cal_dark.c

00001 /* $Id: hawki_cal_dark.c,v 1.20 2010/10/27 10:26:57 cgarcia Exp $
00002  *
00003  * This file is part of the HAWKI Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
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: cgarcia $
00023  * $Date: 2010/10/27 10:26:57 $
00024  * $Revision: 1.20 $
00025  * $Name: hawki-1_8_0 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <math.h>
00037 #include <cpl.h>
00038 
00039 #include "irplib_utils.h"
00040 
00041 #include "hawki_utils.h"
00042 #include "hawki_image_stats.h"
00043 #include "hawki_pfits.h"
00044 #include "hawki_dfs.h"
00045 #include "hawki_load.h"
00046 #include "hawki_save.h"
00047 #include "hawki_variance.h"
00048 
00049 /*-----------------------------------------------------------------------------
00050                             Functions prototypes
00051  -----------------------------------------------------------------------------*/
00052 
00053 static int hawki_cal_dark_create(cpl_plugin *) ;
00054 static int hawki_cal_dark_exec(cpl_plugin *) ;
00055 static int hawki_cal_dark_destroy(cpl_plugin *) ;
00056 static int hawki_cal_dark(cpl_parameterlist *, cpl_frameset *) ;
00057 
00058 void hawki_cal_dark_initialise_qc(void);
00059 static int hawki_cal_dark_retrieve_input_param
00060 (cpl_parameterlist * parlist);
00061 static double hawki_cal_dark_ron(const cpl_image *, const cpl_image *, int) ;
00062 static int hawki_cal_dark_save
00063 (const cpl_imagelist *   dark,
00064  const cpl_imagelist *   master_dark_err,
00065  const cpl_imagelist *   bpmdark,
00066  cpl_table           **  raw_dark_stats,
00067  const cpl_vector    **  rons,
00068  const cpl_frameset  *   used_frames,
00069  cpl_parameterlist   *   parlist,
00070  cpl_frameset        *   set);
00071 
00072 /*-----------------------------------------------------------------------------
00073                             Static variables
00074  -----------------------------------------------------------------------------*/
00075 
00076 static struct {
00077     /* Inputs */
00078     int         hsize ;
00079     int         nsamples ;
00080     double      sigma ;
00081     int         llx ;
00082     int         lly ;
00083     int         urx ;
00084     int         ury ;
00085     double      gain;
00086     double      ron;
00087     int         error_tracking;
00088 } hawki_cal_dark_config ;
00089 
00090 static struct {
00091     /* Outputs */
00092     int         nb_badpix[HAWKI_NB_DETECTORS] ;
00093     double      master_dark_mean[HAWKI_NB_DETECTORS] ;
00094     double      master_dark_med[HAWKI_NB_DETECTORS] ;
00095     double      master_dark_stdev[HAWKI_NB_DETECTORS] ;
00096     double      master_dark_error_mean[HAWKI_NB_DETECTORS] ;
00097     double      master_dark_error_med[HAWKI_NB_DETECTORS] ;
00098     double      master_dark_error_stdev[HAWKI_NB_DETECTORS] ;
00099     double      vc_mean[HAWKI_NB_DETECTORS][HAWKI_NB_VC] ;
00100     double      vc_med[HAWKI_NB_DETECTORS][HAWKI_NB_VC] ;
00101     double      vc_stdev[HAWKI_NB_DETECTORS][HAWKI_NB_VC] ;
00102     double      dit;
00103     int         ndit;
00104     int         ndsamples;
00105 } hawki_cal_dark_outputs;
00106 
00107 static char hawki_cal_dark_description[] =
00108 "hawki_cal_dark -- Dark recipe\n"
00109 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00110 "raw-file.fits "HAWKI_CAL_DARK_RAW" or\n"
00111 "raw-file.fits "HAWKI_TEC_FLAT_RAW".\n"
00112 "The recipe creates as an output:\n"
00113 "hawki_cal_dark.fits ("HAWKI_CALPRO_DARK"): The master dark\n"
00114 "hawki_cal_dark_bpmdark.fits("HAWKI_CALPRO_BPM_HOT"): The bad pixel mask associated to the dark\n"
00115 "hawki_cal_dark_stats.fits("HAWKI_CALPRO_DARK_STATS"): Statistics of the raw darks\n"
00116 "Optionally it also creates:\n"
00117 "hawki_cal_dark_err.fits("HAWKI_CALPRO_DARK_ERR"): The error in the master dark\n"
00118 "Return code:\n"
00119 "esorex exits with an error code of 0 if the recipe completes successfully\n"
00120 "or 1 otherwise";
00121 
00122 /*-----------------------------------------------------------------------------
00123                                 Functions code
00124  -----------------------------------------------------------------------------*/
00125 
00126 /*----------------------------------------------------------------------------*/
00135 /*----------------------------------------------------------------------------*/
00136 int cpl_plugin_get_info(cpl_pluginlist * list)
00137 {
00138     cpl_recipe  *   recipe = cpl_calloc(1, sizeof *recipe ) ;
00139     cpl_plugin  *   plugin = &recipe->interface ;
00140 
00141     cpl_plugin_init(plugin,
00142                     CPL_PLUGIN_API,
00143                     HAWKI_BINARY_VERSION,
00144                     CPL_PLUGIN_TYPE_RECIPE,
00145                     "hawki_cal_dark",
00146                     "Dark recipe",
00147                     hawki_cal_dark_description,
00148                     "Cesar Enrique Garcia Dabo",
00149                     PACKAGE_BUGREPORT,
00150                     hawki_get_license(),
00151                     hawki_cal_dark_create,
00152                     hawki_cal_dark_exec,
00153                     hawki_cal_dark_destroy) ;
00154 
00155     cpl_pluginlist_append(list, plugin) ;
00156     
00157     return 0;
00158 }
00159 
00160 /*----------------------------------------------------------------------------*/
00168 /*----------------------------------------------------------------------------*/
00169 static int hawki_cal_dark_create(cpl_plugin * plugin)
00170 {
00171     cpl_recipe      *   recipe ;
00172     cpl_parameter   *   p ;
00173         
00174     /* Check that the plugin is part of a valid recipe */
00175     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00176         recipe = (cpl_recipe *)plugin ;
00177     else return -1 ;
00178 
00179     /* Create the parameters list in the cpl_recipe object */
00180     recipe->parameters = cpl_parameterlist_new() ; 
00181 
00182     /* Fill the parameters list */
00183     /* --sigma */
00184     p = cpl_parameter_new_value("hawki.hawki_cal_dark.sigma",
00185             CPL_TYPE_DOUBLE, "sigma for hot bad pixels detection",
00186             "hawki.hawki_cal_dark", 10.0) ;
00187     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sigma") ;
00188     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00189     cpl_parameterlist_append(recipe->parameters, p) ;
00190     /* --nsamples */
00191     p = cpl_parameter_new_value("hawki.hawki_cal_dark.nsamples",
00192             CPL_TYPE_INT, "number of samples for RON computation",
00193             "hawki.hawki_cal_dark", 100) ;
00194     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nsamples") ;
00195     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00196     cpl_parameterlist_append(recipe->parameters, p) ;
00197     /* --hsize */
00198     p = cpl_parameter_new_value("hawki.hawki_cal_dark.hsize",
00199             CPL_TYPE_INT, "half size of the window for RON computation",
00200             "hawki.hawki_cal_dark", 6) ;
00201     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hsize") ;
00202     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00203     cpl_parameterlist_append(recipe->parameters, p) ;
00204     /* --zone */
00205     p = cpl_parameter_new_value("hawki.hawki_cal_dark.zone",
00206                                 CPL_TYPE_STRING,
00207                                 "Stats zone",
00208                                 "hawki.hawki_cal_dark",
00209                                 "512,512,1536,1536") ;
00210     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "zone") ;
00211     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00212     cpl_parameterlist_append(recipe->parameters, p) ;
00213     /* --gain */
00214     p = cpl_parameter_new_value("hawki.hawki_cal_dark.gain",
00215                                 CPL_TYPE_DOUBLE,
00216                                 "Detector nominal gain (e-/ADU)",
00217                                 "hawki.hawki_cal_dark",
00218                                 -1.);
00219     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "gain") ;
00220     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00221     cpl_parameterlist_append(recipe->parameters, p) ;
00222     /* --ron */
00223     p = cpl_parameter_new_value("hawki.hawki_cal_dark.ron",
00224                                 CPL_TYPE_DOUBLE,
00225                                 "Detector nominal RON for a single readout (ADU)",
00226                                 "hawki.hawki_cal_dark",
00227                                 -1.);
00228     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ron") ;
00229     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00230     cpl_parameterlist_append(recipe->parameters, p) ;
00231 
00232     /* Return */
00233     return 0;
00234 }
00235 
00236 /*----------------------------------------------------------------------------*/
00242 /*----------------------------------------------------------------------------*/
00243 static int hawki_cal_dark_exec(cpl_plugin * plugin)
00244 {
00245     cpl_recipe  *   recipe ;
00246     
00247     /* Get the recipe out of the plugin */
00248     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00249         recipe = (cpl_recipe *)plugin ;
00250     else return -1 ;
00251 
00252     /* Issue a banner */
00253     hawki_print_banner();
00254 
00255     return hawki_cal_dark(recipe->parameters, recipe->frames) ;
00256 }
00257 
00258 /*----------------------------------------------------------------------------*/
00264 /*----------------------------------------------------------------------------*/
00265 static int hawki_cal_dark_destroy(cpl_plugin * plugin)
00266 {
00267     cpl_recipe  *   recipe ;
00268     
00269     /* Get the recipe out of the plugin */
00270     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00271         recipe = (cpl_recipe *)plugin ;
00272     else return -1 ;
00273 
00274     cpl_parameterlist_delete(recipe->parameters) ; 
00275     return 0 ;
00276 }
00277 
00278 /*----------------------------------------------------------------------------*/
00285 /*----------------------------------------------------------------------------*/
00286 static int hawki_cal_dark(
00287         cpl_parameterlist   *   parlist, 
00288         cpl_frameset        *   frameset)
00289 {
00290     cpl_frameset        *   rawframes ;
00291     cpl_frame           *   ref_frame ;
00292     cpl_propertylist    *   plist ;
00293     cpl_imagelist       *   darks_raw ;
00294     cpl_imagelist       *   master_dark;
00295     cpl_imagelist       *   master_dark_err;
00296     cpl_imagelist       *   bpmdark;
00297     cpl_image           *   bpm ;
00298     cpl_image           *   ima_curr ;
00299     cpl_image           *   ima_next ;
00300     cpl_image           *   ima_accu ;
00301     cpl_image           *   ima_accu_err = NULL;
00302     int                     nframes ;
00303     cpl_vector          *   rons[HAWKI_NB_DETECTORS] ;
00304     cpl_table           **  raw_dark_stats;
00305     double                  ron ;
00306     int                     vc_urx, vc_ury, vc_llx, vc_lly ;
00307     int                     j, k ;
00308     int                     idet;
00309     cpl_errorstate          error_prevstate;      
00310     
00311     /* Initialise */
00312     rawframes = NULL ;
00313     ima_accu = NULL ;
00314     ima_next = NULL ;
00315     master_dark_err = NULL;
00316     hawki_cal_dark_initialise_qc();
00317 
00318     /* Retrieve input parameters */
00319     if(hawki_cal_dark_retrieve_input_param(parlist))
00320     {
00321         cpl_msg_error(__func__, "Wrong parameters");
00322         return -1;
00323     }
00324  
00325     /* Identify the RAW and CALIB frames in the input frameset */
00326     if (hawki_dfs_set_groups(frameset)) {
00327         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00328         return -1 ;
00329     }
00330         
00331     /* Retrieve raw frames */
00332     rawframes = hawki_extract_frameset(frameset, HAWKI_CAL_DARK_RAW) ;
00333 
00334     /* Test if raw frames have been found */
00335     if (rawframes == NULL) {
00336         cpl_msg_error(__func__, "No raw frame in input (%s)",HAWKI_CAL_DARK_RAW);
00337         return -1 ;
00338     }
00339 
00340     /* At least 3 frames */
00341     if (cpl_frameset_get_size(rawframes) < 3) {
00342         cpl_msg_error(__func__, "Not enough input frames");
00343         cpl_frameset_delete(rawframes) ;
00344         return -1 ;
00345     }
00346     
00347     /* Get DIT / NDIT from the header */
00348     error_prevstate = cpl_errorstate_get();
00349     ref_frame = cpl_frameset_get_frame(rawframes, 0) ;
00350     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00351                     0)) == NULL) {
00352         cpl_msg_error(__func__, "Cannot get header from frame");
00353         cpl_msg_indent_less() ;
00354         cpl_frameset_delete(rawframes) ;
00355         return -1 ;
00356     }
00357     hawki_cal_dark_outputs.dit = hawki_pfits_get_dit(plist) ;
00358     hawki_cal_dark_outputs.ndit = hawki_pfits_get_ndit(plist) ;
00359     hawki_cal_dark_outputs.ndsamples = hawki_pfits_get_ndsamples(plist);
00360     cpl_propertylist_delete(plist) ;
00361     if(!cpl_errorstate_is_equal(error_prevstate))
00362     {
00363         cpl_msg_error(__func__, "Cannot get the DIT/NDIT from the header") ;
00364         cpl_msg_indent_less() ;
00365         cpl_frameset_delete(rawframes) ;
00366         return -1 ;
00367     }
00368     cpl_msg_info(__func__, "DIT value: %g sec.", hawki_cal_dark_outputs.dit) ;
00369     cpl_msg_info(__func__, "NDIT value: %d", hawki_cal_dark_outputs.ndit) ;
00370     cpl_msg_info(__func__, "NDSAMPLES value: %d", hawki_cal_dark_outputs.ndsamples) ;
00371 
00372     /* Number of frames */
00373     nframes = cpl_frameset_get_size(rawframes) ;
00374 
00375     /* Create the statistics table */
00376     raw_dark_stats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *));
00377     for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00378     {
00379         raw_dark_stats[idet] = cpl_table_new(nframes);
00380     }
00381     hawki_image_stats_initialize(raw_dark_stats);
00382     
00383     /* Loop on the detectors */
00384     master_dark = cpl_imagelist_new();
00385     if(hawki_cal_dark_config.error_tracking)
00386         master_dark_err = cpl_imagelist_new();
00387     bpmdark = cpl_imagelist_new();
00388     cpl_msg_info(__func__, "Dark computation");
00389     cpl_msg_indent_more() ;
00390     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
00391         cpl_msg_info(__func__, "Handle chip number %d", idet+1) ;
00392 
00393         /* Create the rons vectors */
00394         rons[idet] = cpl_vector_new(nframes) ;
00395         
00396         /* Load the input data */
00397         darks_raw = hawki_load_detector(rawframes, idet+1, CPL_TYPE_FLOAT) ;
00398 
00399         /* Loop on the frames */
00400         for (j=0 ; j<nframes ; j++) {
00401             /* Load the current and next images */
00402             if (j==nframes-1) {
00403                 ima_curr = cpl_imagelist_get(darks_raw, j) ;
00404                 ima_next = cpl_imagelist_get(darks_raw, 0) ;
00405             } else {
00406                 ima_curr = cpl_imagelist_get(darks_raw, j) ;
00407                 ima_next = cpl_imagelist_get(darks_raw, j+1) ;
00408             }
00409 
00410             /* Compute the dark stats and store in table */
00411             if(hawki_image_stats_fill_from_image
00412                 (raw_dark_stats,
00413                  ima_curr,
00414                  hawki_cal_dark_config.llx,
00415                  hawki_cal_dark_config.lly,
00416                  hawki_cal_dark_config.urx,
00417                  hawki_cal_dark_config.ury,
00418                  idet,
00419                  j) != 0)
00420             {
00421                 cpl_msg_error(__func__, "Cannot compute statistics") ;
00422                 cpl_msg_indent_less() ; 
00423                 cpl_frameset_delete(rawframes) ;
00424                 cpl_imagelist_delete(master_dark);
00425                 if(hawki_cal_dark_config.error_tracking)
00426                     cpl_imagelist_delete(master_dark_err);                
00427                 cpl_imagelist_delete(darks_raw); 
00428                 cpl_imagelist_delete(bpmdark) ;
00429                 for (k=0 ; k<=idet ; k++) 
00430                     cpl_vector_delete(rons[k]) ;
00431                 for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 
00432                     cpl_table_delete(raw_dark_stats[idet]);
00433                 cpl_free(raw_dark_stats);
00434                 return -1 ;
00435             }
00436            
00437             /* Compute the RON */
00438             ron = hawki_cal_dark_ron(ima_curr, ima_next, hawki_cal_dark_outputs.ndit) ;
00439             cpl_vector_set(rons[idet], j, ron);
00440         }
00441         
00442         /* Collapse */
00443         if (nframes > 2)
00444         {
00445             ima_accu = cpl_imagelist_collapse_minmax_create(darks_raw, 0, 1) ;
00446             if(hawki_cal_dark_config.error_tracking)
00447             {
00448                 cpl_imagelist * variances;
00449                 cpl_image     * accu_var;
00450                 cpl_msg_info(__func__, "Computing the uncertainty in dark");
00451                 variances = hawki_imglist_create_variances_and_delete
00452                     (darks_raw, hawki_cal_dark_config.gain, 
00453                      hawki_cal_dark_config.ron, hawki_cal_dark_outputs.ndit,
00454                      hawki_cal_dark_outputs.ndsamples);
00455                 /* The variances are collapsed, like the dark_raw. Given that
00456                  * the variances are a monotically increasing function with
00457                  * respect to the dark_raw, the minmax algorithm will select
00458                  * the same values as for the dark_raw 
00459                  * The nframes - 1 is because only one frame is being rejected*/  
00460                 accu_var = cpl_imagelist_collapse_minmax_create(variances,0,1);
00461                 cpl_image_divide_scalar(accu_var, nframes - 1);
00462                 ima_accu_err = cpl_image_duplicate(accu_var);
00463                 cpl_image_power(ima_accu_err, 0.5);
00464                 cpl_imagelist_delete(variances);
00465                 cpl_image_delete(accu_var);
00466             }
00467 
00468         } else {
00469             ima_accu = cpl_imagelist_collapse_create(darks_raw) ;
00470             if(hawki_cal_dark_config.error_tracking)
00471             {
00472                 cpl_imagelist * variances;
00473                 cpl_image     * accu_var;
00474                 cpl_msg_info(__func__, "Computing the uncertainty in dark");
00475                 variances = hawki_imglist_create_variances_and_delete 
00476                     (darks_raw, hawki_cal_dark_config.gain, 
00477                      hawki_cal_dark_config.ron, hawki_cal_dark_outputs.ndit,
00478                      hawki_cal_dark_outputs.ndsamples);
00479                 accu_var = cpl_imagelist_collapse_create(variances);                
00480                 cpl_image_divide_scalar(accu_var, nframes); 
00481                 ima_accu_err = cpl_image_duplicate(accu_var);
00482                 cpl_image_power(ima_accu_err, 0.5);
00483                 cpl_imagelist_delete(variances);
00484                 cpl_image_delete(accu_var);
00485             }
00486         }
00487         if (ima_accu == NULL) {
00488             cpl_msg_error(__func__, "Cannot compute the average") ;
00489             cpl_frameset_delete(rawframes) ;
00490             cpl_imagelist_delete(bpmdark) ;
00491             cpl_imagelist_delete(master_dark) ;
00492             if(ima_accu_err != NULL)
00493                 cpl_image_delete(ima_accu_err);
00494             cpl_imagelist_delete(darks_raw); 
00495             for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00496                 cpl_vector_delete(rons[idet]) ;
00497             for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 
00498                  cpl_table_delete(raw_dark_stats[idet]);
00499             cpl_free(raw_dark_stats);
00500             return -1 ;
00501         }
00502         cpl_imagelist_delete(darks_raw) ;
00503 
00504         /* Put the result in the list */
00505         cpl_imagelist_set(master_dark, ima_accu, idet) ;
00506         if(hawki_cal_dark_config.error_tracking)
00507             cpl_imagelist_set(master_dark_err, ima_accu_err, idet) ;
00508 
00509         /* Compute the dark_med and stdev */
00510         hawki_cal_dark_outputs.master_dark_med[idet]=
00511             cpl_image_get_median(ima_accu) / hawki_cal_dark_outputs.dit;
00512         hawki_cal_dark_outputs.master_dark_mean[idet] =
00513             cpl_image_get_mean(ima_accu) / hawki_cal_dark_outputs.dit;
00514         hawki_cal_dark_outputs.master_dark_stdev[idet] =
00515             cpl_image_get_stdev(ima_accu) / hawki_cal_dark_outputs.dit;
00516         if(hawki_cal_dark_config.error_tracking)
00517         {
00518             hawki_cal_dark_outputs.master_dark_error_med[idet]=
00519                 cpl_image_get_median(ima_accu_err) / hawki_cal_dark_outputs.dit;
00520             hawki_cal_dark_outputs.master_dark_error_mean[idet] =
00521                 cpl_image_get_mean(ima_accu_err) / hawki_cal_dark_outputs.dit;
00522             hawki_cal_dark_outputs.master_dark_error_stdev[idet] =
00523                 cpl_image_get_stdev(ima_accu_err) / hawki_cal_dark_outputs.dit;
00524         }
00525 
00526         /* Compute the Video Channels stats */
00527         vc_lly = 973 ;
00528         vc_ury = 1036 ;
00529         for (j=0 ; j<HAWKI_NB_VC ; j++) {
00530             vc_llx = j*(2048/HAWKI_NB_VC) + 1 ;
00531             vc_urx = (j+1)*(2048/HAWKI_NB_VC) ;
00532 
00533             hawki_cal_dark_outputs.vc_mean[idet][j] =
00534                 cpl_image_get_mean_window(ima_accu, vc_llx, vc_lly,
00535                         vc_urx, vc_ury) ;
00536 
00537             hawki_cal_dark_outputs.vc_med[idet][j] =
00538                 cpl_image_get_median_window(ima_accu, vc_llx, vc_lly,
00539                         vc_urx, vc_ury) ;
00540 
00541             hawki_cal_dark_outputs.vc_stdev[idet][j] =
00542                 cpl_image_get_stdev_window(ima_accu, vc_llx, vc_lly,
00543                         vc_urx, vc_ury) ;
00544         }
00545 
00546         /* Compute the HOT pixels map */
00547         cpl_msg_info(__func__, "Compute the BPM from the dark") ;
00548         cpl_msg_indent_more() ;
00549         if ((bpm=hawki_compute_darkbpm(ima_accu, 
00550                         hawki_cal_dark_config.sigma)) == NULL) {
00551             cpl_msg_error(__func__, "Cannot compute the hot pixels") ;
00552             cpl_msg_indent_less() ; 
00553             cpl_frameset_delete(rawframes) ;
00554             cpl_imagelist_delete(bpmdark) ;
00555             cpl_imagelist_delete(master_dark);
00556             if(hawki_cal_dark_config.error_tracking)
00557                 cpl_imagelist_delete(master_dark_err);
00558             for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00559                 cpl_vector_delete(rons[idet]) ;
00560             for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 
00561                 cpl_table_delete(raw_dark_stats[idet]);
00562             cpl_free(raw_dark_stats);
00563             return -1 ;
00564         }
00565         cpl_imagelist_set(bpmdark, bpm, idet) ;
00566         hawki_cal_dark_outputs.nb_badpix[idet]=(int)cpl_image_get_flux(bpm);
00567         cpl_msg_indent_less() ;
00568     }
00569     cpl_msg_indent_less() ;
00570     
00571     /* Divide by DIT */
00572     cpl_msg_info(__func__, "Division by DIT") ;
00573     cpl_imagelist_divide_scalar(master_dark, hawki_cal_dark_outputs.dit);
00574     if(hawki_cal_dark_config.error_tracking)
00575         cpl_imagelist_divide_scalar(master_dark_err, hawki_cal_dark_outputs.dit);
00576 
00577     /* Save the product */
00578     cpl_msg_info(__func__, "Save the products") ;
00579     cpl_msg_indent_more() ;
00580     if (hawki_cal_dark_save(master_dark, master_dark_err,
00581                             bpmdark, raw_dark_stats, 
00582                             (const cpl_vector **)rons,
00583                             rawframes,
00584                             parlist, frameset)) 
00585         cpl_msg_warning(__func__,"Some data could not be saved. "
00586                                  "Check permisions or disk space");
00587 
00588     /* Free */
00589     cpl_frameset_delete(rawframes) ;
00590     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00591         cpl_vector_delete(rons[idet]) ;
00592     cpl_imagelist_delete(master_dark) ;
00593     if(hawki_cal_dark_config.error_tracking)
00594         cpl_imagelist_delete(master_dark_err);
00595     cpl_imagelist_delete(bpmdark) ;
00596     cpl_msg_indent_less() ;
00597     for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 
00598          cpl_table_delete(raw_dark_stats[idet]);
00599     cpl_free(raw_dark_stats);
00600 
00601     /* Return */
00602     if (cpl_error_get_code())
00603     {
00604         cpl_msg_error(__func__,
00605                       "HAWK-I pipeline could not recover from previous errors");
00606         return -1 ;
00607     }
00608     else return 0 ;
00609 }
00610 
00611 /*----------------------------------------------------------------------------*/
00619 /*----------------------------------------------------------------------------*/
00620 static double hawki_cal_dark_ron(
00621         const cpl_image     *   ima1, 
00622         const cpl_image     *   ima2, 
00623         int                     ndit) 
00624 {
00625     cpl_image       *   ima ;
00626     double              norm ;
00627     double              ron ;
00628 
00629     /* Test entries */
00630     if (ima1 == NULL)   return -1.0 ;
00631     if (ima2 == NULL)   return -1.0 ;
00632     if (ndit < 1)       return -1.0 ;
00633 
00634     /* Compute norm */
00635     norm = 0.5 * ndit ;
00636     norm = sqrt(norm) ;
00637 
00638     /* Subtraction */
00639     if ((ima = cpl_image_subtract_create(ima2, ima1)) == NULL) return -1.0 ;
00640    
00641     /* RON measurement */
00642     cpl_flux_get_noise_window(ima, NULL, hawki_cal_dark_config.hsize,
00643             hawki_cal_dark_config.nsamples, &ron, NULL) ;
00644     cpl_image_delete(ima) ;
00645     return norm*ron ;
00646 }
00647 
00648 /*----------------------------------------------------------------------------*/
00658 /*----------------------------------------------------------------------------*/
00659 static int hawki_cal_dark_save
00660 (const cpl_imagelist *   master_dark,
00661  const cpl_imagelist *   master_dark_err,
00662  const cpl_imagelist *   bpmdark,
00663  cpl_table           **  raw_dark_stats,
00664  const cpl_vector    **  rons,
00665  const cpl_frameset  *   used_frames,
00666  cpl_parameterlist   *   parlist,
00667  cpl_frameset        *   set)
00668 {
00669     cpl_propertylist    **  qclists ;
00670     const cpl_frame     *   ref_frame ;
00671     char                    sval[32] ;
00672     cpl_propertylist    *   inputlist ;
00673     int                     ext_nb ;
00674     const char          *   recipe_name = "hawki_cal_dark" ;
00675     int                     i, j ;
00676     cpl_errorstate          error_prevstate = cpl_errorstate_get();
00677     
00678 
00679     /* Get the reference frame */
00680     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00681 
00682     /* Create the QC lists */
00683     qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00684     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00685         qclists[i] = cpl_propertylist_new();
00686         cpl_propertylist_append_int(qclists[i], "ESO QC DARK NBADPIX",
00687                 hawki_cal_dark_outputs.nb_badpix[i]);
00688         cpl_propertylist_append_double(qclists[i], "ESO QC DARK MEAN",
00689                 hawki_cal_dark_outputs.master_dark_mean[i]);
00690         cpl_propertylist_append_double(qclists[i], "ESO QC DARK MED",
00691                 hawki_cal_dark_outputs.master_dark_med[i]);
00692         cpl_propertylist_append_double(qclists[i], "ESO QC DARK STDEV",
00693                 hawki_cal_dark_outputs.master_dark_stdev[i]);
00694         cpl_propertylist_append_double(qclists[i], "ESO QC DARK NONORM MEAN",
00695                 hawki_cal_dark_outputs.master_dark_mean[i] * hawki_cal_dark_outputs.dit);
00696         cpl_propertylist_append_double(qclists[i], "ESO QC DARK NONORM MED",
00697                 hawki_cal_dark_outputs.master_dark_med[i] * hawki_cal_dark_outputs.dit);
00698         cpl_propertylist_append_double(qclists[i], "ESO QC DARK NONORM STDEV",
00699                 hawki_cal_dark_outputs.master_dark_stdev[i] * hawki_cal_dark_outputs.dit);
00700         if(hawki_cal_dark_config.error_tracking)
00701         {
00702             cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR MEAN",
00703                  hawki_cal_dark_outputs.master_dark_error_mean[i]);
00704             cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR MED",
00705                  hawki_cal_dark_outputs.master_dark_error_med[i]);
00706             cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR STDEV",
00707                  hawki_cal_dark_outputs.master_dark_error_stdev[i]);
00708             cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR NONORM MEAN",
00709                  hawki_cal_dark_outputs.master_dark_error_mean[i] * hawki_cal_dark_outputs.dit);
00710             cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR NONORM MED",
00711                  hawki_cal_dark_outputs.master_dark_error_med[i] * hawki_cal_dark_outputs.dit);
00712             cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR NONORM STDEV",
00713                  hawki_cal_dark_outputs.master_dark_error_stdev[i] * hawki_cal_dark_outputs.dit);
00714         }
00715         for (j=0 ; j<HAWKI_NB_VC ; j++) {
00716             sprintf(sval, "ESO QC DARK VC%d MEAN", j+1) ;
00717             cpl_propertylist_append_double(qclists[i], sval,
00718                     hawki_cal_dark_outputs.vc_mean[i][j]) ;
00719             sprintf(sval, "ESO QC DARK VC%d MED", j+1) ;
00720             cpl_propertylist_append_double(qclists[i], sval,
00721                     hawki_cal_dark_outputs.vc_med[i][j]) ;
00722             sprintf(sval, "ESO QC DARK VC%d STDEV", j+1) ;
00723             cpl_propertylist_append_double(qclists[i], sval,
00724                     hawki_cal_dark_outputs.vc_stdev[i][j]) ;
00725         }
00726         for (j=0 ; j<cpl_vector_get_size(rons[i]) ; j++) {
00727             sprintf(sval, "ESO QC RON%d", j+1) ;
00728             cpl_propertylist_append_double(qclists[i], sval,
00729                     cpl_vector_get(rons[i], j)) ;
00730         } 
00731         cpl_propertylist_append_double(qclists[i], "ESO QC RON MEAN",
00732                 cpl_vector_get_mean(rons[i])) ;
00733         cpl_propertylist_append_double(qclists[i], "ESO QC RON MED",
00734                 cpl_vector_get_median_const(rons[i])) ;
00735         cpl_propertylist_append_double(qclists[i], "ESO QC RON STDEV",
00736                 cpl_vector_get_stdev(rons[i])) ;
00737         cpl_propertylist_append_double(qclists[i], "ESO QC DATANCOM",
00738                 cpl_frameset_get_size(set)) ;
00739        
00740         /* Propagate some keywords from input raw frame extensions */
00741         ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1);
00742         inputlist = cpl_propertylist_load_regexp(
00743                 cpl_frame_get_filename(ref_frame), ext_nb, 
00744                 HAWKI_HEADER_EXT_FORWARD, 0) ;
00745         cpl_propertylist_append(qclists[i], inputlist) ; 
00746         cpl_propertylist_delete(inputlist) ;
00747     }
00748     /* Statistics of the raw images in the QC */
00749     hawki_image_stats_stats(raw_dark_stats, qclists);
00750 
00751     /* Write the dark image */
00752     hawki_imagelist_save(set,
00753                          parlist,
00754                          used_frames, 
00755                          master_dark, 
00756                          recipe_name,
00757                          HAWKI_CALPRO_DARK, 
00758                          HAWKI_PROTYPE_DARK,
00759                          NULL,
00760                          (const cpl_propertylist**)qclists,
00761                          "hawki_cal_dark.fits") ;
00762 
00763     /* Write the dark image error */
00764     if(master_dark_err != NULL)
00765     {
00766         hawki_imagelist_save(set,
00767                              parlist,
00768                              used_frames, 
00769                              master_dark_err, 
00770                              recipe_name,
00771                              HAWKI_CALPRO_DARK_ERR, 
00772                              HAWKI_PROTYPE_DARK_ERR,
00773                              NULL,
00774                              NULL,
00775                              "hawki_cal_dark_err.fits") ;
00776     }
00777 
00778     /* Write the bpmdark pixels image */
00779     hawki_imagelist_save(set,
00780                          parlist,
00781                          used_frames, 
00782                          bpmdark, 
00783                          recipe_name,
00784                          HAWKI_CALPRO_BPM_HOT, 
00785                          HAWKI_PROTYPE_BPM,
00786                          NULL,
00787                          NULL,
00788                          "hawki_cal_dark_bpmdark.fits") ;
00789 
00790     
00791     /* Write the table with the statistics */
00792     hawki_tables_save(set,
00793                       parlist,
00794                       used_frames,
00795                       (const cpl_table **)raw_dark_stats,
00796                       recipe_name,
00797                       HAWKI_CALPRO_DARK_STATS,
00798                       HAWKI_PROTYPE_DARK_STATS,
00799                       NULL,
00800                       NULL,
00801                       "hawki_cal_dark_stats.fits") ;
00802 
00803     /* Free and return */
00804     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00805         cpl_propertylist_delete(qclists[i]) ;
00806     }
00807     cpl_free(qclists) ;
00808     if(!cpl_errorstate_is_equal(error_prevstate))
00809     {
00810         cpl_errorstate_set(CPL_ERROR_NONE);
00811         return -1;
00812     }
00813     return  0;
00814 }
00815 
00816 static int hawki_cal_dark_retrieve_input_param
00817 (cpl_parameterlist * parlist)
00818 {
00819     cpl_parameter       *   par ;
00820     const char          *   sval ;
00821     cpl_errorstate          error_prevstate = cpl_errorstate_get();
00822     
00823     /* Retrieve input parameters */
00824     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.sigma") ;
00825     hawki_cal_dark_config.sigma = cpl_parameter_get_double(par) ;
00826     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.hsize") ;
00827     hawki_cal_dark_config.hsize = cpl_parameter_get_int(par) ;
00828     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.nsamples") ;
00829     hawki_cal_dark_config.nsamples = cpl_parameter_get_int(par) ;
00830     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.zone") ;
00831     sval = cpl_parameter_get_string(par) ;
00832     if (sscanf(sval, "%d,%d,%d,%d",
00833                     &hawki_cal_dark_config.llx,
00834                     &hawki_cal_dark_config.lly,
00835                     &hawki_cal_dark_config.urx,
00836                     &hawki_cal_dark_config.ury)!=4) {
00837         return -1 ;
00838     }
00839     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.gain") ;
00840     hawki_cal_dark_config.gain = cpl_parameter_get_double(par);
00841     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.ron") ;
00842     hawki_cal_dark_config.ron = cpl_parameter_get_double(par);
00843     hawki_cal_dark_config.error_tracking = 0; 
00844     if(hawki_cal_dark_config.gain > 0 && hawki_cal_dark_config.ron > 0)
00845         hawki_cal_dark_config.error_tracking = 1; 
00846     
00847     if(!cpl_errorstate_is_equal(error_prevstate))
00848         return -1;
00849 
00850     return 0;
00851 }
00852 
00853 void hawki_cal_dark_initialise_qc(void)
00854 {
00855     int idet;
00856     int j;
00857     
00858     for(idet=0; idet<HAWKI_NB_DETECTORS; idet++) 
00859     {
00860         hawki_cal_dark_outputs.nb_badpix[idet] = -1 ;
00861         hawki_cal_dark_outputs.master_dark_mean[idet] = -1.0 ;
00862         hawki_cal_dark_outputs.master_dark_med[idet] = -1.0 ;
00863         hawki_cal_dark_outputs.master_dark_stdev[idet] = -1.0 ;
00864         hawki_cal_dark_outputs.master_dark_error_mean[idet] = -1.0 ;
00865         hawki_cal_dark_outputs.master_dark_error_med[idet] = -1.0 ;
00866         hawki_cal_dark_outputs.master_dark_error_stdev[idet] = -1.0 ;
00867         for (j=0 ; j<HAWKI_NB_VC ; j++) 
00868         {
00869             hawki_cal_dark_outputs.vc_mean[idet][j] = -1.0 ;
00870             hawki_cal_dark_outputs.vc_med[idet][j] = -1.0 ;
00871             hawki_cal_dark_outputs.vc_stdev[idet][j] = -1.0 ;
00872         }
00873     }
00874 }

Generated on Thu Feb 17 17:13:07 2011 for HAWKI Pipeline Reference Manual by  doxygen 1.4.7