36 #include "naco_recipe.h"
42 #define RECIPE_STRING "naco_img_lampflat"
48 static cpl_image * naco_img_lampflat_reduce(cpl_propertylist *,
49 const irplib_framelist *,
52 static cpl_error_code naco_img_lampflat_qc(cpl_propertylist *,
54 const irplib_framelist *);
56 static cpl_error_code naco_img_lampflat_save(cpl_frameset *,
57 const cpl_parameterlist *,
58 const cpl_propertylist *,
59 const cpl_propertylist *,
61 int,
const irplib_framelist *);
63 static char * naco_img_lampflat_make_tag(
const cpl_frame*,
64 const cpl_propertylist *,
int);
66 NACO_RECIPE_DEFINE(naco_img_lampflat, NACO_PARAM_REJBORD,
67 "Flat recipe using a lamp",
68 RECIPE_STRING
" -- NACO imaging flat-field creation from "
70 "The files listed in the Set Of Frames (sof-file) "
72 "NACO-raw-file.fits " NACO_IMG_LAMPFLAT_RAW
"\n"
74 "Furthermore, the input set of frames must have values of "
76 NACO_PFITS_INT_LAMP2
" that alternate between zero and "
77 "non-zero (with non-zero for the first frame).\n"
78 "It is further required that the light from the lamp is "
79 "in a range without a significant thermal background.");
100 static int naco_img_lampflat(cpl_frameset * framelist,
101 const cpl_parameterlist * parlist)
103 cpl_errorstate cleanstate = cpl_errorstate_get();
104 irplib_framelist * allframes = NULL;
105 irplib_framelist * rawframes = NULL;
106 irplib_framelist * f_one = NULL;
107 const char ** taglist = NULL;
108 const char * rej_bord;
109 cpl_image * lamp_flat = NULL;
110 cpl_propertylist * qclist = cpl_propertylist_new();
111 cpl_propertylist * paflist = cpl_propertylist_new();
114 int rej_left, rej_right, rej_bottom, rej_top;
121 skip_if (sscanf(rej_bord,
"%d %d %d %d",
122 &rej_left, &rej_right, &rej_bottom, &rej_top) != 4);
128 skip_if(allframes == NULL);
131 skip_if(rawframes == NULL);
135 IRPLIB_PFITS_REGEXP_RECAL
"|"
136 NACO_PFITS_REGEXP_LAMPFLAT
"|"
137 NACO_PFITS_REGEXP_LAMPFLAT_PAF
142 skip_if(taglist == NULL);
144 cpl_msg_info(cpl_func,
"Identified %d setting(s) in %d frames",
148 for (i=0 ; i < nsets ; i++) {
151 cpl_msg_info(cpl_func,
"Reducing data set %d of %d", i+1, nsets);
159 cpl_msg_info(cpl_func,
"Reducing frame set %d of %d (size=%d) with "
160 "setting: %s", i+1, nsets,
163 skip_if (f_one == NULL);
165 lamp_flat = naco_img_lampflat_reduce(qclist, f_one, rej_left, rej_right,
166 rej_bottom, rej_top);
169 if (lamp_flat == NULL) {
171 irplib_error_recover(cleanstate,
"Could not compute the flat for "
174 skip_if(naco_img_lampflat_qc(qclist, paflist, f_one));
176 bug_if(cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
177 NACO_IMG_LAMPFLAT_RES));
178 skip_if(naco_img_lampflat_save(framelist, parlist, qclist, paflist,
179 lamp_flat, i+1, f_one));
180 cpl_image_delete(lamp_flat);
184 cpl_propertylist_empty(qclist);
185 cpl_propertylist_empty(paflist);
190 irplib_ensure(nb_good > 0, CPL_ERROR_DATA_NOT_FOUND,
191 "None of the %d sets could be reduced", nsets);
196 cpl_image_delete(lamp_flat);
200 cpl_propertylist_delete(qclist);
201 cpl_propertylist_delete(paflist);
203 return cpl_error_get_code();
218 static cpl_image * naco_img_lampflat_reduce(cpl_propertylist * qclist,
219 const irplib_framelist * framelist,
220 int rej_left,
int rej_right,
221 int rej_bottom,
int rej_top)
224 cpl_image * image = NULL;
225 cpl_image * aver = NULL;
226 cpl_image * diff = NULL;
227 cpl_image * prev = NULL;
228 cpl_image * image0= NULL;
229 double gain, fp_noise;
230 double lamp_flux = DBL_MAX;
232 double mean = DBL_MAX;
237 bug_if (framelist == NULL);
242 skip_if_lt(nfiles, 4,
"frames");
245 irplib_ensure (nfiles % 2 == 0, CPL_ERROR_ILLEGAL_INPUT,
246 "The number of frames must be even, not %d", nfiles);
249 CPL_TYPE_DOUBLE, CPL_TRUE, 1e-5));
252 CPL_TYPE_INT, CPL_FALSE, 0.0));
256 for (i=0 ; i < nfiles ; i++) {
258 const char * name = cpl_frame_get_filename(frame);
259 const cpl_propertylist * plist
263 skip_if(name == NULL);
264 skip_if(plist == NULL);
271 cpl_msg_info(cpl_func,
"Filter: [%s]", sval);
274 skip_if(cpl_propertylist_append_string(qclist,
"ESO QC FILTER OBS",
278 skip_if(cpl_propertylist_append_string(qclist,
"ESO QC FILTER NDENS",
282 skip_if(cpl_propertylist_append_string(qclist,
"ESO QC FILTER POL",
286 cpl_msg_info(cpl_func,
"File %02d: %s", i+1, name);
291 irplib_ensure (ival == 0, CPL_ERROR_ILLEGAL_INPUT,
292 "Frame number %d must have %s set to zero, not %d",
293 i+1, NACO_PFITS_INT_LAMP2, ival);
295 irplib_ensure (ival != 0, CPL_ERROR_ILLEGAL_INPUT,
296 "Frame number %d must have a non-zero %s",
297 i+1, NACO_PFITS_INT_LAMP2);
300 irplib_check(image = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0),
301 "Could not load FITS-image from %s", name);
304 irplib_check(mean = cpl_image_get_mean(image),
305 "Could not compute mean");
306 image0 = image; image = NULL;
308 const int ifirst = i == 3 ? 1 : 0;
313 irplib_check(diff = cpl_image_subtract_create(image0, image),
314 "Could not subtract the images %d and %d",
317 irplib_check(cpl_flux_get_noise_window(diff, NULL, -1, -1,
319 "Could not compute noise on difference between"
320 " images %d and %d", ifirst+1, i+1);
322 std_diff[i-1] = noise * noise;
327 const double median = cpl_image_get_median(diff);
330 skip_if (cpl_error_get_code());
331 skip_if (ditval <= 0.0);
333 lamp_flux = median / ditval;
339 cpl_image_delete(diff);
342 cpl_image_delete(image0);
344 image0 = i == 2 ? prev : NULL;
349 if (i > 1 && i % 2 != 0) {
351 irplib_check(cpl_image_subtract(prev, image),
352 "Could not correct for the dark");
355 irplib_check(cpl_image_add(aver, prev),
356 "Could not sum up the dark corrected images");
358 cpl_image_delete(image);
359 cpl_image_delete(prev);
368 cpl_msg_info(cpl_func,
"Computing the QC parameters");
371 square = std_diff[1] - std_diff[2];
372 if (square != 0.0) square = 2.0*mean/square;
373 gain = square > 0.0 ? sqrt(square) : 0.0;
376 square = std_diff[0] - std_diff[1] - std_diff[2];
377 fp_noise = square > 0.0 ? sqrt(square) : 0.0;
380 cpl_msg_info(cpl_func,
"Gain: %g", gain);
381 cpl_msg_info(cpl_func,
"Noise: %g", fp_noise);
382 cpl_msg_info(cpl_func,
"Lamp flux: %g", lamp_flux);
385 cpl_msg_info(cpl_func,
"Average the dark corrected frames");
386 irplib_check(cpl_image_divide_scalar(aver, (
double)(nfiles/2)),
387 "Could not average the %d dark corrected frames", nfiles/2);
391 = cpl_image_get_mean_window(aver, rej_left,
392 cpl_image_get_size_x(aver)
395 cpl_image_get_size_y(aver)
397 cpl_image_divide_scalar(aver, mean),
398 "Could not average the %d dark corrected frames", nfiles/2);
401 skip_if(cpl_propertylist_append_double(qclist,
"ESO QC GAIN", gain));
402 skip_if(cpl_propertylist_append_double(qclist,
"ESO QC FPNOISE", fp_noise));
403 skip_if(cpl_propertylist_append_double(qclist,
"ESO QC LAMPFLUX",
408 if (cpl_error_get_code()) {
409 cpl_image_delete(aver);
413 cpl_image_delete(image);
414 cpl_image_delete(diff);
415 cpl_image_delete(prev);
416 cpl_image_delete(image0);
431 static cpl_error_code naco_img_lampflat_qc(cpl_propertylist * qclist,
432 cpl_propertylist * paflist,
433 const irplib_framelist * rawframes)
436 const cpl_propertylist * reflist
438 const char pafcopy[] =
"^(" NACO_PFITS_REGEXP_LAMPFLAT_PAF
")$";
445 skip_if (cpl_propertylist_copy_property_regexp(paflist, reflist, pafcopy,
447 skip_if (cpl_propertylist_append(paflist, qclist));
449 bug_if (cpl_propertylist_copy_property_regexp(qclist, reflist,
"^("
450 IRPLIB_PFITS_REGEXP_RECAL
457 return cpl_error_get_code();
473 static cpl_error_code naco_img_lampflat_save(cpl_frameset * set_tot,
474 const cpl_parameterlist * parlist,
475 const cpl_propertylist * qclist,
476 const cpl_propertylist * paflist,
477 const cpl_image * flat,
479 const irplib_framelist * rawframes)
482 char * filename = NULL;
490 filename = cpl_sprintf(RECIPE_STRING
"_set%02d" CPL_DFS_FITS, set_nb);
492 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
493 NACO_IMG_LAMPFLAT_RES, qclist, NULL,
494 naco_pipe_id, filename));
498 filename = cpl_sprintf(RECIPE_STRING
"_set%02d" CPL_DFS_PAF, set_nb);
499 skip_if (cpl_dfs_save_paf(
"NACO", RECIPE_STRING, paflist, filename));
501 bug_if(paflist == NULL);
507 cpl_frameset_delete(proframes);
509 return cpl_error_get_code();
525 static char * naco_img_lampflat_make_tag(
const cpl_frame*
self,
526 const cpl_propertylist * plist,
539 skip_if (cpl_error_get_code());
541 skip_if(
self == NULL);
542 skip_if(plist == NULL);
548 skip_if(cpl_error_get_code());
552 skip_if(cpl_error_get_code());
556 skip_if(cpl_error_get_code());
560 skip_if(cpl_error_get_code());
564 skip_if(cpl_error_get_code());
568 skip_if(cpl_error_get_code());
571 tag = cpl_sprintf(
"%s:%s:%s:%s:%s:%.5f", filter,
572 opti7, opti3, rom, mode, dit);
577 if (cpl_error_get_code()) {
cpl_frameset * irplib_frameset_cast(const irplib_framelist *self)
Create a CPL frameset from an irplib_framelist.
const char * naco_pfits_get_rom_name(const cpl_propertylist *self)
find out the read out mode name
double naco_pfits_get_dit(const cpl_propertylist *self)
find out the DIT
const char * naco_pfits_get_opti4_name(const cpl_propertylist *self)
find out the OPTI4.NAME key
int naco_pfits_get_lamp2(const cpl_propertylist *self)
find out the INS.LAMP2.SET keyword
cpl_error_code irplib_framelist_set_tag_all(irplib_framelist *self, const char *tag)
Set the tag of all frames in the list.
int naco_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
cpl_error_code irplib_pfits_set_airmass(cpl_propertylist *self, const irplib_framelist *rawframes)
Update/Set the AIRMASS property.
const char * naco_pfits_get_opti7_name(const cpl_propertylist *self)
find out the OPTI7.NAME key
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
void irplib_framelist_empty(irplib_framelist *self)
Erase all frames from a framelist.
cpl_error_code irplib_dfs_save_image(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_image *image, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist *self, int ind, const char *regexp, cpl_boolean invert)
Load the propertylists of all frames in the framelist.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
const char ** naco_framelist_set_tag(irplib_framelist *self, char *(*pftag)(const cpl_frame *, const cpl_propertylist *, int), int *pntags)
Retag a framelist according to the given tagging function.
const char * naco_pfits_get_opti3_name(const cpl_propertylist *self)
find out the OPTI3.NAME key
void irplib_framelist_delete(irplib_framelist *self)
Deallocate an irplib_framelist with its frames and properties.
cpl_error_code irplib_framelist_contains(const irplib_framelist *self, const char *key, cpl_type type, cpl_boolean is_equal, double fp_tol)
Verify that a property is present for all frames.
const char * naco_pfits_get_mode(const cpl_propertylist *self)
find out the mode name
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
const char * naco_parameterlist_get_string(const cpl_parameterlist *self, const char *recipe, naco_parameter bitmask)
Retrieve the value of a NACO string parameter.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.
const char * naco_pfits_get_filter(const cpl_propertylist *self)
find out the filter