IIINSTRUMENT Pipeline Reference Manual 6.2.5
isaac_img_twflat.c
1/* $Id: isaac_img_twflat.c,v 1.45 2013-03-12 08:06:48 llundin Exp $
2 *
3 * This file is part of the ISAAC Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: llundin $
23 * $Date: 2013-03-12 08:06:48 $
24 * $Revision: 1.45 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include <string.h>
37#include <math.h>
38#include <cpl.h>
39
40#include "irplib_utils.h"
41#include "irplib_flat.h"
42
43#include "isaac_utils.h"
44#include "irplib_oddeven.h"
45#include "isaac_pfits.h"
46#include "isaac_dfs.h"
47
48/* FIXME: To be removed when CPL4.2 is available */
49#define PRO_DATANCOM "ESO PRO DATANCOM"
50
51/*-----------------------------------------------------------------------------
52 Functions prototypes
53 -----------------------------------------------------------------------------*/
54
55static int isaac_img_twflat_create(cpl_plugin *);
56static int isaac_img_twflat_exec(cpl_plugin *);
57static int isaac_img_twflat_destroy(cpl_plugin *);
58static int isaac_img_twflat(cpl_parameterlist *, cpl_frameset *);
59static cpl_imagelist * isaac_img_twflat_reduce(cpl_frameset *, cpl_frameset *);
60static int isaac_img_twflat_save(cpl_imagelist *, cpl_image *, int,
61 const cpl_frameset *, cpl_parameterlist *,
62 cpl_frameset *);
63static int isaac_img_twflat_compare(const cpl_frame *, const cpl_frame *);
64
65/*-----------------------------------------------------------------------------
66 Static variables
67 -----------------------------------------------------------------------------*/
68
69static struct {
70 double low_thresh;
71 double high_thresh;
72 int nb_badpix;
73 double med_stdev;
74 double med_avg;
75 double med_min;
76 double med_max;
77 int prop_flag;
78 int bpm_flag;
79 int errmap_flag;
80 int intercept_flag;
81 double oddeven_ll_max;
82 double oddeven_lr_max;
83 double oddeven_ul_max;
84 double oddeven_ur_max;
85 double oddeven_ll_stdev;
86 double oddeven_lr_stdev;
87 double oddeven_ul_stdev;
88 double oddeven_ur_stdev;
89 double oddeven_ll_mean;
90 double oddeven_lr_mean;
91 double oddeven_ul_mean;
92 double oddeven_ur_mean;
93} isaac_img_twflat_config;
94
95static char isaac_img_twflat_description[] =
96"isaac_img_twflat -- ISAAC imaging flat-field creation from twillight images.\n"
97"The files listed in the Set Of Frames (sof-file) must be tagged:\n"
98"raw-file.fits "ISAAC_IMG_TWFLAT_RAW" or\n"
99"raw-file.fits "ISAAC_IMG_TWFLAT_POL_RAW" or\n"
100"dark-raw-file.fits "ISAAC_CALIB_DARK"\n";
101
102/*-----------------------------------------------------------------------------
103 Functions code
104 -----------------------------------------------------------------------------*/
105
106/*----------------------------------------------------------------------------*/
114/*----------------------------------------------------------------------------*/
115int cpl_plugin_get_info(cpl_pluginlist * list)
116{
117 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
118 cpl_plugin * plugin = &recipe->interface;
119
120 cpl_plugin_init(plugin,
121 CPL_PLUGIN_API,
122 ISAAC_BINARY_VERSION,
123 CPL_PLUGIN_TYPE_RECIPE,
124 "isaac_img_twflat",
125 "Twillight flat recipe",
126 isaac_img_twflat_description,
127 "Lars Lundin",
128 PACKAGE_BUGREPORT,
130 isaac_img_twflat_create,
131 isaac_img_twflat_exec,
132 isaac_img_twflat_destroy);
133
134 cpl_pluginlist_append(list, plugin);
135
136 return 0;
137}
138
139/*----------------------------------------------------------------------------*/
148/*----------------------------------------------------------------------------*/
149static int isaac_img_twflat_create(cpl_plugin * plugin)
150{
151 cpl_recipe * recipe;
152 cpl_parameter * p;
153
154 /* Get the recipe out of the plugin */
155 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
156 recipe = (cpl_recipe *)plugin;
157 else return CPL_ERROR_UNSPECIFIED;
158
159 /* Create the parameters list in the cpl_recipe object */
160 recipe->parameters = cpl_parameterlist_new();
161
162 /* Fill the parameters list */
163 /* --t */
164 p = cpl_parameter_new_value("isaac.isaac_img_twflat.thresholds",
165 CPL_TYPE_STRING,
166 "Low and high thresholds for the BPM",
167 "isaac.isaac_img_twflat",
168 "0.5,2.0");
169 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "t");
170 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
171 cpl_parameterlist_append(recipe->parameters, p);
172 /* --prop */
173 p = cpl_parameter_new_value("isaac.isaac_img_twflat.proport", CPL_TYPE_BOOL,
174 "flag to activate the proportional fit", "isaac.isaac_img_twflat",
175 FALSE);
176 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "prop");
177 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
178 cpl_parameterlist_append(recipe->parameters, p);
179
180 /* --bpm */
181 p = cpl_parameter_new_value("isaac.isaac_img_twflat.bpm", CPL_TYPE_BOOL,
182 "flag to create the bad pixels map", "isaac.isaac_img_twflat",
183 TRUE);
184 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bpm");
185 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
186 cpl_parameterlist_append(recipe->parameters, p);
187
188 /* --errmap */
189 p = cpl_parameter_new_value("isaac.isaac_img_twflat.errmap", CPL_TYPE_BOOL,
190 "flag to create the error map", "isaac.isaac_img_twflat",
191 FALSE);
192 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "errmap");
193 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
194 cpl_parameterlist_append(recipe->parameters, p);
195
196 /* --intercept */
197 p = cpl_parameter_new_value("isaac.isaac_img_twflat.intercept",
198 CPL_TYPE_BOOL, "flag to create the intercept image",
199 "isaac.isaac_img_twflat", FALSE);
200 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "intercept");
201 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
202 cpl_parameterlist_append(recipe->parameters, p);
203
204 /* Return */
205 return 0;
206}
207
208/*----------------------------------------------------------------------------*/
214/*----------------------------------------------------------------------------*/
215static int isaac_img_twflat_exec(cpl_plugin * plugin)
216{
217 cpl_recipe * recipe;
218
219 /* Get the recipe out of the plugin */
220 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
221 recipe = (cpl_recipe *)plugin;
222 else return CPL_ERROR_UNSPECIFIED;
223
224 return isaac_img_twflat(recipe->parameters, recipe->frames);
225}
226
227/*----------------------------------------------------------------------------*/
233/*----------------------------------------------------------------------------*/
234static int isaac_img_twflat_destroy(cpl_plugin * plugin)
235{
236 cpl_recipe * recipe;
237
238 /* Get the recipe out of the plugin */
239 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
240 recipe = (cpl_recipe *)plugin;
241 else return CPL_ERROR_UNSPECIFIED;
242
243 cpl_parameterlist_delete(recipe->parameters);
244 return 0;
245}
246
247/*----------------------------------------------------------------------------*/
254/*----------------------------------------------------------------------------*/
255static int isaac_img_twflat(
256 cpl_parameterlist * parlist,
257 cpl_frameset * framelist)
258{
259 const char * sval;
260 cpl_parameter * par;
261 cpl_size * labels;
262 cpl_size nlabels;
263 cpl_frameset * flatframes;
264 cpl_frameset * darkframes;
265 cpl_frameset * flat_one;
266 cpl_frameset * dark_one;
267 int ndarks;
268 cpl_imagelist * twflat;
269 cpl_mask * bpm;
270 cpl_image * bpm_im;
271 cpl_boolean did_reduce = CPL_FALSE;
272 int i;
273
274 /* Initialise */
275 par = NULL;
276 bpm_im = NULL;
277 isaac_img_twflat_config.nb_badpix = -1;
278
279 /* Retrieve input parameters */
280 /* --t */
281 par = cpl_parameterlist_find(parlist, "isaac.isaac_img_twflat.thresholds");
282 sval = cpl_parameter_get_string(par);
283 if (sscanf(sval, "%lg,%lg",
284 &isaac_img_twflat_config.low_thresh,
285 &isaac_img_twflat_config.high_thresh)!=2) {
286 return CPL_ERROR_UNSPECIFIED;
287 }
288 /* --prop */
289 par = cpl_parameterlist_find(parlist, "isaac.isaac_img_twflat.proport");
290 isaac_img_twflat_config.prop_flag = cpl_parameter_get_bool(par);
291 /* --bpm */
292 par = cpl_parameterlist_find(parlist, "isaac.isaac_img_twflat.bpm");
293 isaac_img_twflat_config.bpm_flag = cpl_parameter_get_bool(par);
294 /* --errmap */
295 par = cpl_parameterlist_find(parlist, "isaac.isaac_img_twflat.errmap");
296 isaac_img_twflat_config.errmap_flag = cpl_parameter_get_bool(par);
297 /* --intercept */
298 par = cpl_parameterlist_find(parlist, "isaac.isaac_img_twflat.intercept");
299 isaac_img_twflat_config.intercept_flag = cpl_parameter_get_bool(par);
300
301 /* Identify the RAW and CALIB frames in the input frameset */
302 if (isaac_dfs_set_groups(framelist)) {
303 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
304 return CPL_ERROR_UNSPECIFIED;
305 }
306
307 /* Retrieve raw frames */
308 if ((flatframes = isaac_extract_frameset(framelist,
309 ISAAC_IMG_TWFLAT_RAW)) != NULL) {
310 } else if ((flatframes = isaac_extract_frameset(framelist,
311 ISAAC_IMG_TWFLAT_POL_RAW)) != NULL) {
312 } else {
313 cpl_msg_error(cpl_func, "Cannot find flat frames in the input list");
314 return CPL_ERROR_UNSPECIFIED;
315 }
316 darkframes = isaac_extract_frameset(framelist, ISAAC_CALIB_DARK);
317
318 /* If dark frames are provided - check their number */
319 if (darkframes != NULL) {
320 ndarks = cpl_frameset_get_size(darkframes);
321 if ((ndarks != 1) && (cpl_frameset_get_size(flatframes) != ndarks)) {
322 cpl_msg_error(cpl_func, "Invalid number of dark frames submitted");
323 cpl_frameset_delete(flatframes);
324 cpl_frameset_delete(darkframes);
325 return CPL_ERROR_UNSPECIFIED;
326 }
327 }
328
329 /* Labelise all input frames */
330 labels = cpl_frameset_labelise(flatframes, isaac_img_twflat_compare,
331 &nlabels);
332 if (labels == NULL) {
333 cpl_msg_error(cpl_func, "Cannot labelise input frames");
334 cpl_frameset_delete(flatframes);
335 if (darkframes) cpl_frameset_delete(darkframes);
336 return CPL_ERROR_UNSPECIFIED;
337 }
338
339 /* Extract settings and reduce each of them */
340 for (i=0; i<nlabels; i++) {
341 /* Reduce data set nb i */
342 cpl_msg_info(cpl_func, "Reduce data set no %d out of %d", i+1,
343 (int)nlabels);
344 cpl_msg_indent_more();
345 flat_one = cpl_frameset_extract(flatframes, labels, i);
346 dark_one = NULL;
347 if (darkframes) dark_one = cpl_frameset_extract(darkframes, labels, i);
348 twflat = isaac_img_twflat_reduce(flat_one, dark_one);
349 cpl_msg_indent_less();
350
351 /* Save the products */
352 cpl_msg_info(cpl_func, "Save the products");
353 cpl_msg_indent_more();
354 if (twflat == NULL) {
355 cpl_msg_warning(cpl_func, "Cannot reduce set nb %d", i+1);
356 } else {
357 /* Create the Bad pixels map */
358 if (isaac_img_twflat_config.bpm_flag) {
359 if ((bpm = cpl_mask_threshold_image_create(
360 cpl_imagelist_get(twflat, 0),
361 isaac_img_twflat_config.low_thresh,
362 isaac_img_twflat_config.high_thresh)) == NULL) {
363 cpl_msg_warning(cpl_func, "Cannot create bad pixels map");
364 } else {
365 cpl_mask_not(bpm);
366 isaac_img_twflat_config.nb_badpix = cpl_mask_count(bpm);
367 bpm_im = cpl_image_new_from_mask(bpm);
368 cpl_mask_delete(bpm);
369 }
370 }
371 isaac_img_twflat_save(twflat, bpm_im, i+1, flat_one, parlist,
372 framelist);
373 if (bpm_im) cpl_image_delete(bpm_im);
374 cpl_imagelist_delete(twflat);
375 if (!cpl_error_get_code()) did_reduce = CPL_TRUE;
376 }
377 cpl_msg_indent_less();
378 cpl_frameset_delete(flat_one);
379 if (dark_one) cpl_frameset_delete(dark_one);
380 }
381
382 /* Free and return */
383 cpl_frameset_delete(flatframes);
384 if (darkframes) cpl_frameset_delete(darkframes);
385 cpl_free(labels);
386
387 cpl_ensure_code(did_reduce, CPL_ERROR_ILLEGAL_INPUT);
388
389 return cpl_error_set_where(cpl_func); /* Propagate error, if any */
390}
391
392/*----------------------------------------------------------------------------*/
403/*----------------------------------------------------------------------------*/
404static cpl_imagelist * isaac_img_twflat_reduce(
405 cpl_frameset * flatframes,
406 cpl_frameset * darkframes)
407{
408 cpl_frame * frame;
409 cpl_propertylist * plist;
410 const char * sval;
411 cpl_image * flat_image;
412 cpl_imagelist * in,
413 * dark,
414 * results;
415 cpl_stats * stats_ima;
416 cpl_vector * medians;
417 double gradient;
418 double norm;
419 int nima;
420 cpl_vector * reve_ll;
421 cpl_vector * reve_lr;
422 cpl_vector * reve_ul;
423 cpl_vector * reve_ur;
424 double ll, lr, ul, ur;
425 int i;
426
427 /* Test entries */
428 if (flatframes == NULL) return NULL;
429
430 /* Initialise */
431 nima = cpl_frameset_get_size(flatframes);
432
433 /* Check the error status */
434 if (cpl_error_get_code()) return NULL;
435
436 /* Print out the filter and the read-out mode */
437 frame = cpl_frameset_get_position(flatframes, 0);
438 plist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
439 sval = isaac_pfits_get_filter(plist);
440 if (cpl_error_get_code()) {
441 cpl_msg_error(cpl_func, "Cannot get the filter or ROM or TPL.ID");
442 cpl_propertylist_delete(plist);
443 return NULL;
444 }
445 cpl_msg_info(cpl_func, "Filter: [%s]", sval);
446 cpl_propertylist_delete(plist);
447
448 /* Load input image set */
449 cpl_msg_info(cpl_func, "---> Loading input set");
450 if ((in = cpl_imagelist_load_frameset(flatframes, CPL_TYPE_FLOAT, 1,
451 0)) == NULL) {
452 cpl_msg_error(cpl_func, "Cannot load the image set");
453 return NULL;
454 }
455
456 /* Compute some stats on input images */
457 cpl_msg_info(cpl_func, "---> Computing stats");
458 cpl_msg_info(cpl_func, "image min max med rms");
459 cpl_msg_info(cpl_func, "---------------------------------------------");
460 medians = cpl_vector_new(nima);
461 for (i=0; i<nima; i++) {
462 stats_ima = cpl_stats_new_from_image(cpl_imagelist_get(in, i),
463 CPL_STATS_ALL);
464 if (stats_ima == NULL) {
465 cpl_msg_error(cpl_func, "Cannot compute stats on image %d", i+1);
466 cpl_imagelist_delete(in);
467 cpl_vector_delete(medians);
468 return NULL;
469 }
470 cpl_vector_set(medians, i, cpl_stats_get_median(stats_ima));
471 cpl_msg_info(cpl_func, "%02d %10.2f %10.2f %10.2f %10.2f",
472 i+1,
473 cpl_stats_get_min(stats_ima),
474 cpl_stats_get_max(stats_ima),
475 cpl_stats_get_median(stats_ima),
476 cpl_stats_get_stdev(stats_ima));
477 if (cpl_stats_get_median(stats_ima) < 1e-6) {
478 cpl_msg_error(cpl_func, "image %d has negative flux: aborting",
479 i+1);
480 cpl_imagelist_delete(in);
481 cpl_vector_delete(medians);
482 cpl_stats_delete(stats_ima);
483 return NULL;
484 }
485 cpl_stats_delete(stats_ima);
486 }
487 cpl_msg_info(cpl_func, "---------------------------------------------");
488
489 /* Compute min max stdev and mean of the medians */
490 isaac_img_twflat_config.med_min = cpl_vector_get_min(medians);
491 isaac_img_twflat_config.med_max = cpl_vector_get_max(medians);
492 isaac_img_twflat_config.med_avg = cpl_vector_get_mean(medians);
493 isaac_img_twflat_config.med_stdev = cpl_vector_get_stdev(medians);
494 cpl_vector_delete(medians);
495
496 /* Apply dark correction to all planes if requested */
497 if (darkframes) {
498 cpl_msg_info(cpl_func, "---> Subtracting dark");
499 /* Load dark cube */
500 if ((dark = cpl_imagelist_load_frameset(darkframes, CPL_TYPE_FLOAT, 1,
501 0)) == NULL) {
502 cpl_msg_error(cpl_func, "Cannot load the darks set");
503 cpl_imagelist_delete(in);
504 return NULL;
505 }
506 /* Dark correction */
507 if (cpl_imagelist_get_size(dark) == 1) {
508 cpl_imagelist_subtract_image(in, cpl_imagelist_get(dark, 0));
509 } else {
510 cpl_imagelist_subtract(in, dark);
511 }
512 cpl_imagelist_delete(dark);
513
514 /* With the darks provided, the proportional method is used */
515 cpl_msg_info(cpl_func, "switching to proportional fit");
516 isaac_img_twflat_config.prop_flag = 1;
517 }
518
519 /* See if flux gradient is large enough for a correct fit */
520 if (!isaac_img_twflat_config.prop_flag) {
521 gradient=fabs(isaac_img_twflat_config.med_max/
522 isaac_img_twflat_config.med_min);
523 if (gradient < 4.0) {
524 cpl_msg_warning(cpl_func, "low flux gradient: %g", gradient);
525 cpl_msg_warning(cpl_func,"a proportional fit may give better ");
526 cpl_msg_warning(cpl_func,"results (requires a master dark frame)");
527 }
528 }
529
530 /* Monitor the odd/even column effect */
531 cpl_msg_info(cpl_func, "---> Monitor odd/even column effect");
532 reve_ll = cpl_vector_new(nima);
533 reve_lr = cpl_vector_new(nima);
534 reve_ul = cpl_vector_new(nima);
535 reve_ur = cpl_vector_new(nima);
536 for (i=0; i<nima; i++) {
537 irplib_oddeven_monitor(cpl_imagelist_get(in, i), 1, &ll);
538 irplib_oddeven_monitor(cpl_imagelist_get(in, i), 2, &lr);
539 irplib_oddeven_monitor(cpl_imagelist_get(in, i), 3, &ul);
540 irplib_oddeven_monitor(cpl_imagelist_get(in, i), 4, &ur);
541 cpl_vector_set(reve_ll, i, ll);
542 cpl_vector_set(reve_lr, i, lr);
543 cpl_vector_set(reve_ul, i, ul);
544 cpl_vector_set(reve_ur, i, ur);
545 }
546 isaac_img_twflat_config.oddeven_ll_max = cpl_vector_get_max(reve_ll);
547 isaac_img_twflat_config.oddeven_lr_max = cpl_vector_get_max(reve_lr);
548 isaac_img_twflat_config.oddeven_ul_max = cpl_vector_get_max(reve_ul);
549 isaac_img_twflat_config.oddeven_ur_max = cpl_vector_get_max(reve_ur);
550 isaac_img_twflat_config.oddeven_ll_stdev = cpl_vector_get_stdev(reve_ll);
551 isaac_img_twflat_config.oddeven_lr_stdev = cpl_vector_get_stdev(reve_lr);
552 isaac_img_twflat_config.oddeven_ul_stdev = cpl_vector_get_stdev(reve_ul);
553 isaac_img_twflat_config.oddeven_ur_stdev = cpl_vector_get_stdev(reve_ur);
554 isaac_img_twflat_config.oddeven_ll_mean = cpl_vector_get_mean(reve_ll);
555 isaac_img_twflat_config.oddeven_lr_mean = cpl_vector_get_mean(reve_lr);
556 isaac_img_twflat_config.oddeven_ul_mean = cpl_vector_get_mean(reve_ul);
557 isaac_img_twflat_config.oddeven_ur_mean = cpl_vector_get_mean(reve_ur);
558 cpl_vector_delete(reve_ll);
559 cpl_vector_delete(reve_lr);
560 cpl_vector_delete(reve_ul);
561 cpl_vector_delete(reve_ur);
562
563 /* Fit slopes, get results */
564 cpl_msg_info(cpl_func, "---> Fitting slopes");
565 if (isaac_img_twflat_config.prop_flag) {
566 results = irplib_flat_fit_set(in, 0);
567 if (results == NULL) {
568 cpl_msg_error(cpl_func, "creating twilight flat-field: aborting");
569 cpl_imagelist_delete(in);
570 return NULL;
571 }
572 } else {
573 results = irplib_flat_fit_set(in, 1);
574 if (results == NULL) {
575 cpl_msg_error(cpl_func, "creating twilight flat-field: aborting");
576 cpl_imagelist_delete(in);
577 return NULL;
578 }
579 }
580 cpl_imagelist_delete(in);
581
582 /* Normalize gain */
583 flat_image = cpl_imagelist_get(results, 0);
584 norm = cpl_image_get_mean(flat_image);
585 cpl_image_divide_scalar(flat_image, norm);
586 if (cpl_error_get_code()) {
587 cpl_imagelist_delete(results);
588 return NULL;
589 }
590
591 return results;
592}
593
594/*----------------------------------------------------------------------------*/
604/*----------------------------------------------------------------------------*/
605static int isaac_img_twflat_save(
606 cpl_imagelist * flat,
607 cpl_image * bpm,
608 int set_nb,
609 const cpl_frameset * set,
610 cpl_parameterlist * parlist,
611 cpl_frameset * set_tot)
612{
613 const cpl_size nframes = cpl_frameset_get_size(set);
614 cpl_propertylist * plist;
615 cpl_propertylist * paflist;
616 cpl_propertylist * qclist;
617 const cpl_frame * ref_frame;
618 char * filename;
619 const char * sval;
620 int nima, file_id;
621 int nraw;
622
623 /* Initialise */
624 nima = cpl_imagelist_get_size(flat);
625 if (nima != 2 && nima != 3) return CPL_ERROR_UNSPECIFIED;
626
627 /* Get the QC params in qclist */
628 qclist = cpl_propertylist_new();
629
630 /* Get the reference frame */
631 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
632 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
633 0)) == NULL) {
634 cpl_msg_error(cpl_func, "getting header from reference frame");
635 cpl_propertylist_delete(qclist);
636 return CPL_ERROR_UNSPECIFIED;
637 }
638 /* Test the status */
639 if (cpl_error_get_code()) {
640 cpl_propertylist_delete(qclist);
641 cpl_propertylist_delete(plist);
642 return CPL_ERROR_UNSPECIFIED;
643 }
644 /* Add FILTER */
645 sval = isaac_pfits_get_filter(plist);
646 if (cpl_error_get_code()) cpl_error_reset();
647 else cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
648 /* Add OBJECTIVE */
649 sval = isaac_pfits_get_objective(plist);
650 if (cpl_error_get_code()) cpl_error_reset();
651 else cpl_propertylist_append_string(qclist, "ESO QC OBJECTIVE", sval);
652 cpl_propertylist_delete(plist);
653 cpl_propertylist_append_double(qclist, "ESO QC TWFLAT MEDMIN",
654 isaac_img_twflat_config.med_min);
655 cpl_propertylist_append_double(qclist, "ESO QC TWFLAT MEDMAX",
656 isaac_img_twflat_config.med_max);
657 cpl_propertylist_append_double(qclist, "ESO QC TWFLAT MEDAVG",
658 isaac_img_twflat_config.med_avg);
659 cpl_propertylist_append_double(qclist, "ESO QC TWFLAT MEDSTDEV",
660 isaac_img_twflat_config.med_stdev);
661 if (isaac_img_twflat_config.nb_badpix >=0 ) {
662 cpl_propertylist_append_int(qclist, "ESO QC TWFLAT NBADPIX",
663 isaac_img_twflat_config.nb_badpix);
664 }
665 cpl_propertylist_append_int(qclist, "ESO QC TWFLAT NFRAMES",
666 nframes);
667 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN LLMAX",
668 isaac_img_twflat_config.oddeven_ll_max);
669 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN LLMEAN",
670 isaac_img_twflat_config.oddeven_ll_mean);
671 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN LLSTDEV",
672 isaac_img_twflat_config.oddeven_ll_stdev);
673 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN LRMAX",
674 isaac_img_twflat_config.oddeven_lr_max);
675 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN LRMEAN",
676 isaac_img_twflat_config.oddeven_lr_mean);
677 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN LRSTDEV",
678 isaac_img_twflat_config.oddeven_lr_stdev);
679 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN ULMAX",
680 isaac_img_twflat_config.oddeven_ul_max);
681 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN ULMEAN",
682 isaac_img_twflat_config.oddeven_ul_mean);
683 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN ULSTDEV",
684 isaac_img_twflat_config.oddeven_ul_stdev);
685 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN URMAX",
686 isaac_img_twflat_config.oddeven_ur_max);
687 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN URMEAN",
688 isaac_img_twflat_config.oddeven_ur_mean);
689 cpl_propertylist_append_double(qclist, "ESO QC ODDEVEN URSTDEV",
690 isaac_img_twflat_config.oddeven_ur_stdev);
691
692 /* Write the flat image */
693 filename = cpl_sprintf("isaac_img_twflat_set%02d.fits", set_nb);
694 irplib_dfs_save_image(set_tot,
695 parlist,
696 set,
697 cpl_imagelist_get(flat, 0),
698 CPL_BPP_IEEE_FLOAT,
699 "isaac_img_twflat",
700 ISAAC_IMG_TWFLAT_RES,
701 qclist,
702 NULL,
703 PACKAGE "/" PACKAGE_VERSION,
704 filename);
705 cpl_free(filename);
706
707 /* Write the bpm image */
708 if (bpm) {
709 filename = cpl_sprintf("isaac_img_twflat_set%02d_bpm.fits", set_nb);
710 irplib_dfs_save_image(set_tot,
711 parlist,
712 set,
713 bpm,
714 CPL_BPP_IEEE_FLOAT,
715 "isaac_img_twflat",
716 ISAAC_IMG_TWFLAT_BPM,
717 qclist,
718 NULL,
719 PACKAGE "/" PACKAGE_VERSION,
720 filename);
721 cpl_free(filename);
722 }
723
724 /* Write the intercept image */
725 if (isaac_img_twflat_config.intercept_flag && nima == 3) {
726 filename = cpl_sprintf("isaac_img_twflat_set%02d_inter.fits",set_nb);
727 irplib_dfs_save_image(set_tot,
728 parlist,
729 set,
730 cpl_imagelist_get(flat, 1),
731 CPL_BPP_IEEE_FLOAT,
732 "isaac_img_twflat",
733 ISAAC_IMG_TWFLAT_INTERC,
734 qclist,
735 NULL,
736 PACKAGE "/" PACKAGE_VERSION,
737 filename);
738 cpl_free(filename);
739 }
740
741 /* Write the error map image */
742 if (isaac_img_twflat_config.errmap_flag) {
743 if (nima == 2) file_id = 1;
744 else file_id = 2;
745 filename=cpl_sprintf("isaac_img_twflat_set%02d_errmap.fits", set_nb);
746 irplib_dfs_save_image(set_tot,
747 parlist,
748 set,
749 cpl_imagelist_get(flat, file_id),
750 CPL_BPP_IEEE_FLOAT,
751 "isaac_img_twflat",
752 ISAAC_IMG_TWFLAT_ERR,
753 qclist,
754 NULL,
755 PACKAGE "/" PACKAGE_VERSION,
756 filename);
757 cpl_free(filename);
758 }
759
760 /* Get FITS header from reference file */
761 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
762 0)) == NULL) {
763 cpl_msg_error(cpl_func, "getting header from reference frame");
764 cpl_propertylist_delete(qclist);
765 return CPL_ERROR_UNSPECIFIED;
766 }
767
768 /* Get the keywords for the paf file */
769 paflist = cpl_propertylist_new();
770 cpl_propertylist_copy_property_regexp(paflist, plist,
771 "^(DATE-OBS|ESO DET CHIP NAME|ARCFILE|ESO TPL ID|ESO DET MODE NAME|"
772 "ESO DET NCORRS NAME|ESO DET RSPEED|ESO DET DIT)$", 0);
773 cpl_propertylist_delete(plist);
774
775
776 /* Add PRO.DATANCOM keyword (DFS05421) */
777 nraw = 0;
778 for (cpl_size i = 0; i < nframes; i++) {
779 const cpl_frame* iframe = cpl_frameset_get_position_const(set, i);
780 if (cpl_frame_get_group(iframe) == CPL_FRAME_GROUP_RAW) nraw++;
781 }
782
783 if (!cpl_propertylist_has(paflist, PRO_DATANCOM)) {
784 cpl_propertylist_update_int(paflist, PRO_DATANCOM, nraw);
785 cpl_propertylist_set_comment(paflist, PRO_DATANCOM,
786 "Number of combined frames");
787 }
788 /* The above piece of code regarding DFS05421 has been partially copied
789 from cpl_dfs.c as a workaround for that request until PAF files are
790 completely deprecated (which is planned for the long term). */
791
792 /* Copy the QC in paflist */
793 cpl_propertylist_copy_property_regexp(paflist, qclist, ".", 0);
794 cpl_propertylist_delete(qclist);
795
796 /* PRO.CATG */
797 cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG,
798 ISAAC_IMG_TWFLAT_RES);
799
800 /* Save the PAF file */
801 filename = cpl_sprintf("isaac_img_twflat_set%02d.paf", set_nb);
802 cpl_dfs_save_paf("ISAAC",
803 "isaac_img_twflat",
804 paflist,
805 filename);
806 cpl_free(filename);
807 cpl_propertylist_delete(paflist);
808 return 0;
809}
810
811/*----------------------------------------------------------------------------*/
818/*----------------------------------------------------------------------------*/
819static int isaac_img_twflat_compare(
820 const cpl_frame * frame1,
821 const cpl_frame * frame2)
822{
823 int comparison;
824 cpl_propertylist * plist1;
825 cpl_propertylist * plist2;
826 const char * sval1,
827 * sval2;
828
829 /* Test entries */
830 if (frame1==NULL || frame2==NULL) return CPL_ERROR_UNSPECIFIED;
831
832 /* Get property lists */
833 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
834 0)) == NULL) {
835 cpl_msg_error(cpl_func, "getting header from reference frame");
836 return CPL_ERROR_UNSPECIFIED;
837 }
838 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
839 0)) == NULL) {
840 cpl_msg_error(cpl_func, "getting header from reference frame");
841 cpl_propertylist_delete(plist1);
842 return CPL_ERROR_UNSPECIFIED;
843 }
844
845 /* Test status */
846 if (cpl_error_get_code()) {
847 cpl_propertylist_delete(plist1);
848 cpl_propertylist_delete(plist2);
849 return CPL_ERROR_UNSPECIFIED;
850 }
851
852 comparison = 1;
853
854 /* Compare filters */
855 sval1 = isaac_pfits_get_filter(plist1);
856 sval2 = isaac_pfits_get_filter(plist2);
857 if (cpl_error_get_code()) {
858 cpl_msg_error(cpl_func, "cannot get the filter");
859 cpl_propertylist_delete(plist1);
860 cpl_propertylist_delete(plist2);
861 return CPL_ERROR_UNSPECIFIED;
862 }
863 if (strcmp(sval1, sval2)) comparison = 0;
864
865 cpl_propertylist_delete(plist1);
866 cpl_propertylist_delete(plist2);
867 return comparison;
868}
869
870
int isaac_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: isaac_dfs.c:60
const char * isaac_pfits_get_objective(const cpl_propertylist *plist)
find out the objective
Definition: isaac_pfits.c:642
const char * isaac_pfits_get_filter(const cpl_propertylist *plist)
find out the filter
Definition: isaac_pfits.c:880
cpl_frameset * isaac_extract_frameset(const cpl_frameset *self, const char *tag)
Extract the frames with the given tag from a frameset.
Definition: isaac_utils.c:356
const char * isaac_get_license(void)
Get the pipeline copyright and license.
Definition: isaac_utils.c:62