HAWKI Pipeline Reference Manual 1.8.12
|
00001 /* $Id: hawki_cal_dark.c,v 1.21 2011/02/16 16:33:21 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: 2011/02/16 16:33:21 $ 00024 * $Revision: 1.21 $ 00025 * $Name: hawki-1_8_12 $ 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/NDSAMPLES 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 /* Check that DIT/NDIT and NDSAMPLES are the same for all the frames */ 00373 if(!hawki_utils_check_equal_double_keys(rawframes, &hawki_pfits_get_dit) || 00374 !hawki_utils_check_equal_int_keys(rawframes, &hawki_pfits_get_ndit)|| 00375 !hawki_utils_check_equal_int_keys(rawframes, &hawki_pfits_get_ndsamples)) 00376 { 00377 cpl_msg_error(__func__, "Not all input darks have the same " 00378 "DIT/NDIT/NDSAMPLES values"); 00379 cpl_msg_indent_less() ; 00380 return -1 ; 00381 } 00382 00383 /* Number of frames */ 00384 nframes = cpl_frameset_get_size(rawframes) ; 00385 00386 /* Create the statistics table */ 00387 raw_dark_stats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *)); 00388 for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00389 { 00390 raw_dark_stats[idet] = cpl_table_new(nframes); 00391 } 00392 hawki_image_stats_initialize(raw_dark_stats); 00393 00394 /* Loop on the detectors */ 00395 master_dark = cpl_imagelist_new(); 00396 if(hawki_cal_dark_config.error_tracking) 00397 master_dark_err = cpl_imagelist_new(); 00398 bpmdark = cpl_imagelist_new(); 00399 cpl_msg_info(__func__, "Dark computation"); 00400 cpl_msg_indent_more() ; 00401 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) { 00402 cpl_msg_info(__func__, "Handle chip number %d", idet+1) ; 00403 00404 /* Create the rons vectors */ 00405 rons[idet] = cpl_vector_new(nframes) ; 00406 00407 /* Load the input data */ 00408 darks_raw = hawki_load_detector(rawframes, idet+1, CPL_TYPE_FLOAT) ; 00409 00410 /* Loop on the frames */ 00411 for (j=0 ; j<nframes ; j++) { 00412 /* Load the current and next images */ 00413 if (j==nframes-1) { 00414 ima_curr = cpl_imagelist_get(darks_raw, j) ; 00415 ima_next = cpl_imagelist_get(darks_raw, 0) ; 00416 } else { 00417 ima_curr = cpl_imagelist_get(darks_raw, j) ; 00418 ima_next = cpl_imagelist_get(darks_raw, j+1) ; 00419 } 00420 00421 /* Compute the dark stats and store in table */ 00422 if(hawki_image_stats_fill_from_image 00423 (raw_dark_stats, 00424 ima_curr, 00425 hawki_cal_dark_config.llx, 00426 hawki_cal_dark_config.lly, 00427 hawki_cal_dark_config.urx, 00428 hawki_cal_dark_config.ury, 00429 idet, 00430 j) != 0) 00431 { 00432 cpl_msg_error(__func__, "Cannot compute statistics") ; 00433 cpl_msg_indent_less() ; 00434 cpl_frameset_delete(rawframes) ; 00435 cpl_imagelist_delete(master_dark); 00436 if(hawki_cal_dark_config.error_tracking) 00437 cpl_imagelist_delete(master_dark_err); 00438 cpl_imagelist_delete(darks_raw); 00439 cpl_imagelist_delete(bpmdark) ; 00440 for (k=0 ; k<=idet ; k++) 00441 cpl_vector_delete(rons[k]) ; 00442 for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00443 cpl_table_delete(raw_dark_stats[idet]); 00444 cpl_free(raw_dark_stats); 00445 return -1 ; 00446 } 00447 00448 /* Compute the RON */ 00449 ron = hawki_cal_dark_ron(ima_curr, ima_next, hawki_cal_dark_outputs.ndit) ; 00450 cpl_vector_set(rons[idet], j, ron); 00451 } 00452 00453 /* Collapse */ 00454 if (nframes > 2) 00455 { 00456 ima_accu = cpl_imagelist_collapse_minmax_create(darks_raw, 0, 1) ; 00457 if(hawki_cal_dark_config.error_tracking) 00458 { 00459 cpl_imagelist * variances; 00460 cpl_image * accu_var; 00461 cpl_msg_info(__func__, "Computing the uncertainty in dark"); 00462 variances = hawki_imglist_create_variances_and_delete 00463 (darks_raw, hawki_cal_dark_config.gain, 00464 hawki_cal_dark_config.ron, hawki_cal_dark_outputs.ndit, 00465 hawki_cal_dark_outputs.ndsamples); 00466 /* The variances are collapsed, like the dark_raw. Given that 00467 * the variances are a monotically increasing function with 00468 * respect to the dark_raw, the minmax algorithm will select 00469 * the same values as for the dark_raw 00470 * The nframes - 1 is because only one frame is being rejected*/ 00471 accu_var = cpl_imagelist_collapse_minmax_create(variances,0,1); 00472 cpl_image_divide_scalar(accu_var, nframes - 1); 00473 ima_accu_err = cpl_image_duplicate(accu_var); 00474 cpl_image_power(ima_accu_err, 0.5); 00475 cpl_imagelist_delete(variances); 00476 cpl_image_delete(accu_var); 00477 } 00478 00479 } else { 00480 ima_accu = cpl_imagelist_collapse_create(darks_raw) ; 00481 if(hawki_cal_dark_config.error_tracking) 00482 { 00483 cpl_imagelist * variances; 00484 cpl_image * accu_var; 00485 cpl_msg_info(__func__, "Computing the uncertainty in dark"); 00486 variances = hawki_imglist_create_variances_and_delete 00487 (darks_raw, hawki_cal_dark_config.gain, 00488 hawki_cal_dark_config.ron, hawki_cal_dark_outputs.ndit, 00489 hawki_cal_dark_outputs.ndsamples); 00490 accu_var = cpl_imagelist_collapse_create(variances); 00491 cpl_image_divide_scalar(accu_var, nframes); 00492 ima_accu_err = cpl_image_duplicate(accu_var); 00493 cpl_image_power(ima_accu_err, 0.5); 00494 cpl_imagelist_delete(variances); 00495 cpl_image_delete(accu_var); 00496 } 00497 } 00498 if (ima_accu == NULL) { 00499 cpl_msg_error(__func__, "Cannot compute the average") ; 00500 cpl_frameset_delete(rawframes) ; 00501 cpl_imagelist_delete(bpmdark) ; 00502 cpl_imagelist_delete(master_dark) ; 00503 if(ima_accu_err != NULL) 00504 cpl_image_delete(ima_accu_err); 00505 cpl_imagelist_delete(darks_raw); 00506 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00507 cpl_vector_delete(rons[idet]) ; 00508 for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00509 cpl_table_delete(raw_dark_stats[idet]); 00510 cpl_free(raw_dark_stats); 00511 return -1 ; 00512 } 00513 cpl_imagelist_delete(darks_raw) ; 00514 00515 /* Put the result in the list */ 00516 cpl_imagelist_set(master_dark, ima_accu, idet) ; 00517 if(hawki_cal_dark_config.error_tracking) 00518 cpl_imagelist_set(master_dark_err, ima_accu_err, idet) ; 00519 00520 /* Compute the dark_med and stdev */ 00521 hawki_cal_dark_outputs.master_dark_med[idet]= 00522 cpl_image_get_median(ima_accu) / hawki_cal_dark_outputs.dit; 00523 hawki_cal_dark_outputs.master_dark_mean[idet] = 00524 cpl_image_get_mean(ima_accu) / hawki_cal_dark_outputs.dit; 00525 hawki_cal_dark_outputs.master_dark_stdev[idet] = 00526 cpl_image_get_stdev(ima_accu) / hawki_cal_dark_outputs.dit; 00527 if(hawki_cal_dark_config.error_tracking) 00528 { 00529 hawki_cal_dark_outputs.master_dark_error_med[idet]= 00530 cpl_image_get_median(ima_accu_err) / hawki_cal_dark_outputs.dit; 00531 hawki_cal_dark_outputs.master_dark_error_mean[idet] = 00532 cpl_image_get_mean(ima_accu_err) / hawki_cal_dark_outputs.dit; 00533 hawki_cal_dark_outputs.master_dark_error_stdev[idet] = 00534 cpl_image_get_stdev(ima_accu_err) / hawki_cal_dark_outputs.dit; 00535 } 00536 00537 /* Compute the Video Channels stats */ 00538 vc_lly = 973 ; 00539 vc_ury = 1036 ; 00540 for (j=0 ; j<HAWKI_NB_VC ; j++) { 00541 vc_llx = j*(2048/HAWKI_NB_VC) + 1 ; 00542 vc_urx = (j+1)*(2048/HAWKI_NB_VC) ; 00543 00544 hawki_cal_dark_outputs.vc_mean[idet][j] = 00545 cpl_image_get_mean_window(ima_accu, vc_llx, vc_lly, 00546 vc_urx, vc_ury) ; 00547 00548 hawki_cal_dark_outputs.vc_med[idet][j] = 00549 cpl_image_get_median_window(ima_accu, vc_llx, vc_lly, 00550 vc_urx, vc_ury) ; 00551 00552 hawki_cal_dark_outputs.vc_stdev[idet][j] = 00553 cpl_image_get_stdev_window(ima_accu, vc_llx, vc_lly, 00554 vc_urx, vc_ury) ; 00555 } 00556 00557 /* Compute the HOT pixels map */ 00558 cpl_msg_info(__func__, "Compute the BPM from the dark") ; 00559 cpl_msg_indent_more() ; 00560 if ((bpm=hawki_compute_darkbpm(ima_accu, 00561 hawki_cal_dark_config.sigma)) == NULL) { 00562 cpl_msg_error(__func__, "Cannot compute the hot pixels") ; 00563 cpl_msg_indent_less() ; 00564 cpl_frameset_delete(rawframes) ; 00565 cpl_imagelist_delete(bpmdark) ; 00566 cpl_imagelist_delete(master_dark); 00567 if(hawki_cal_dark_config.error_tracking) 00568 cpl_imagelist_delete(master_dark_err); 00569 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00570 cpl_vector_delete(rons[idet]) ; 00571 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00572 cpl_table_delete(raw_dark_stats[idet]); 00573 cpl_free(raw_dark_stats); 00574 return -1 ; 00575 } 00576 cpl_imagelist_set(bpmdark, bpm, idet) ; 00577 hawki_cal_dark_outputs.nb_badpix[idet]=(int)cpl_image_get_flux(bpm); 00578 cpl_msg_indent_less() ; 00579 } 00580 cpl_msg_indent_less() ; 00581 00582 /* Divide by DIT */ 00583 cpl_msg_info(__func__, "Division by DIT") ; 00584 cpl_imagelist_divide_scalar(master_dark, hawki_cal_dark_outputs.dit); 00585 if(hawki_cal_dark_config.error_tracking) 00586 cpl_imagelist_divide_scalar(master_dark_err, hawki_cal_dark_outputs.dit); 00587 00588 /* Save the product */ 00589 cpl_msg_info(__func__, "Save the products") ; 00590 cpl_msg_indent_more() ; 00591 if (hawki_cal_dark_save(master_dark, master_dark_err, 00592 bpmdark, raw_dark_stats, 00593 (const cpl_vector **)rons, 00594 rawframes, 00595 parlist, frameset)) 00596 cpl_msg_warning(__func__,"Some data could not be saved. " 00597 "Check permisions or disk space"); 00598 00599 /* Free */ 00600 cpl_frameset_delete(rawframes) ; 00601 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00602 cpl_vector_delete(rons[idet]) ; 00603 cpl_imagelist_delete(master_dark) ; 00604 if(hawki_cal_dark_config.error_tracking) 00605 cpl_imagelist_delete(master_dark_err); 00606 cpl_imagelist_delete(bpmdark) ; 00607 cpl_msg_indent_less() ; 00608 for( idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 00609 cpl_table_delete(raw_dark_stats[idet]); 00610 cpl_free(raw_dark_stats); 00611 00612 /* Return */ 00613 if (cpl_error_get_code()) 00614 { 00615 cpl_msg_error(__func__, 00616 "HAWK-I pipeline could not recover from previous errors"); 00617 return -1 ; 00618 } 00619 else return 0 ; 00620 } 00621 00622 /*----------------------------------------------------------------------------*/ 00630 /*----------------------------------------------------------------------------*/ 00631 static double hawki_cal_dark_ron( 00632 const cpl_image * ima1, 00633 const cpl_image * ima2, 00634 int ndit) 00635 { 00636 cpl_image * ima ; 00637 double norm ; 00638 double ron ; 00639 00640 /* Test entries */ 00641 if (ima1 == NULL) return -1.0 ; 00642 if (ima2 == NULL) return -1.0 ; 00643 if (ndit < 1) return -1.0 ; 00644 00645 /* Compute norm */ 00646 norm = 0.5 * ndit ; 00647 norm = sqrt(norm) ; 00648 00649 /* Subtraction */ 00650 if ((ima = cpl_image_subtract_create(ima2, ima1)) == NULL) return -1.0 ; 00651 00652 /* RON measurement */ 00653 cpl_flux_get_noise_window(ima, NULL, hawki_cal_dark_config.hsize, 00654 hawki_cal_dark_config.nsamples, &ron, NULL) ; 00655 cpl_image_delete(ima) ; 00656 return norm*ron ; 00657 } 00658 00659 /*----------------------------------------------------------------------------*/ 00669 /*----------------------------------------------------------------------------*/ 00670 static int hawki_cal_dark_save 00671 (const cpl_imagelist * master_dark, 00672 const cpl_imagelist * master_dark_err, 00673 const cpl_imagelist * bpmdark, 00674 cpl_table ** raw_dark_stats, 00675 const cpl_vector ** rons, 00676 const cpl_frameset * used_frames, 00677 cpl_parameterlist * parlist, 00678 cpl_frameset * set) 00679 { 00680 cpl_propertylist ** qclists ; 00681 const cpl_frame * ref_frame ; 00682 char sval[32] ; 00683 cpl_propertylist * inputlist ; 00684 int ext_nb ; 00685 const char * recipe_name = "hawki_cal_dark" ; 00686 int i, j ; 00687 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00688 00689 00690 /* Get the reference frame */ 00691 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ; 00692 00693 /* Create the QC lists */ 00694 qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 00695 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00696 qclists[i] = cpl_propertylist_new(); 00697 cpl_propertylist_append_int(qclists[i], "ESO QC DARK NBADPIX", 00698 hawki_cal_dark_outputs.nb_badpix[i]); 00699 cpl_propertylist_append_double(qclists[i], "ESO QC DARK MEAN", 00700 hawki_cal_dark_outputs.master_dark_mean[i]); 00701 cpl_propertylist_append_double(qclists[i], "ESO QC DARK MED", 00702 hawki_cal_dark_outputs.master_dark_med[i]); 00703 cpl_propertylist_append_double(qclists[i], "ESO QC DARK STDEV", 00704 hawki_cal_dark_outputs.master_dark_stdev[i]); 00705 cpl_propertylist_append_double(qclists[i], "ESO QC DARK NONORM MEAN", 00706 hawki_cal_dark_outputs.master_dark_mean[i] * hawki_cal_dark_outputs.dit); 00707 cpl_propertylist_append_double(qclists[i], "ESO QC DARK NONORM MED", 00708 hawki_cal_dark_outputs.master_dark_med[i] * hawki_cal_dark_outputs.dit); 00709 cpl_propertylist_append_double(qclists[i], "ESO QC DARK NONORM STDEV", 00710 hawki_cal_dark_outputs.master_dark_stdev[i] * hawki_cal_dark_outputs.dit); 00711 if(hawki_cal_dark_config.error_tracking) 00712 { 00713 cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR MEAN", 00714 hawki_cal_dark_outputs.master_dark_error_mean[i]); 00715 cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR MED", 00716 hawki_cal_dark_outputs.master_dark_error_med[i]); 00717 cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR STDEV", 00718 hawki_cal_dark_outputs.master_dark_error_stdev[i]); 00719 cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR NONORM MEAN", 00720 hawki_cal_dark_outputs.master_dark_error_mean[i] * hawki_cal_dark_outputs.dit); 00721 cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR NONORM MED", 00722 hawki_cal_dark_outputs.master_dark_error_med[i] * hawki_cal_dark_outputs.dit); 00723 cpl_propertylist_append_double(qclists[i], "ESO QC DARK ERR NONORM STDEV", 00724 hawki_cal_dark_outputs.master_dark_error_stdev[i] * hawki_cal_dark_outputs.dit); 00725 } 00726 for (j=0 ; j<HAWKI_NB_VC ; j++) { 00727 sprintf(sval, "ESO QC DARK VC%d MEAN", j+1) ; 00728 cpl_propertylist_append_double(qclists[i], sval, 00729 hawki_cal_dark_outputs.vc_mean[i][j]) ; 00730 sprintf(sval, "ESO QC DARK VC%d MED", j+1) ; 00731 cpl_propertylist_append_double(qclists[i], sval, 00732 hawki_cal_dark_outputs.vc_med[i][j]) ; 00733 sprintf(sval, "ESO QC DARK VC%d STDEV", j+1) ; 00734 cpl_propertylist_append_double(qclists[i], sval, 00735 hawki_cal_dark_outputs.vc_stdev[i][j]) ; 00736 } 00737 for (j=0 ; j<cpl_vector_get_size(rons[i]) ; j++) { 00738 sprintf(sval, "ESO QC RON%d", j+1) ; 00739 cpl_propertylist_append_double(qclists[i], sval, 00740 cpl_vector_get(rons[i], j)) ; 00741 } 00742 cpl_propertylist_append_double(qclists[i], "ESO QC RON MEAN", 00743 cpl_vector_get_mean(rons[i])) ; 00744 cpl_propertylist_append_double(qclists[i], "ESO QC RON MED", 00745 cpl_vector_get_median_const(rons[i])) ; 00746 cpl_propertylist_append_double(qclists[i], "ESO QC RON STDEV", 00747 cpl_vector_get_stdev(rons[i])) ; 00748 cpl_propertylist_append_double(qclists[i], "ESO QC DATANCOM", 00749 cpl_frameset_get_size(set)) ; 00750 00751 /* Propagate some keywords from input raw frame extensions */ 00752 ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1); 00753 inputlist = cpl_propertylist_load_regexp( 00754 cpl_frame_get_filename(ref_frame), ext_nb, 00755 HAWKI_HEADER_EXT_FORWARD, 0) ; 00756 cpl_propertylist_append(qclists[i], inputlist) ; 00757 cpl_propertylist_delete(inputlist) ; 00758 } 00759 /* Statistics of the raw images in the QC */ 00760 hawki_image_stats_stats(raw_dark_stats, qclists); 00761 00762 /* Write the dark image */ 00763 hawki_imagelist_save(set, 00764 parlist, 00765 used_frames, 00766 master_dark, 00767 recipe_name, 00768 HAWKI_CALPRO_DARK, 00769 HAWKI_PROTYPE_DARK, 00770 NULL, 00771 (const cpl_propertylist**)qclists, 00772 "hawki_cal_dark.fits") ; 00773 00774 /* Write the dark image error */ 00775 if(master_dark_err != NULL) 00776 { 00777 hawki_imagelist_save(set, 00778 parlist, 00779 used_frames, 00780 master_dark_err, 00781 recipe_name, 00782 HAWKI_CALPRO_DARK_ERR, 00783 HAWKI_PROTYPE_DARK_ERR, 00784 NULL, 00785 NULL, 00786 "hawki_cal_dark_err.fits") ; 00787 } 00788 00789 /* Write the bpmdark pixels image */ 00790 hawki_imagelist_save(set, 00791 parlist, 00792 used_frames, 00793 bpmdark, 00794 recipe_name, 00795 HAWKI_CALPRO_BPM_HOT, 00796 HAWKI_PROTYPE_BPM, 00797 NULL, 00798 NULL, 00799 "hawki_cal_dark_bpmdark.fits") ; 00800 00801 00802 /* Write the table with the statistics */ 00803 hawki_tables_save(set, 00804 parlist, 00805 used_frames, 00806 (const cpl_table **)raw_dark_stats, 00807 recipe_name, 00808 HAWKI_CALPRO_DARK_STATS, 00809 HAWKI_PROTYPE_DARK_STATS, 00810 NULL, 00811 NULL, 00812 "hawki_cal_dark_stats.fits") ; 00813 00814 /* Free and return */ 00815 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) { 00816 cpl_propertylist_delete(qclists[i]) ; 00817 } 00818 cpl_free(qclists) ; 00819 if(!cpl_errorstate_is_equal(error_prevstate)) 00820 { 00821 cpl_errorstate_set(CPL_ERROR_NONE); 00822 return -1; 00823 } 00824 return 0; 00825 } 00826 00827 static int hawki_cal_dark_retrieve_input_param 00828 (cpl_parameterlist * parlist) 00829 { 00830 cpl_parameter * par ; 00831 const char * sval ; 00832 cpl_errorstate error_prevstate = cpl_errorstate_get(); 00833 00834 /* Retrieve input parameters */ 00835 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.sigma") ; 00836 hawki_cal_dark_config.sigma = cpl_parameter_get_double(par) ; 00837 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.hsize") ; 00838 hawki_cal_dark_config.hsize = cpl_parameter_get_int(par) ; 00839 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.nsamples") ; 00840 hawki_cal_dark_config.nsamples = cpl_parameter_get_int(par) ; 00841 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.zone") ; 00842 sval = cpl_parameter_get_string(par) ; 00843 if (sscanf(sval, "%d,%d,%d,%d", 00844 &hawki_cal_dark_config.llx, 00845 &hawki_cal_dark_config.lly, 00846 &hawki_cal_dark_config.urx, 00847 &hawki_cal_dark_config.ury)!=4) { 00848 return -1 ; 00849 } 00850 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.gain") ; 00851 hawki_cal_dark_config.gain = cpl_parameter_get_double(par); 00852 par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_dark.ron") ; 00853 hawki_cal_dark_config.ron = cpl_parameter_get_double(par); 00854 hawki_cal_dark_config.error_tracking = 0; 00855 if(hawki_cal_dark_config.gain > 0 && hawki_cal_dark_config.ron > 0) 00856 hawki_cal_dark_config.error_tracking = 1; 00857 00858 if(!cpl_errorstate_is_equal(error_prevstate)) 00859 return -1; 00860 00861 return 0; 00862 } 00863 00864 void hawki_cal_dark_initialise_qc(void) 00865 { 00866 int idet; 00867 int j; 00868 00869 for(idet=0; idet<HAWKI_NB_DETECTORS; idet++) 00870 { 00871 hawki_cal_dark_outputs.nb_badpix[idet] = -1 ; 00872 hawki_cal_dark_outputs.master_dark_mean[idet] = -1.0 ; 00873 hawki_cal_dark_outputs.master_dark_med[idet] = -1.0 ; 00874 hawki_cal_dark_outputs.master_dark_stdev[idet] = -1.0 ; 00875 hawki_cal_dark_outputs.master_dark_error_mean[idet] = -1.0 ; 00876 hawki_cal_dark_outputs.master_dark_error_med[idet] = -1.0 ; 00877 hawki_cal_dark_outputs.master_dark_error_stdev[idet] = -1.0 ; 00878 for (j=0 ; j<HAWKI_NB_VC ; j++) 00879 { 00880 hawki_cal_dark_outputs.vc_mean[idet][j] = -1.0 ; 00881 hawki_cal_dark_outputs.vc_med[idet][j] = -1.0 ; 00882 hawki_cal_dark_outputs.vc_stdev[idet][j] = -1.0 ; 00883 } 00884 } 00885 }