30#include <eris_pfits.h>
31#include "eris_ifu_sdp.h"
32#include "eris_ifu_dfs.h"
35#include <eris_utils.h>
36#include <eris_ifu_utils.h>
37#include <eris_ifu_wavecal_static.h>
53#define KEY_ASSON "ASSON"
54#define KEY_ASSON_COMMENT "Associated file name"
55#define KEY_ASSOC "ASSON"
56#define KEY_ASSOC_COMMENT "Associated file category"
57#define KEY_ASSOM "ASSOM"
58#define KEY_ASSOM_COMMENT "Associated file datamd5"
61#define KEY_DEC_COMMENT "[deg] Image center (J2000)"
62#define KEY_EXPTIME "EXPTIME"
63#define KEY_EXPTIME_COMMENT "[s] Total integration time per pixel"
64#define KEY_FLUXCAL "FLUXCAL"
65#define KEY_FLUXCAL_COMMENT "Type of flux calibration (ABSOLUTE or UNCALIBRATED)"
66#define KEY_FLUXCAL_VALUE_FALSE "UNCALIBRATED"
67#define KEY_FLUXCAL_VALUE_TRUE "ABSOLUTE"
68#define KEY_MJDOBS "MJD-OBS"
69#define KEY_MJDOBS_COMMENT "[d] Start of observations (days)"
70#define KEY_MJDEND "MJD-END"
71#define KEY_MJDEND_COMMENT "[d] End of observations (days)"
72#define KEY_OBID "OBID"
73#define KEY_OBID1 "OBID1"
74#define KEY_OBID_COMMENT "Observation block ID"
75#define KEY_OBSTECH "OBSTECH"
76#define KEY_OBSTECH_COMMENT "Technique for observation"
77#define KEY_PROCSOFT "PROCSOFT"
78#define KEY_PROCSOFT_COMMENT "ESO pipeline version"
79#define KEY_PRODCATG "PRODCATG"
80#define KEY_PRODCATG_COMMENT "Data product category"
81#define KEY_PRODCATG_VALUE_IFS_CUBE "SCIENCE.CUBE.IFS"
82#define KEY_PRODCATG_VALUE_FOV_IMAGE "ANCILLARY.IMAGE"
83#define KEY_PROG_ID "PROG_ID"
84#define KEY_PROG_ID_COMMENT "ESO programme identification"
85#define KEY_PROG_ID_VALUE_MULTIPLE "MULTI"
86#define KEY_PROGID "PROGID"
87#define KEY_PROGID_COMMENT KEY_PROG_ID_COMMENT
88#define KEY_PROV "PROV"
89#define KEY_PROV_COMMENT "Originating raw science file"
91#define KEY_RA_COMMENT "[deg] Image center (J2000)"
92#define KEY_REFERENC "REFERENC"
93#define KEY_REFERENC_COMMENT "Reference publication"
94#define KEY_TEXPTIME "TEXPTIME"
95#define KEY_TEXPTIME_COMMENT "[s] Total integration time of all exposures"
96#define KEY_WAVELMIN "WAVELMIN"
97#define KEY_WAVELMIN_COMMENT "[nm] Minimum wavelength"
98#define KEY_WAVELMAX "WAVELMAX"
99#define KEY_WAVELMAX_COMMENT "[nm] Maximum wavelength"
100#define KEY_SKY_RES "SKY_RES"
101#define KEY_SKY_RES_COMMENT "[arcsec] FWHM effective spatial resolution"
102#define KEY_SKY_RERR "SKY_RERR"
103#define KEY_SKY_RERR_COMMENT "[arcsec] Error of SKY_RES"
104#define KEY_SPEC_RES "SPEC_RES"
105#define KEY_SPEC_RES_COMMENT "Spectral resolving power at central wavelength"
106#define KEY_SPEC_ERR "CRDER3"
107#define KEY_SPEC_ERR_COMMENT "[angstrom] Random error in spectral coordinate"
108#define KEY_SPECSYS "SPECSYS"
109#define KEY_SPECSYS_COMMENT "Frame of reference for spectral coordinates."
110#define KEY_PIXNOISE "PIXNOISE"
111#define KEY_PIXNOISE_COMMENT "[erg.s**(-1).cm**(-2).angstrom**(-1)] pixel-to-pixel noise"
112#define KEY_ABMAGLIM "ABMAGLIM"
113#define KEY_ABMAGLIM_COMMENT "5-sigma magnitude limit for point sources"
114#define KEY_NCOMBINE "NCOMBINE"
115#define KEY_NCOMBINE_COMMENT "No. of combined raw science data files"
118#define CLEAN_KEYS_REGEXP \
119 "^(" KEY_MJDEND "|" \
123 KEY_PROGID "[0-9]+|" \
138 KEY_ASSON "[0-9]+" ")$"
172} eris_ifu_specres_lut_entry;
254static const double day2sec = 86400.0;
421eris_ifu_sdp_compute_fwhm(cpl_frameset* set)
423 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, 0);
425 cpl_frame* frm = NULL;
427 cpl_size kexposure = 0;
429 cpl_propertylist* phead;
432 frm = cpl_frameset_get_position(set, kexposure);
433 next = cpl_frame_get_nextensions(frm);
434 fname = cpl_frame_get_filename(frm);
435 phead = cpl_propertylist_load(fname, 0);
436 cpl_msg_info(cpl_func,
"fname: %s next: %lld",fname, next);
438 double IA_fwhm_corr = 0;
439 double IA_fwhm_corr_pix = 0;
444 asm_data = cpl_table_load(fname, 1, 0);
445 if(cpl_table_has_column(asm_data,
"IA_FWHM")) {
446 IA_fwhm = cpl_table_get_column_mean(asm_data,
"IA_FWHM");
447 }
else if (cpl_propertylist_has(phead,
"ESO TEL IA FWHM")) {
448 IA_fwhm = cpl_propertylist_get_double(phead,
"ESO TEL IA FWHM");
450 if(cpl_table_has_column(asm_data,
"DIMM_SEEING")) {
451 dimm = cpl_table_get_column_mean(asm_data,
"DIMM_SEEING");
453 double airm_start = 0;
456 if (cpl_propertylist_has(phead,
"ESO TEL AMBI FWHM START")) {
460 if (cpl_propertylist_has(phead,
"ESO TEL AMBI FWHM END")) {
464 if(airm_start > 0 && airm_end > 0) {
465 dimm = 0.5 * (airm_start + airm_end);
466 }
else if (airm_start > 0 && airm_end == 0) {
468 }
else if (airm_start > 0 && airm_end == 0) {
473 cpl_table_delete(asm_data);
476 eris_ifu_get_central_lambda(bandId, &lambda_c);
478 double pix_scale = 1;
480 case S25MAS: pix_scale = 0.025;
break;
481 case S100MAS:pix_scale = 0.100;
break;
482 case S250MAS:pix_scale = 0.250;
break;
484 cpl_msg_error(cpl_func,
"scale not found");
489 IA_fwhm_corr = IA_fwhm * pow((0.500/lambda_c), 0.2 );
490 IA_fwhm_corr_pix = IA_fwhm_corr / pix_scale;
491 cpl_msg_info(cpl_func,
"IA_fwhm_corr: %g",IA_fwhm_corr);
492 cpl_msg_info(cpl_func,
"IA_fwhm_corr_pix: %g",IA_fwhm_corr_pix);
493 double airmass = eris_pfits_get_airmass(phead);
495 double dimm_corr = dimm *
496 pow((0.500/lambda_c),0.2) *
497 pow(airmass,(3./5.)) *
499 (pow( (lambda_c / 1.e6), 0.4) *
500 (pow(airmass, -0.2) / pow(dimm, (1./3.)))
502 cpl_msg_info(cpl_func,
"dimm_corr: %g",dimm_corr);
503 double dimm_corr_pix = dimm_corr/pix_scale;
504 cpl_msg_info(cpl_func,
"dimm_corr_pix: %g",dimm_corr_pix);
507 cpl_propertylist_delete(phead);
540eris_ifu_sdp_compute_pixnoise(cpl_frameset* set) {
542 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, 0);
543 cpl_frame* frm = NULL;
545 cpl_error_code error_code = cpl_error_get_code();
546 cpl_error_set(cpl_func, error_code);
548 if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
549 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
550 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_MEAN_FLUXCAL)) {
551 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_MEAN_FLUXCAL);
552 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN)) {
553 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN);
554 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN)) {
555 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
556 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN)) {
557 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
558 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
559 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN);
562 const char* fname = cpl_frame_get_filename(frm);
563 cpl_msg_warning(cpl_func,
"fname: %s",fname);
564 cpl_image* data = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 1);
565 cpl_image* errs = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 2);
566 cpl_image* qual = cpl_image_load(fname, CPL_TYPE_INT, 0, 3);
568 cpl_mask* bpm = cpl_mask_threshold_image_create(qual, DBL_MIN, 0.9);
569 cpl_image_reject_from_mask(data, bpm);
570 cpl_mask_delete(bpm);
575 cpl_image_delete(data);
576 cpl_image_delete(errs);
577 cpl_image_delete(qual);
591 cpl_mask_delete(obj_mask);
621eris_ifu_sdp_get_obj_mean(cpl_frameset* set) {
623 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, NULL);
624 cpl_frame* frm = NULL;
626 cpl_error_code error_code = cpl_error_get_code();
627 cpl_error_set(cpl_func, error_code);
628 cpl_msg_warning(cpl_func,
"search input frame");
630 if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN)) {
631 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN);
632 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
633 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
634 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN)) {
635 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN);
636 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN)) {
637 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
638 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN)) {
639 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
640 }
else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
641 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN);
644 const char* fname = cpl_frame_get_filename(frm);
646 cpl_image* data = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 1);
647 cpl_image* errs = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 2);
648 cpl_image* qual = cpl_image_load(fname, CPL_TYPE_INT, 0, 3);
649 cpl_mask* bpm = cpl_mask_threshold_image_create(qual, DBL_MIN, 0.9);
651 cpl_image_set_bpm(data, bpm);
663 cpl_image_delete(data);
664 cpl_image_delete(errs);
665 cpl_image_delete(qual);
666 cpl_mask_delete(obj_mask);
694eris_ifu_sdp_compute_zp(ifsBand band)
714 case J_LOW: ZP = -23.564080671;
break;
715 case J_SHORT: ZP = -23.370149709;
break;
716 case J_MIDDLE: ZP = -23.575634864;
break;
717 case J_LONG: ZP = -23.746457445;
break;
718 case H_LOW: ZP = -23.764826331;
break;
719 case H_SHORT: ZP = -23.961968187;
break;
720 case H_MIDDLE: ZP = -24.238252577;
break;
721 case H_LONG: ZP = -24.396966217;
break;
722 case K_LOW: ZP = -24.89135131;
break;
723 case K_SHORT: ZP = -24.730943402;
break;
724 case K_MIDDLE: ZP = -24.8542167693;
break;
725 case K_LONG: ZP = -25.24818993;
break;
726 default: ZP = 2;
break;
761eris_ifu_sdp_compute_abmaglimit(
const double sky_rms,
const double fwhm,
766 double ZP = eris_ifu_sdp_compute_zp(band);
767 abmaglim = -2.5*log10(5. * fwhm * sky_rms * sqrt(CPL_MATH_PI) /
768 (2. * sqrt(log(4)))) - 2.5 * log10(2.) + ZP;
790eris_ifu_sdp_properties *
792 eris_ifu_sdp_properties *properties = cpl_calloc(1,
sizeof *properties);
816 cpl_array_delete(aProperties->obid);
817 cpl_array_delete(aProperties->progid);
818 cpl_propertylist_delete(aProperties->prov);
819 cpl_array_delete(aProperties->asson);
823 cpl_array_delete(aProperties->assoc);
824 cpl_free((
char *)aProperties->prodcatg);
826 cpl_free((
char *)aProperties->specsys);
827 cpl_free((
char *)aProperties->obstech);
828 cpl_free((
char *)aProperties->referenc);
830 cpl_free(aProperties);
853 const char *value = cpl_propertylist_get_string(aHeaders,
"ORIGFILE");
854 cpl_ensure(value, cpl_error_get_code(), NULL);
904eris_ifu_get_sdp_frames(cpl_frameset* set,
const cpl_parameterlist* parlist,
905 const char* recipe_name, eris_ifu_sdp_properties *properties,
906 cpl_frameset** raws_obj, cpl_frameset** raws_sky, cpl_frameset** pros_obj)
909 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
910 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
911 cpl_ensure(recipe_name != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
912 cpl_ensure(properties != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
914 char* param_name = cpl_sprintf(
"eris.%s.dar-corr", recipe_name);
915 cpl_boolean is_dar_cor =
916 cpl_parameter_get_bool(cpl_parameterlist_find_const(parlist, param_name));
917 cpl_free(param_name);
920 param_name = cpl_sprintf(
"eris.%s.sky_tweak", recipe_name);
922 cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, param_name));
923 cpl_free(param_name);
925 cpl_size nexposures = 0;
926 cpl_frame* frm = NULL;
929 if (strstr(recipe_name,
"jitter") != NULL) {
938 if(is_sky_tweak > 0) {
943 if(*pros_obj != NULL) {
946 if(NULL == (frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN))) {
947 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
950 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
953 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
957 if(is_sky_tweak > 0) {
958 if(NULL == (frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN))) {
959 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
962 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
965 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
972 if(*pros_obj != NULL) {
974 if(is_sky_tweak > 0) {
975 if(NULL == (frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN))) {
976 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN);
980 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
985 if(*pros_obj == NULL) {
989 nexposures = cpl_frameset_count_tags(*raws_obj, ERIS_IFU_RAW_OBJ);
990 }
else if (strstr(recipe_name,
"stdstar") != NULL) {
999 if(*pros_obj != NULL) {
1001 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
1003 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
1006 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1010 if(pros_obj != NULL) {
1012 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
1014 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
1017 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1021 if(*pros_obj != NULL) {
1023 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN);
1025 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN);
1028 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1031 nexposures = cpl_frameset_count_tags(*raws_obj, ERIS_IFU_RAW_STD_FLUX);
1037 properties->ncombine = nexposures;
1041 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_EXPOSURE_MAP);
1043 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1048 return cpl_error_get_code();
1091eris_ifu_sdp_properties *
1093 const cpl_parameterlist* parlist,
const char* recipe_name)
1096 cpl_ensure(aCube != NULL, CPL_ERROR_NULL_INPUT, NULL);
1097 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, NULL);
1098 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
1099 cpl_ensure(recipe_name != NULL, CPL_ERROR_NULL_INPUT, NULL);
1102 cpl_frameset* raws_obj = NULL;
1103 cpl_frameset* raws_sky = NULL;
1104 cpl_frameset* pros_obj = NULL;
1105 cpl_propertylist* header = aCube->header;
1110 properties->wlerror = 0.026;
1112 eris_ifu_get_sdp_frames(set, parlist, recipe_name, properties, &raws_obj,
1113 &raws_sky, &pros_obj);
1115 if(raws_sky != NULL) {
1116 cpl_frameset_join(pros_obj, raws_sky);
1118cpl_frameset_delete(raws_sky);
1119 cpl_size nexposures = properties->ncombine;
1122 properties->obid = cpl_array_new(nexposures, CPL_TYPE_LONG);
1123 properties->progid = cpl_array_new(nexposures, CPL_TYPE_STRING);
1125 cpl_msg_info(cpl_func,
"obid array size: %lld",
1126 cpl_array_get_size(properties->obid));
1128 cpl_msg_info(cpl_func,
"progid array size: %lld",
1129 cpl_array_get_size(properties->progid));
1131 properties->prov = cpl_propertylist_new();
1133 const char* fname = NULL;
1134 cpl_propertylist* phead = NULL;
1135 cpl_propertylist* pchead = NULL;
1140 properties->texptime = 0;
1141 double ia_fwhm_corr = 0;
1142 for(cpl_size kexposure = 0; kexposure < properties->ncombine; kexposure++) {
1144 frm = cpl_frameset_get_position(raws_obj, kexposure);
1145 fname = cpl_frame_get_filename(frm);
1146 phead = cpl_propertylist_load(fname, 0);
1151 cpl_msg_info(cpl_func,
"obid: %ld",obid);
1154 exptime = dit * ndit;
1158 double endtime = mjd + exptime / day2sec;
1160 properties->texptime += exptime;
1161 properties->mjd_end = CPL_MAX(endtime, properties->mjd_end);
1167 cpl_msg_info(cpl_func,
"compute FWHM");
1168 if (strstr(recipe_name,
"jitter") != NULL) {
1169 ia_fwhm_corr = eris_ifu_sdp_compute_fwhm(raws_obj);
1175 properties->skyres += ia_fwhm_corr;
1176 cpl_msg_info(cpl_func,
"compute exposure time");
1177 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_EXPOSURE_MAP);
1178 cpl_image* expt = cpl_image_load(cpl_frame_get_filename(frm),
1179 CPL_TYPE_DOUBLE, 0, 0);
1180 cpl_mask* bpm = cpl_image_get_bpm(expt);
1181 cpl_mask_threshold_image(bpm, expt, 0, DBL_MAX, CPL_BINARY_0);
1182 cpl_image_set_bpm(expt, bpm);
1183 properties->exptime = cpl_image_get_median(expt);
1184 cpl_image_delete(expt);
1187 cpl_array_set_long(properties->obid, kexposure, obid);
1189 cpl_array_set_string(properties->progid, kexposure, progid);
1193 unsigned int nraw = cpl_propertylist_get_size(properties->prov);
1204 char *name = cpl_sprintf(
"PROV%-u", ++nraw);
1205 cpl_propertylist_append_string(properties->prov, name, prov);
1208 unsigned int iraw = 1;
1211 char *name = cpl_sprintf(
"PROV%-u", ++nraw);
1212 cpl_propertylist_append_string(properties->prov, name, prov);
1218 cpl_propertylist_delete(phead);
1220 properties->skyres /= properties->ncombine;
1225 double abmaglim = 0.0;
1227 cpl_msg_info(cpl_func,
"compute abmaglim");
1229 double pixnoise = 1;
1231 pixnoise = eris_ifu_sdp_compute_pixnoise(pros_obj);
1233 properties->pixnoise = pixnoise;
1234 cpl_size nobj = cpl_frameset_get_size(raws_obj);
1235 cpl_frameset_delete(raws_obj);
1236 cpl_msg_info(cpl_func,
"obid array size: %lld",
1237 cpl_array_get_size(properties->obid));
1239 cpl_frame* wave_frm = cpl_frameset_find(set, ERIS_IFU_CALIB_WAVE_MAP);
1240 fname = cpl_frame_get_filename(wave_frm);
1241 phead = cpl_propertylist_load(fname, 0);
1245 cpl_propertylist_delete(phead);
1247 hdrl_image* hima_obj_mean = eris_ifu_sdp_get_obj_mean(pros_obj);
1251 double zp = eris_ifu_sdp_compute_zp(bandId);
1253 const cpl_size kernel_size_x = 3;
1254 const cpl_size kernel_size_y = 3;
1257 double histo_min = 0.;
1258 double histo_max = 0.;
1259 double bin_size = 0.;
1260 cpl_size error_niter = 0;
1261 hdrl_mode_type mode_method = HDRL_MODE_MEDIAN;
1268 histo_max, bin_size, mode_method, error_niter);
1271 HDRL_IMAGE_EXTEND_NEAREST, mode_parameter,&abmaglim);
1274 cpl_msg_info(cpl_func,
"HDRL computed abmaglim: %g", abmaglim);
1275 abmaglim = eris_ifu_sdp_compute_abmaglimit(pixnoise, ia_fwhm_corr, bandId);
1276 properties->abmaglimit = abmaglim;
1277 cpl_msg_info(cpl_func,
"LODO computed abmaglim: %g", abmaglim);
1281 properties->prodcatg = cpl_strdup(KEY_PRODCATG_VALUE_IFS_CUBE);
1282 properties->obstech = cpl_strdup(
"IFU");
1284 char *key = cpl_sprintf(
"ESO PRO REC1 PIPE ID");
1285 if(cpl_propertylist_has(header, key)) {
1286 properties->procsoft = cpl_propertylist_get_string(header, key);
1289 properties->referenc = NULL;
1290 if(cpl_propertylist_has(header, KEY_PROG_ID) ){
1291 cpl_propertylist_get_string(header, KEY_PROG_ID);
1293 properties->fluxcal = CPL_TRUE;
1296 cpl_size npros = cpl_frameset_get_size(pros_obj);
1298 properties->asson = cpl_array_new(npros, CPL_TYPE_STRING);
1299 cpl_size kstart = 0;
1302 properties->nobj = 1;
1305 for(cpl_size kexposure = kstart; kexposure < npros; kexposure++) {
1306 frm = cpl_frameset_get_position(pros_obj, kexposure);
1307 fname = cpl_frame_get_filename(frm);
1308 pchead = cpl_propertylist_load(fname, 0);
1309 cpl_array_set_string(properties->asson, kexposure,
1311 cpl_propertylist_delete(pchead);
1318 properties->specres = resol_med;
1319 properties->specsys = cpl_sprintf(
"TOPOCENT");
1323 if(cpl_propertylist_has(header,
"CRVAL3")) {
1324 properties->wlenrange[0] = cpl_propertylist_get_double(header,
"CRVAL3");
1328 if(cpl_propertylist_has(header,
"CD3_3")) {
1329 cd3_3 = cpl_propertylist_get_double(header,
"CD3_3");
1331 properties->wlenrange[1] = properties->wlenrange[0] + cd3_3 * (double)(naxis3 -1.);
1354 if (pros_obj) cpl_frameset_delete(pros_obj);
1366static int cmp_double_asc(
const void *p1,
const void *p2) {
1367 double d = (*(
const double *)p1 - *(
const double *)p2);
1368 return (d < 0)?-1:(d>0)?1:0;
1372static int cmp_double_desc(
const void *p1,
const void *p2) {
1373 double d = (*(
const double *)p1 - *(
const double *)p2);
1374 return (d < 0)?1:(d>0)?-1:0;
1378static int cmp_float_asc(
const void *p1,
const void *p2) {
1379 float d = (*(
const float *)p1 - *(
const float *)p2);
1380 return (d < 0)?-1:(d>0)?1:0;
1384static int cmp_float_desc(
const void *p1,
const void *p2) {
1385 float d = (*(
const float *)p1 - *(
const float *)p2);
1386 return (d < 0)?1:(d>0)?-1:0;
1390static int cmp_int_asc(
const void *p1,
const void *p2) {
1391 return (*(
const int *)p1 - *(
const int *)p2);
1395static int cmp_int_desc(
const void *p1,
const void *p2) {
1396 return (*(
const int *)p2 - *(
const int *)p1);
1400static int cmp_long_asc(
const void *p1,
const void *p2) {
1401 return (*(
const long *)p1 - *(
const long *)p2);
1405static int cmp_long_desc(
const void *p1,
const void *p2) {
1406 return (*(
const long *)p2 - *(
const long *)p1);
1410static int cmp_string_asc(
const void *p1,
const void *p2) {
1411 return strcmp(*(
const char **)p1, *(
const char **)p2);
1415static int cmp_string_desc(
const void *p1,
const void *p2) {
1416 return strcmp(*(
const char **)p2, *(
const char **)p1);
1442 cpl_ensure_code(aArray != NULL, CPL_ERROR_NULL_INPUT);
1443 cpl_ensure_code(!cpl_array_has_invalid(aArray), CPL_ERROR_NULL_INPUT);
1445 cpl_size n = cpl_array_get_size(aArray);
1446 if (cpl_array_get_type(aArray) == CPL_TYPE_DOUBLE) {
1447 double *d = cpl_array_get_data_double(aArray);
1448 qsort(d, n,
sizeof(
double), (aOrder)?cmp_double_asc:cmp_double_desc);
1449 return CPL_ERROR_NONE;
1450 }
else if (cpl_array_get_type(aArray) == CPL_TYPE_FLOAT) {
1451 float *d = cpl_array_get_data_float(aArray);
1452 qsort(d, n,
sizeof(
float), (aOrder)?cmp_float_asc:cmp_float_desc);
1453 return CPL_ERROR_NONE;
1454 }
else if (cpl_array_get_type(aArray) == CPL_TYPE_INT) {
1455 int *d = cpl_array_get_data_int(aArray);
1456 qsort(d, n,
sizeof(
int), (aOrder)?cmp_int_asc:cmp_int_desc);
1457 return CPL_ERROR_NONE;
1458 }
else if (cpl_array_get_type(aArray) == CPL_TYPE_LONG) {
1459 long *d = cpl_array_get_data_long(aArray);
1460 qsort(d, n,
sizeof(
long), (aOrder)?cmp_long_asc:cmp_long_desc);
1461 return CPL_ERROR_NONE;
1462 }
else if (cpl_array_get_type(aArray) == CPL_TYPE_STRING) {
1463 char **d = cpl_array_get_data_string(aArray);
1464 qsort(d, n,
sizeof(
char *), (aOrder)?cmp_string_asc:cmp_string_desc);
1465 return CPL_ERROR_NONE;
1467 return CPL_ERROR_ILLEGAL_INPUT;
1510 const eris_ifu_sdp_properties *aProperties)
1512 cpl_ensure(aHeader && aProperties, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
1515 cpl_ensure(cpl_array_get_size(aProperties->obid) == aProperties->ncombine,
1516 CPL_ERROR_ILLEGAL_INPUT, CPL_ERROR_ILLEGAL_INPUT);
1518 cpl_ensure(cpl_array_get_size(aProperties->progid) == aProperties->ncombine,
1519 CPL_ERROR_ILLEGAL_INPUT, CPL_ERROR_ILLEGAL_INPUT);
1520 cpl_ensure(cpl_propertylist_get_size(aProperties->prov) >= aProperties->ncombine,
1521 CPL_ERROR_ILLEGAL_INPUT, CPL_ERROR_ILLEGAL_INPUT);
1524 cpl_propertylist_erase_regexp(aHeader, CLEAN_KEYS_REGEXP, 0);
1526 cpl_propertylist_update_double(aHeader, KEY_RA, aProperties->fovcenter[0]);
1527 cpl_propertylist_set_comment(aHeader, KEY_RA, KEY_RA_COMMENT);
1528 cpl_propertylist_update_double(aHeader, KEY_DEC, aProperties->fovcenter[1]);
1529 cpl_propertylist_set_comment(aHeader, KEY_DEC, KEY_DEC_COMMENT);
1530 cpl_propertylist_update_double(aHeader, KEY_EXPTIME, aProperties->exptime);
1531 cpl_propertylist_set_comment(aHeader, KEY_EXPTIME, KEY_EXPTIME_COMMENT);
1533 cpl_propertylist_insert_after_double(aHeader, KEY_EXPTIME,
1534 KEY_TEXPTIME, aProperties->texptime);
1535 cpl_propertylist_set_comment(aHeader, KEY_TEXPTIME, KEY_TEXPTIME_COMMENT);
1537 cpl_propertylist_insert_after_int(aHeader, KEY_TEXPTIME,
1538 KEY_NCOMBINE, aProperties->ncombine);
1539 cpl_propertylist_set_comment(aHeader, KEY_NCOMBINE, KEY_NCOMBINE_COMMENT);
1541 cpl_propertylist_set_comment(aHeader, KEY_MJDOBS, KEY_MJDOBS_COMMENT);
1542 cpl_propertylist_insert_after_double(aHeader, KEY_MJDOBS,
1543 KEY_MJDEND, aProperties->mjd_end);
1544 cpl_propertylist_set_comment(aHeader, KEY_MJDEND, KEY_MJDEND_COMMENT);
1547 cpl_array *obids = cpl_array_duplicate(aProperties->obid);
1552 long obid = cpl_array_get_long(obids, 0, NULL);
1553 cpl_msg_warning(cpl_func,
"obid: %ld",obid);
1554 cpl_propertylist_update_long(aHeader, KEY_OBID1, obid);
1555 cpl_propertylist_set_comment(aHeader, KEY_OBID1, KEY_OBID_COMMENT);
1557 if (aProperties->ncombine > 1) {
1558 unsigned int ik = 1;
1560 for (idx = 1; idx < aProperties->ncombine; ++idx) {
1561 long _obid = cpl_array_get_long(obids, idx, NULL);
1562 if (_obid != obid) {
1563 char *key = cpl_sprintf(KEY_OBID
"%-u", ++ik);
1564 cpl_propertylist_update_long(aHeader, key, _obid);
1565 cpl_propertylist_set_comment(aHeader, key, KEY_OBID_COMMENT);
1571 cpl_array_delete(obids);
1578 if(aProperties->progid != NULL) {
1580 cpl_array *progids = cpl_array_duplicate(aProperties->progid);
1585 const char *progid = cpl_array_get_string(progids, 0);
1587 if (aProperties->ncombine > 1) {
1588 unsigned int nprogid = 1;
1590 for (idx = 1; idx < aProperties->ncombine; ++idx) {
1591 const char *_progid = cpl_array_get_string(progids, idx);
1592 if (strcmp(_progid, progid) != 0) {
1598 progid = cpl_array_get_string(progids, 0);
1600 cpl_propertylist_update_string(aHeader, KEY_PROG_ID, progid);
1602 cpl_propertylist_update_string(aHeader, KEY_PROG_ID,
1603 KEY_PROG_ID_VALUE_MULTIPLE);
1604 cpl_propertylist_update_string(aHeader, KEY_PROGID
"1", progid);
1605 cpl_propertylist_set_comment(aHeader, KEY_PROGID
"1", KEY_PROGID_COMMENT);
1607 unsigned int ik = 1;
1608 for (idx = 1; idx < aProperties->ncombine; ++idx) {
1609 const char *_progid = cpl_array_get_string(progids, idx);
1610 if (strcmp(_progid, progid) != 0) {
1611 char *key = cpl_sprintf(KEY_PROGID
"%-u", ++ik);
1612 cpl_propertylist_update_string(aHeader, key, _progid);
1613 cpl_propertylist_set_comment(aHeader, key, KEY_PROGID_COMMENT);
1619 cpl_propertylist_set_comment(aHeader, KEY_PROG_ID, KEY_PROG_ID_COMMENT);
1622 cpl_propertylist_update_string(aHeader, KEY_PROG_ID, progid);
1623 cpl_propertylist_set_comment(aHeader, KEY_PROG_ID, KEY_PROG_ID_COMMENT);
1625 cpl_array_delete(progids);
1630 cpl_propertylist_append(aHeader, aProperties->prov);
1634 cpl_size idx_start = 0;
1635 if(aProperties->nobj == 1) {
1639 for (cpl_size idx = idx_start; idx < cpl_array_get_size(aProperties->asson); ++idx) {
1640 char *name = cpl_sprintf(KEY_ASSON
"%-" CPL_SIZE_FORMAT, idx - idx_start + 1 );
1641 cpl_propertylist_update_string(aHeader, name,
1642 cpl_array_get_string(aProperties->asson, idx));
1647 cpl_propertylist_update_string(aHeader, KEY_PRODCATG, aProperties->prodcatg);
1648 cpl_propertylist_set_comment(aHeader, KEY_PRODCATG, KEY_PRODCATG_COMMENT);
1650 cpl_propertylist_update_string(aHeader, KEY_PROCSOFT, aProperties->procsoft);
1651 cpl_propertylist_set_comment(aHeader, KEY_PROCSOFT, KEY_PROCSOFT_COMMENT);
1653 cpl_propertylist_update_string(aHeader, KEY_OBSTECH, aProperties->obstech);
1654 cpl_propertylist_set_comment(aHeader, KEY_OBSTECH, KEY_OBSTECH_COMMENT);
1656 const char *fluxcal = KEY_FLUXCAL_VALUE_TRUE;
1657 if (aProperties->fluxcal == CPL_FALSE) {
1658 fluxcal = KEY_FLUXCAL_VALUE_FALSE;
1661 cpl_propertylist_update_string(aHeader, KEY_FLUXCAL, fluxcal);
1662 cpl_propertylist_set_comment(aHeader, KEY_FLUXCAL, KEY_FLUXCAL_COMMENT);
1663 double um2nm = 1000.;
1664 cpl_propertylist_insert_after_double(aHeader, KEY_FLUXCAL, KEY_WAVELMIN,
1665 aProperties->wlenrange[0] * um2nm);
1666 cpl_propertylist_set_comment(aHeader, KEY_WAVELMIN, KEY_WAVELMIN_COMMENT);
1667 cpl_propertylist_insert_after_double(aHeader, KEY_WAVELMIN, KEY_WAVELMAX,
1668 aProperties->wlenrange[1] * um2nm);
1669 cpl_propertylist_set_comment(aHeader, KEY_WAVELMAX, KEY_WAVELMAX_COMMENT);
1670 cpl_propertylist_insert_after_double(aHeader, KEY_WAVELMAX, KEY_SPEC_RES,
1671 aProperties->specres);
1672 cpl_propertylist_set_comment(aHeader, KEY_SPEC_RES, KEY_SPEC_RES_COMMENT);
1673 cpl_propertylist_insert_after_string(aHeader, KEY_SPEC_RES, KEY_SPECSYS,
1674 aProperties->specsys);
1675 cpl_propertylist_set_comment(aHeader, KEY_SPECSYS, KEY_SPECSYS_COMMENT);
1682 cpl_propertylist_insert_after_double(aHeader, KEY_SPEC_RES, KEY_SKY_RES,
1683 fabs(aProperties->skyres));
1685 const char *method_qualifier = (aProperties->skyres < 0.) ?
1686 "default" :
"measured";
1687 char *comment = cpl_sprintf(KEY_SKY_RES_COMMENT
" (%s)", method_qualifier);
1688 cpl_propertylist_set_comment(aHeader, KEY_SKY_RES, comment);
1699 cpl_propertylist_insert_after_double(aHeader, KEY_SKY_RES, KEY_PIXNOISE,
1700 aProperties->pixnoise);
1701 cpl_propertylist_set_comment(aHeader, KEY_PIXNOISE, KEY_PIXNOISE_COMMENT);
1704 cpl_propertylist_insert_after_double(aHeader, KEY_WAVELMAX, KEY_ABMAGLIM,
1705 aProperties->abmaglimit);
1706 cpl_propertylist_set_comment(aHeader, KEY_ABMAGLIM, KEY_ABMAGLIM_COMMENT);
1708 const char *reference =
"";
1709 if (aProperties->referenc) {
1710 reference = aProperties->referenc;
1712 cpl_propertylist_update_string(aHeader, KEY_REFERENC, reference);
1713 cpl_propertylist_set_comment(aHeader, KEY_REFERENC, KEY_REFERENC_COMMENT);
1752 return CPL_ERROR_NONE;
ifsPreopticsScale eris_ifu_get_preopticsScale(cpl_propertylist *header)
Return the the pre-optics scaling.
ifsBand eris_ifu_get_band(const cpl_propertylist *header)
Determine preoptic band.
eris_ifu_sdp_properties * eris_ifu_sdp_properties_new(void)
Allocate and initialize new SDP properties structure.
const char * eris_ifu_pfits_get_origfile(const cpl_propertylist *aHeaders)
Get ORIGFILE keyword value from FITS header.
cpl_error_code eris_ifu_cplarray_sort(cpl_array *aArray, cpl_boolean aOrder)
Sort CPL array in place using quicksort.
eris_ifu_sdp_properties * eris_ifu_sdp_properties_collect(hdrl_resample_result *aCube, cpl_frameset *set, const cpl_parameterlist *parlist, const char *recipe_name)
Collect all SDP metadata from cube, frameset, and parameters.
void eris_ifu_sdp_properties_delete(eris_ifu_sdp_properties *aProperties)
Free SDP properties structure and all contained data.
cpl_error_code eris_ifu_sdp_properties_update(cpl_propertylist *aHeader, const eris_ifu_sdp_properties *aProperties)
Update FITS header with ESO Science Data Product keywords.
cpl_error_code eris_ifu_mask_nans_in_hdrlimage(hdrl_image **hima)
Flag NaNs in HDRL image.
double eris_ifu_get_band_resolution(ifsBand band)
Get nominal spectral resolution for a given band.
cpl_mask * eris_ifu_hima_get_obj_mask(hdrl_image *hima, const cpl_size niter, const double kappa)
find mask flagging pixels above a threshold set by ks-clip algorithm
double eris_pfits_get_mjdobs(const cpl_propertylist *aHeaders)
find out the Julian Date of the observation
const char * eris_pfits_get_raw_filename(const cpl_propertylist *aHeaders, unsigned int idx)
find out the i-th raw file name.
const char * eris_pfits_get_arcfile(const cpl_propertylist *plist)
find out the arcfile
double eris_pfits_get_fwhm_start(const cpl_propertylist *aHeaders)
find out the ambient seeing at start of exposure (in arcsec)
double eris_pfits_get_fwhm_end(const cpl_propertylist *aHeaders)
find out the ambient seeing at end of exposure (in arcsec)
const char * eris_pfits_get_pipefile(const cpl_propertylist *aHeaders)
find out the PIPEFILE id
int eris_pfits_get_ndit(const cpl_propertylist *plist)
find out the DIT value
const char * eris_pfits_get_ancestor(const cpl_propertylist *aHeaders)
find out the ancestor of a file.
const char * eris_pfits_get_progid(const cpl_propertylist *aHeaders)
find out the ESO program identification
long eris_pfits_get_obsid(const cpl_propertylist *aHeaders)
find out the observation block id
double eris_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
cpl_frameset * eris_dfs_extract_frames_with_tag(cpl_frameset *input, const char *rtag)
Extract frames of user given tag.
hdrl_parameter * hdrl_collapse_mode_parameter_create(double histo_min, double histo_max, double bin_size, hdrl_mode_type mode_method, cpl_size error_niter)
create a parameter object for the mode
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
double hdrl_image_get_stdev(const hdrl_image *self)
computes the standard deviation of the data of an image
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
cpl_error_code hdrl_maglim_compute(const cpl_image *image, const double zeropoint, const double fwhm, const cpl_size kernel_size_x, const cpl_size kernel_size_y, const hdrl_image_extend_method image_extend_method, const hdrl_parameter *mode_parameter, double *limiting_magnitude)
Computes the limiting magnitude of an image.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter