36#include "visir_recipe.h"
46#define RECIPE_STRING "visir_util_apply_calib"
53cpl_recipe_define(visir_util_apply_calib, VISIR_BINARY_VERSION,
54 "Julian Taylor", PACKAGE_BUGREPORT,
"2012",
55 "Attempt to remove stripes in spectral data",
56 "The files listed in the Set Of Frames (sof-file) "
58 "VISIR-chopnod-corrected-file.fits "
59 "\nThe product(s) will have a FITS card\n"
60 "'HIERARCH ESO PRO CATG' with a value of:\n");
72static inline cpl_boolean
73plist_strcmp(
const cpl_propertylist * plist,
74 const char * key,
const char * val)
76 if (!cpl_propertylist_has(plist, key))
78 return strcmp(cpl_propertylist_get_string(plist, key), val) == 0;
92visir_util_apply_calib_fill_parameterlist(cpl_parameterlist * self)
95 return CPL_ERROR_NONE;
100get_img_conv(
double * conv,
double * error,
101 irplib_framelist * phot_frames)
103 cpl_vector * v = NULL;
105 cpl_errorstate cleanstate = cpl_errorstate_get();
106 irplib_framelist * one_frames = NULL;
107 irplib_framelist * cmb_frames = NULL;
108 cpl_frameset * usedframes = cpl_frameset_new();
109 cpl_propertylist * cmb_plist;
111 cpl_ensure(conv, CPL_ERROR_NULL_INPUT, NULL);
113 skip_if(irplib_framelist_load_propertylist_all(phot_frames, 0,
116 cmb_frames = irplib_framelist_extract(phot_frames,
117 VISIR_IMG_PHOT_COMBINED_PROCATG);
119 skip_if(irplib_framelist_contains(cmb_frames,
"ESO QC CONVER",
120 CPL_TYPE_DOUBLE, CPL_FALSE, 0.));
121 cmb_plist = irplib_framelist_get_propertylist(cmb_frames, 0);
122 cpl_frameset_insert(usedframes,
123 cpl_frame_duplicate(irplib_framelist_get(cmb_frames, 0)));
125 one_frames = irplib_framelist_extract(phot_frames,
126 VISIR_IMG_PHOT_ONEBEAM_PROCATG);
127 if (one_frames == NULL)
128 cpl_errorstate_set(cleanstate);
131 skip_if(irplib_framelist_contains(one_frames,
"ESO QC CONVER",
132 CPL_TYPE_DOUBLE, CPL_FALSE, 0.));
134 v = cpl_vector_new(irplib_framelist_get_size(one_frames));
136 for (
int i = 0; i < irplib_framelist_get_size(one_frames); i++) {
137 const cpl_propertylist * plist =
138 irplib_framelist_get_propertylist_const(one_frames, i);
139 double conver = cpl_propertylist_get_double(plist,
"ESO QC CONVER");
142 cpl_vector_set(v, i, conver);
146 *conv = cpl_propertylist_get_double(cmb_plist,
"ESO QC CONVER");
149 cpl_msg_info(cpl_func,
"Conversion factor: %g +- %g", *conv, derror);
151 cpl_msg_info(cpl_func,
"Conversion factor: %g", *conv);
158 cpl_vector_delete(v);
159 irplib_framelist_delete(cmb_frames);
160 irplib_framelist_delete(one_frames);
161 if (cpl_error_get_code()) {
162 cpl_frameset_delete(usedframes);
169update_error(cpl_image * eimg_,
const cpl_image * img_,
170 const double conv,
const double cerror)
172 cpl_image * img = cpl_image_cast(img_, CPL_TYPE_DOUBLE);
173 cpl_image * eimg = cpl_image_cast(eimg_, CPL_TYPE_DOUBLE);
174 size_t nx = cpl_image_get_size_x(img);
175 size_t npix = nx * cpl_image_get_size_y(img);
176 double * eimgd = cpl_image_get_data_double(eimg);
177 const double * imgd = cpl_image_get_data_double_const(img);
179 cpl_ensure_code(conv != 0. && cerror >= 0., CPL_ERROR_ILLEGAL_INPUT);
180 skip_if(imgd == NULL || eimgd == NULL);
182 for (
size_t i = 0; i < npix; i++) {
184 double da = eimgd[i] / conv;
185 double db = cerror * imgd[i] / (conv * conv);
186 cpl_image_set(eimg_, i % nx + 1, i / nx + 1, hypot(da, db));
190 cpl_image_delete(img);
191 cpl_image_delete(eimg);
193 return cpl_error_get_code();
199 cpl_propertylist * plist;
203visir_plane_new(cpl_image * img, cpl_table * tbl, cpl_propertylist * plist)
205 visir_plane * pl = cpl_calloc(1,
sizeof(visir_plane));
212static void visir_plane_delete(visir_plane * pl)
215 cpl_image_delete(pl->img);
216 cpl_table_delete(pl->tbl);
217 cpl_propertylist_delete(pl->plist);
224planelist_from_frame(
const cpl_frame * frame)
226 cpl_size next = cpl_frame_get_nextensions(frame);
227 const char * fn = cpl_frame_get_filename(frame);
228 cpl_errorstate cleanstate = cpl_errorstate_get();
229 cx_list * planelist = NULL;
230 cpl_propertylist * plist = NULL;
231 cpl_image * img = NULL;
232 cpl_table * tbl = NULL;
234 plist = cpl_propertylist_load(fn, 0);
235 skip_if(plist == NULL);
237 visir_dfs_update_header(plist);
238 planelist = cx_list_new();
240 img = cpl_image_load(fn, CPL_TYPE_UNSPECIFIED, 0, 0);
242 cpl_errorstate_set(cleanstate);
244 cx_list_push_back(planelist, visir_plane_new(img, NULL, plist));
249 for (cpl_size e = 1; e < next + 1; e++) {
250 img = cpl_image_load(fn, CPL_TYPE_UNSPECIFIED, 0, e);
252 cpl_errorstate_set(cleanstate);
253 tbl = cpl_table_load(fn, e, 0);
256 plist = cpl_propertylist_load(fn, e);
257 skip_if(plist == NULL);
259 visir_dfs_update_header(plist);
260 cx_list_push_back(planelist, visir_plane_new(img, tbl, plist));
267 cpl_image_delete(img);
268 cpl_propertylist_delete(plist);
270 if (cpl_error_get_code() != CPL_ERROR_NONE) {
271 cx_list_destroy(planelist, (visir_free)visir_plane_delete);
280apply_img_calib(cpl_frameset *framelist,
const cpl_parameterlist * parlist,
281 irplib_framelist * objects,
282 const double conv,
const double error,
283 cpl_frameset * calibframes)
285 cpl_frameset * usedframes = cpl_frameset_new();
286 cx_list * planes = NULL;
288 for (
int i = 0; i < irplib_framelist_get_size(objects); i++) {
289 cpl_frame * frm = irplib_framelist_get(objects, i);
290 cpl_image * eimg = NULL;
292 visir_plane * skip[] = {NULL, NULL};
294 planes = planelist_from_frame(frm);
295 skip_if(planes == NULL);
297 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
299 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
300 FOR_EACH_FRAMESET(cfrm, calibframes) {
301 cpl_frame_set_group(cfrm, CPL_FRAME_GROUP_RAW);
302 cpl_frameset_insert(usedframes, cpl_frame_duplicate(cfrm));
306 visir_plane * first = cx_list_front(planes);
308 cpl_image_multiply_scalar_create(first->img, 1. / conv);
309 skip_if(simg == NULL);
310 cpl_propertylist_update_string(first->plist,
"BUNIT",
"Jy");
312 sprintf(buffer,
"visir_calibrated_%03d.fits", i + 1);
313 irplib_dfs_save_image(framelist, parlist, usedframes, simg,
314 CPL_TYPE_FLOAT, RECIPE_STRING,
315 VISIR_IMG_OBJ_CALIBRATED_PROCATG, first->plist,
316 NULL, visir_pipe_id, buffer);
317 cpl_image_delete(simg);
321 FOR_EACH_T(visir_plane * pl, planes) {
322 if (plist_strcmp(pl->plist,
"EXTNAME", VISIR_EXTN_ERROR)) {
325 update_error(eimg, first->img, conv, error);
326 cpl_propertylist_update_string(pl->plist,
"BUNIT",
"Jy");
328 cpl_image_save(eimg, buffer, CPL_TYPE_FLOAT,
329 pl->plist, CPL_IO_EXTEND);
335 FOR_EACH_T(visir_plane * pl, planes) {
336 if (plist_strcmp(pl->plist,
"EXTNAME", VISIR_EXTN_WEIGHT)) {
337 cpl_image * wgt = cpl_image_power_create(eimg, -2);
338 cpl_image_fill_rejected(wgt, 0);
340 cpl_image_save(wgt, buffer, CPL_TYPE_FLOAT,
341 pl->plist, CPL_IO_EXTEND);
342 cpl_image_delete(wgt);
348 FOR_EACH_T(visir_plane * pl, planes) {
349 if (pl == first || pl == skip[0] || pl == skip[1])
353 cpl_image_save(pl->img, buffer, CPL_TYPE_UNSPECIFIED,
354 pl->plist, CPL_IO_EXTEND);
356 cpl_table_save(pl->tbl, NULL, pl->plist, buffer,
359 cpl_propertylist_save(pl->plist, buffer, CPL_IO_EXTEND);
362 cx_list_destroy(planes, (visir_free)visir_plane_delete);
367 cx_list_destroy(planes, (visir_free)visir_plane_delete);
369 cpl_frameset_delete(usedframes);
371 return cpl_error_get_code();
375propagate_all(cpl_frameset * framelist,
const cpl_parameterlist * parlist,
376 irplib_framelist * allframes)
378 cpl_frameset * usedframes = cpl_frameset_new();
379 cx_list * planes = NULL;
381 for (
int i = 0; i < irplib_framelist_get_size(allframes); i++) {
382 cpl_frame * frm = irplib_framelist_get(allframes, i);
384 sprintf(buffer,
"visir_result_%03d.fits", i + 1);
386 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
387 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
389 planes = planelist_from_frame(frm);
390 skip_if(planes == NULL);
391 visir_plane * first = cx_list_front(planes);
394 irplib_dfs_save_image(framelist, parlist, usedframes, first->img,
395 CPL_TYPE_UNSPECIFIED, RECIPE_STRING,
396 cpl_frame_get_tag(frm), first->plist,
397 NULL, visir_pipe_id, buffer);
399 irplib_dfs_save_propertylist(framelist, parlist, usedframes,
401 cpl_frame_get_tag(frm),
403 visir_pipe_id, buffer);
406 FOR_EACH_T(visir_plane * pl, planes) {
410 cpl_image_save(pl->img, buffer, CPL_TYPE_UNSPECIFIED,
411 pl->plist, CPL_IO_EXTEND);
413 cpl_table_save(pl->tbl, NULL, pl->plist, buffer,
416 cpl_propertylist_save(pl->plist, buffer, CPL_IO_EXTEND);
420 cx_list_destroy(planes, (visir_free)visir_plane_delete);
425 cpl_frameset_delete(usedframes);
426 cx_list_destroy(planes, (visir_free)visir_plane_delete);
428 return cpl_error_get_code();
433calibrate_frame(
const cpl_frame * frm,
const int ext,
434 const cpl_bivector * std,
const cpl_bivector * stde)
436 const char * dfn = cpl_frame_get_filename(frm);
437 const cpl_vector * swlen = cpl_bivector_get_x_const(std);
438 cpl_bivector * intstd = NULL;
439 cpl_bivector * intstde = NULL;
440 cpl_table * obj = cpl_table_load(dfn, ext, 0);
441 skip_if(obj == NULL);
442 const size_t n = cpl_table_get_nrow(obj);
446 cpl_vector_wrap(n, cpl_table_get_data_double(obj,
"WLEN"));
448 const double smin = cpl_vector_get(swlen, 0);
449 const double smax = cpl_vector_get(swlen, cpl_vector_get_size(swlen) - 1);
450 const size_t l = visir_lower_bound(objv, smin);
451 const size_t u = visir_upper_bound(objv, smax);
454 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
455 "Calibration data has no wavelength overlap "
457 cpl_vector_unwrap(objv);
460 cpl_msg_info(cpl_func,
"Overlapping wavelength: %.4g [mu] (%zu) to "
461 "%.4g [mu] (%zu)", cpl_vector_get(objv, l) * 1e6, l,
462 cpl_vector_get(objv, u - 1) * 1e6, u);
463 cpl_vector_unwrap(objv);
467 intstd = cpl_bivector_new(u - l);
468 intstde = cpl_bivector_new(u - l);
469 skip_if(intstd == NULL);
470 skip_if(intstde == NULL);
472 memcpy(cpl_bivector_get_x_data(intstd),
473 cpl_table_get_data_double_const(obj,
"WLEN") + l,
474 sizeof(
double) * (u - l));
475 memcpy(cpl_bivector_get_x_data(intstde),
476 cpl_table_get_data_double_const(obj,
"WLEN") + l,
477 sizeof(
double) * (u - l));
480 skip_if(cpl_bivector_interpolate_linear(intstd, std));
481 skip_if(cpl_bivector_interpolate_linear(intstde, stde));
486 const char *fn = cpl_frame_get_filename(frm);
489 cpl_table_duplicate_column(obj,
"SPC_CALIBRATED",
490 obj,
"SPC_EXTRACTED");
494 cpl_propertylist *plist = cpl_propertylist_load(fn, ext);
497 cpl_propertylist_update_string(plist,
"TUNIT7",
"mJy");
500 cpl_propertylist_update_string(plist,
"TUNIT8",
"mJy");
504 double * d = cpl_table_get_data_double(obj,
"SPC_CALIBRATED");
505 double * v = cpl_vector_get_data(cpl_bivector_get_y(intstd));
506 for (
size_t i = 0; i < n; i++) {
508 cpl_table_set_invalid(obj,
"SPC_CALIBRATED", i);
514 cpl_table_new_column(obj,
"SPC_CALIBRATED_ERROR", CPL_TYPE_DOUBLE);
518 double * ed = cpl_table_get_data_double(obj,
"SPC_ERROR");
519 double * vd = cpl_table_get_data_double(obj,
"SPC_EXTRACTED");
520 double * svd = cpl_bivector_get_y_data(intstd);
521 double * sed = cpl_bivector_get_y_data(intstde);
522 for (
size_t j = 0; j < n; j++) {
524 cpl_table_set_invalid(obj,
"SPC_CALIBRATED_ERROR", j);
526 double da = ed[j] / svd[j - l];
527 double db = sed[j - l] * vd[j] / (svd[j - l] * svd[j - l]);
528 cpl_table_set_double(obj,
"SPC_CALIBRATED_ERROR",
538 cpl_bivector_delete(intstd);
539 cpl_bivector_delete(intstde);
545get_spec_std(cpl_frameset * framelist,
546 const irplib_framelist * stdtab,
547 const irplib_framelist * objtab,
548 const cpl_parameterlist * parlist,
549 const char * procatg)
551 const cpl_frame * frm;
552 cpl_bivector * std = NULL;
553 cpl_bivector * stde = NULL;
555 const char* std_fn = NULL;
556 skip_if(stdtab == NULL);
557 skip_if(objtab == NULL);
559 cpl_ensure_code(irplib_framelist_get_size(stdtab) == 1,
560 CPL_ERROR_UNSUPPORTED_MODE);
562 cpl_ensure_code(irplib_framelist_get_size(objtab) > 0,
563 CPL_ERROR_UNSUPPORTED_MODE);
566 frm = irplib_framelist_get_const(stdtab, 0);
567 skip_if(frm == NULL);
568 n_std_ext = cpl_frame_get_nextensions(frm);
569 std_fn = cpl_frame_get_filename(frm);
572 for (
int i = 0; i < irplib_framelist_get_size(objtab); i++) {
575 cpl_frame_duplicate(irplib_framelist_get_const(objtab, i));
576 sprintf(buffer,
"visir_calibrated_%03d.fits", i + 1);
580 const int next = cpl_frame_get_nextensions(ofrm);
581 const char * fn = cpl_frame_get_filename(ofrm);
583 cpl_ensure_code(next == n_std_ext, CPL_ERROR_ILLEGAL_INPUT);
586 cpl_frame * sfrm = cpl_frame_duplicate(frm);
587 cpl_frameset * usedframes = cpl_frameset_new();
588 cpl_frame_set_group(sfrm, CPL_FRAME_GROUP_CALIB);
589 cpl_frame_set_group(ofrm, CPL_FRAME_GROUP_RAW);
590 cpl_frameset_insert(usedframes, sfrm);
591 cpl_frameset_insert(usedframes, ofrm);
593 cpl_propertylist * phu = cpl_propertylist_load(fn, 0);
596 for (
int j=1; j<=next; j++) {
598 cpl_propertylist * plist = cpl_propertylist_load(fn, j);
599 const char * xt = cpl_propertylist_get_string(plist,
"XTENSION");
600 cpl_msg_info(cpl_func,
"object %s extension %d is %s", fn, j, xt);
602 visir_dfs_update_header(plist);
603 if (!strcmp(xt,
"BINTABLE")) {
606 cpl_bivector * model = visir_bivector_load_fits(std_fn,
"WLEN",
607 "STD_STAR_MODEL", j);
608 std = visir_bivector_load_fits(std_fn,
"WLEN",
"SPC_EXTRACTED", j);
609 stde = visir_bivector_load_fits(std_fn,
"WLEN",
"SPC_ERROR", j);
611 cpl_vector_divide(cpl_bivector_get_y(std), cpl_bivector_get_y(model));
612 cpl_vector_divide(cpl_bivector_get_y(stde), cpl_bivector_get_y(model));
613 cpl_bivector_delete(model);
616 cpl_table * obj = calibrate_frame(ofrm, j, std, stde);
619 cpl_propertylist *updated_plist = cpl_propertylist_load(fn, j);
621 visir_dfs_update_header(updated_plist);
623 if (cpl_propertylist_has(updated_plist,
"BUNIT")) {
624 const char *bunit = cpl_propertylist_get_string(updated_plist,
"BUNIT");
625 if (strstr(bunit,
"ADU") != NULL) {
626 cpl_propertylist_update_string(updated_plist,
"BUNIT",
"Jy");
634 irplib_dfs_save_table(framelist, parlist, usedframes, obj,
635 updated_plist ? updated_plist : plist,
636 RECIPE_STRING, procatg, phu,
637 NULL, visir_pipe_id, buffer);
640 cpl_table_save(obj, NULL, updated_plist ? updated_plist : plist,
641 buffer, CPL_IO_EXTEND);
645 cpl_propertylist_delete(updated_plist);
648 cpl_bivector_delete(std);
649 cpl_bivector_delete(stde);
651 }
else if (!strcmp(xt,
"IMAGE")) {
654 cpl_image * img = cpl_image_load(fn, CPL_TYPE_UNSPECIFIED, 0, j);
655 cpl_image_save(img, buffer, CPL_TYPE_UNSPECIFIED, plist, CPL_IO_EXTEND);
656 cpl_image_delete(img);
659 cpl_msg_warning(cpl_func,
"Cannot process %s extension %d of unknown type %s", fn, j, xt);
661 cpl_propertylist_delete(plist);
663 cpl_propertylist_delete(phu);
665 cpl_frameset_delete(usedframes);
671 return cpl_error_get_code();
683static int visir_util_apply_calib(cpl_frameset * framelist,
684 const cpl_parameterlist * parlist)
686 irplib_framelist * allframes = irplib_framelist_cast(framelist);
687 cpl_errorstate cleanstate = cpl_errorstate_get();
689 irplib_framelist * others = NULL;
690 irplib_framelist * objects =
691 irplib_framelist_extract_regexp(allframes,
".*OBJ.*", CPL_FALSE);
692 irplib_framelist * specobs =
693 irplib_framelist_extract_regexp(allframes,
".*SPC_OBS.*", CPL_FALSE);
695 if (irplib_framelist_get_size(allframes) > 0)
696 cpl_errorstate_set(cleanstate);
699 if (objects && irplib_framelist_get_size(objects) <
700 irplib_framelist_get_size(allframes)) {
701 double conv = 1., error = 0.;
702 cpl_msg_info(cpl_func,
"Applying conversion factor");
703 cpl_frameset * calibframes = get_img_conv(&conv, &error, allframes);
704 skip_if(calibframes == NULL);
705 skip_if(apply_img_calib(framelist, parlist, objects, conv, error, calibframes));
706 others = irplib_framelist_extract_regexp(allframes,
".*OBJ.*", CPL_TRUE);
707 skip_if(propagate_all(framelist, parlist, others));
709 else if (specobs && irplib_framelist_get_size(specobs) <
710 irplib_framelist_get_size(allframes)) {
711 irplib_framelist * stdtab =
712 irplib_framelist_extract_regexp(allframes,
".*PHOT.*TAB", CPL_FALSE);
713 irplib_framelist * objtab =
714 irplib_framelist_extract_regexp(allframes,
".*OBS.*TAB", CPL_FALSE);
715 cpl_msg_info(cpl_func,
"Removing telluric lines");
716 skip_if(get_spec_std(framelist, stdtab, objtab,
717 parlist,
"SPC_OBS_LMR_TAB"));
718 others = irplib_framelist_extract_regexp(allframes,
".*OBS.*TAB", CPL_TRUE);
719 propagate_all(framelist, parlist, others);
720 irplib_framelist_delete(objtab);
721 irplib_framelist_delete(stdtab);
725 cpl_msg_info(cpl_func,
"No calibration data to apply, doing nothing");
726 skip_if(propagate_all(framelist, parlist, allframes));
730 irplib_framelist_delete(allframes);
731 irplib_framelist_delete(objects);
732 irplib_framelist_delete(specobs);
733 irplib_framelist_delete(others);
735 return cpl_error_get_code();