36#define SBRM_UNDERSCORE_MACRO
39#include "visir_inputs.h"
40#include "visir_recipe.h"
41#include "visir_spectro.h"
42#include "visir_spc_distortion.h"
43#include "visir_spc_photom.h"
54#define RESET SBRM_RESET
56#define CLEANUP SBRM_CLEANUP
59#define ERR_TO_WARN SBRM_WARN
60#define ERR_TO_INFO SBRM_INFO
61#define VLIST SBRM_VLIST
62#define VALLOC SBRM_VALLOC
63#define NALLOC SBRM_NALLOC
65#define RECIPE_STRING "visir_old_spc_obs"
67#define RECIPE_SAVE_STRING "visir_spc_obs"
70#define RECIPE_KEYS_REGEXP_ALL \
71 VISIR_PFITS_REGEXP_IMG_RECOMBINE \
72 "|" VISIR_PFITS_REGEXP_SPC_GET_RES_WL
75#define RECIPE_KEYS_REGEXP \
76 RECIPE_KEYS_REGEXP_ALL \
77 "|" VISIR_PFITS_REGEXP_CAPA \
78 "|" VISIR_PFITS_REGEXP_SPC_WCAL_PAF
81#define RECIPE_KEYS_REGEXP_WCS \
83 "|" IRPLIB_PFITS_WCS_REGEXP
85#define IS_PREPROCESSED 1
89#define PREPROCESSED_INPUT IS_PREPROCESSED
90#define RAW_PHOT_INPUT IS_PHOT
91#define PREPROCESSED_PHOT_INPUT (IS_PHOT | IS_PREPROCESSED)
97#define UNUSED_ORDER 99
99#define MSG_WARN(...) cpl_msg_warning(cpl_func, __VA_ARGS__)
100#define MSG_INFO(...) cpl_msg_info(cpl_func, __VA_ARGS__)
101#define MSG_ERR(...) cpl_msg_error(cpl_func, __VA_ARGS__)
102#define MSG_DBG(...) cpl_msg_debug(cpl_func, __VA_ARGS__)
111 cpl_image * weight2d;
113 cpl_propertylist * qclist;
116static void match_delete(match m);
118typedef VLIST(match) matchlist;
119#define matchlist_new(size) VALLOC(matchlist, match, size)
120static void matchlist_delete(matchlist * ml);
127 cpl_image * comnarrow;
129 visir_aplist * aplist;
131static void order_delete(order o);
133typedef VLIST(order) orderlist;
134#define orderlist_new(size, ...) NALLOC(orderlist, order, size, __VA_ARGS__)
135static void orderlist_delete(orderlist * ol);
140static cpl_error_code visir_spc_obs_save(cpl_frameset *,
141 const cpl_parameterlist *,
144 const cpl_propertylist *,
149 const int,
const int,
const size_t);
151static cpl_error_code visir_spc_obs_extend(cpl_propertylist *,
155 const int,
const int,
const size_t);
157static cpl_error_code visir_spc_obs_extend_combined(
const cpl_image *);
159static cpl_error_code visir_spc_qc_summarise(cpl_propertylist *, orderlist *,
163#define cpl_plugin_get_info visir_old_spc_obs_get_info
165VISIR_RECIPE_DEFINE(visir_old_spc_obs,
166 VISIR_PARAM_EMIS_TOL |
167 VISIR_PARAM_REFINE | VISIR_PARAM_XCORR |
168 VISIR_PARAM_OFFSETS | VISIR_PARAM_OBJECTS |
169 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
170 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE |
171 VISIR_PARAM_UNION | VISIR_PARAM_REJECT |
172 VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
173 VISIR_PARAM_PLOT | VISIR_PARAM_SLITSKEW |
174 VISIR_PARAM_SPECSKEW | VISIR_PARAM_VERTARC |
175 VISIR_PARAM_REJLEFT | VISIR_PARAM_REJRIGHT |
176 VISIR_PARAM_HORIARC | VISIR_PARAM_FIXCOMBI |
177 VISIR_PARAM_BKG_CORRECT | VISIR_PARAM_APERT_FILE |
178 VISIR_PARAM_GAIN | VISIR_PARAM_RONOISE |
179 VISIR_PARAM_OXSIGMA | VISIR_PARAM_OXNITER |
180 VISIR_PARAM_OXSMOOTH | VISIR_PARAM_OXKERNEL |
182 "Old DRS detector: Spectroscopic Observation recipe",
183 "This recipe estimates the dispersion relation using the "
184 "atmospheric spectrum\n"
185 "in a long-slit spectroscopy half-cycle frame.\n"
186 "It also extracts the spectrum of an observed object using "
187 "a combined frame.\n"
188 "The files listed in the Set Of Frames (sof-file) "
190 "VISIR-Long-Slit-Spectroscopy-file.fits "
191 VISIR_SPC_OBS_RAW
"\n"
192 "VISIR-Quantum-Efficiency-Calibration-file.fits "
193 VISIR_CALIB_QEFF_SPC
"\n"
194 "VISIR-Atmospheric-Emission-Lines-Calibration-file.fits "
195 VISIR_CALIB_LINES_SPC
197 MAN_VISIR_CALIB_BPM_SPC);
213static void biimage_delete(cpl_image ** bi)
216 cpl_image_delete(bi[0]);
217 cpl_image_delete(bi[1]);
221static void match_delete(match m)
223 cpl_propertylist_delete(m.qclist);
227 if (m.aps->ident < 0) visir_apdefs_delete(m.aps);
228 cpl_table_delete(m.spc_tbl);
229 cpl_image_delete(m.weight2d);
232static void matchlist_delete(matchlist * ml)
235 for (
size_t i = 0; i < ml->sz; ++i) match_delete(ml->data[i]);
239static void order_delete(order o)
241 cpl_image_delete(o.comnarrow);
242 visir_aplist_delete(o.aplist);
243 matchlist_delete(o.matches);
246static void orderlist_delete(orderlist * ol)
249 for (
size_t i = 0; i < ol->sz; ++i) order_delete(ol->data[i]);
261static const char * pn(
const int oo)
264 const char * sign = oo ? (oo > 0 ?
"+" :
"-") :
"";
265 snprintf(buf,
sizeof(buf),
"%s%d", sign, abs(oo));
277static void * visir_old_spc_obs_(cpl_frameset * framelist,
278 const cpl_parameterlist * parlist)
282 visir_spc_config spc_config;
283 spc_config.recipename = RECIPE_STRING;
284 spc_config.parlist = parlist;
285 spc_config.phot_emis_tol = 1.0;
288 SET(phu, cpl_propertylist) = cpl_propertylist_new();
289 spc_config.phu = phu->o;
293 parlist, RECIPE_STRING, VISIR_PARAM_PLOT);
295 parlist, RECIPE_STRING, VISIR_PARAM_SLITSKEW);
297 parlist, RECIPE_STRING, VISIR_PARAM_SPECSKEW);
299 parlist, RECIPE_STRING, VISIR_PARAM_VERTARC);
301 parlist, RECIPE_STRING, VISIR_PARAM_HORIARC);
303 parlist, RECIPE_STRING, VISIR_PARAM_GAIN);
305 parlist, RECIPE_STRING, VISIR_PARAM_RONOISE);
307 parlist, RECIPE_STRING, VISIR_PARAM_OXSIGMA);
309 parlist, RECIPE_STRING, VISIR_PARAM_OXNITER);
311 parlist, RECIPE_STRING, VISIR_PARAM_OXSMOOTH);
313 parlist, RECIPE_STRING, VISIR_PARAM_OXKERNEL);
315 parlist, RECIPE_STRING, VISIR_PARAM_FIXCOMBI);
317 parlist, RECIPE_STRING, VISIR_PARAM_EMIS_TOL);
319 parlist, RECIPE_STRING, VISIR_PARAM_BKG_CORRECT);
321 parlist, RECIPE_STRING, VISIR_PARAM_RESPCAL);
324 parlist, RECIPE_STRING, VISIR_PARAM_APERT_FILE);
331 SET(aplist, visir_aplist, v, visir_aplist_destroy) = NULL;
332 if (visir_str_par_is_empty(apfile))
333 RESET(aplist) = visir_aplist_new();
352 SET(all, irplib_framelist) = irplib_framelist_cast _(framelist);
353 char const *
const inraw =
"Input: raw %s frame (%s)";
354 char const *
const inprep =
"Input: preprocessed %s frame (%s)";
358 SET(raws, irplib_framelist) = NULL;
359 if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_PP)) {
360 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_OBS_PP);
361 rawtag = VISIR_SPC_OBS_PP;
362 MSG_INFO(inprep,
"observation", VISIR_SPC_OBS_PP);
363 input_mode = PREPROCESSED_INPUT;
365 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_PP)) {
366 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_PHOT_PP);
367 rawtag = VISIR_SPC_PHOT_PP;
368 MSG_INFO(inprep,
"photometric", VISIR_SPC_PHOT_PP);
369 input_mode = PREPROCESSED_PHOT_INPUT;
371 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_ECH_PP)) {
372 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_OBS_ECH_PP);
373 rawtag = VISIR_SPC_OBS_ECH_PP;
374 MSG_INFO(inprep,
"observation echelle", VISIR_SPC_OBS_ECH_PP);
375 input_mode = PREPROCESSED_INPUT | IS_ECH;
377 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_ECH_PP)) {
378 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_PHOT_ECH_PP);
379 rawtag = VISIR_SPC_PHOT_ECH_PP;
380 MSG_INFO(inprep,
"photometric echelle", VISIR_SPC_PHOT_ECH_PP);
381 input_mode = PREPROCESSED_PHOT_INPUT | IS_ECH;
383 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_RAW)) {
384 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_OBS_RAW);
385 rawtag = VISIR_SPC_OBS_RAW;
386 MSG_INFO(inraw,
"observation", VISIR_SPC_OBS_RAW);
387 input_mode = RAW_INPUT;
389 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_RAW)) {
390 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_PHOT_RAW);
391 rawtag = VISIR_SPC_PHOT_RAW;
392 MSG_INFO(inraw,
"photometric", VISIR_SPC_PHOT_RAW);
393 input_mode = RAW_PHOT_INPUT;
395 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_ECH_RAW)) {
396 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_OBS_ECH_RAW);
397 rawtag = VISIR_SPC_OBS_ECH_RAW;
398 MSG_INFO(inraw,
"observation echelle", VISIR_SPC_OBS_ECH_RAW);
399 input_mode = RAW_INPUT | IS_ECH;
401 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_ECH_RAW)) {
402 RESET(raws) = irplib_framelist_extract _(all->o, VISIR_SPC_PHOT_ECH_RAW);
403 rawtag = VISIR_SPC_PHOT_ECH_RAW;
404 MSG_INFO(inraw,
"photometric echelle", VISIR_SPC_PHOT_ECH_RAW);
405 input_mode = RAW_PHOT_INPUT | IS_ECH;
408 return ERR(CPL_ERROR_ILLEGAL_INPUT,
"Input frame set must contain "
409 "frame(s) tagged as one of: " VISIR_SPC_OBS_RAW
", "
410 VISIR_SPC_PHOT_RAW
", " VISIR_SPC_OBS_PP
","
411 VISIR_SPC_PHOT_PP
"," VISIR_SPC_OBS_ECH_RAW
","
412 VISIR_SPC_OBS_ECH_PP
"," VISIR_SPC_PHOT_ECH_RAW
","
413 VISIR_SPC_PHOT_ECH_PP);
416 cpl_size
const nframes = irplib_framelist_get_size _(raws->o);
418 irplib_framelist_load_propertylist_all _(raws->o, 0,
"^("
419 VISIR_PFITS_REGEXP_SPC_SENSIT
420 "|" RECIPE_KEYS_REGEXP_ALL
421 "|" RECIPE_KEYS_REGEXP_WCS
422 "|" VISIR_PFITS_REGEXP_DIT
423 "|" VISIR_PFITS_DOUBLE_WLEN
424 "|" VISIR_PFITS_DOUBLE_PWLEN
426 "|" "ESO PRO DATANCOM"
428 "|" "ESO QC EXECTIME"
429 "|" "ESO QC BACKGD MEAN"
434 cpl_propertylist
const *
const pl =
435 irplib_framelist_get_propertylist_const _(raws->o, 0);
436 int const has_seq = cpl_propertylist_has _(pl, VISIR_PFITS_DOUBLE_SEQ1_DIT);
437 char const *
const dit_key = has_seq ? VISIR_PFITS_DOUBLE_SEQ1_DIT
438 : VISIR_PFITS_DOUBLE_DIT;
441 char const *
const star_cat =
442 irplib_frameset_find_file _(framelist, VISIR_CALIB_STDSTAR_SPC);
443 if ((input_mode & IS_PHOT) && star_cat == NULL)
return ERR(
444 CPL_ERROR_DATA_NOT_FOUND,
"Frame set with a photometric frame (%s) "
445 "must include a standard star catalogue (" VISIR_CALIB_STDSTAR_SPC
448 visir_data_type data_type;
449 cpl_frame
const *
const frm = irplib_framelist_get_const _(raws->o, 0);
450 visir_get_data_type _(frm, pl, &data_type, NULL);
452 if (visir_data_is_drs(data_type)) {
455 cpl_parameter
const * par = cpl_parameterlist_find_const _(
456 parlist, PACKAGE
"." RECIPE_STRING
".ksi");
457 tmp = cpl_parameter_get_default_double _(par);
458 if (spc_config.ksi == tmp * CPL_MATH_RAD_DEG)
459 spc_config.ksi = VISIR_DRS_DIST_KSI;
461 par = cpl_parameterlist_find_const _(
462 parlist, PACKAGE
"." RECIPE_STRING
".eps");
463 tmp = cpl_parameter_get_default_double _(par);
464 if (spc_config.eps == tmp) spc_config.eps = VISIR_DRS_DIST_EPS;
466 par = cpl_parameterlist_find_const _(
467 parlist, PACKAGE
"." RECIPE_STRING
".delta");
468 tmp = cpl_parameter_get_default_double _(par);
469 if (spc_config.delta == tmp) spc_config.delta = VISIR_DRS_DIST_DELTA;
471 par = cpl_parameterlist_find_const _(
472 parlist, PACKAGE
"." RECIPE_STRING
".phi");
473 tmp = cpl_parameter_get_default_double _(par);
474 if (spc_config.phi == tmp * CPL_MATH_RAD_DEG)
475 spc_config.phi = VISIR_DRS_DIST_PHI;
479 char const *
const spc_cal_qeff =
480 irplib_frameset_find_file _(framelist, VISIR_CALIB_QEFF_SPC);
483 char const *
const spc_cal_lines =
484 irplib_frameset_find_file _(framelist, VISIR_CALIB_LINES_SPC);
487 char const *
const badpix =
488 irplib_frameset_find_file _(framelist, VISIR_CALIB_BPM);
491 char const *
const flat =
492 irplib_frameset_find_file _(framelist, VISIR_CALIB_FLAT);
495 double wlen, slitw, temp, fwhm;
496 visir_spc_resol resol = visir_spc_get_res_wl _(raws->o, &wlen, &slitw,
497 &temp, &fwhm, visir_data_is_aqu(data_type));
501 if (resol == VISIR_SPC_R_GHR) {
502 if (!(input_mode & IS_ECH) && !(input_mode & IS_PREPROCESSED))
503 return ERR(CPL_ERROR_TYPE_MISMATCH,
"Will not reduce echelle data "
504 "tagged as long slit data");
505 n_orders = MAX_ORDERS;
507 MSG_WARN(
"Reducing non-HR Grism data as main order");
510 cpl_boolean drop_wcs;
511 SET(imhcycle, cpl_image) = NULL;
512 SET(combinedpair, cpl_image*, v, biimage_delete) = NULL;
513 if (input_mode & IS_PREPROCESSED) {
514 CSET(plists, cpl_propertylist*, v, cpl_free) = cpl_malloc(
515 nframes *
sizeof(cpl_propertylist *));
518 SET(imagelist, cpl_imagelist) = cpl_imagelist_new();
519 for (cpl_size i = 0; i < nframes; i++) {
520 cpl_frame
const *
const frame = irplib_framelist_get _(raws->o, i);
521 char const *
const fname = cpl_frame_get_filename _(frame);
522 cpl_size
const next = cpl_fits_count_extensions _(fname);
524 plists->o[i] = irplib_framelist_get_propertylist_const _(raws->o,i);
525 if (cpl_propertylist_has(plists->o[i],
"ESO QC BACKGD MEAN")) {
526 bg_sum += cpl_propertylist_get_double _(plists->o[i],
527 "ESO QC BACKGD MEAN");
530 SET(tmplist, cpl_imagelist) = cpl_imagelist_new();
531 for (cpl_size j = 0; j < 1 + next; j++) {
532 SET(img, cpl_image) = cpl_image_load(
533 fname, CPL_TYPE_UNSPECIFIED, 0, j);
534 if (cpl_error_get_code()) {
535 ERR_TO_INFO(
"No image in extension %d", (
int)j);
538 cpl_image_reject_value _(img->o, CPL_VALUE_NAN);
539 cpl_size
const lsz = cpl_imagelist_get_size _(tmplist->o);
540 cpl_imagelist_set _(tmplist->o, img->o, lsz);
543 SET(tmp, cpl_image) = cpl_imagelist_collapse_create _(tmplist->o);
544 cpl_size
const lsz = cpl_imagelist_get_size _(imagelist->o);
545 cpl_imagelist_set _(imagelist->o, tmp->o, lsz);
550 imagelist->o, plists->o, CPL_GEOM_FIRST, &drop_wcs);
552 cpl_propertylist_append_double _(phu->o,
"ESO QC BACKGD MEAN",
558 SET(skys, irplib_framelist) = irplib_framelist_extract(
559 all->o, VISIR_SPC_OBS_SKYFRAME);
560 if (cpl_error_get_code())
return ERR(CPL_ERROR_ILLEGAL_INPUT,
561 "Frame set with a preprocessed frame (%s) must include a "
562 "sky frame (" VISIR_SPC_OBS_SKYFRAME
")", rawtag);
565 cpl_frame
const *
const frame = irplib_framelist_get _(skys->o, 0);
566 char const *
const fname = cpl_frame_get_filename _(frame);
567 RESET(imhcycle) = cpl_image_load _(fname, CPL_TYPE_UNSPECIFIED,0,0);
568 cpl_image_reject_value _(imhcycle->o, CPL_VALUE_NAN);
574 raws->o, badpix, flat, CPL_GEOM_FIRST, &drop_wcs,
575 !spc_config.do_fixcombi, wlen, resol);
579 RESET(imhcycle) = cpl_imagelist_unset _(hcycle->o, 0);
581 visir_spc_det_fix _(&imhcycle->o, 1, CPL_FALSE, wlen, resol,
582 spc_config.phi, spc_config.ksi,
583 spc_config.eps, spc_config.delta,
586 visir_qc_append_background _(phu->o, raws->o, 0, 0);
589 SET(combined, cpl_image) = cpl_image_cast _(combinedpair->o[0],
594 if (!(input_mode & IS_PREPROCESSED)) {
597 SET(tmp, cpl_image) = visir_spc_flip _(combined->o, wlen, resol,
598 VISIR_DATA_CUBE2, &rev);
599 RESET(combined) = YANK(tmp);
602 RESET(tmp) = visir_spc_flip _(imhcycle->o, wlen, resol,
603 VISIR_DATA_CUBE2, NULL);
604 RESET(imhcycle) = YANK(tmp);
607 int const ncomb = visir_get_ncombine _(raws->o);
609 if (spc_config.do_fixcombi && !(input_mode & IS_PREPROCESSED)) {
610 visir_spc_det_fix _(&combined->o, 1, CPL_TRUE, wlen, resol,
611 spc_config.phi, spc_config.ksi,
612 spc_config.eps, spc_config.delta,
616 visir_optmod ins_settings;
617 visir_spc_optmod_init _(resol, wlen, &ins_settings,
618 visir_data_is_aqu(data_type));
620 MSG_DBG(
"resol = %d, input_mode = %d", resol, input_mode);
621 SET(paflist, cpl_propertylist) = cpl_propertylist_new();
624 SET(orders, orderlist) = orderlist_new(n_orders, {0, 0, 0, 0},
625 {1, 0, 0, 0}, {-1, 0, 0, 0}, {2, 0, 0, 0}, {-2, 0, 0, 0},
626 {3, 0, 0, 0}, {-3, 0, 0, 0}, {4, 0, 0, 0}, {-4, 0, 0, 0});
630 for (
size_t i = 0; i < orders->o->sz; ++i) {
631 order *
const oi = &orders->o->data[i];
633 if (input_mode & IS_ECH) snprintf(pfx,
sizeof(pfx),
"Echelle order %2d: "
634 "offset %s: ", oi->cutout + visir_spc_optmod_get_echelle_order(
635 &ins_settings), pn(oi->cutout));
636 MSG_INFO(
"%sattempting extraction", pfx);
638 int lcol = -1, rcol = -1;
639 spc_config.orderoffset = oi->cutout;
640 SET(imhcyclenarrow, cpl_image) = NULL;
641 visir_spc_extract_order(&imhcyclenarrow->o, &oi->comnarrow, &lcol,
642 &rcol, combined->o, imhcycle->o, wlen,
643 &spc_config, (input_mode & IS_ECH) == IS_ECH,
644 visir_data_is_aqu(data_type));
645 if (cpl_error_get_code()) {
646 ERR_TO_WARN(
"%scutout failed", pfx);
647 oi->cutout = UNUSED_ORDER;
651 MSG_INFO(
"%scutout success", pfx);
652 MSG_DBG(
"extents mapping:\t[raw] =>\t[relative (to cutout)]");
653 MSG_DBG(
"=======================================================");
654 MSG_DBG(
" cutout:\t\t[%d;%d] =>\t[%d;%d]", lcol, rcol,
655 lcol - lcol + 1, rcol - lcol + 1);
658 oi->aplist = visir_aplist_new();
659 int const ncol = rcol - lcol + 1;
660 FOR_EACH_T(visir_apdefs
const *
const aps, aplist->o) {
661 bool matched =
false;
662 int const l = visir_norm_coord(rev, -0.0, lcol, rcol, aps);
663 int const r = visir_norm_coord(rev, +0.0, lcol, rcol, aps);
664 if (1 <= l && l <= ncol && 1 <= r && r <= ncol) {
666 visir_aplist_push_back(oi->aplist, aps);
668 MSG_DBG(
"%capfile entry %d:\t[%d;%d] =>\t[%d;%d]",
669 matched ?
'*' :
' ', aps->ident, aps->limits[0].l,
670 aps->limits[0].r, l, r);
674 cxsize
const nmatches = visir_aplist_size(oi->aplist);
677 oi->matches = matchlist_new(nmatches);
678 FOR_EACH_T(visir_apdefs *
const aps, oi->aplist) {
679 cpl_propertylist *
const pl = cpl_propertylist_new();
680 oi->matches->data[j++] = (match){ oi->cutout, 0, 0, pl, aps };
685 int const ident = -(i+1);
686 visir_apdefs *
const aps = visir_apdefs_new(1, ident,
'O', 0);
687 aps->limits[0] = (visir_aplimits){ lcol, rcol };
688 cpl_propertylist *
const pl = cpl_propertylist_new();
689 oi->matches = matchlist_new(1);
690 oi->matches->data[0] = (match){ oi->cutout, 0, 0, pl, aps };
696 for (
size_t j = 0; j < oi->matches->sz; ++j) {
697 match *
const mj = &oi->matches->data[j];
699 cpl_propertylist_update_int _(mj->qclist,
"ESO DRS APDEF",
702 if (visir_aplist_size(aplist->o) && nmatches < 1) {
703 MSG_WARN(
"%sextraction %ld: no apdefs matched", pfx, j);
704 mj->extract = UNUSED_ORDER;
709 spc_config.extract = j;
710 visir_spc_extract_wcal(oi->comnarrow, imhcyclenarrow->o,
711 lcol, rcol, wlen, slitw, temp, fwhm, resol, &spc_config,
712 spc_cal_lines, spc_cal_qeff, visir_data_is_aqu(data_type),
713 mj->aps, ncomb, rev, &mj->spc_tbl, &mj->weight2d, mj->qclist);
714 if (cpl_error_get_code()) {
715 ERR_TO_WARN(
"%sextraction %ld: wlen calib failed", pfx, j);
720 cpl_table_erase_column X(mj->spc_tbl,
"SPC_EMISSIVITY");
721 mj->extract = UNUSED_ORDER;
724 MSG_INFO(
"%sextraction %ld: success", pfx, j);
726 visir_spectro_qc _(mj->qclist, paflist->o, drop_wcs, raws->o, NULL,
727 "^(" VISIR_PFITS_REGEXP_SPC_WCAL_PAF
")$");
730 if (!(input_mode & IS_PHOT))
731 MSG_INFO(
"The frame set contains observation frame(s) "
732 "(%s) together with a standard star catalogue ("
733 VISIR_CALIB_STDSTAR_SPC
"), attempting to "
734 "perform a photometric calibration", rawtag);
738 &mj->weight2d, mj->qclist, mj->spc_tbl,
740 if (cpl_error_get_code()) {
742 if (input_mode & IS_PHOT)
return ERR();
744 "The frame set contains observation frame(s) (%s) "
745 "together with a standard star catalogue ("
746 VISIR_CALIB_STDSTAR_SPC
") but the photometric "
747 "calibration failed", rawtag);
749 input_mode |= IS_PHOT;
753 cpl_table_erase_column _(mj->spc_tbl,
"SPC_EMISSIVITY");
760 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC BACKGD SIGMA");
761 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC GAUSSFIT FWHM");
762 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC GAUSSFIT FWHM_ERR");
763 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC GAUSSFIT PEAK");
764 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC GAUSSFIT PEAK_ERR");
765 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC XFWHM");
766 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC SENS MEDIAN");
767 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC SENS MEAN");
768 visir_spc_qc_summarise _(phu->o, orders->o,
"ESO QC SENS STDEV");
771 cpl_propertylist_append_string _(paflist->o, CPL_DFS_PRO_CATG,
772 VISIR_SPC_OBS_COMBINED_PROCATG);
774 char const *
const procat = input_mode & IS_PHOT ? (input_mode & IS_ECH ?
775 VISIR_SPC_PHOT_ECH_TAB_PROCATG : VISIR_SPC_PHOT_TAB_PROCATG) : (
776 input_mode & IS_ECH ? VISIR_SPC_OBS_ECH_TAB_PROCATG :
777 VISIR_SPC_OBS_TAB_PROCATG);
781 for (
size_t i = 0; i < orders->o->sz; ++i) {
782 order
const *
const oi = &orders->o->data[i];
783 if (oi->cutout == UNUSED_ORDER)
continue;
786 if (input_mode & IS_ECH) snprintf(pfx,
sizeof(pfx),
"Echelle order %2d: "
787 "offset %s: ", oi->cutout + visir_spc_optmod_get_echelle_order(
788 &ins_settings), pn(oi->cutout));
789 for (
size_t j = 0; j < oi->matches->sz; ++j) {
790 match
const *
const mj = &oi->matches->data[j];
791 if (mj->extract == UNUSED_ORDER)
continue;
793 MSG_INFO(
"%sextraction %ld: saving", pfx, j);
796 visir_spc_obs_save _(framelist, parlist, phu->o, mj->qclist,
797 paflist->o, mj->weight2d, mj->spc_tbl,
798 oi->comnarrow, procat, input_mode,
801 visir_spc_obs_extend _(mj->qclist, mj->weight2d, mj->spc_tbl,
802 oi->comnarrow, input_mode, oi->cutout,
809 visir_spc_obs_extend_combined _(combined->o);
823static int visir_old_spc_obs(cpl_frameset * framelist,
824 const cpl_parameterlist * parlist)
826 visir_old_spc_obs_(framelist, parlist);
827 return cpl_error_get_code();
847static cpl_error_code visir_spc_obs_save(cpl_frameset * set,
848 const cpl_parameterlist * parlist,
849 cpl_propertylist * phu_qclist,
850 cpl_propertylist * qclist,
851 const cpl_propertylist * paflist,
852 const cpl_image * weight2d,
853 const cpl_table * table,
854 const cpl_image * comnarrow,
855 const char * tab_procatg,
856 const int input_mode,
857 const int ord,
const size_t extract)
863 if (input_mode & IS_ECH) snprintf(offset,
sizeof(offset),
"%s:", pn(ord));
866 cpl_propertylist * plist = cpl_propertylist_new();
867 snprintf(msgbuf,
sizeof(msgbuf),
"TAB_SPECTRUM_%s%ld", offset, extract);
868 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
869 cpl_propertylist_append(plist, qclist);
872 skip_if (irplib_dfs_save_table(set, parlist, set, table, plist,
873 RECIPE_SAVE_STRING, tab_procatg,
874 phu_qclist, NULL, visir_pipe_id,
875 RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS));
876 cpl_propertylist_delete(plist);
878 plist = cpl_propertylist_new();
880 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_WEIGHT_%s%ld", offset, extract);
881 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
882 skip_if(cpl_image_save(weight2d, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
883 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
884 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_%s%ld", offset, extract);
885 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
886 skip_if(cpl_image_save(comnarrow, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
887 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
888 cpl_propertylist_delete(plist);
893 skip_if (cpl_dfs_save_paf(
"VISIR", RECIPE_SAVE_STRING, paflist,
894 RECIPE_SAVE_STRING CPL_DFS_PAF));
896 bug_if(paflist == NULL);
901 return cpl_error_get_code();
915static cpl_error_code visir_spc_obs_extend(cpl_propertylist * qclist,
916 const cpl_image * weight2d,
917 const cpl_table * table,
918 const cpl_image * comnarrow,
919 const int input_mode,
920 const int ord,
const size_t extract)
926 if (input_mode & IS_ECH) snprintf(offset,
sizeof(offset),
"%s:", pn(ord));
929 cpl_propertylist * plist = cpl_propertylist_duplicate(qclist);
930 snprintf(msgbuf,
sizeof(msgbuf),
"TAB_SPECTRUM_%s%ld", offset, extract);
931 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
932 skip_if (cpl_table_save(table, NULL, plist, RECIPE_SAVE_STRING
"_tab"
933 CPL_DFS_FITS, CPL_IO_EXTEND));
934 cpl_propertylist_delete(plist);
936 plist = cpl_propertylist_new();
937 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_WEIGHT_%s%ld", offset, extract);
938 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
939 skip_if(cpl_image_save(weight2d, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
940 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
941 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_%s%ld", offset, extract);
942 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
943 skip_if(cpl_image_save(comnarrow, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
944 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
945 cpl_propertylist_delete(plist);
949 return cpl_error_get_code();
959static cpl_error_code visir_spc_obs_extend_combined(
const cpl_image * combined)
963 cpl_propertylist * plist = cpl_propertylist_new();
964 cpl_propertylist_update_string(plist,
"EXTNAME",
"IMG_COMBINED");
965 skip_if(cpl_image_save(combined, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
966 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
967 cpl_propertylist_delete(plist);
971 return cpl_error_get_code();
985static cpl_error_code visir_spc_qc_summarise(cpl_propertylist * phu_qclist,
991 for (
size_t i = 0; i < orders->sz; ++i) {
992 order
const *
const oi = &orders->data[i];
993 if (oi->cutout == UNUSED_ORDER)
continue;
995 for (
size_t j = 0; oi->matches && j < oi->matches->sz; ++j) {
996 match
const *
const mj = &oi->matches->data[j];
997 if (mj->extract == UNUSED_ORDER)
continue;
999 double const val = cpl_propertylist_get_double(mj->qclist, key);
1000 if (cpl_error_get_code()) cpl_error_reset();
1009 cpl_propertylist_append_double(phu_qclist, key, sum / count);
1010 return CPL_ERROR_NONE;
1012 return CPL_ERROR_DATA_NOT_FOUND;
cpl_error_code visir_dfs_check_framelist_tag(const irplib_framelist *self)
Check the tags in a frameset (group raw only)
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
int visir_parameterlist_get_int(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR integer parameter.
const char * visir_parameterlist_get_string(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR string parameter.
double visir_parameterlist_get_double(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR parameter of type double.
cpl_boolean visir_parameterlist_get_bool(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR boolean parameter.
cpl_error_code visir_spc_phot_sensit(const irplib_framelist *rawframes, const visir_spc_config *cfg, const cpl_propertylist *plist, const char *star_cat, cpl_image **pweight2d, cpl_propertylist *qclist, cpl_table *spc_table, const visir_spc_resol resol, const char *dit_key)
Compute the sensitivity from an extracted spectrum.