36 #include "visir_recipe.h"
46 #define RECIPE_STRING "visir_util_apply_calib"
53 cpl_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");
72 static inline cpl_boolean
73 plist_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;
92 visir_util_apply_calib_fill_parameterlist(cpl_parameterlist *
self)
95 return CPL_ERROR_NONE;
100 get_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_propertylist * cmb_plist;
110 cpl_ensure_code(conv, CPL_ERROR_NULL_INPUT);
116 VISIR_IMG_PHOT_COMBINED_PROCATG);
119 CPL_TYPE_DOUBLE, CPL_FALSE, 0.));
123 VISIR_IMG_PHOT_ONEBEAM_PROCATG);
124 if (one_frames == NULL)
125 cpl_errorstate_set(cleanstate);
128 CPL_TYPE_DOUBLE, CPL_FALSE, 0.));
133 const cpl_propertylist * plist =
135 double conver = cpl_propertylist_get_double(plist,
"ESO QC CONVER");
138 cpl_vector_set(v, i, conver);
142 *conv = cpl_propertylist_get_double(cmb_plist,
"ESO QC CONVER");
145 cpl_msg_info(cpl_func,
"Conversion factor: %g +- %g", *conv, derror);
147 cpl_msg_info(cpl_func,
"Conversion factor: %g", *conv);
154 cpl_vector_delete(v);
158 return cpl_error_get_code();
161 static cpl_error_code
162 update_error(cpl_image * eimg_,
const cpl_image * img_,
163 const double conv,
const double cerror)
165 cpl_image * img = cpl_image_cast(img_, CPL_TYPE_DOUBLE);
166 cpl_image * eimg = cpl_image_cast(eimg_, CPL_TYPE_DOUBLE);
167 size_t nx = cpl_image_get_size_x(img);
168 size_t npix = nx * cpl_image_get_size_y(img);
169 double * eimgd = cpl_image_get_data_double(eimg);
170 const double * imgd = cpl_image_get_data_double_const(img);
172 cpl_ensure_code(conv != 0. && cerror >= 0., CPL_ERROR_ILLEGAL_INPUT);
173 skip_if(imgd == NULL || eimgd == NULL);
175 for (
size_t i = 0; i < npix; i++) {
177 double da = eimgd[i] / conv;
178 double db = cerror * imgd[i] / (conv * conv);
179 cpl_image_set(eimg_, i % nx + 1, i / nx + 1, hypot(da, db));
183 cpl_image_delete(img);
184 cpl_image_delete(eimg);
186 return cpl_error_get_code();
192 cpl_propertylist * plist;
196 visir_plane_new(cpl_image * img, cpl_table * tbl, cpl_propertylist * plist)
208 cpl_image_delete(pl->img);
209 cpl_table_delete(pl->tbl);
210 cpl_propertylist_delete(pl->plist);
217 planelist_from_frame(
const cpl_frame * frame)
219 cpl_size next = cpl_frame_get_nextensions(frame);
220 const char * fn = cpl_frame_get_filename(frame);
221 cpl_errorstate cleanstate = cpl_errorstate_get();
222 cx_list * planelist = NULL;
223 cpl_propertylist * plist = NULL;
224 cpl_image * img = NULL;
225 cpl_table * tbl = NULL;
227 plist = cpl_propertylist_load(fn, 0);
228 skip_if(plist == NULL);
229 planelist = cx_list_new();
231 img = cpl_image_load(fn, CPL_TYPE_UNSPECIFIED, 0, 0);
233 cpl_errorstate_set(cleanstate);
235 cx_list_push_back(planelist, visir_plane_new(img, NULL, plist));
240 for (cpl_size e = 1; e < next + 1; e++) {
241 img = cpl_image_load(fn, CPL_TYPE_UNSPECIFIED, 0, e);
243 cpl_errorstate_set(cleanstate);
244 tbl = cpl_table_load(fn, e, 0);
247 plist = cpl_propertylist_load(fn, e);
248 skip_if(plist == NULL);
249 cx_list_push_back(planelist, visir_plane_new(img, tbl, plist));
256 cpl_image_delete(img);
257 cpl_propertylist_delete(plist);
259 if (cpl_error_get_code() != CPL_ERROR_NONE) {
260 cx_list_destroy(planelist, (visir_free)visir_plane_delete);
268 static cpl_error_code
269 apply_img_calib(cpl_frameset *framelist,
const cpl_parameterlist * parlist,
270 irplib_framelist * objects,
271 const double conv,
const double error)
273 cpl_frameset * usedframes = cpl_frameset_new();
274 cx_list * planes = NULL;
278 cpl_image * eimg = NULL;
282 planes = planelist_from_frame(frm);
283 skip_if(planes == NULL);
285 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
286 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
291 cpl_image_multiply_scalar_create(first->img, 1. / conv);
292 skip_if(simg == NULL);
293 cpl_propertylist_update_string(first->plist,
"BUNIT",
"Jy");
295 sprintf(buffer,
"visir_calibrated_%03d.fits", i + 1);
297 CPL_TYPE_FLOAT, RECIPE_STRING,
298 cpl_frame_get_tag(frm), first->plist,
299 NULL, visir_pipe_id, buffer);
300 cpl_image_delete(simg);
305 if (plist_strcmp(pl->plist,
"EXTNAME", VISIR_EXTN_ERROR)) {
308 update_error(eimg, first->img, conv, error);
309 cpl_propertylist_update_string(pl->plist,
"BUNIT",
"Jy");
311 cpl_image_save(eimg, buffer, CPL_TYPE_FLOAT,
312 pl->plist, CPL_IO_EXTEND);
319 if (plist_strcmp(pl->plist,
"EXTNAME", VISIR_EXTN_WEIGHT)) {
320 cpl_image * wgt = cpl_image_power_create(eimg, -2);
321 cpl_image_fill_rejected(wgt, 0);
323 cpl_image_save(wgt, buffer, CPL_TYPE_FLOAT,
324 pl->plist, CPL_IO_EXTEND);
325 cpl_image_delete(wgt);
332 if (pl == first || pl == skip[0] || pl == skip[1])
336 cpl_image_save(pl->img, buffer, CPL_TYPE_UNSPECIFIED,
337 pl->plist, CPL_IO_EXTEND);
339 cpl_table_save(pl->tbl, NULL, pl->plist, buffer,
342 cpl_propertylist_save(pl->plist, buffer, CPL_IO_EXTEND);
345 cx_list_destroy(planes, (visir_free)visir_plane_delete);
350 cx_list_destroy(planes, (visir_free)visir_plane_delete);
352 cpl_frameset_delete(usedframes);
354 return cpl_error_get_code();
357 static cpl_error_code
358 propagate_all(cpl_frameset * framelist,
const cpl_parameterlist * parlist,
359 irplib_framelist * allframes)
361 cpl_frameset * usedframes = cpl_frameset_new();
362 cx_list * planes = NULL;
367 sprintf(buffer,
"visir_result_%03d.fits", i + 1);
369 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
370 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
372 planes = planelist_from_frame(frm);
373 skip_if(planes == NULL);
378 CPL_TYPE_UNSPECIFIED, RECIPE_STRING,
379 cpl_frame_get_tag(frm), first->plist,
380 NULL, visir_pipe_id, buffer);
384 cpl_frame_get_tag(frm),
386 visir_pipe_id, buffer);
393 cpl_image_save(pl->img, buffer, CPL_TYPE_UNSPECIFIED,
394 pl->plist, CPL_IO_EXTEND);
396 cpl_table_save(pl->tbl, NULL, pl->plist, buffer,
399 cpl_propertylist_save(pl->plist, buffer, CPL_IO_EXTEND);
403 cx_list_destroy(planes, (visir_free)visir_plane_delete);
408 cpl_frameset_delete(usedframes);
409 cx_list_destroy(planes, (visir_free)visir_plane_delete);
411 return cpl_error_get_code();
416 calibrate_frame(
const cpl_frame * frm,
const cpl_bivector * std,
417 const cpl_bivector * stde)
419 const char * dfn = cpl_frame_get_filename(frm);
420 const cpl_vector * swlen = cpl_bivector_get_x_const(std);
421 cpl_bivector * intstd = NULL;
422 cpl_bivector * intstde = NULL;
423 cpl_table * obj = cpl_table_load(dfn, 1, 0);
424 skip_if(obj == NULL);
425 const size_t n = cpl_table_get_nrow(obj);
429 cpl_vector_wrap(n, cpl_table_get_data_double(obj,
"WLEN"));
431 const double smin = cpl_vector_get(swlen, 0);
432 const double smax = cpl_vector_get(swlen, cpl_vector_get_size(swlen) - 1);
433 const size_t l = visir_lower_bound(objv, smin);
434 const size_t u = visir_upper_bound(objv, smax);
437 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
438 "Calibration data has no wavelength overlap "
440 cpl_vector_unwrap(objv);
443 cpl_msg_info(cpl_func,
"Overlapping wavelength: %.4g [mu] (%zu) to "
444 "%.4g [mu] (%zu)", cpl_vector_get(objv, l) * 1e6, l,
445 cpl_vector_get(objv, u - 1) * 1e6, u);
446 cpl_vector_unwrap(objv);
450 intstd = cpl_bivector_new(u - l);
451 intstde = cpl_bivector_new(u - l);
452 skip_if(intstd == NULL);
453 skip_if(intstde == NULL);
455 memcpy(cpl_bivector_get_x_data(intstd),
456 cpl_table_get_data_double_const(obj,
"WLEN") + l,
457 sizeof(
double) * (u - l));
458 memcpy(cpl_bivector_get_x_data(intstde),
459 cpl_table_get_data_double_const(obj,
"WLEN") + l,
460 sizeof(
double) * (u - l));
463 skip_if(cpl_bivector_interpolate_linear(intstd, std));
464 skip_if(cpl_bivector_interpolate_linear(intstde, stde));
470 cpl_table_duplicate_column(obj,
"SPC_CALIBRATED",
471 obj,
"SPC_EXTRACTED");
474 double * d = cpl_table_get_data_double(obj,
"SPC_CALIBRATED");
475 double * v = cpl_vector_get_data(cpl_bivector_get_y(intstd));
476 for (
size_t i = 0; i < n; i++) {
478 cpl_table_set_invalid(obj,
"SPC_CALIBRATED", i);
484 cpl_table_new_column(obj,
"SPC_CALIBRATED_ERROR", CPL_TYPE_DOUBLE);
488 double * ed = cpl_table_get_data_double(obj,
"SPC_ERROR");
489 double * vd = cpl_table_get_data_double(obj,
"SPC_EXTRACTED");
490 double * svd = cpl_bivector_get_y_data(intstd);
491 double * sed = cpl_bivector_get_y_data(intstde);
492 for (
size_t j = 0; j < n; j++) {
494 cpl_table_set_invalid(obj,
"SPC_CALIBRATED_ERROR", j);
496 double da = ed[j] / svd[j - l];
497 double db = sed[j - l] * vd[j] / (svd[j - l] * svd[j - l]);
498 cpl_table_set_double(obj,
"SPC_CALIBRATED_ERROR",
508 cpl_bivector_delete(intstd);
509 cpl_bivector_delete(intstde);
514 static cpl_error_code
515 get_spec_std(cpl_frameset * framelist,
516 const irplib_framelist * stdtab,
517 const irplib_framelist * objtab,
518 const cpl_parameterlist * parlist,
519 const char * procatg)
521 const cpl_frame * frm;
522 cpl_bivector * std = NULL;
523 cpl_bivector * stde = NULL;
524 skip_if(stdtab == NULL);
525 skip_if(objtab == NULL);
527 CPL_ERROR_UNSUPPORTED_MODE);
529 CPL_ERROR_UNSUPPORTED_MODE);
532 skip_if(frm == NULL);
534 const char * fn = cpl_frame_get_filename(frm);
535 cpl_bivector * model = visir_bivector_load_fits(fn,
"WLEN",
536 "STD_STAR_MODEL", 1);
537 std = visir_bivector_load_fits(fn,
"WLEN",
"SPC_EXTRACTED", 1);
538 stde = visir_bivector_load_fits(fn,
"WLEN",
"SPC_ERROR", 1);
541 cpl_vector_divide(cpl_bivector_get_y(std), cpl_bivector_get_y(model));
542 cpl_vector_divide(cpl_bivector_get_y(stde), cpl_bivector_get_y(model));
543 cpl_bivector_delete(model);
551 cpl_frame * sfrm = cpl_frame_duplicate(frm);
552 cpl_frameset * usedframes = cpl_frameset_new();
553 cpl_frame_set_group(sfrm, CPL_FRAME_GROUP_CALIB);
554 cpl_frame_set_group(ofrm, CPL_FRAME_GROUP_RAW);
555 cpl_frameset_insert(usedframes, sfrm);
556 cpl_frameset_insert(usedframes, ofrm);
558 cpl_table * obj = calibrate_frame(ofrm, std, stde);
559 sprintf(buffer,
"visir_calibrated_%03d.fits", i + 1);
561 NULL, RECIPE_STRING, procatg, NULL,
562 NULL, visir_pipe_id, buffer);
565 if (cpl_frame_get_nextensions(ofrm) == 3) {
566 cpl_propertylist * plist =
567 cpl_propertylist_load(cpl_frame_get_filename(ofrm), 2);
568 cpl_image * img = cpl_image_load(cpl_frame_get_filename(ofrm),
569 CPL_TYPE_UNSPECIFIED, 0, 2);
570 cpl_image_save(img, buffer, CPL_TYPE_UNSPECIFIED, plist, CPL_IO_EXTEND);
571 cpl_image_delete(img);
572 cpl_propertylist_delete(plist);
573 plist = cpl_propertylist_load(cpl_frame_get_filename(ofrm), 2);
574 img = cpl_image_load(cpl_frame_get_filename(ofrm),
575 CPL_TYPE_UNSPECIFIED, 0, 2);
576 cpl_image_save(img, buffer, CPL_TYPE_UNSPECIFIED, plist, CPL_IO_EXTEND);
577 cpl_image_delete(img);
578 cpl_propertylist_delete(plist);
581 cpl_frameset_delete(usedframes);
582 cpl_table_delete(obj);
588 cpl_bivector_delete(std);
589 cpl_bivector_delete(stde);
591 return cpl_error_get_code();
603 static int visir_util_apply_calib(cpl_frameset * framelist,
604 const cpl_parameterlist * parlist)
607 cpl_errorstate cleanstate = cpl_errorstate_get();
609 irplib_framelist * others = NULL;
610 irplib_framelist * objects =
612 irplib_framelist * specobs =
616 cpl_errorstate_set(cleanstate);
621 double conv = 1., error = 0.;
622 cpl_msg_info(cpl_func,
"Applying conversion factor");
623 skip_if(get_img_conv(&conv, &error, allframes));
624 skip_if(apply_img_calib(framelist, parlist, objects, conv, error));
626 skip_if(propagate_all(framelist, parlist, others));
630 irplib_framelist * stdtab =
632 irplib_framelist * objtab =
634 cpl_msg_info(cpl_func,
"Removing telluric lines");
635 skip_if(get_spec_std(framelist, stdtab, objtab,
636 parlist,
"SPC_OBS_LMR_TAB"));
638 propagate_all(framelist, parlist, others);
644 cpl_msg_info(cpl_func,
"No calibration data to apply, doing nothing");
645 skip_if(propagate_all(framelist, parlist, allframes));
654 return cpl_error_get_code();
cpl_error_code irplib_dfs_save_table(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_table *table, const cpl_propertylist *tablelist, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a table as a DFS-compliant pipeline product.
cpl_error_code irplib_dfs_save_propertylist(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a propertylist as a DFS-compliant pipeline product.
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.
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the 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.
cpl_frame * irplib_framelist_get(irplib_framelist *self, int pos)
Get the specified frame from 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.
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.
cpl_propertylist * irplib_framelist_get_propertylist(irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
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.