37#include "visir_inputs.h"
38#include "visir_recipe.h"
39#include "visir_spectro.h"
40#include "visir_spc_distortion.h"
41#include "visir_spc_photom.h"
48#define RECIPE_STRING "visir_old_spc_obs"
50#define RECIPE_SAVE_STRING "visir_spc_obs"
53#define RECIPE_KEYS_REGEXP_ALL \
54 VISIR_PFITS_REGEXP_IMG_RECOMBINE \
55 "|" VISIR_PFITS_REGEXP_SPC_GET_RES_WL
58#define RECIPE_KEYS_REGEXP \
59 RECIPE_KEYS_REGEXP_ALL \
60 "|" VISIR_PFITS_REGEXP_CAPA \
61 "|" VISIR_PFITS_REGEXP_SPC_WCAL_PAF
64#define RECIPE_KEYS_REGEXP_WCS \
66 "|" IRPLIB_PFITS_WCS_REGEXP
68#define IS_PREPROCESSED 1
72#define PREPROCESSED_INPUT IS_PREPROCESSED
73#define RAW_PHOT_INPUT IS_PHOT
74#define PREPROCESSED_PHOT_INPUT (IS_PHOT | IS_PREPROCESSED)
80#define UNUSED_ORDER 99
82#define MSG_WARN(...) cpl_msg_warning(cpl_func, __VA_ARGS__)
83#define MSG_INFO(...) cpl_msg_info(cpl_func, __VA_ARGS__)
84#define MSG_ERR(...) cpl_msg_error(cpl_func, __VA_ARGS__)
85#define MSG_DBG(...) cpl_msg_debug(cpl_func, __VA_ARGS__)
96 cpl_propertylist * qclist;
105static void match_delete(match m);
106static matchlist* matchlist_new(
size_t sz);
107static void matchlist_delete(matchlist * ml);
114 cpl_image * comnarrow;
116 visir_aplist * aplist;
124static void order_delete(order o);
125static orderlist* orderlist_new(
size_t sz);
126static void orderlist_delete(orderlist * ol);
131static cpl_error_code visir_spc_obs_save(cpl_frameset *,
132 const cpl_parameterlist *,
135 const cpl_propertylist *,
140 const int,
const int,
const size_t);
142static cpl_error_code visir_spc_obs_extend(cpl_propertylist *,
146 const int,
const int,
const size_t);
148static cpl_error_code visir_spc_obs_extend_combined(
const cpl_image *);
150static cpl_error_code visir_spc_qc_summarise(cpl_propertylist *, orderlist *,
154#define cpl_plugin_get_info visir_old_spc_obs_get_info
156VISIR_RECIPE_DEFINE(visir_old_spc_obs,
157 VISIR_PARAM_EMIS_TOL |
158 VISIR_PARAM_REFINE | VISIR_PARAM_XCORR |
159 VISIR_PARAM_OFFSETS | VISIR_PARAM_OBJECTS |
160 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
161 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE |
162 VISIR_PARAM_UNION | VISIR_PARAM_REJECT |
163 VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
164 VISIR_PARAM_PLOT | VISIR_PARAM_SLITSKEW |
165 VISIR_PARAM_SPECSKEW | VISIR_PARAM_VERTARC |
166 VISIR_PARAM_REJLEFT | VISIR_PARAM_REJRIGHT |
167 VISIR_PARAM_HORIARC | VISIR_PARAM_FIXCOMBI |
168 VISIR_PARAM_BKG_CORRECT | VISIR_PARAM_APERT_FILE |
169 VISIR_PARAM_GAIN | VISIR_PARAM_RONOISE |
170 VISIR_PARAM_OXSIGMA | VISIR_PARAM_OXNITER |
171 VISIR_PARAM_OXSMOOTH | VISIR_PARAM_OXKERNEL |
173 "Old DRS detector: Spectroscopic Observation recipe",
174 "This recipe estimates the dispersion relation using the "
175 "atmospheric spectrum\n"
176 "in a long-slit spectroscopy half-cycle frame.\n"
177 "It also extracts the spectrum of an observed object using "
178 "a combined frame.\n"
179 "The files listed in the Set Of Frames (sof-file) "
181 "VISIR-Long-Slit-Spectroscopy-file.fits "
182 VISIR_SPC_OBS_RAW
"\n"
183 "VISIR-Quantum-Efficiency-Calibration-file.fits "
184 VISIR_CALIB_QEFF_SPC
"\n"
185 "VISIR-Atmospheric-Emission-Lines-Calibration-file.fits "
186 VISIR_CALIB_LINES_SPC
188 MAN_VISIR_CALIB_BPM_SPC);
204static void biimage_delete(cpl_image ** bi)
207 cpl_image_delete(bi[0]);
208 cpl_image_delete(bi[1]);
212static void match_delete(match m)
214 cpl_propertylist_delete(m.qclist);
218 if (m.aps->ident < 0) visir_apdefs_delete(m.aps);
219 cpl_table_delete(m.spc_tbl);
220 cpl_image_delete(m.weight2d);
223static matchlist* matchlist_new(
size_t sz)
225 matchlist* ml = cpl_malloc(
sizeof(matchlist));
227 ml->data = cpl_calloc(sz,
sizeof(match));
231static void matchlist_delete(matchlist * ml)
234 for (
size_t i = 0; i < ml->sz; ++i) {
235 match_delete(ml->data[i]);
241static void order_delete(order o)
243 cpl_image_delete(o.comnarrow);
244 visir_aplist_delete(o.aplist);
245 matchlist_delete(o.matches);
248static orderlist* orderlist_new(
size_t sz)
250 orderlist* ol = cpl_malloc(
sizeof(orderlist));
252 ol->data = cpl_calloc(sz,
sizeof(order));
256static void orderlist_delete(orderlist * ol)
259 for (
size_t i = 0; i < ol->sz; ++i) {
260 order_delete(ol->data[i]);
274static const char * pn(
const int oo)
277 const char * sign = oo ? (oo > 0 ?
"+" :
"-") :
"";
278 snprintf(buf,
sizeof(buf),
"%s%d", sign, abs(oo));
290static void * visir_old_spc_obs_(cpl_frameset * framelist,
291 const cpl_parameterlist * parlist)
293 cpl_propertylist* phu = NULL;
294 visir_aplist* aplist = NULL;
295 cpl_image* combined = NULL;
296 cpl_image* imhcycle = NULL;
297 cpl_image** combinedpair = NULL;
298 cpl_propertylist* paflist = NULL;
299 orderlist* orders = NULL;
300 irplib_framelist* raws = NULL;
301 irplib_framelist* all = NULL;
303 visir_spc_config spc_config;
304 spc_config.recipename = RECIPE_STRING;
305 spc_config.parlist = parlist;
306 spc_config.phot_emis_tol = 1.0;
309 phu = cpl_propertylist_new();
310 spc_config.phu = phu;
314 parlist, RECIPE_STRING, VISIR_PARAM_PLOT);
316 parlist, RECIPE_STRING, VISIR_PARAM_SLITSKEW);
318 parlist, RECIPE_STRING, VISIR_PARAM_SPECSKEW);
320 parlist, RECIPE_STRING, VISIR_PARAM_VERTARC);
322 parlist, RECIPE_STRING, VISIR_PARAM_HORIARC);
324 parlist, RECIPE_STRING, VISIR_PARAM_GAIN);
326 parlist, RECIPE_STRING, VISIR_PARAM_RONOISE);
328 parlist, RECIPE_STRING, VISIR_PARAM_OXSIGMA);
330 parlist, RECIPE_STRING, VISIR_PARAM_OXNITER);
332 parlist, RECIPE_STRING, VISIR_PARAM_OXSMOOTH);
334 parlist, RECIPE_STRING, VISIR_PARAM_OXKERNEL);
336 parlist, RECIPE_STRING, VISIR_PARAM_FIXCOMBI);
338 parlist, RECIPE_STRING, VISIR_PARAM_EMIS_TOL);
340 parlist, RECIPE_STRING, VISIR_PARAM_BKG_CORRECT);
342 parlist, RECIPE_STRING, VISIR_PARAM_RESPCAL);
347 parlist, RECIPE_STRING, VISIR_PARAM_APERT_FILE);
354 if (visir_str_par_is_empty(apfile))
355 aplist = visir_aplist_new();
378 all = irplib_framelist_cast(framelist);
379 char const *
const inraw =
"Input: raw %s frame (%s)";
380 char const *
const inprep =
"Input: preprocessed %s frame (%s)";
384 if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_PP)) {
385 raws = irplib_framelist_extract(all, VISIR_SPC_OBS_PP);
386 rawtag = VISIR_SPC_OBS_PP;
387 MSG_INFO(inprep,
"observation", VISIR_SPC_OBS_PP);
388 input_mode = PREPROCESSED_INPUT;
389 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_PP)) {
390 raws = irplib_framelist_extract(all, VISIR_SPC_PHOT_PP);
391 rawtag = VISIR_SPC_PHOT_PP;
392 MSG_INFO(inprep,
"photometric", VISIR_SPC_PHOT_PP);
393 input_mode = PREPROCESSED_PHOT_INPUT;
394 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_ECH_PP)) {
395 raws = irplib_framelist_extract(all, VISIR_SPC_OBS_ECH_PP);
396 rawtag = VISIR_SPC_OBS_ECH_PP;
397 MSG_INFO(inprep,
"observation echelle", VISIR_SPC_OBS_ECH_PP);
398 input_mode = PREPROCESSED_INPUT | IS_ECH;
399 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_ECH_PP)) {
400 raws = irplib_framelist_extract(all, VISIR_SPC_PHOT_ECH_PP);
401 rawtag = VISIR_SPC_PHOT_ECH_PP;
402 MSG_INFO(inprep,
"photometric echelle", VISIR_SPC_PHOT_ECH_PP);
403 input_mode = PREPROCESSED_PHOT_INPUT | IS_ECH;
404 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_RAW)) {
405 raws = irplib_framelist_extract(all, VISIR_SPC_OBS_RAW);
406 rawtag = VISIR_SPC_OBS_RAW;
407 MSG_INFO(inraw,
"observation", VISIR_SPC_OBS_RAW);
408 input_mode = RAW_INPUT;
409 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_RAW)) {
410 raws = irplib_framelist_extract(all, VISIR_SPC_PHOT_RAW);
411 rawtag = VISIR_SPC_PHOT_RAW;
412 MSG_INFO(inraw,
"photometric", VISIR_SPC_PHOT_RAW);
413 input_mode = RAW_PHOT_INPUT;
414 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_OBS_ECH_RAW)) {
415 raws = irplib_framelist_extract(all, VISIR_SPC_OBS_ECH_RAW);
416 rawtag = VISIR_SPC_OBS_ECH_RAW;
417 MSG_INFO(inraw,
"observation echelle", VISIR_SPC_OBS_ECH_RAW);
418 input_mode = RAW_INPUT | IS_ECH;
419 }
else if (irplib_frameset_find_file(framelist, VISIR_SPC_PHOT_ECH_RAW)) {
420 raws = irplib_framelist_extract(all, VISIR_SPC_PHOT_ECH_RAW);
421 rawtag = VISIR_SPC_PHOT_ECH_RAW;
422 MSG_INFO(inraw,
"photometric echelle", VISIR_SPC_PHOT_ECH_RAW);
423 input_mode = RAW_PHOT_INPUT | IS_ECH;
425 cpl_msg_error(cpl_func,
"Input frame set must contain "
426 "frame(s) tagged as one of: " VISIR_SPC_OBS_RAW
", "
427 VISIR_SPC_PHOT_RAW
", " VISIR_SPC_OBS_PP
","
428 VISIR_SPC_PHOT_PP
"," VISIR_SPC_OBS_ECH_RAW
","
429 VISIR_SPC_OBS_ECH_PP
"," VISIR_SPC_PHOT_ECH_RAW
","
430 VISIR_SPC_PHOT_ECH_PP);
431 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
436 cpl_size
const nframes = irplib_framelist_get_size(raws);
438 irplib_framelist_load_propertylist_all(raws, 0,
"^("
439 VISIR_PFITS_REGEXP_SPC_SENSIT
440 "|" RECIPE_KEYS_REGEXP_ALL
441 "|" RECIPE_KEYS_REGEXP_WCS
442 "|" VISIR_PFITS_REGEXP_DIT
443 "|" VISIR_PFITS_DOUBLE_WLEN
444 "|" VISIR_PFITS_DOUBLE_PWLEN
446 "|" "ESO PRO DATANCOM"
448 "|" "ESO QC EXECTIME"
449 "|" "ESO QC BACKGD MEAN"
456 cpl_propertylist
const *
const pl =
457 irplib_framelist_get_propertylist_const(raws, 0);
458 int const has_seq = cpl_propertylist_has(pl, VISIR_PFITS_DOUBLE_SEQ1_DIT);
459 char const *
const dit_key = has_seq ? VISIR_PFITS_DOUBLE_SEQ1_DIT
460 : VISIR_PFITS_DOUBLE_DIT;
463 char const *
const star_cat =
464 irplib_frameset_find_file(framelist, VISIR_CALIB_STDSTAR_SPC);
465 if ((input_mode & IS_PHOT) && star_cat == NULL) {
466 cpl_msg_error(cpl_func,
"Frame set with a photometric frame (%s) "
467 "must include a standard star catalogue ("
468 VISIR_CALIB_STDSTAR_SPC
")", rawtag);
469 cpl_error_set(cpl_func, CPL_ERROR_DATA_NOT_FOUND);
474 visir_data_type data_type;
475 cpl_frame
const *
const frm = irplib_framelist_get_const(raws, 0);
476 visir_get_data_type(frm, pl, &data_type, NULL);
480 if (visir_data_is_drs(data_type)) {
483 cpl_parameter
const * par = cpl_parameterlist_find_const(
484 parlist, PACKAGE
"." RECIPE_STRING
".ksi");
485 tmp = cpl_parameter_get_default_double(par);
486 if (spc_config.ksi == tmp * CPL_MATH_RAD_DEG)
487 spc_config.ksi = VISIR_DRS_DIST_KSI;
489 par = cpl_parameterlist_find_const(
490 parlist, PACKAGE
"." RECIPE_STRING
".eps");
491 tmp = cpl_parameter_get_default_double(par);
492 if (spc_config.eps == tmp) spc_config.eps = VISIR_DRS_DIST_EPS;
494 par = cpl_parameterlist_find_const(
495 parlist, PACKAGE
"." RECIPE_STRING
".delta");
496 tmp = cpl_parameter_get_default_double(par);
497 if (spc_config.delta == tmp) spc_config.delta = VISIR_DRS_DIST_DELTA;
499 par = cpl_parameterlist_find_const(
500 parlist, PACKAGE
"." RECIPE_STRING
".phi");
501 tmp = cpl_parameter_get_default_double(par);
502 if (spc_config.phi == tmp * CPL_MATH_RAD_DEG)
503 spc_config.phi = VISIR_DRS_DIST_PHI;
509 char const *
const spc_cal_qeff =
510 irplib_frameset_find_file(framelist, VISIR_CALIB_QEFF_SPC);
513 char const *
const spc_cal_lines =
514 irplib_frameset_find_file(framelist, VISIR_CALIB_LINES_SPC);
517 char const *
const badpix =
518 irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
521 char const *
const flat =
522 irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
525 double wlen, slitw, temp, fwhm;
526 visir_spc_resol resol = visir_spc_get_res_wl(raws, &wlen, &slitw,
527 &temp, &fwhm, visir_data_is_aqu(data_type));
533 if (resol == VISIR_SPC_R_GHR) {
534 if (!(input_mode & IS_ECH) && !(input_mode & IS_PREPROCESSED)) {
535 cpl_msg_error(cpl_func,
"Will not reduce echelle data "
536 "tagged as long slit data");
537 cpl_error_set(cpl_func, CPL_ERROR_TYPE_MISMATCH);
539 n_orders = MAX_ORDERS;
541 MSG_WARN(
"Reducing non-HR Grism data as main order");
546 cpl_boolean drop_wcs;
548 if (input_mode & IS_PREPROCESSED) {
549 const cpl_propertylist** plists = cpl_malloc(
550 nframes *
sizeof(cpl_propertylist *));
553 cpl_imagelist* imagelist = cpl_imagelist_new();
554 for (cpl_size i = 0; i < nframes; i++) {
555 cpl_frame
const *
const frame = irplib_framelist_get(raws, i);
556 char const *
const fname = cpl_frame_get_filename(frame);
557 cpl_size
const next = cpl_fits_count_extensions(fname);
559 plists[i] = irplib_framelist_get_propertylist_const(raws,i);
560 if (cpl_propertylist_has(plists[i],
"ESO QC BACKGD MEAN")) {
561 bg_sum += cpl_propertylist_get_double(plists[i],
562 "ESO QC BACKGD MEAN");
565 cpl_imagelist* tmplist = cpl_imagelist_new();
566 for (cpl_size j = 0; j < 1 + next; j++) {
567 cpl_image* img = cpl_image_load(fname,
568 CPL_TYPE_UNSPECIFIED, 0, j);
569 if (cpl_error_get_code()) {
571 cpl_msg_info(cpl_func,
"No image in extension %d", (
int)j);
572 cpl_image_delete(img);
575 cpl_image_reject_value(img, CPL_VALUE_NAN);
576 cpl_size
const lsz = cpl_imagelist_get_size(tmplist);
577 cpl_imagelist_set(tmplist, img, lsz);
579 if (cpl_imagelist_get_size(tmplist)) {
580 cpl_image* tmp = cpl_imagelist_collapse_create(tmplist);
581 cpl_size
const lsz = cpl_imagelist_get_size(imagelist);
582 cpl_imagelist_set(imagelist, tmp, lsz);
584 cpl_imagelist_delete(tmplist);
588 imagelist, plists, CPL_GEOM_FIRST, &drop_wcs);
590 cpl_propertylist_append_double(phu,
"ESO QC BACKGD MEAN",
592 cpl_imagelist_delete(imagelist); imagelist = NULL;
593 cpl_free(plists); plists = NULL;
596 irplib_framelist* skys = irplib_framelist_extract(
597 all, VISIR_SPC_OBS_SKYFRAME);
598 if (cpl_error_get_code()) {
599 cpl_msg_error(cpl_func,
600 "Frame set with a preprocessed frame (%s) must include a "
601 "sky frame (" VISIR_SPC_OBS_SKYFRAME
")", rawtag);
602 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
605 cpl_frame
const *
const frame = irplib_framelist_get(skys, 0);
606 char const *
const fname = cpl_frame_get_filename(frame);
607 imhcycle = cpl_image_load(fname, CPL_TYPE_UNSPECIFIED,0,0);
608 cpl_image_reject_value(imhcycle, CPL_VALUE_NAN);
614 raws, badpix, flat, CPL_GEOM_FIRST, &drop_wcs,
615 !spc_config.do_fixcombi, wlen, resol);
619 imhcycle = cpl_imagelist_unset(hcycle, 0);
621 visir_spc_det_fix(&imhcycle, 1, CPL_FALSE, wlen, resol,
622 spc_config.phi, spc_config.ksi,
623 spc_config.eps, spc_config.delta,
626 visir_qc_append_background(phu, raws, 0, 0);
632 combined = cpl_image_cast(combinedpair[0], CPL_TYPE_DOUBLE);
633 cpl_image_delete(combinedpair[0]);
634 cpl_image_delete(combinedpair[1]);
635 cpl_free(combinedpair);
640 if (!(input_mode & IS_PREPROCESSED)) {
643 cpl_image* tmp = visir_spc_flip(combined, wlen, resol,
644 VISIR_DATA_CUBE2, &rev);
646 cpl_image_delete(combined);
651 tmp = visir_spc_flip(imhcycle, wlen, resol,
652 VISIR_DATA_CUBE2, NULL);
654 cpl_image_delete(imhcycle);
659 int const ncomb = visir_get_ncombine(raws);
661 if (spc_config.do_fixcombi && !(input_mode & IS_PREPROCESSED)) {
662 visir_spc_det_fix(&combined, 1, CPL_TRUE, wlen, resol,
663 spc_config.phi, spc_config.ksi,
664 spc_config.eps, spc_config.delta,
668 visir_optmod ins_settings;
669 visir_spc_optmod_init(resol, wlen, &ins_settings,
670 visir_data_is_aqu(data_type));
672 MSG_DBG(
"resol = %d, input_mode = %d", resol, input_mode);
673 paflist = cpl_propertylist_new();
675 const int default_orders[] = {0, 1, -1, 2, -2, 3, -3, 4, -4};
676 orders = orderlist_new(n_orders);
677 for (
size_t i = 0; i < n_orders; ++i) {
678 orders->data[i].cutout = default_orders[i];
683 for (
size_t i = 0; i < orders->sz; ++i) {
684 order *
const oi = &orders->data[i];
686 if (input_mode & IS_ECH) snprintf(pfx,
sizeof(pfx),
"Echelle order %2d: "
687 "offset %s: ", oi->cutout + visir_spc_optmod_get_echelle_order(
688 &ins_settings), pn(oi->cutout));
689 MSG_INFO(
"%sattempting extraction", pfx);
691 int lcol = -1, rcol = -1;
692 spc_config.orderoffset = oi->cutout;
693 cpl_image* imhcyclenarrow = NULL;
694 visir_spc_extract_order(&imhcyclenarrow, &oi->comnarrow, &lcol,
695 &rcol, combined, imhcycle, wlen,
696 &spc_config, (input_mode & IS_ECH) == IS_ECH,
697 visir_data_is_aqu(data_type));
698 if (cpl_error_get_code()) {
699 cpl_msg_warning(cpl_func,
"%scutout failed", pfx);
701 oi->cutout = UNUSED_ORDER;
702 if (imhcyclenarrow) {
703 cpl_image_delete(imhcyclenarrow);
708 MSG_INFO(
"%scutout success", pfx);
709 MSG_DBG(
"extents mapping:\t[raw] =>\t[relative (to cutout)]");
710 MSG_DBG(
"=======================================================");
711 MSG_DBG(
" cutout:\t\t[%d;%d] =>\t[%d;%d]", lcol, rcol,
712 lcol - lcol + 1, rcol - lcol + 1);
715 oi->aplist = visir_aplist_new();
716 int const ncol = rcol - lcol + 1;
717 FOR_EACH_T(visir_apdefs
const *
const aps, aplist) {
718 bool matched =
false;
719 int const l = visir_norm_coord(rev, -0.0, lcol, rcol, aps);
720 int const r = visir_norm_coord(rev, +0.0, lcol, rcol, aps);
721 if (1 <= l && l <= ncol && 1 <= r && r <= ncol) {
723 visir_aplist_push_back(oi->aplist, aps);
725 MSG_DBG(
"%capfile entry %d:\t[%d;%d] =>\t[%d;%d]",
726 matched ?
'*' :
' ', aps->ident, aps->limits[0].l,
727 aps->limits[0].r, l, r);
731 cxsize
const nmatches = visir_aplist_size(oi->aplist);
734 oi->matches = matchlist_new(nmatches);
735 FOR_EACH_T(visir_apdefs *
const aps, oi->aplist) {
736 cpl_propertylist *
const pl = cpl_propertylist_new();
737 oi->matches->data[j++] = (match){ oi->cutout, 0, 0, pl, aps };
742 int const ident = -(i+1);
743 visir_apdefs *
const aps = visir_apdefs_new(1, ident,
'O', 0);
744 aps->limits[0] = (visir_aplimits){ lcol, rcol };
745 cpl_propertylist *
const pl = cpl_propertylist_new();
746 oi->matches = matchlist_new(1);
747 oi->matches->data[0] = (match){ oi->cutout, 0, 0, pl, aps };
753 for (
size_t j = 0; j < oi->matches->sz; ++j) {
754 match *
const mj = &oi->matches->data[j];
756 cpl_propertylist_update_int(mj->qclist,
"ESO DRS APDEF",
759 if (visir_aplist_size(aplist) && nmatches < 1) {
760 MSG_WARN(
"%sextraction %ld: no apdefs matched", pfx, j);
761 mj->extract = UNUSED_ORDER;
766 spc_config.extract = j;
767 visir_spc_extract_wcal(oi->comnarrow, imhcyclenarrow,
768 lcol, rcol, wlen, slitw, temp, fwhm, resol, &spc_config,
769 spc_cal_lines, spc_cal_qeff, visir_data_is_aqu(data_type),
770 mj->aps, ncomb, rev, &mj->spc_tbl, &mj->weight2d, mj->qclist);
771 if (cpl_error_get_code()) {
772 cpl_msg_warning(cpl_func,
"%sextraction %ld: wlen calib failed",
775 cpl_table_erase_column(mj->spc_tbl,
"SPC_EMISSIVITY");
776 mj->extract = UNUSED_ORDER;
780 MSG_INFO(
"%sextraction %ld: success", pfx, j);
782 visir_spectro_qc(mj->qclist, paflist, drop_wcs, raws, NULL,
783 "^(" VISIR_PFITS_REGEXP_SPC_WCAL_PAF
")$");
786 if (!(input_mode & IS_PHOT))
787 MSG_INFO(
"The frame set contains observation frame(s) "
788 "(%s) together with a standard star catalogue ("
789 VISIR_CALIB_STDSTAR_SPC
"), attempting to "
790 "perform a photometric calibration", rawtag);
794 &mj->weight2d, mj->qclist, mj->spc_tbl,
796 if (cpl_error_get_code()) {
798 if (input_mode & IS_PHOT) {
804 cpl_msg_warning(cpl_func,
805 "The frame set contains observation frame(s) (%s) "
806 "together with a standard star catalogue ("
807 VISIR_CALIB_STDSTAR_SPC
") but the photometric "
808 "calibration failed", rawtag);
811 input_mode |= IS_PHOT;
815 cpl_table_erase_column(mj->spc_tbl,
"SPC_EMISSIVITY");
819 cpl_image_delete(imhcyclenarrow); imhcyclenarrow = NULL;
826 visir_spc_qc_summarise(phu, orders,
"ESO QC BACKGD SIGMA");
827 visir_spc_qc_summarise(phu, orders,
"ESO QC GAUSSFIT FWHM");
828 visir_spc_qc_summarise(phu, orders,
"ESO QC GAUSSFIT FWHM_ERR");
829 visir_spc_qc_summarise(phu, orders,
"ESO QC GAUSSFIT PEAK");
830 visir_spc_qc_summarise(phu, orders,
"ESO QC GAUSSFIT PEAK_ERR");
831 visir_spc_qc_summarise(phu, orders,
"ESO QC XFWHM");
832 visir_spc_qc_summarise(phu, orders,
"ESO QC SENS MEDIAN");
833 visir_spc_qc_summarise(phu, orders,
"ESO QC SENS MEAN");
834 visir_spc_qc_summarise(phu, orders,
"ESO QC SENS STDEV");
837 cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
838 VISIR_SPC_OBS_COMBINED_PROCATG);
840 char const *
const procat = input_mode & IS_PHOT ? (input_mode & IS_ECH ?
841 VISIR_SPC_PHOT_ECH_TAB_PROCATG : VISIR_SPC_PHOT_TAB_PROCATG) : (
842 input_mode & IS_ECH ? VISIR_SPC_OBS_ECH_TAB_PROCATG :
843 VISIR_SPC_OBS_TAB_PROCATG);
847 for (
size_t i = 0; i < orders->sz; ++i) {
848 order
const *
const oi = &orders->data[i];
849 if (oi->cutout == UNUSED_ORDER)
continue;
852 if (input_mode & IS_ECH) snprintf(pfx,
sizeof(pfx),
"Echelle order %2d: "
853 "offset %s: ", oi->cutout + visir_spc_optmod_get_echelle_order(
854 &ins_settings), pn(oi->cutout));
855 for (
size_t j = 0; j < oi->matches->sz; ++j) {
856 match
const *
const mj = &oi->matches->data[j];
857 if (mj->extract == UNUSED_ORDER)
continue;
859 MSG_INFO(
"%sextraction %ld: saving", pfx, j);
862 visir_spc_obs_save(framelist, parlist, phu, mj->qclist,
863 paflist, mj->weight2d, mj->spc_tbl,
864 oi->comnarrow, procat, input_mode,
867 visir_spc_obs_extend(mj->qclist, mj->weight2d, mj->spc_tbl,
868 oi->comnarrow, input_mode, oi->cutout,
875 visir_spc_obs_extend_combined(combined);
880 cpl_propertylist_delete(phu);
881 visir_aplist_delete(aplist);
882 cpl_image_delete(combined);
883 cpl_image_delete(imhcycle);
885 cpl_image_delete(combinedpair[0]);
886 cpl_image_delete(combinedpair[1]);
887 cpl_free(combinedpair);
890 cpl_propertylist_delete(paflist);
891 orderlist_delete(orders);
892 irplib_framelist_delete(raws);
893 irplib_framelist_delete(all);
906static int visir_old_spc_obs(cpl_frameset * framelist,
907 const cpl_parameterlist * parlist)
909 visir_old_spc_obs_(framelist, parlist);
910 return cpl_error_get_code();
930static cpl_error_code visir_spc_obs_save(cpl_frameset * set,
931 const cpl_parameterlist * parlist,
932 cpl_propertylist * phu_qclist,
933 cpl_propertylist * qclist,
934 const cpl_propertylist * paflist,
935 const cpl_image * weight2d,
936 const cpl_table * table,
937 const cpl_image * comnarrow,
938 const char * tab_procatg,
939 const int input_mode,
940 const int ord,
const size_t extract)
946 if (input_mode & IS_ECH) snprintf(offset,
sizeof(offset),
"%s:", pn(ord));
949 cpl_propertylist * plist = cpl_propertylist_new();
950 snprintf(msgbuf,
sizeof(msgbuf),
"TAB_SPECTRUM_%s%ld", offset, extract);
951 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
952 cpl_propertylist_append(plist, qclist);
955 skip_if (irplib_dfs_save_table(set, parlist, set, table, plist,
956 RECIPE_SAVE_STRING, tab_procatg,
957 phu_qclist, NULL, visir_pipe_id,
958 RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS));
959 cpl_propertylist_delete(plist);
961 plist = cpl_propertylist_new();
963 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_WEIGHT_%s%ld", offset, extract);
964 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
965 skip_if(cpl_image_save(weight2d, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
966 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
967 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_%s%ld", offset, extract);
968 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
969 skip_if(cpl_image_save(comnarrow, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
970 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
971 cpl_propertylist_delete(plist);
976 skip_if (cpl_dfs_save_paf(
"VISIR", RECIPE_SAVE_STRING, paflist,
977 RECIPE_SAVE_STRING CPL_DFS_PAF));
979 bug_if(paflist == NULL);
984 return cpl_error_get_code();
998static cpl_error_code visir_spc_obs_extend(cpl_propertylist * qclist,
999 const cpl_image * weight2d,
1000 const cpl_table * table,
1001 const cpl_image * comnarrow,
1002 const int input_mode,
1003 const int ord,
const size_t extract)
1005 char offset[8] =
"";
1009 if (input_mode & IS_ECH) snprintf(offset,
sizeof(offset),
"%s:", pn(ord));
1012 cpl_propertylist * plist = cpl_propertylist_duplicate(qclist);
1013 snprintf(msgbuf,
sizeof(msgbuf),
"TAB_SPECTRUM_%s%ld", offset, extract);
1014 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
1015 skip_if (cpl_table_save(table, NULL, plist, RECIPE_SAVE_STRING
"_tab"
1016 CPL_DFS_FITS, CPL_IO_EXTEND));
1017 cpl_propertylist_delete(plist);
1019 plist = cpl_propertylist_new();
1020 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_WEIGHT_%s%ld", offset, extract);
1021 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
1022 skip_if(cpl_image_save(weight2d, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
1023 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
1024 snprintf(msgbuf,
sizeof(msgbuf),
"IMG_%s%ld", offset, extract);
1025 cpl_propertylist_update_string(plist,
"EXTNAME", msgbuf);
1026 skip_if(cpl_image_save(comnarrow, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
1027 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
1028 cpl_propertylist_delete(plist);
1032 return cpl_error_get_code();
1042static cpl_error_code visir_spc_obs_extend_combined(
const cpl_image * combined)
1046 cpl_propertylist * plist = cpl_propertylist_new();
1047 cpl_propertylist_update_string(plist,
"EXTNAME",
"IMG_COMBINED");
1048 skip_if(cpl_image_save(combined, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
1049 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
1050 cpl_propertylist_delete(plist);
1054 return cpl_error_get_code();
1068static cpl_error_code visir_spc_qc_summarise(cpl_propertylist * phu_qclist,
1074 for (
size_t i = 0; i < orders->sz; ++i) {
1075 order
const *
const oi = &orders->data[i];
1076 if (oi->cutout == UNUSED_ORDER)
continue;
1078 for (
size_t j = 0; oi->matches && j < oi->matches->sz; ++j) {
1079 match
const *
const mj = &oi->matches->data[j];
1080 if (mj->extract == UNUSED_ORDER)
continue;
1082 double const val = cpl_propertylist_get_double(mj->qclist, key);
1083 if (cpl_error_get_code()) cpl_error_reset();
1092 cpl_propertylist_append_double(phu_qclist, key, sum / count);
1093 return CPL_ERROR_NONE;
1095 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.