36 #include "visir_recipe.h"
37 #include "visir_spectro.h"
38 #include "visir_spc_distortion.h"
39 #include "visir_spc_photom.h"
46 #define RECIPE_STRING "visir_old_spc_obs"
48 #define RECIPE_SAVE_STRING "visir_spc_obs"
51 #define RECIPE_KEYS_REGEXP_ALL \
52 VISIR_PFITS_REGEXP_IMG_RECOMBINE \
53 "|" VISIR_PFITS_REGEXP_SPC_GET_RES_WL
56 #define RECIPE_KEYS_REGEXP \
57 RECIPE_KEYS_REGEXP_ALL \
58 "|" VISIR_PFITS_REGEXP_CAPA \
59 "|" VISIR_PFITS_REGEXP_SPC_WCAL_PAF
62 #define RECIPE_KEYS_REGEXP_WCS \
64 "|" IRPLIB_PFITS_WCS_REGEXP
66 #define IS_PREPROCESSED 1
70 #define PREPROCESSED_INPUT IS_PREPROCESSED
71 #define RAW_PHOT_INPUT IS_PHOT
72 #define PREPROCESSED_PHOT_INPUT (IS_PHOT | IS_PREPROCESSED)
77 static cpl_error_code visir_spc_obs_save(cpl_frameset *,
78 const cpl_parameterlist *,
80 const cpl_propertylist *,
87 #define cpl_plugin_get_info visir_old_spc_obs_get_info
89 VISIR_RECIPE_DEFINE(visir_old_spc_obs,
90 VISIR_PARAM_ORDEROFF |
91 VISIR_PARAM_EMIS_TOL |
92 VISIR_PARAM_REFINE | VISIR_PARAM_XCORR |
93 VISIR_PARAM_OFFSETS | VISIR_PARAM_OBJECTS |
94 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
95 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE |
96 VISIR_PARAM_UNION | VISIR_PARAM_REJECT |
97 VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
98 VISIR_PARAM_PLOT | VISIR_PARAM_SLITSKEW |
99 VISIR_PARAM_SPECSKEW | VISIR_PARAM_VERTARC |
100 VISIR_PARAM_REJLEFT | VISIR_PARAM_REJRIGHT |
101 VISIR_PARAM_HORIARC | VISIR_PARAM_FIXCOMBI |
102 VISIR_PARAM_BKG_CORRECT,
103 "Old DRS detector: Spectroscopic Observation recipe",
104 "This recipe estimates the dispersion relation using the "
105 "atmospheric spectrum\n"
106 "in a long-slit spectroscopy half-cycle frame.\n"
107 "It also extracts the spectrum of an observed object using "
108 "a combined frame.\n"
109 "The files listed in the Set Of Frames (sof-file) "
111 "VISIR-Long-Slit-Spectroscopy-file.fits "
112 VISIR_SPC_OBS_RAW
"\n"
113 "VISIR-Quantum-Efficiency-Calibration-file.fits "
114 VISIR_CALIB_QEFF_SPC
"\n"
115 "VISIR-Atmospheric-Emission-Lines-Calibration-file.fits "
116 VISIR_CALIB_LINES_SPC
118 MAN_VISIR_CALIB_BPM_SPC);
142 static int visir_old_spc_obs(cpl_frameset * framelist,
143 const cpl_parameterlist * parlist)
145 irplib_framelist * allframes = NULL;
146 irplib_framelist * rawframes = NULL;
147 irplib_framelist * skyframes = NULL;
148 cpl_propertylist * qclist = cpl_propertylist_new();
149 cpl_propertylist * paflist = cpl_propertylist_new();
151 const char * star_cat;
152 const char * spc_cal_qeff;
153 const char * spc_cal_lines;
155 cpl_image * combined = NULL;
156 cpl_image * flipped = NULL;
157 cpl_image * comnarrow = NULL;
158 cpl_imagelist * hcycle = NULL;
159 cpl_table * spc_table = NULL;
160 cpl_image * weight2d = NULL;
161 cpl_image * imhcycle = NULL;
162 cpl_image * imhcyclenarrow = NULL;
163 cpl_image ** combinedpair;
164 double wlen, slitw, temp, fwhm;
165 visir_spc_resol resol;
166 cpl_boolean drop_wcs;
168 cpl_boolean bkgcorrect;
170 const char * dit_key = VISIR_PFITS_DOUBLE_DIT;
173 spc_config.recipename = RECIPE_STRING;
174 spc_config.parlist = parlist;
175 spc_config.orderoffset = 0;
176 spc_config.phot_emis_tol = 1.0;
191 spc_config.orderoffset =
195 VISIR_PARAM_FIXCOMBI);
196 spc_config.phot_emis_tol =
200 VISIR_PARAM_BKG_CORRECT);
208 skip_if(allframes == NULL);
213 rawtag = VISIR_SPC_OBS_PP;
214 cpl_msg_info(cpl_func,
"Input: preprocessed observation frame ("
215 VISIR_SPC_OBS_PP
")");
216 input_mode = PREPROCESSED_INPUT;
221 rawtag = VISIR_SPC_PHOT_PP;
222 cpl_msg_info(cpl_func,
"Input: preprocessed photometric frame ("
223 VISIR_SPC_PHOT_PP
")");
224 input_mode = PREPROCESSED_PHOT_INPUT;
229 rawtag = VISIR_SPC_OBS_ECH_PP;
230 cpl_msg_info(cpl_func,
"Input: preprocessed observation echelle frame ("
231 VISIR_SPC_OBS_ECH_PP
")");
232 input_mode = PREPROCESSED_INPUT | IS_ECH;
237 rawtag = VISIR_SPC_PHOT_ECH_PP;
238 cpl_msg_info(cpl_func,
"Input: preprocessed photometric echelle frame ("
239 VISIR_SPC_PHOT_ECH_PP
")");
240 input_mode = PREPROCESSED_PHOT_INPUT | IS_ECH;
245 rawtag = VISIR_SPC_OBS_RAW;
246 cpl_msg_info(cpl_func,
"Input: raw observation frame ("
247 VISIR_SPC_OBS_RAW
")");
248 input_mode = RAW_INPUT;
253 rawtag = VISIR_SPC_PHOT_RAW;
254 cpl_msg_info(cpl_func,
"Input: raw photometric frame ("
255 VISIR_SPC_PHOT_RAW
")");
256 input_mode = RAW_PHOT_INPUT;
261 rawtag = VISIR_SPC_OBS_ECH_RAW;
262 cpl_msg_info(cpl_func,
"Input: raw observation echelle frame ("
263 VISIR_SPC_OBS_ECH_RAW
")");
264 input_mode = RAW_INPUT | IS_ECH;
269 rawtag = VISIR_SPC_PHOT_ECH_RAW;
270 cpl_msg_info(cpl_func,
"Input: raw photometric echelle frame ("
271 VISIR_SPC_PHOT_ECH_RAW
")");
272 input_mode = RAW_PHOT_INPUT | IS_ECH;
275 error_if(1, CPL_ERROR_ILLEGAL_INPUT,
"Input frame set must contain "
276 "frame(s) tagged as one of: " VISIR_SPC_OBS_RAW
", "
277 VISIR_SPC_PHOT_RAW
", " VISIR_SPC_OBS_PP
","
278 VISIR_SPC_PHOT_PP
"," VISIR_SPC_OBS_ECH_RAW
","
279 VISIR_SPC_OBS_ECH_PP
"," VISIR_SPC_PHOT_ECH_RAW
","
280 VISIR_SPC_PHOT_ECH_PP);
283 bug_if (rawframes == NULL);
285 if (input_mode & IS_PREPROCESSED) {
287 error_if(skyframes == NULL, CPL_ERROR_ILLEGAL_INPUT,
288 "Frame set with a preprocessed frame (%s) must include a sky "
289 "frame (" VISIR_SPC_OBS_SKYFRAME
")", rawtag);
295 VISIR_PFITS_REGEXP_SPC_SENSIT
296 "|" RECIPE_KEYS_REGEXP_ALL
297 "|" RECIPE_KEYS_REGEXP_WCS
298 "|" VISIR_PFITS_REGEXP_DIT
299 "|" VISIR_PFITS_DOUBLE_WLEN
300 "|" VISIR_PFITS_DOUBLE_PWLEN
303 "|" "ESO QC EXECTIME"
304 "|" "ESO QC BACKGD MEAN"
310 VISIR_PFITS_DOUBLE_SEQ1_DIT))
311 dit_key = VISIR_PFITS_DOUBLE_SEQ1_DIT;
316 error_if ((input_mode & IS_PHOT) && star_cat == NULL,
317 CPL_ERROR_DATA_NOT_FOUND,
"Frame set with a photometric frame "
318 "(%s) must include a standard star catalogue ("
319 VISIR_CALIB_STDSTAR_SPC
")", rawtag);
321 visir_data_type data_type;
324 skip_if(visir_get_data_type(frm, plist, &data_type, NULL));
326 if (visir_data_is_drs(data_type)) {
328 const cpl_parameter * par =
329 cpl_parameterlist_find_const(parlist, PACKAGE
"." RECIPE_STRING
".ksi");
330 if (spc_config.ksi == cpl_parameter_get_default_double(par) * CPL_MATH_RAD_DEG) {
331 spc_config.ksi = VISIR_DRS_DIST_KSI;
333 par = cpl_parameterlist_find_const(parlist, PACKAGE
"." RECIPE_STRING
".eps");
334 if (spc_config.eps == cpl_parameter_get_default_double(par)) {
335 spc_config.eps = VISIR_DRS_DIST_EPS;
337 par = cpl_parameterlist_find_const(parlist, PACKAGE
"." RECIPE_STRING
".delta");
338 if (spc_config.delta == cpl_parameter_get_default_double(par)) {
339 spc_config.delta = VISIR_DRS_DIST_DELTA;
341 par = cpl_parameterlist_find_const(parlist, PACKAGE
"." RECIPE_STRING
".phi");
342 if (spc_config.phi == cpl_parameter_get_default_double(par) * CPL_MATH_RAD_DEG) {
343 spc_config.phi = VISIR_DRS_DIST_PHI;
360 resol = visir_spc_get_res_wl(rawframes, &wlen, &slitw, &temp, &fwhm,
361 visir_data_is_aqu(data_type));
365 if (resol == VISIR_SPC_R_GHR) {
366 error_if(!(input_mode & IS_ECH) && !(input_mode & IS_PREPROCESSED),
367 CPL_ERROR_TYPE_MISMATCH,
"Will not "
368 "reduce echelle data tagged as long slit data");
370 if (spc_config.orderoffset == 0) {
371 cpl_msg_warning(cpl_func,
"Reducing non-HR Grism data as main order");
373 cpl_msg_error(cpl_func,
"This recipe cannot reduce non-HR Grism "
374 "data with an order-offset of %d",
375 spc_config.orderoffset);
376 visir_error_set(CPL_ERROR_TYPE_MISMATCH);
381 if (input_mode & IS_PREPROCESSED) {
382 cpl_imagelist * imagelist = cpl_imagelist_new();
384 const cpl_propertylist ** plists =
385 cpl_malloc(nframes *
sizeof(cpl_propertylist *));
388 for (cpl_size i = 0; i < nframes; i++) {
390 const char * fname = cpl_frame_get_filename(frame);
391 const cpl_size next = cpl_fits_count_extensions(fname);
392 cpl_imagelist * tmplist = cpl_imagelist_new();
393 cpl_errorstate prestate = cpl_errorstate_get();
397 if (cpl_propertylist_has(plists[i],
"ESO QC BACKGD MEAN"))
398 bg_sum += cpl_propertylist_get_double(plists[i],
399 "ESO QC BACKGD MEAN");
402 for (cpl_size j = 0; j < 1 + next; j++) {
404 cpl_image_load(fname, CPL_TYPE_UNSPECIFIED, 0, j);
406 cpl_errorstate_set(prestate);
407 cpl_msg_info(cpl_func,
"No image in extension %d", (
int)j);
410 cpl_image_reject_value(img, CPL_VALUE_NAN);
411 cpl_imagelist_set(tmplist, img, cpl_imagelist_get_size(tmplist));
414 tmp = cpl_imagelist_collapse_create(tmplist);
416 cpl_imagelist_set(imagelist, tmp,
417 cpl_imagelist_get_size(imagelist));
418 cpl_imagelist_delete(tmplist);
422 plists, CPL_GEOM_FIRST, &drop_wcs);
425 cpl_propertylist_append_double(qclist,
"ESO QC BACKGD MEAN",
427 cpl_imagelist_delete(imagelist);
434 const char * fname = cpl_frame_get_filename(frame);
435 imhcycle = cpl_image_load(fname, CPL_TYPE_UNSPECIFIED, 0, 0);
436 cpl_image_reject_value(imhcycle, CPL_VALUE_NAN);
437 skip_if(imhcycle == NULL);
442 bug_if (input_mode & IS_PREPROCESSED);
445 badpix, flat, CPL_GEOM_FIRST,
446 &drop_wcs, !spc_config.do_fixcombi,
453 imhcycle = cpl_imagelist_unset(hcycle, 0);
455 skip_if (visir_spc_det_fix(&imhcycle, 1, CPL_FALSE,
463 skip_if(visir_qc_append_background(qclist, rawframes, 0, 0));
466 error_if (combinedpair == NULL, cpl_error_get_code(),
467 "Could not combine the input frames (%s)", rawtag);
469 cpl_image_delete(combinedpair[1]);
470 combined = cpl_image_cast(combinedpair[0], CPL_TYPE_DOUBLE);
471 cpl_image_delete(combinedpair[0]);
472 cpl_free(combinedpair);
476 if (!(input_mode & IS_PREPROCESSED)) {
479 flipped = visir_spc_flip(combined, wlen, resol, VISIR_DATA_CUBE2);
481 cpl_image_delete(combined);
486 flipped = visir_spc_flip(imhcycle, wlen, resol, VISIR_DATA_CUBE2);
488 cpl_image_delete(imhcycle);
493 skip_if (spc_config.do_fixcombi && !(input_mode & IS_PREPROCESSED) &&
494 visir_spc_det_fix(&combined, 1, CPL_TRUE, wlen, resol,
495 spc_config.phi, spc_config.ksi,
496 spc_config.eps, spc_config.delta,
499 cpl_msg_info(cpl_func,
"input_mode %d", input_mode);
500 skip_if(visir_spc_extract_order(&imhcyclenarrow, &comnarrow,
501 combined, imhcycle, wlen, &spc_config,
502 (input_mode & IS_ECH) == IS_ECH,
503 visir_data_is_aqu(data_type)));
505 skip_if (visir_spc_extract_wcal(comnarrow, imhcyclenarrow,
506 wlen, slitw, temp, fwhm,
507 resol, spc_config.orderoffset,
508 spc_cal_lines, spc_cal_qeff,
509 &spc_table, &weight2d, qclist,
510 spc_config.plot, bkgcorrect,
511 visir_data_is_aqu(data_type)));
514 bug_if (visir_spectro_qc(qclist, paflist, drop_wcs, rawframes, NULL,
515 "^(" VISIR_PFITS_REGEXP_SPC_WCAL_PAF
")$"));
518 cpl_errorstate prestate = cpl_errorstate_get();
519 const cpl_propertylist * plist =
523 if (!(input_mode & IS_PHOT))
524 cpl_msg_info(cpl_func,
"The frame set contains observation frame"
525 "(s) (%s) together with a standard star catalogue ("
526 VISIR_CALIB_STDSTAR_SPC
"), attempting to perform a "
527 "photometric calibration", rawtag);
530 &weight2d, qclist, spc_table, dit_key)) {
531 if (!(input_mode & IS_PHOT)) {
532 irplib_error_recover(prestate,
"The frame set contains "
533 "observation frame(s) (%s) together with "
534 "a standard star catalogue ("
535 VISIR_CALIB_STDSTAR_SPC
") but the "
536 "photometric calibration failed", rawtag);
541 input_mode |= IS_PHOT;
543 bug_if(input_mode & IS_PHOT);
545 bug_if (cpl_table_erase_column(spc_table,
"SPC_EMISSIVITY"));
551 cpl_msg_info(cpl_func,
"Saving the produced spectrum");
554 bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
555 VISIR_SPC_OBS_COMBINED_PROCATG));
557 if (input_mode & IS_PHOT) {
558 if (input_mode & IS_ECH)
559 skip_if (visir_spc_obs_save(framelist, parlist, qclist, paflist,
560 combined, weight2d, spc_table,
561 VISIR_SPC_PHOT_ECH_TAB_PROCATG));
563 skip_if (visir_spc_obs_save(framelist, parlist, qclist, paflist,
564 combined, weight2d, spc_table,
565 VISIR_SPC_PHOT_TAB_PROCATG));
568 if (input_mode & IS_ECH)
569 skip_if (visir_spc_obs_save(framelist, parlist, qclist, paflist,
570 combined, weight2d, spc_table,
571 VISIR_SPC_OBS_ECH_TAB_PROCATG));
573 skip_if (visir_spc_obs_save(framelist, parlist, qclist, paflist,
574 combined, weight2d, spc_table,
575 VISIR_SPC_OBS_TAB_PROCATG));
580 cpl_propertylist_delete(qclist);
581 cpl_propertylist_delete(paflist);
585 cpl_image_delete(flipped);
586 cpl_image_delete(combined);
587 cpl_image_delete(comnarrow);
588 cpl_image_delete(imhcycle);
589 cpl_image_delete(imhcyclenarrow);
590 cpl_table_delete(spc_table);
591 cpl_image_delete(weight2d);
592 cpl_imagelist_delete(hcycle);
594 return cpl_error_get_code();
614 static cpl_error_code visir_spc_obs_save(cpl_frameset * set,
615 const cpl_parameterlist * parlist,
616 cpl_propertylist * qclist,
617 const cpl_propertylist * paflist,
618 const cpl_image * combined,
619 const cpl_image * weight2d,
620 const cpl_table * table,
621 const char * tab_procatg)
626 cpl_propertylist_update_string(qclist,
"EXTNAME",
"TAB_SPECTRUM");
629 qclist, NULL, visir_pipe_id,
630 RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS));
632 cpl_propertylist * plist = cpl_propertylist_new();
633 cpl_propertylist_update_string(plist,
"EXTNAME",
"IMG_COMBINED");
634 skip_if(cpl_image_save(combined, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
635 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
636 cpl_propertylist_update_string(plist,
"EXTNAME",
"IMG_WEIGHT");
637 skip_if(cpl_image_save(weight2d, RECIPE_SAVE_STRING
"_tab" CPL_DFS_FITS,
638 CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND));
639 cpl_propertylist_delete(plist);
641 #ifdef VISIR_SAVE_PAF
644 skip_if (cpl_dfs_save_paf(
"VISIR", RECIPE_SAVE_STRING, paflist,
645 RECIPE_SAVE_STRING CPL_DFS_PAF));
647 bug_if(paflist == NULL);
652 return cpl_error_get_code();
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_error_code visir_dfs_check_framelist_tag(const irplib_framelist *self)
Check the tags in a frameset (group raw only)
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 visir_spc_phot_sensit(const irplib_framelist *rawframes, const visir_spc_config *pconfig, const cpl_propertylist *plist, const char *star_cat, cpl_image **pweight2d, cpl_propertylist *qclist, cpl_table *spc_table, const char *dit_key)
Compute the sensitivity from an extracted spectrum.
int visir_parameterlist_get_int(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR integer parameter.
cpl_boolean visir_parameterlist_get_bool(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR boolean parameter.
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
void irplib_framelist_empty(irplib_framelist *self)
Erase all frames from a framelist.
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.
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.
const char * irplib_frameset_find_file(const cpl_frameset *self, const char *tag)
Find the filename with the given tag in a frame set.
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.