CR2RE Pipeline Reference Manual 1.6.8
cr2res_cal_dark.c
1/*
2 * This file is part of the CR2RES Pipeline
3 * Copyright (C) 2002,2003 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include <math.h>
29#include <string.h>
30#include <cpl.h>
31#include "hdrl.h"
32
33#include "cr2res_utils.h"
34#include "cr2res_pfits.h"
35#include "cr2res_dfs.h"
36#include "cr2res_io.h"
37#include "cr2res_bpm.h"
38#include "cr2res_qc.h"
39#include "cr2res_calib.h"
40
41/*-----------------------------------------------------------------------------
42 Define
43 -----------------------------------------------------------------------------*/
44
45#define RECIPE_STRING "cr2res_cal_dark"
46
47/*-----------------------------------------------------------------------------
48 Plugin registration
49 -----------------------------------------------------------------------------*/
50
51int cpl_plugin_get_info(cpl_pluginlist * list);
52
53/*-----------------------------------------------------------------------------
54 Private function prototypes
55 -----------------------------------------------------------------------------*/
56
57static int cr2res_cal_dark_compare(
58 const cpl_frame * frame1,
59 const cpl_frame * frame2) ;
60
61static int cr2res_cal_dark_create(cpl_plugin *);
62static int cr2res_cal_dark_exec(cpl_plugin *);
63static int cr2res_cal_dark_destroy(cpl_plugin *);
64static int cr2res_cal_dark(cpl_frameset *, const cpl_parameterlist *);
65
66/*-----------------------------------------------------------------------------
67 Static variables
68 -----------------------------------------------------------------------------*/
69
70static char cr2res_cal_dark_description[] = "\
71Dark \n\
72 Compute the master dark \n\
73 \n\
74 Inputs \n\
75 raw.fits " CR2RES_DARK_RAW " [3 to n] \n\
76 \n\
77 Outputs \n\
78 cr2res_cal_dark_[setting]_DITxNDIT_master.fits "
79 CR2RES_CAL_DARK_MASTER_PROCATG "\n\
80 cr2res_cal_dark_[setting]_DITxNDIT_bpm.fits "
81 CR2RES_CAL_DARK_BPM_PROCATG "\n\
82 \n\
83 Algorithm \n\
84 group the input frames by different values of DET SEQ1 DIT \n\
85 or/and DET NDIT or/and WLEN ID \n\
86 loop on groups g: \n\
87 loop on detectors d: \n\
88 Load the images and create the associate error for each of \n\
89 them using cr2res_detector_shotnoise_model(--gain) \n\
90 Collapse the images with hdrl_imagelist_collapse(--collapse.*) \n\
91 Compute BPM from the collapsed master dark using \n\
92 cr2res_bpm_compute(--bpm_kappa, --bpm_lines_ratio) \n\
93 Set the BPM in the master dark \n\
94 Compute the QCs with statistics and \n\
95 cr2res_dark_qc_ron(--ron_hsize, --ron_nsamples) \n\
96 save master dark(g) \n\
97 save bpm(g) \n\
98 \n\
99 Library Functions used \n\
100 cr2res_detector_shotnoise_model() \n\
101 cr2res_bpm_compute() \n\
102 cr2res_bpm_from_mask() \n\
103 cr2res_dark_qc_ron() \n\
104 cr2res_bpm_count() \n\
105 cr2res_io_save_MASTER_DARK() \n\
106 cr2res_io_save_BPM() \n\
107" ;
108
109/*-----------------------------------------------------------------------------
110 Function code
111 -----------------------------------------------------------------------------*/
112
113/*----------------------------------------------------------------------------*/
123/*----------------------------------------------------------------------------*/
124int cpl_plugin_get_info(cpl_pluginlist * list)
125{
126 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
127 cpl_plugin * plugin = &recipe->interface;
128
129 if (cpl_plugin_init(plugin,
130 CPL_PLUGIN_API,
131 CR2RES_BINARY_VERSION,
132 CPL_PLUGIN_TYPE_RECIPE,
133 RECIPE_STRING,
134 "Dark recipe",
135 cr2res_cal_dark_description,
136 CR2RES_PIPELINE_AUTHORS,
137 PACKAGE_BUGREPORT,
139 cr2res_cal_dark_create,
140 cr2res_cal_dark_exec,
141 cr2res_cal_dark_destroy)) {
142 cpl_msg_error(cpl_func, "Plugin initialization failed");
143 (void)cpl_error_set_where(cpl_func);
144 return 1;
145 }
146
147 if (cpl_pluginlist_append(list, plugin)) {
148 cpl_msg_error(cpl_func, "Error adding plugin to list");
149 (void)cpl_error_set_where(cpl_func);
150 return 1;
151 }
152
153 return 0;
154}
155
156/*----------------------------------------------------------------------------*/
164/*----------------------------------------------------------------------------*/
165static int cr2res_cal_dark_create(cpl_plugin * plugin)
166{
167 cpl_recipe * recipe ;
168 cpl_parameter * p ;
169 cpl_parameterlist * collapse_par ;
170 hdrl_parameter * sigclip_def ;
171 hdrl_parameter * minmax_def ;
172 hdrl_parameter * mode_def ;
173
174 /* Check that the plugin is part of a valid recipe */
175 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
176 recipe = (cpl_recipe *)plugin;
177 else
178 return -1;
179
180 /* Create the parameters list in the cpl_recipe object */
181 recipe->parameters = cpl_parameterlist_new();
182
183 /* Fill the parameters list */
184
185 /* --detector */
186 p = cpl_parameter_new_value("cr2res.cr2res_cal_dark.detector",
187 CPL_TYPE_INT, "Only reduce the specified detector",
188 "cr2res.cr2res_cal_dark", 0);
189 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detector");
190 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
191 cpl_parameterlist_append(recipe->parameters, p);
192
193 /* --bpm_method */
194 p = cpl_parameter_new_value("cr2res.cr2res_cal_dark.bpm_method",
195 CPL_TYPE_STRING, "Method (DEFAULT, GLOBAL, LOCAL or RUNNING)",
196 "cr2res.cr2res_cal_dark", "DEFAULT");
197 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm_method");
198 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
199 cpl_parameterlist_append(recipe->parameters, p);
200
201 /* --bpm_kappa */
202 p = cpl_parameter_new_value("cr2res_cal_dark.bpm_kappa", CPL_TYPE_DOUBLE,
203 "Kappa Threshold for the BPM", "cr2res_cal_dark", -1.0);
204 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm_kappa");
205 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
206 cpl_parameterlist_append(recipe->parameters, p);
207
208 /* --bpm_lines_ratio */
209 p = cpl_parameter_new_value("cr2res_cal_dark.bpm_lines_ratio",
210 CPL_TYPE_DOUBLE, "Maximum ratio of bad pixels per line",
211 "cr2res_cal_dark", 0.5);
212 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm_lines_ratio");
213 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
214 cpl_parameterlist_append(recipe->parameters, p);
215
216 /* --ron_hsize */
217 p = cpl_parameter_new_value("cr2res_cal_dark.ron_hsize",
218 CPL_TYPE_INT, "Half size of the window for RON computation",
219 "cr2res_cal_dark", 6);
220 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ron_hsize");
221 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
222 cpl_parameterlist_append(recipe->parameters, p);
223
224 /* --ron_nsamples */
225 p = cpl_parameter_new_value("cr2res_cal_dark.ron_nsamples",
226 CPL_TYPE_INT, "Number of samples for RON computation",
227 "cr2res_cal_dark", 100);
228 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ron_nsamples");
229 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
230 cpl_parameterlist_append(recipe->parameters, p);
231
232 /* --gain */
233 p = cpl_parameter_new_value("cr2res_cal_dark.gain", CPL_TYPE_DOUBLE,
234 "Gain in [e- / ADU]", "cr2res_cal_dark", 2.1);
235 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "gain");
236 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
237 cpl_parameterlist_append(recipe->parameters, p);
238
239 /* Collapsing related parameters */
240 sigclip_def = hdrl_collapse_sigclip_parameter_create(3., 3., 5);
241 minmax_def = hdrl_collapse_minmax_parameter_create(1., 1.);
242 mode_def = hdrl_collapse_mode_parameter_create(10., 1., 0.,
243 HDRL_MODE_MEDIAN, 0);
244 collapse_par = hdrl_collapse_parameter_create_parlist("cr2res_cal_dark",
245 "collapse", "MEAN", sigclip_def, minmax_def, mode_def) ;
246 hdrl_parameter_delete(sigclip_def);
247 hdrl_parameter_delete(minmax_def);
248 hdrl_parameter_delete(mode_def);
249 for (p = cpl_parameterlist_get_first(collapse_par) ;
250 p != NULL; p = cpl_parameterlist_get_next(collapse_par))
251 cpl_parameterlist_append(recipe->parameters,cpl_parameter_duplicate(p));
252 cpl_parameterlist_delete(collapse_par);
253
254 return 0;
255}
256
257/*----------------------------------------------------------------------------*/
263/*----------------------------------------------------------------------------*/
264static int cr2res_cal_dark_exec(cpl_plugin * plugin)
265{
266 cpl_recipe *recipe;
267
268 /* Get the recipe out of the plugin */
269 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
270 recipe = (cpl_recipe *)plugin;
271 else return -1;
272
273 return cr2res_cal_dark(recipe->frames, recipe->parameters);
274}
275
276/*----------------------------------------------------------------------------*/
282/*----------------------------------------------------------------------------*/
283static int cr2res_cal_dark_destroy(cpl_plugin * plugin)
284{
285 cpl_recipe *recipe;
286
287 /* Get the recipe out of the plugin */
288 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
289 recipe = (cpl_recipe *)plugin;
290 else return -1 ;
291
292 cpl_parameterlist_delete(recipe->parameters);
293 return 0 ;
294}
295
296/*----------------------------------------------------------------------------*/
303/*----------------------------------------------------------------------------*/
304static int cr2res_cal_dark(
305 cpl_frameset * frameset,
306 const cpl_parameterlist * parlist)
307{
308 const cpl_parameter * par ;
309 int reduce_det, ron_hsize, ron_nsamples, ndit ;
310 double gain, dit, bpm_kappa, bpm_lines_ratio ;
311 cr2res_bpm_method bpm_method, my_bpm_method ;
312 const char * sval ;
313 hdrl_parameter * collapse_params ;
314 cpl_frameset * rawframes ;
315 cpl_frameset * raw_one ;
316 cpl_frameset * raw_one_calib ;
317 cpl_size * labels ;
318 cpl_size nlabels ;
319 cpl_propertylist * plist ;
320 cpl_propertylist * qc_main ;
321 char * setting_id ;
322 double bpm_kappa_global_default, bpm_kappa_local_default,
323 bpm_kappa_running_default, my_bpm_kappa ;
324
325 hdrl_image * master_darks[CR2RES_NB_DETECTORS] ;
326 cpl_image * bpms[CR2RES_NB_DETECTORS] ;
327 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
328
329 hdrl_imagelist * dark_cube ;
330 cpl_mask * my_bpm ;
331 const char * fname ;
332 hdrl_image * ima_data ;
333 hdrl_image * ima_data_err ;
334 cpl_image * ima_err ;
335
336 double ron1, ron2, med, mean, sigma ;
337 cpl_image * contrib_map;
338 cpl_mask * bpm ;
339 char * filename ;
340 cpl_frame * frame ;
341 int i, l, det_nr, nb_bad ;
342 int single_dit_ndit_setting ;
343 int original_ndit ;
344 double original_dit ;
345 char * original_setting ;
346
347 /* Initialise */
348 bpm_kappa_global_default = 0.5 ;
349 bpm_kappa_local_default = 6.0 ;
350 bpm_kappa_running_default = 5.0 ;
351
352 /* RETRIEVE INPUT PARAMETERS */
353 /* --detector */
354 par = cpl_parameterlist_find_const(parlist,
355 "cr2res.cr2res_cal_dark.detector");
356 reduce_det = cpl_parameter_get_int(par);
357
358 /* --bpm_method */
359 par = cpl_parameterlist_find_const(parlist,
360 "cr2res.cr2res_cal_dark.bpm_method");
361 sval = cpl_parameter_get_string(par);
362 if (!strcmp(sval, "GLOBAL")) bpm_method = CR2RES_BPM_GLOBAL_STATS ;
363 else if (!strcmp(sval, "LOCAL")) bpm_method = CR2RES_BPM_LOCAL_STATS ;
364 else if (!strcmp(sval, "RUNNING")) bpm_method = CR2RES_BPM_RUNNING_FILTER ;
365 else if (!strcmp(sval, "DEFAULT")) bpm_method = CR2RES_BPM_UNSPECIFIED ;
366 else {
367 cpl_msg_error(__func__, "Unsupported bpm method") ;
368 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
369 return -1 ;
370 }
371
372 /* --ron_hsize */
373 par = cpl_parameterlist_find_const(parlist, "cr2res_cal_dark.ron_hsize");
374 ron_hsize = cpl_parameter_get_int(par);
375
376 /* --ron_nsamples */
377 par = cpl_parameterlist_find_const(parlist, "cr2res_cal_dark.ron_nsamples");
378 ron_nsamples = cpl_parameter_get_int(par);
379
380 /* --bpm_kappa */
381 par = cpl_parameterlist_find_const(parlist, "cr2res_cal_dark.bpm_kappa");
382 bpm_kappa = cpl_parameter_get_double(par);
383 /* Set default depending on the method */
384 if (bpm_kappa < 0.0) {
385 if (bpm_method == CR2RES_BPM_GLOBAL_STATS)
386 bpm_kappa = bpm_kappa_global_default ;
387 if (bpm_method == CR2RES_BPM_LOCAL_STATS)
388 bpm_kappa = bpm_kappa_local_default ;
389 if (bpm_method == CR2RES_BPM_RUNNING_FILTER)
390 bpm_kappa = bpm_kappa_running_default ;
391 }
392
393 /* --bpm_lines_ratio */
394 par = cpl_parameterlist_find_const(parlist,
395 "cr2res_cal_dark.bpm_lines_ratio");
396 bpm_lines_ratio = cpl_parameter_get_double(par);
397
398 /* --gain */
399 par = cpl_parameterlist_find_const(parlist, "cr2res_cal_dark.gain");
400 gain = cpl_parameter_get_double(par);
401
402 /* Collapse parameters */
403 collapse_params = hdrl_collapse_parameter_parse_parlist(parlist,
404 "cr2res_cal_dark.collapse") ;
405
406 /* Identify the RAW and CALIB frames in the input frameset */
407 if (cr2res_dfs_set_groups(frameset)) {
408 hdrl_parameter_destroy(collapse_params) ;
409 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
410 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
411 return -1 ;
412 }
413
414 /* Retrieve calibration data */
415
416 /* Extract RAW frames */
417 rawframes = cr2res_extract_frameset(frameset, CR2RES_DARK_RAW) ;
418 if (rawframes==NULL || cpl_frameset_get_size(rawframes) <= 0) {
419 hdrl_parameter_destroy(collapse_params) ;
420 cpl_msg_error(__func__, "Cannot find any RAW file") ;
421 cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND) ;
422 return -1 ;
423 }
424
425 /* Labelise the raw frames with the different settings */
426 if ((labels = cpl_frameset_labelise(rawframes, cr2res_cal_dark_compare,
427 &nlabels)) == NULL) {
428 cpl_msg_error(__func__, "Cannot labelise input frames") ;
429 cpl_frameset_delete(rawframes) ;
430 hdrl_parameter_destroy(collapse_params) ;
431 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
432 return -1 ;
433 }
434
435 /* Identify if there are several DIT/NDIT/setting */
436 single_dit_ndit_setting = -1 ;
437 original_setting = NULL ;
438 for (l=0 ; l<(int)nlabels ; l++) {
439 /* Get the frames for the current setting */
440 raw_one = cpl_frameset_extract(rawframes, labels, (cpl_size)l) ;
441
442 /* Get the current setting */
443 plist = cpl_propertylist_load(cpl_frame_get_filename(
444 cpl_frameset_get_position(raw_one, 0)), 0) ;
445 dit = cr2res_pfits_get_dit(plist) ;
446 ndit = cr2res_pfits_get_ndit(plist) ;
447 setting_id = cpl_strdup(cr2res_pfits_get_wlen_id(plist)) ;
448 cr2res_format_setting(setting_id) ;
449 cpl_propertylist_delete(plist) ;
450
451 /* Update single_dit_ndit_setting information */
452 if (single_dit_ndit_setting < 0) {
453 single_dit_ndit_setting = 1;
454 original_dit = dit ;
455 original_ndit = ndit ;
456 original_setting = cpl_strdup(setting_id) ;
457 } else {
458 if (fabs(original_dit-dit)>1e-3 || original_ndit != ndit ||
459 strcmp(original_setting, setting_id)) {
460 single_dit_ndit_setting = 0 ;
461 }
462 }
463 cpl_free(setting_id);
464 cpl_frameset_delete(raw_one) ;
465 }
466 cpl_free(original_setting);
467
468 /* Loop on the settings */
469 for (l = 0; l < (int)nlabels; l++) {
470 cpl_vector *qc_ron1, *qc_ron2, *qc_nb_bad, *qc_mean, *qc_med, *qc_sigma;
471 const char *first_fname;
472 int nb_frames;
473 /* Get the frames for the current setting */
474 raw_one = cpl_frameset_extract(rawframes, labels, (cpl_size)l) ;
475 nb_frames = cpl_frameset_get_size(raw_one) ;
476 first_fname =
477 cpl_frame_get_filename(cpl_frameset_get_position(raw_one, 0)) ;
478
479 /* Get the current setting */
480 plist = cpl_propertylist_load(first_fname, 0) ;
481 dit = cr2res_pfits_get_dit(plist) ;
482 ndit = cr2res_pfits_get_ndit(plist) ;
483 setting_id = cpl_strdup(cr2res_pfits_get_wlen_id(plist)) ;
484 cr2res_format_setting(setting_id) ;
485 cpl_propertylist_delete(plist) ;
486
487 cpl_msg_info(__func__, "Process SETTING %s / DIT %g / %d",
488 setting_id, dit, ndit) ;
489 cpl_msg_indent_more() ;
490
491 /* Allocate qc values vectors */
492 qc_ron1 = cpl_vector_new(CR2RES_NB_DETECTORS);
493 qc_ron2 = cpl_vector_new(CR2RES_NB_DETECTORS);
494 qc_nb_bad = cpl_vector_new(CR2RES_NB_DETECTORS);
495 qc_mean = cpl_vector_new(CR2RES_NB_DETECTORS);
496 qc_med = cpl_vector_new(CR2RES_NB_DETECTORS);
497 qc_sigma = cpl_vector_new(CR2RES_NB_DETECTORS);
498
499 /* Loop on the detectors */
500 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
501 /* Initialise */
502 master_darks[det_nr-1] = NULL ;
503 bpms[det_nr-1] = NULL ;
504 cpl_vector_set(qc_ron1, det_nr-1, -1.0) ;
505 cpl_vector_set(qc_ron2, det_nr-1, -1.0) ;
506 cpl_vector_set(qc_nb_bad, det_nr-1, -1.0) ;
507 cpl_vector_set(qc_mean, det_nr-1, -1.0) ;
508 cpl_vector_set(qc_med, det_nr-1, -1.0) ;
509 cpl_vector_set(qc_sigma, det_nr-1, -1.0) ;
510
511 /* Store the extension header for product saving */
512 ext_plist[det_nr-1] = cpl_propertylist_load(first_fname,
513 cr2res_io_get_ext_idx(first_fname, det_nr, 1)) ;
514
515 /* Compute only one detector */
516 if (reduce_det != 0 && det_nr != reduce_det) continue ;
517
518 cpl_msg_info(__func__, "Process Detector nb %i", det_nr) ;
519 cpl_msg_indent_more() ;
520
521 /* Loop on the frames */
522 dark_cube = hdrl_imagelist_new();
523 for (i=0; i<nb_frames ; i++) {
524 /* Identify current file */
525 fname=cpl_frame_get_filename(
526 cpl_frameset_get_position(raw_one, i)) ;
527 cpl_msg_info(__func__, "Load Image from File %s / Detector %i",
528 cr2res_get_base_name(fname), det_nr) ;
529
530 /* Load the image */
531 if ((ima_data = cr2res_io_load_image(fname, det_nr)) == NULL) {
532 cpl_msg_error(__func__,
533 "Cannot load image from File %s / Detector %d",
534 fname, det_nr) ;
535 cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND) ;
536 cpl_msg_indent_less() ;
537 cpl_msg_indent_less() ;
538 cpl_frameset_delete(rawframes) ;
539 hdrl_parameter_destroy(collapse_params) ;
540 cpl_free(labels);
541 cpl_free(setting_id) ;
542 cpl_frameset_delete(raw_one) ;
543 hdrl_imagelist_delete(dark_cube) ;
544 cpl_vector_delete(qc_ron1) ;
545 cpl_vector_delete(qc_ron2) ;
546 cpl_vector_delete(qc_nb_bad) ;
547 cpl_vector_delete(qc_mean) ;
548 cpl_vector_delete(qc_med) ;
549 cpl_vector_delete(qc_sigma) ;
550 return -1 ;
551 }
552
553 /* Create the noise image */
554 cpl_msg_info(__func__, "Create the associated Noise image");
556 hdrl_image_get_image(ima_data), gain, 0.0,
557 &ima_err) != CPL_ERROR_NONE) {
558 cpl_free(labels);
559 cpl_msg_error(__func__, "Cannot create the Noise image") ;
560 cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND) ;
561 cpl_msg_indent_less() ;
562 cpl_msg_indent_less() ;
563 cpl_frameset_delete(rawframes) ;
564 hdrl_parameter_destroy(collapse_params) ;
565 cpl_free(setting_id) ;
566 cpl_free(labels);
567 cpl_frameset_delete(raw_one) ;
568 hdrl_imagelist_delete(dark_cube) ;
569 hdrl_image_delete(ima_data);
570 cpl_vector_delete(qc_ron1) ;
571 cpl_vector_delete(qc_ron2) ;
572 cpl_vector_delete(qc_nb_bad) ;
573 cpl_vector_delete(qc_mean) ;
574 cpl_vector_delete(qc_med) ;
575 cpl_vector_delete(qc_sigma) ;
576 return -1 ;
577 }
578
579 /* Set the new error image */
580 ima_data_err =
581 hdrl_image_create(hdrl_image_get_image(ima_data), ima_err);
582 cpl_image_delete(ima_err) ;
583 hdrl_image_delete(ima_data) ;
584
585 /* Store the hdrl image in the dark_cube */
586 hdrl_imagelist_set(dark_cube, ima_data_err, i);
587 }
588
589 /* Get the proper collapsing function and do frames combination */
590 if (hdrl_imagelist_collapse(dark_cube, collapse_params,
591 &(master_darks[det_nr-1]), &contrib_map) != CPL_ERROR_NONE){
592 cpl_msg_warning(__func__, "Cannot collapse Detector %d",det_nr);
593 master_darks[det_nr-1] = NULL ;
594 contrib_map = NULL ;
595 }
596 cpl_image_delete(contrib_map);
597
598 /* Compute BPM from the MASTER dark */
599 if (master_darks[det_nr-1] != NULL) {
600
601 /* Handle default method */
602 if (bpm_method == CR2RES_BPM_UNSPECIFIED) {
603 if (cr2res_is_short_wavelength(setting_id)) {
604 my_bpm_method = CR2RES_BPM_GLOBAL_STATS ;
605 if (bpm_kappa < 0.0)
606 my_bpm_kappa = bpm_kappa_global_default ;
607 else
608 my_bpm_kappa = bpm_kappa ;
609 } else {
610 my_bpm_method = CR2RES_BPM_LOCAL_STATS ;
611 if (bpm_kappa < 0.0)
612 my_bpm_kappa = bpm_kappa_local_default ;
613 else
614 my_bpm_kappa = bpm_kappa ;
615 }
616 } else {
617 my_bpm_method = bpm_method ;
618 my_bpm_kappa = bpm_kappa ;
619 }
620 if ((my_bpm = cr2res_bpm_compute(
621 hdrl_image_get_image(master_darks[det_nr-1]),
622 my_bpm_method, my_bpm_kappa, bpm_lines_ratio,
623 0))==NULL) {
624 cpl_msg_warning(__func__, "Cannot create BPM") ;
625 } else {
626 /* Convert mask to BPM */
627 bpms[det_nr-1] = cr2res_bpm_from_mask(my_bpm,
628 CR2RES_BPM_DARK);
629 cpl_mask_delete(my_bpm) ;
630 }
631 }
632
633 /* Set the BPM in the master dark and the RAW */
634 if (bpms[det_nr-1] != NULL) {
635 /* Get Mask */
636 bpm = cpl_mask_threshold_image_create(bpms[det_nr-1],-0.5,0.5) ;
637 cpl_mask_not(bpm) ;
638
639 /* In dark_cube */
640 for (i=0; i<hdrl_imagelist_get_size(dark_cube) ; i++) {
642 i), bpm) ;
643 }
644
645 /* In Master Dark */
646 hdrl_image_reject_from_mask(master_darks[det_nr-1], bpm) ;
647
648 cpl_mask_delete(bpm) ;
649 }
650
651 /* QCs */
652
653 /* QCs from RAW */
654 if (hdrl_imagelist_get_size(dark_cube) >= 3) {
655 ron1 = cr2res_dark_qc_ron(
658 ron_hsize, ron_nsamples, ndit) ;
659 ron2 = cr2res_dark_qc_ron(
662 ron_hsize, ron_nsamples, ndit) ;
663 if (cpl_error_get_code()) {
664 cpl_error_reset() ;
665 } else {
666 cpl_propertylist_append_double(ext_plist[det_nr-1],
667 CR2RES_HEADER_QC_DARK_RON1, ron1) ;
668 cpl_propertylist_append_double(ext_plist[det_nr-1],
669 CR2RES_HEADER_QC_DARK_RON2, ron2) ;
670 cpl_vector_set(qc_ron1, det_nr-1, ron1) ;
671 cpl_vector_set(qc_ron2, det_nr-1, ron2) ;
672 }
673
674 }
675 hdrl_imagelist_delete(dark_cube);
676
677 /* QCs from MASTER DARK */
678 if (master_darks[det_nr-1] != NULL) {
679 /* Compute Thresholds */
680 med = cpl_image_get_median_dev(
681 hdrl_image_get_image(master_darks[det_nr-1]), &sigma) ;
682 mean = cpl_image_get_mean(
683 hdrl_image_get_image(master_darks[det_nr-1])) ;
684
685 cpl_propertylist_append_double(ext_plist[det_nr-1],
686 CR2RES_HEADER_QC_DARK_MEAN, mean) ;
687 cpl_propertylist_append_double(ext_plist[det_nr-1],
688 CR2RES_HEADER_QC_DARK_MEDIAN, med) ;
689 cpl_propertylist_append_double(ext_plist[det_nr-1],
690 CR2RES_HEADER_QC_DARK_STDEV, sigma) ;
691 cpl_vector_set(qc_mean, det_nr-1, mean) ;
692 cpl_vector_set(qc_med, det_nr-1, med) ;
693 cpl_vector_set(qc_sigma, det_nr-1, sigma) ;
694 }
695 /* QCs from BPM */
696 if (bpms[det_nr-1] != NULL) {
697 nb_bad = cr2res_bpm_count(bpms[det_nr-1], CR2RES_BPM_DARK) ;
698 cpl_propertylist_append_int(ext_plist[det_nr-1],
699 CR2RES_HEADER_QC_DARK_NBAD, nb_bad) ;
700 cpl_vector_set(qc_nb_bad, det_nr-1, (double)nb_bad) ;
701 }
702 cpl_msg_indent_less() ;
703 }
704
705 /* Compute Global QCs (primary header) */
706 qc_main = NULL ;
707 if (reduce_det == 0) {
708 qc_main = cpl_propertylist_new() ;
709 cpl_propertylist_append_double(qc_main,
710 CR2RES_HEADER_QC_DARK_RON1_AVG,
711 cpl_vector_get_mean(qc_ron1)) ;
712 cpl_propertylist_append_double(qc_main,
713 CR2RES_HEADER_QC_DARK_RON1_RMS,
714 cpl_vector_get_stdev(qc_ron1)) ;
715
716 cpl_propertylist_append_double(qc_main,
717 CR2RES_HEADER_QC_DARK_RON2_AVG,
718 cpl_vector_get_mean(qc_ron2)) ;
719 cpl_propertylist_append_double(qc_main,
720 CR2RES_HEADER_QC_DARK_RON2_RMS,
721 cpl_vector_get_stdev(qc_ron2)) ;
722
723 cpl_propertylist_append_double(qc_main,
724 CR2RES_HEADER_QC_DARK_NBAD_AVG,
725 cpl_vector_get_mean(qc_nb_bad)) ;
726 cpl_propertylist_append_double(qc_main,
727 CR2RES_HEADER_QC_DARK_NBAD_RMS,
728 cpl_vector_get_stdev(qc_nb_bad)) ;
729
730 cpl_propertylist_append_double(qc_main,
731 CR2RES_HEADER_QC_DARK_MEAN_AVG,
732 cpl_vector_get_mean(qc_mean)) ;
733 cpl_propertylist_append_double(qc_main,
734 CR2RES_HEADER_QC_DARK_MEAN_RMS,
735 cpl_vector_get_stdev(qc_mean)) ;
736
737 cpl_propertylist_append_double(qc_main,
738 CR2RES_HEADER_QC_DARK_MEDIAN_AVG,
739 cpl_vector_get_mean(qc_med)) ;
740 cpl_propertylist_append_double(qc_main,
741 CR2RES_HEADER_QC_DARK_MEDIAN_RMS,
742 cpl_vector_get_stdev(qc_med)) ;
743
744 cpl_propertylist_append_double(qc_main,
745 CR2RES_HEADER_QC_DARK_STDEV_AVG,
746 cpl_vector_get_mean(qc_sigma)) ;
747 cpl_propertylist_append_double(qc_main,
748 CR2RES_HEADER_QC_DARK_STDEV_RMS,
749 cpl_vector_get_stdev(qc_sigma)) ;
750
751 }
752 cpl_vector_delete(qc_ron1) ;
753 cpl_vector_delete(qc_ron2) ;
754 cpl_vector_delete(qc_nb_bad) ;
755 cpl_vector_delete(qc_mean) ;
756 cpl_vector_delete(qc_med) ;
757 cpl_vector_delete(qc_sigma) ;
758
759 /* Save the results */
760
761 /* Add the Calibrations (if any) to the frameset */
762 raw_one_calib = cpl_frameset_duplicate(raw_one) ;
763 cpl_frameset_delete(raw_one) ;
764 for (i=0 ; i<cpl_frameset_get_size(frameset) ; i++) {
765 frame = cpl_frameset_get_position(frameset, i);
766 if (cpl_frame_get_group(frame) == CPL_FRAME_GROUP_CALIB) {
767 cpl_frameset_insert(raw_one_calib,
768 cpl_frame_duplicate(frame)) ;
769 }
770 }
771
772 /* MASTER DARK */
773 if (single_dit_ndit_setting) {
774 filename = cpl_sprintf("%s_master.fits", RECIPE_STRING);
775 } else {
776 filename = cpl_sprintf("%s_%s_%gx%d_master.fits",
777 RECIPE_STRING, setting_id, dit, ndit);
778 }
779
780 if (cr2res_io_save_MASTER_DARK(filename, frameset, raw_one_calib,
781 parlist, master_darks, qc_main, ext_plist,
782 CR2RES_CAL_DARK_MASTER_PROCATG, RECIPE_STRING) != 0) {
783 if (qc_main != NULL) cpl_propertylist_delete(qc_main) ;
784 cpl_frameset_delete(rawframes) ;
785 cpl_frameset_delete(raw_one_calib) ;
786 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
787 if (bpms[det_nr-1] != NULL)
788 cpl_image_delete(bpms[det_nr-1]);
789 if (master_darks[det_nr-1] != NULL)
790 hdrl_image_delete(master_darks[det_nr-1]);
791 if (ext_plist[det_nr-1] != NULL)
792 cpl_propertylist_delete(ext_plist[det_nr-1]);
793 }
794 cpl_free(labels);
795 cpl_free(setting_id);
796 hdrl_parameter_destroy(collapse_params) ;
797 cpl_free(filename) ;
798 cpl_msg_error(__func__, "Cannot save the MASTER DARK") ;
799 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
800 cpl_msg_indent_less() ;
801 return -1 ;
802
803 }
804 if (qc_main != NULL) cpl_propertylist_delete(qc_main) ;
805 cpl_free(filename) ;
806
807 /* BPM */
808 if (single_dit_ndit_setting) {
809 filename = cpl_sprintf("%s_bpm.fits", RECIPE_STRING);
810 } else {
811 filename = cpl_sprintf("%s_%s_%gx%d_bpm.fits",
812 RECIPE_STRING, setting_id, dit, ndit);
813 }
814
815 if (cr2res_io_save_BPM(filename, frameset, raw_one_calib,
816 parlist, bpms, NULL, ext_plist,
817 CR2RES_CAL_DARK_BPM_PROCATG, RECIPE_STRING) != 0) {
818 cpl_frameset_delete(rawframes) ;
819 cpl_frameset_delete(raw_one_calib) ;
820 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
821 if (bpms[det_nr-1] != NULL)
822 cpl_image_delete(bpms[det_nr-1]);
823 if (master_darks[det_nr-1] != NULL)
824 hdrl_image_delete(master_darks[det_nr-1]);
825 if (ext_plist[det_nr-1] != NULL)
826 cpl_propertylist_delete(ext_plist[det_nr-1]);
827 }
828 cpl_free(labels);
829 cpl_free(setting_id);
830 hdrl_parameter_destroy(collapse_params) ;
831 cpl_free(filename) ;
832 cpl_msg_error(__func__, "Cannot save the BPM") ;
833 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
834 cpl_msg_indent_less() ;
835 return -1 ;
836
837 }
838 cpl_free(filename) ;
839
840 /* Free */
841 cpl_free(setting_id);
842 cpl_frameset_delete(raw_one_calib) ;
843 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
844 if (bpms[det_nr-1] != NULL)
845 cpl_image_delete(bpms[det_nr-1]);
846 if (master_darks[det_nr-1] != NULL)
847 hdrl_image_delete(master_darks[det_nr-1]);
848 if (ext_plist[det_nr-1] != NULL)
849 cpl_propertylist_delete(ext_plist[det_nr-1]);
850 }
851 cpl_msg_indent_less() ;
852 }
853 cpl_free(labels);
854 hdrl_parameter_delete(collapse_params);
855 cpl_frameset_delete(rawframes) ;
856
857 return (int)cpl_error_get_code();
858}
859
860/*----------------------------------------------------------------------------*/
867/*----------------------------------------------------------------------------*/
868static int cr2res_cal_dark_compare(
869 const cpl_frame * frame1,
870 const cpl_frame * frame2)
871{
872 int comparison ;
873 cpl_propertylist * plist1 ;
874 cpl_propertylist * plist2 ;
875 double dval1, dval2 ;
876 int ival1, ival2 ;
877 const char * sval1 ;
878 const char * sval2 ;
879
880 /* Test entries */
881 if (frame1==NULL || frame2==NULL) return -1 ;
882
883 /* Get property lists */
884 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0))==NULL){
885 cpl_msg_error(__func__, "getting header from reference frame");
886 return -1 ;
887 }
888 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0))==NULL){
889 cpl_msg_error(__func__, "getting header from reference frame");
890 cpl_propertylist_delete(plist1) ;
891 return -1 ;
892 }
893
894 /* Test status */
895 if (cpl_error_get_code()) {
896 cpl_propertylist_delete(plist1) ;
897 cpl_propertylist_delete(plist2) ;
898 return -1 ;
899 }
900
901 comparison = 1 ;
902
903 /* Compare the SETTING used */
904 sval1 = cr2res_pfits_get_wlen_id(plist1) ;
905 sval2 = cr2res_pfits_get_wlen_id(plist2) ;
906 if (cpl_error_get_code()) {
907 cpl_msg_error(__func__, "Cannot get the reference wavelength");
908 cpl_propertylist_delete(plist1) ;
909 cpl_propertylist_delete(plist2) ;
910 return -1 ;
911 }
912 if (strcmp(sval1, sval2)) comparison = 0 ;
913
914 /* Compare the DIT used */
915 dval1 = cr2res_pfits_get_dit(plist1) ;
916 dval2 = cr2res_pfits_get_dit(plist2) ;
917 if (cpl_error_get_code()) {
918 cpl_msg_error(__func__, "Cannot get the DIT");
919 cpl_propertylist_delete(plist1) ;
920 cpl_propertylist_delete(plist2) ;
921 return -1 ;
922 }
923 if (fabs(dval1-dval2) > 1e-3) comparison = 0 ;
924
925 /* Compare the NDIT used */
926 ival1 = cr2res_pfits_get_ndit(plist1) ;
927 ival2 = cr2res_pfits_get_ndit(plist2) ;
928 if (cpl_error_get_code()) {
929 cpl_msg_error(__func__, "Cannot get the NDIT");
930 cpl_propertylist_delete(plist1) ;
931 cpl_propertylist_delete(plist2) ;
932 return -1 ;
933 }
934 if (ival1 != ival2) comparison = 0 ;
935
936 cpl_propertylist_delete(plist1) ;
937 cpl_propertylist_delete(plist2) ;
938 return comparison ;
939}
940
941
942
cpl_image * cr2res_bpm_from_mask(cpl_mask *mask, cr2res_bpm_type type)
Create a BPM from a mask.
Definition: cr2res_bpm.c:175
cpl_mask * cr2res_bpm_compute(cpl_image *in, cr2res_bpm_method method, double kappa, double lines_ratio, int clean_flag)
The BPM computation with min/max threshold.
Definition: cr2res_bpm.c:78
int cr2res_bpm_count(cpl_image *bpm, cr2res_bpm_type type)
Count BPM of a given type.
Definition: cr2res_bpm.c:148
cpl_error_code cr2res_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: cr2res_dfs.c:53
int cr2res_io_save_MASTER_DARK(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **master_darks, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a MASTER_DARK.
Definition: cr2res_io.c:1491
int cr2res_io_get_ext_idx(const char *filename, int detector, int data)
Get the wished extension number for a detector.
Definition: cr2res_io.c:644
hdrl_image * cr2res_io_load_image(const char *in, int detector)
Load an hdrl image from a image file.
Definition: cr2res_io.c:704
int cr2res_io_save_BPM(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_image **bpms, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a BPM.
Definition: cr2res_io.c:1555
const char * cr2res_pfits_get_wlen_id(const cpl_propertylist *plist)
find out the Setting
Definition: cr2res_pfits.c:137
double cr2res_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: cr2res_pfits.c:199
int cr2res_pfits_get_ndit(const cpl_propertylist *plist)
find out the NDIT value
Definition: cr2res_pfits.c:363
double cr2res_dark_qc_ron(const cpl_image *ima1, const cpl_image *ima2, int hsize, int nsamples, int ndit)
The Read Out Noise computation.
Definition: cr2res_qc.c:74
int cr2res_format_setting(char *setting_id)
Format the setting.
Definition: cr2res_utils.c:152
cpl_error_code cr2res_detector_shotnoise_model(const cpl_image *ima_data, const double gain, const double ron, cpl_image **ima_errs)
compute photon count error in [ADU]
int cr2res_is_short_wavelength(const char *setting_id)
Identify Short Wavelength.
Definition: cr2res_utils.c:171
cpl_frameset * cr2res_extract_frameset(const cpl_frameset *in, const char *tag)
Extract the frames with the given tag from a frameset.
char * cr2res_get_base_name(const char *filename)
Find out the base name of a file (i.e. without prefix path)
const char * cr2res_get_license(void)
Get the pipeline copyright and license.
hdrl_parameter * hdrl_collapse_sigclip_parameter_create(double kappa_low, double kappa_high, int niter)
create a parameter object for sigclipped mean
hdrl_parameter * hdrl_collapse_mode_parameter_create(double histo_min, double histo_max, double bin_size, hdrl_mode_type mode_method, cpl_size error_niter)
create a parameter object for the mode
cpl_parameterlist * hdrl_collapse_parameter_create_parlist(const char *base_context, const char *prefix, const char *method_def, hdrl_parameter *sigclip_def, hdrl_parameter *minmax_def, hdrl_parameter *mode_def)
Create parameters for the collapse.
hdrl_parameter * hdrl_collapse_minmax_parameter_create(double nlow, double nhigh)
create a parameter object for min-max rejected mean
hdrl_parameter * hdrl_collapse_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
parse parameterlist for imagelist reduction method
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
Definition: hdrl_image.c:407
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
Definition: hdrl_image.c:295
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
cpl_error_code hdrl_imagelist_collapse(const hdrl_imagelist *himlist, const hdrl_parameter *param, hdrl_image **out, cpl_image **contrib)
collapsing of image list
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
void hdrl_parameter_destroy(hdrl_parameter *obj)
deep delete of a parameter
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter