36 #include "visir_recipe.h"
43 #define RECIPE_STRING "visir_util_join"
50 cpl_error_code visir_util_join_one(cpl_frameset *,
51 const irplib_framelist *,
52 const irplib_framelist *,
53 const irplib_framelist *,
54 const irplib_framelist *,
55 const irplib_framelist *,
56 const irplib_framelist *,
57 int, cpl_boolean, cpl_boolean,
58 cpl_boolean, cpl_boolean,
60 const cpl_parameterlist *);
63 #define cpl_plugin_get_info visir_util_join_get_info
65 VISIR_RECIPE_DEFINE(visir_util_join, 0,
66 "Extend the final product with extensions containing its "
67 "error map, bad pixel map and weight or contribution map",
68 "The files listed in the Set Of Frames (SOF-file) "
70 "VISIR-data.fits " VISIR_UTIL_DATA
"\n"
71 "\nOptionally, the SOF may also contain one or more of "
73 "VISIR-bad-pixel-map.fits " VISIR_CALIB_BPM
"\n"
74 "VISIR-error.fits " VISIR_UTIL_WEIGHT2ERROR_PROCATG
76 "VISIR-contribution-map.fits " VISIR_IMG_CLIPPED_MAP_PROCATG
78 "VISIR-weight-map.fits " VISIR_UTIL_WEIGHT2ERROR
80 "\nThe product(s) will have a FITS card\n"
81 "'HIERARCH " CPL_DFS_PRO_CATG
"' with a value of:\n"
82 VISIR_UTIL_JOIN_PROCATG);
102 static int visir_util_join(cpl_frameset * framelist,
103 const cpl_parameterlist * parlist)
105 irplib_framelist * allframes = NULL;
106 irplib_framelist * rawframes = NULL;
107 irplib_framelist * bpmframes = NULL;
108 irplib_framelist * errframes = NULL;
109 irplib_framelist * conframes = NULL;
110 irplib_framelist * wgtframes = NULL;
111 irplib_framelist * qcframes = NULL;
113 int nbad = 0, nerr = 0, ncon = 0, nwgt = 0, nqc = 0;
118 FOR_EACH_FRAMESET(frm, framelist)
119 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
123 skip_if(allframes == NULL);
128 "|" VISIR_IMG_PHOT_ONEBEAM_PROCATG
129 "|" VISIR_IMG_PHOT_COMBINED_PROCATG
131 "|COADDED_IMAGE_COMBINED"
135 skip_if(rawframes == NULL);
139 if (cpl_frameset_find_const(framelist, VISIR_CALIB_BPM)) {
141 skip_if (bpmframes == NULL);
144 error_if(nbad != n && nbad != 1, CPL_ERROR_INCOMPATIBLE_INPUT,
145 "%d raw-frames <=> %d bpm frames", n, nbad);
148 if (cpl_frameset_find_const(framelist, VISIR_UTIL_ERROR_MAP_PROCATG)) {
150 VISIR_UTIL_ERROR_MAP_PROCATG);
151 skip_if (errframes == NULL);
154 error_if(nerr != n && nerr != 1, CPL_ERROR_INCOMPATIBLE_INPUT,
155 "%d raw-frames <=> %d error frames", n, nerr);
159 if (cpl_frameset_find_const(framelist, VISIR_IMG_CLIPPED_MAP_PROCATG)) {
161 VISIR_IMG_CLIPPED_MAP_PROCATG);
162 skip_if (conframes == NULL);
165 error_if(ncon % n != 0 && ncon != 1, CPL_ERROR_INCOMPATIBLE_INPUT,
166 "%d raw-frames <=> %d contribution frames", n, ncon);
169 if (cpl_frameset_find_const(framelist, VISIR_UTIL_WEIGHT_MAP_PROCATG)) {
171 VISIR_UTIL_WEIGHT_MAP_PROCATG);
172 skip_if (wgtframes == NULL);
175 error_if(nwgt != n && nwgt != 1, CPL_ERROR_INCOMPATIBLE_INPUT,
176 "%d raw-frames <=> %d weight frames", n, nwgt);
179 if (cpl_frameset_find_const(framelist, VISIR_UTIL_QC_PROCATG)) {
181 skip_if (qcframes == NULL);
184 error_if(nqc != n && nqc != 1, CPL_ERROR_INCOMPATIBLE_INPUT,
185 "%d raw-frames <=> %d qc frames", n, nqc);
188 for (
int i = 0; i < n; i++) {
189 cpl_msg_info(cpl_func,
"Joining frame %d/%d", 1+i, n);
191 skip_if (visir_util_join_one(framelist, rawframes, bpmframes, errframes,
192 conframes, wgtframes, qcframes, i, nbad == 1,
193 nerr == 1, ncon == 1, nwgt == 1, nqc == 1,
207 return cpl_error_get_code();
232 cpl_error_code visir_util_join_one(cpl_frameset * framelist,
233 const irplib_framelist * rawframes,
234 const irplib_framelist * bpmframes,
235 const irplib_framelist * errframes,
236 const irplib_framelist * conframes,
237 const irplib_framelist * wgtframes,
238 const irplib_framelist * qcframes,
240 cpl_boolean bshared, cpl_boolean eshared,
241 cpl_boolean cshared, cpl_boolean wshared,
242 cpl_boolean qcshared,
243 const cpl_parameterlist * parlist)
247 const cpl_frame * frame;
248 cpl_frameset * products = cpl_frameset_new();
249 cpl_frameset * usedframes = cpl_frameset_new();
250 const char * filename;
251 cpl_propertylist * img_plist = NULL;
252 char * proname = NULL;
253 cpl_image * img = NULL;
254 cpl_image * csum = NULL;
255 const char * bunit = NULL;
256 char * inpcatg = NULL;
258 cpl_image * bpm = NULL;
259 cpl_image * err = NULL;
260 cpl_image * wgt = NULL;
261 cpl_image * con = NULL;
263 cpl_propertylist * bpm_plist = NULL;
264 cpl_propertylist * err_plist = NULL;
265 cpl_propertylist * wgt_plist = NULL;
266 cpl_propertylist * con_plist = NULL;
267 cpl_propertylist * qc_plist = NULL;
269 const char * procatg = VISIR_UTIL_JOIN_PROCATG;
271 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
276 filename = cpl_frame_get_filename(frame);
278 img_plist = cpl_propertylist_load(filename, 0);
279 skip_if(img_plist == NULL);
281 img = cpl_image_load(filename, CPL_TYPE_UNSPECIFIED, 0, 0);
282 skip_if(img == NULL);
286 filename = cpl_frame_get_filename(frame);
287 qc_plist = cpl_propertylist_load_regexp(filename, 0,
288 "ESO QC |BUNIT|ESO DRS CATG", CPL_FALSE);
289 skip_if (qc_plist == NULL);
290 if (cpl_propertylist_has(qc_plist,
"BUNIT")) {
291 bunit = cpl_propertylist_get_string(qc_plist,
"BUNIT");
293 if (cpl_propertylist_has(qc_plist,
"ESO DRS CATG")) {
295 cpl_strdup(cpl_propertylist_get_string(qc_plist,
"ESO DRS CATG"));
296 cpl_propertylist_erase(qc_plist,
"ESO DRS CATG");
300 if (bunit == NULL && cpl_propertylist_has(img_plist,
"BUNIT")) {
301 bunit = cpl_propertylist_get_string(img_plist,
"BUNIT");
303 if (inpcatg == NULL && cpl_propertylist_has(img_plist,
"ESO DRS CATG")) {
305 cpl_strdup(cpl_propertylist_get_string(img_plist,
"ESO DRS CATG"));
306 cpl_propertylist_erase(img_plist,
"ESO DRS CATG");
308 cpl_propertylist_append(img_plist, qc_plist);
310 if (!strcmp(cpl_frame_get_tag(frame), VISIR_IMG_PHOT_ONEBEAM_PROCATG))
311 procatg = VISIR_IMG_PHOT_ONEBEAM_PROCATG;
312 else if (!strcmp(cpl_frame_get_tag(frame), VISIR_IMG_PHOT_COMBINED_PROCATG))
313 procatg = VISIR_IMG_PHOT_COMBINED_PROCATG;
314 else if (!strcmp(cpl_frame_get_tag(frame),
"COADDED_IMAGE_COMBINED"))
315 procatg = VISIR_IMG_OBJ_COMBINED_PROCATG;
316 else if (!strcmp(cpl_frame_get_tag(frame),
"COADDED_IMAGE"))
317 procatg = VISIR_IMG_OBJ_ONEBEAM_PROCATG;
319 procatg = visir_dfs_output_catg(inpcatg, procatg);
321 if (cpl_propertylist_has(img_plist,
"ESO QC BEAMID")) {
322 const char * b = cpl_propertylist_get_string(img_plist,
324 proname = cpl_sprintf(RECIPE_STRING
"_b%s_%03d"
325 CPL_DFS_FITS, b, 1+i);
328 proname = cpl_sprintf(RECIPE_STRING
"_%03d"
331 if (bpmframes != NULL) {
335 filename = cpl_frame_get_filename(frame);
337 bpm = cpl_image_load(filename, CPL_TYPE_INT, 0, 0);
338 skip_if(bpm == NULL);
340 bpm_plist = cpl_propertylist_load_regexp(filename, 0,
" ESO QC | ESO PRO ",
342 skip_if(bpm_plist == NULL);
343 cpl_propertylist_append_string(bpm_plist,
"EXTNAME", VISIR_EXTN_BPM);
346 if (errframes != NULL) {
351 filename = cpl_frame_get_filename(frame);
353 err = cpl_image_load(filename, CPL_TYPE_UNSPECIFIED, 0, 0);
354 skip_if(err == NULL);
356 err_plist = cpl_propertylist_load_regexp(filename, 0,
" ESO QC | ESO PRO ",
358 skip_if(err_plist == NULL);
359 cpl_propertylist_append_string(err_plist,
"EXTNAME", VISIR_EXTN_ERROR);
361 cpl_propertylist_append_string(err_plist,
"BUNIT", bunit);
364 if (wgtframes == NULL) {
365 wgt = cpl_image_new(cpl_image_get_size_x(err),
366 cpl_image_get_size_y(err),
368 cpl_image_add_scalar(wgt, 1.0);
369 cpl_image_divide(wgt, err);
370 cpl_image_power(wgt, 2);
371 wgt_plist = cpl_propertylist_new();
372 cpl_propertylist_append_string(wgt_plist,
"EXTNAME", VISIR_EXTN_WEIGHT);
378 if (conframes != NULL) {
385 filename = cpl_frame_get_filename(frame);
387 con = cpl_image_load(filename, CPL_TYPE_INT, 0, 0);
388 skip_if(con == NULL);
390 con_plist = cpl_propertylist_load_regexp(filename, 0,
" ESO QC | ESO PRO ",
392 skip_if(con_plist == NULL);
397 const int nz = ncon / n;
400 for (j = i * nz; j < i * nz + nz; j ++) {
402 bug_if(cpl_frameset_insert(usedframes,
403 cpl_frame_duplicate(frame)));
405 filename = cpl_frame_get_filename(frame);
409 con = cpl_image_load(filename, CPL_TYPE_INT, 0, 0);
410 skip_if(con == NULL);
413 csum = cpl_image_load(filename, CPL_TYPE_INT, 0, 0);
414 skip_if(csum == NULL);
415 skip_if(cpl_image_add(con, csum));
422 bpm = cpl_image_duplicate(con);
425 bug_if(cpl_image_threshold(bpm, -0.5, 1.0, 0.5, 1.0));
426 bug_if(cpl_image_multiply_scalar(bpm, -1.0));
427 bug_if(cpl_image_add_scalar(bpm, 1.0));
429 bpm_plist = cpl_propertylist_new();
430 cpl_propertylist_append_string(bpm_plist,
"EXTNAME", VISIR_EXTN_BPM);
435 if (wgtframes != NULL) {
440 filename = cpl_frame_get_filename(frame);
442 wgt_plist = cpl_propertylist_load_regexp(filename, 0,
" ESO QC | ESO PRO ",
444 skip_if(wgt_plist == NULL);
446 bug_if(cpl_propertylist_append_string(wgt_plist,
"EXTNAME", VISIR_EXTN_WEIGHT));
448 wgt = cpl_image_load(filename, CPL_TYPE_FLOAT, 0, 0);
449 skip_if(wgt == NULL);
452 err = cpl_image_new(cpl_image_get_size_x(wgt),
453 cpl_image_get_size_y(wgt), CPL_TYPE_FLOAT);
454 cpl_image_add_scalar(err, 1.0);
455 cpl_image_divide(err, wgt);
456 cpl_image_power(err, 0.5);
457 cpl_image_fill_rejected(err, INFINITY);
458 err_plist = cpl_propertylist_new();
459 cpl_propertylist_append_string(err_plist,
"EXTNAME", VISIR_EXTN_ERROR);
461 cpl_propertylist_append_string(err_plist,
"BUNIT", bunit);
468 if (err != NULL && con == NULL && bpm == NULL) {
471 cpl_mask * mbpm = cpl_mask_threshold_image_create(err, -DBL_EPSILON, 1e8);
473 bpm = cpl_image_new_from_mask(mbpm);
474 cpl_mask_delete(mbpm);
476 bpm_plist = cpl_propertylist_new();
477 cpl_propertylist_append_string(bpm_plist,
"EXTNAME", VISIR_EXTN_BPM);
482 if (!cpl_propertylist_has(img_plist,
"ESO QC GAUSSFIT FWHM_MAX")) {
483 cpl_errorstate cleanstate = cpl_errorstate_get();
484 double fwhm_x = -1., fwhm_y = -1.,
485 peak = -1., peak_err = 0.,
486 major = -1., major_err = 0.,
487 minor = -1., minor_err = 0.,
488 angle = -1., angle_err = 0.;
489 cpl_size x_pos = cpl_propertylist_get_double(img_plist,
"CRPIX1");
490 cpl_size y_pos = cpl_propertylist_get_double(img_plist,
"CRPIX2");
491 cpl_image * lwgt = wgt;
494 cpl_image_get_fwhm(img, (
int)x_pos, (
int)y_pos, &fwhm_x, &fwhm_y);
497 lwgt = cpl_image_new(cpl_image_get_size_x(img), cpl_image_get_size_y(img), CPL_TYPE_DOUBLE);
498 cpl_image_add_scalar(lwgt, 1);
500 if (fit_2d_gauss(img, lwgt, (cpl_size)x_pos, (cpl_size)y_pos,
501 fwhm_x, fwhm_y, &peak, &peak_err,
502 &major, &major_err, &minor, &minor_err,
503 &angle, &angle_err) == CPL_ERROR_NONE) {
504 cpl_msg_info(cpl_func,
"Peak: %g +- %g, FWHM : %g +- %g major ; %g +- %g minor, "
505 "angle %g +- %g", peak, peak_err,
506 major, major_err, minor, minor_err,
507 angle * CPL_MATH_DEG_RAD,
508 angle_err * CPL_MATH_DEG_RAD);
509 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT FWHM_MAX",
511 cpl_propertylist_set_comment(img_plist,
"ESO QC GAUSSFIT FWHM_MAX",
513 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT FWHM_MAX_ERR",
515 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT FWHM_MIN",
517 cpl_propertylist_set_comment(img_plist,
"ESO QC GAUSSFIT FWHM_MIN",
519 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT FWHM_MIN_ERR",
521 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT ANGLE",
522 angle * CPL_MATH_DEG_RAD);
523 cpl_propertylist_set_comment(img_plist,
"ESO QC GAUSSFIT ANGLE",
525 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT ANGLE_ERR",
526 angle_err * CPL_MATH_DEG_RAD);
527 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT PEAK",
529 cpl_propertylist_append_double(img_plist,
"ESO QC GAUSSFIT PEAK_ERR",
533 cpl_msg_warning(cpl_func,
"2D gauss fit failed, approximate FWHM : %g"
534 "in x ; %g in y ", fwhm_x, fwhm_y);
538 cpl_image_delete(lwgt);
541 cpl_errorstate_set(cleanstate);
545 img, CPL_TYPE_UNSPECIFIED,
548 NULL, visir_pipe_id, proname));
553 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(frame)));
555 skip_if(cpl_image_save(bpm, proname, CPL_BPP_8_UNSIGNED,
556 bpm_plist, CPL_IO_EXTEND));
561 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(frame)));
563 skip_if(cpl_image_save(err, proname, CPL_TYPE_UNSPECIFIED,
564 err_plist, CPL_IO_EXTEND));
569 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(frame)));
571 skip_if(cpl_image_save(con, proname, CPL_TYPE_UNSPECIFIED,
572 con_plist, CPL_IO_EXTEND));
577 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(frame)));
579 skip_if(cpl_image_save(wgt, proname, CPL_TYPE_UNSPECIFIED,
580 wgt_plist, CPL_IO_EXTEND));
583 FOR_EACH_FRAMESET_C(frm, products) {
584 cpl_frame * copy = cpl_frame_duplicate(frm);
585 cpl_error_code error = cpl_frameset_insert(framelist, copy);
592 cpl_image_delete(img);
593 cpl_image_delete(err);
594 cpl_image_delete(wgt);
595 cpl_image_delete(con);
596 cpl_image_delete(bpm);
597 cpl_image_delete(csum);
600 cpl_propertylist_delete(img_plist);
601 cpl_propertylist_delete(err_plist);
602 cpl_propertylist_delete(wgt_plist);
603 cpl_propertylist_delete(con_plist);
604 cpl_propertylist_delete(bpm_plist);
605 cpl_propertylist_delete(qc_plist);
606 cpl_frameset_delete(usedframes);
607 cpl_frameset_delete(products);
609 return cpl_error_get_code();
irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist *self, const char *regexp, cpl_boolean invert)
Extract the frames with the given tag 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.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
void irplib_framelist_delete(irplib_framelist *self)
Deallocate an irplib_framelist with its frames and properties.
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.