31#include <gsl/gsl_math.h>
32#include <gsl/gsl_interp2d.h>
33#include <gsl/gsl_spline2d.h>
35#include "eris_ifu_error.h"
36#include "eris_ifu_utils.h"
37#include "eris_ifu_functions.h"
38#include "eris_ifu_dfs.h"
39#include "eris_ifu_extract_spec_static.h"
40#include "eris_ifu_jitter_static.h"
41#include "eris_ifu_wavecal_static.h"
42#include "eris_ifu_distortion_static.h"
43#include "eris_ifu_lambda_corr.h"
44#include "eris_ifu_sky_tweak.h"
45#include "eris_ifu_efficiency_response.h"
46#include "eris_ifu_lambda_corr.h"
47#include "eris_utils.h"
48#include "eris_pfits.h"
49#include "skycorr/eris_ifu_skycorr.h"
133#define ERIS_IFU_SKIP_SKY_CORR_PLANES 75
157 if(sof_struct != NULL) {
158 if(sof_struct->exposureTable != NULL) {
159 for(cpl_size i = 0; i < sof_struct->exposureTableCnt; i++) {
160 if (sof_struct->exposureTable != NULL) {
162 if(sof_struct->exposureTable[i].frame != NULL) {
165 if(sof_struct->exposureTable[i].hdr != NULL) {
166 cpl_propertylist_delete(sof_struct->exposureTable[i].hdr);
168 if(sof_struct->exposureTable[i].rawImage != NULL) {
171 if(sof_struct->exposureTable[i].cube != NULL){
174 if(sof_struct->exposureTable[i].cubeBpm != NULL){
175 cpl_imagelist_delete(sof_struct->exposureTable[i].cubeBpm);
177 if(sof_struct->exposureTable[i].cubeHdr != NULL) {
178 cpl_propertylist_delete(sof_struct->exposureTable[i].cubeHdr);
180 if(sof_struct->exposureTable[i].badPixelMask != NULL) {
181 cpl_mask_delete(sof_struct->exposureTable[i].badPixelMask);
183 if(sof_struct->exposureTable[i].darkSubtrImage != NULL){
186 if(sof_struct->exposureTable[i].skySubtrImage != NULL){
196 if(sof_struct->waveMap != NULL) cpl_image_delete(sof_struct->waveMap);
197 if(sof_struct->badPixelMask != NULL) cpl_mask_delete(sof_struct->badPixelMask);
198 if(sof_struct->distortion != NULL) {
199 for (
int sx = 0; sx < SLITLET_CNT; sx++) {
200 cpl_polynomial_delete(sof_struct->distortion[sx]);
202 cpl_free(sof_struct->distortion);
204 if(sof_struct->dqi != NULL) {
205 cpl_image_delete(sof_struct->dqi);
207 if(sof_struct->oh_ref_peaks != NULL) cpl_vector_delete(sof_struct->oh_ref_peaks);
208 if(sof_struct->oh_ref_frame != NULL) cpl_frame_delete(sof_struct->oh_ref_frame);
209 if(sof_struct->borders != NULL) cpl_table_delete(sof_struct->borders);
210 if(sof_struct->poly_u != NULL) cpl_polynomial_delete(sof_struct->poly_u);
211 if(sof_struct->poly_v != NULL) cpl_polynomial_delete(sof_struct->poly_v);
212 if(sof_struct->distances != NULL) cpl_vector_delete(sof_struct->distances);
213 if(sof_struct->positions != NULL) cpl_bivector_delete(sof_struct->positions);
235 cpl_msg_info(cpl_func,
"type: OBJECT_CUBE");
238 cpl_msg_info(cpl_func,
"type: STD_CUBE");
241 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE");
243 case STD_CUBE_NOFLAT:
244 cpl_msg_info(cpl_func,
"type: STD_CUBE_NOFLAT");
246 case STD_FLUX_CUBE_NOFLAT:
247 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE_NOFLAT");
250 cpl_msg_info(cpl_func,
"type: PSF_CUBE");
252 case SKY_OBJECT_CUBE:
253 cpl_msg_info(cpl_func,
"type: SKY_OBJECT_CUBE");
256 cpl_msg_info(cpl_func,
"type: SKY_STD_CUBE");
258 case SKY_STD_FLUX_CUBE:
259 cpl_msg_info(cpl_func,
"type: SKY_STD_FLUX_CUBE");
262 cpl_msg_info(cpl_func,
"type: SKY_PSF_CUBE");
265 cpl_msg_info(cpl_func,
"type: TWEAKED_CUBE");
268 cpl_msg_info(cpl_func,
"type: DAR_CUBE");
271 cpl_msg_info(cpl_func,
"type: JITTER_CUBE");
274 cpl_msg_info(cpl_func,
"type: BPM_CUBE");
276 case OBJECT_CUBE_COADD:
277 cpl_msg_info(cpl_func,
"type: OBJECT_CUBE_COADD");
280 cpl_msg_info(cpl_func,
"type: STD_CUBE_COADD");
283 cpl_msg_info(cpl_func,
"type: PSF_CUBE_COADD");
285 case STD_FLUX_CUBE_COADD:
286 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE_COADD");
288 case DAR_STD_FLUX_CUBE:
289 cpl_msg_info(cpl_func,
"type: DAR_STD_FLUX_CUBE");
291 case TWEAKED_CUBE_COADD:
292 cpl_msg_info(cpl_func,
"type: TWEAKED_CUBE_COADD");
295 cpl_msg_info(cpl_func,
"type: DAR_CUBE_COADD");
297 case STD_FLUX_CUBE_COADD_NOFLAT:
298 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE_COADD_NOFLAT");
300 case STD_CUBE_COADD_NOFLAT:
301 cpl_msg_info(cpl_func,
"type: STD_CUBE_COADD_NOFLAT");
304 cpl_msg_info(cpl_func,
"type: DEFAULT %d",type);
329 coadd_type = OBJECT_CUBE_COADD;
331 case OBJECT_CUBE_COADD:
332 coadd_type = OBJECT_CUBE_COADD;
335 coadd_type = DAR_CUBE_COADD;
338 coadd_type = STD_CUBE_COADD;
341 coadd_type = STD_CUBE_COADD;
344 coadd_type = STD_FLUX_CUBE_COADD;
346 case STD_FLUX_CUBE_COADD:
347 coadd_type = STD_FLUX_CUBE_COADD;
349 case STD_FLUX_CUBE_COADD_NOFLAT:
350 coadd_type = STD_FLUX_CUBE_COADD_NOFLAT;
352 case STD_CUBE_NOFLAT:
353 coadd_type = STD_CUBE_COADD_NOFLAT;
355 case STD_CUBE_COADD_NOFLAT:
356 coadd_type = STD_CUBE_COADD_NOFLAT;
359 coadd_type = PSF_CUBE_COADD;
362 coadd_type = DAR_CUBE_COADD;
364 case DAR_STD_CUBE_COADD:
365 coadd_type = STD_CUBE_COADD;
367 case TWEAKED_CUBE_COADD:
368 coadd_type = TWEAKED_CUBE_COADD;
371 cpl_msg_warning(cpl_func,
"case %d not found switch to default case",type);
372 coadd_type = OBJECT_CUBE_COADD;
407 type = STD_FLUX_CUBE;
442 type = SKY_OBJECT_CUBE;
448 type = SKY_STD_FLUX_CUBE;
454 type = SKY_OBJECT_CUBE;
490eris_ifu_jitter_save_cpl_cube(
491 cpl_frameset *allframes,
492 cpl_frameset *usedframes,
494 const cpl_parameterlist * parlist,
496 hdrl_imagelist *hdrlCube,
497 cpl_imagelist *bpmCube,
498 cpl_propertylist *hdr,
499 struct paramStruct params,
502 const char* recipe_name)
504 cpl_error_code retVal = CPL_ERROR_NONE;
505 char *proCatg = NULL;
506 char *filenamePrefix = NULL;
507 char *filename = NULL;
511 ASSURE(cube != NULL || hdrlCube != NULL,
512 CPL_ERROR_ILLEGAL_INPUT,
"One of cube or hdrlCube must be not NULL");
513 ASSURE(!(cube != NULL && hdrlCube != NULL),
514 CPL_ERROR_ILLEGAL_INPUT,
"One of cube or hdrlCube must be NULL");
518 filename = cpl_sprintf(
"%s_%s_%3.3d.fits", recipe_name, filenamePrefix, counter);
520 filename = cpl_sprintf(
"%s_%s.fits", recipe_name, filenamePrefix);
522 cpl_propertylist_erase(hdr,
"RADECSYS");
533 if (bpmCube != NULL) {
534 cpl_imagelist_save(bpmCube, filename, CPL_TYPE_INT,
539 cpl_imagelist *datacube = cpl_imagelist_new();
540 cpl_imagelist *errorcube = cpl_imagelist_new();
541 cpl_propertylist *applist = NULL;
544 applist = cpl_propertylist_duplicate(hdr);
545 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG, proCatg);
548 cpl_propertylist_update_string(applist, CPL_DFS_PRO_TYPE,
"CUBE");
549 cpl_propertylist_update_string(applist, CPL_DFS_PRO_TECH,
"CUBE");
553 cpl_imagelist *bpmMaskZero;
555 bpmCube, params.bpmThreshold);
587 cpl_imagelist_delete(datacube);
588 cpl_imagelist_delete(errorcube);
589 cpl_propertylist_delete(applist);
590 cpl_imagelist_delete(bpmMaskZero);
595 retVal = cpl_error_get_code();
622eris_ifu_frameset_extract_obj_set(
const cpl_frameset* set,
struct sofStruct* sof,
626 cpl_ensure(set, CPL_ERROR_NULL_INPUT, NULL);
627 cpl_ensure(sof, CPL_ERROR_NULL_INPUT, NULL);
628 cpl_ensure(ix >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
631 cpl_frameset * obj_set = NULL;
632 cpl_frameset * sky_set = NULL;
633 cpl_frameset * cdb_set = NULL;
634 cpl_frameset * out_set = NULL;
637 obj_set = cpl_frameset_new();
642 sky_set = cpl_frameset_new();
647 cdb_set = cpl_frameset_new();
651 cpl_frame* frame = sof->exposureTable[ix].frame;
655 out_set = cpl_frameset_new();
656 cpl_frameset_insert(out_set, cpl_frame_duplicate(frame));
657 cpl_frameset_join(out_set, sky_set);
658 cpl_frameset_join(out_set, cdb_set);
662 cpl_frameset_delete(obj_set);
663 cpl_frameset_delete(sky_set);
664 cpl_frameset_delete(cdb_set);
705 struct stdParamStruct stdParams,
706 struct paramStruct params,
707 cpl_frameset *frameset,
708 const cpl_parameterlist * parlist,
709 const char* recipe_name,
712 cpl_error_code retVal = CPL_ERROR_NONE;
713 hdrl_image *objImg = NULL;
714 hdrl_image *tmpImg = NULL;
715 struct exposureEntry *objEntry;
716 cpl_polynomial *ohLambdaCorrection = NULL;
717 productDepthType productDepth = stdParams.productDepth;
718 bool doOHbasedLambdaCorrection = FALSE;
719 cubeType type = OBJECT_CUBE;
720 const char *expType = NULL;
722 double centralLambda = 0.0;
728 cpl_msg_info(cpl_func,
"Build OBJ and SKY data cubes, may correct wavecal by OH lines, subtract sky background");
730 if ((sof->oh_ref_frame != NULL) && !params.skip_oh_align && !(isSky && params.skip_sky_oh_align)) {
731 doOHbasedLambdaCorrection = TRUE;
733 doOHbasedLambdaCorrection = FALSE;
735 cpl_msg_debug(cpl_func,
"doOHbasedLambdaCorrection: %d, isSky: %d, "
736 "params.skip_sky_oh_align: %d, params.skip_oh_align: %d",
737 doOHbasedLambdaCorrection, isSky,
738 params.skip_sky_oh_align, params.skip_oh_align);
740 if (getenv(
"USE_OCS") != NULL) {
744 for (
int ix=0; ix < sof->exposureTableCnt; ix++) {
745 if (sof->exposureTable[ix].isObject) {
754 cpl_msg_info(__func__,
"Process exposure #\%3.3d %s %s", ix, expType,
755 cpl_frame_get_filename(sof->exposureTable[ix].frame));
757 objEntry = &sof->exposureTable[ix];
758 objImg = objEntry->rawImage;
763 objImg, ix, sof, params,
false,
764 ohLambdaCorrection, productDepth));
769 if (doOHbasedLambdaCorrection) {
776 char* param_name = cpl_sprintf(
"%s.oh_align_poly_order", context);
777 cpl_msg_info(cpl_func,
"pname: %s",param_name);
778 pfit_order = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, param_name));
779 cpl_free(param_name);
783 objEntry->cube, objEntry->cubeHdr, sof->oh_ref_peaks, pfit_order));
785 cdelt = cpl_propertylist_get_double(objEntry->cubeHdr,
"CDELT3");
786 centralLambda = cpl_propertylist_get_double(
787 objEntry->cubeHdr,
"CRVAL3") +
789 shift = cpl_polynomial_eval_1d(
790 ohLambdaCorrection, centralLambda, NULL);
791 cpl_msg_info(__func__,
792 "Overall shift of wavelength due OH lambda correction: %f [micron] %f [pixel]",
798 params.skyTweak, ix, sof, productDepth);
801 tmpImg, ix, sof, params,
true,
802 ohLambdaCorrection, productDepth);
807 objEntry->cubeHdr,
"LAMBDA SHIFT UM", shift,
808 "[um] OH based lambda shift"));
810 objEntry->cubeHdr,
"LAMBDA SHIFT PIXEL", shift/cdelt,
811 "[px] OH based lambda shift"));
813 if (params.skip_oh_align && (ix == 0)) {
814 cpl_msg_warning(cpl_func,
" |------------------------------------------------------|");
815 cpl_msg_warning(cpl_func,
" | WARNING: with parameter --sky_oh_align the spectral |");
816 cpl_msg_warning(cpl_func,
" | calibration of the outputs is expected to |");
817 cpl_msg_warning(cpl_func,
" | be off for several pixels due to flexure of |");
818 cpl_msg_warning(cpl_func,
" | the instrument |");
819 cpl_msg_warning(cpl_func,
" |------------------------------------------------------|");
823 if (productDepth >= PD_AUXILLIARY) {
847 cpl_frameset* obj_set =
848 eris_ifu_frameset_extract_obj_set(frameset, sof, ix);
849 eris_ifu_jitter_save_cpl_cube(frameset, obj_set, objEntry->frame, parlist,
850 NULL, objEntry->cube, objEntry->cubeBpm, objEntry->cubeHdr, params, type, ix, recipe_name);
851 eris_ifu_jitter_save_cpl_cube(frameset, obj_set, objEntry->frame, parlist,
852 objEntry->cubeBpm, NULL, NULL, objEntry->cubeHdr, params, BPM_CUBE, ix, recipe_name);
853 cpl_frameset_delete(obj_set);
857 cpl_boolean chop_nan = CPL_FALSE;
858 char* param_name = cpl_sprintf(
"%s.chop-nan", context);
860 chop_nan = cpl_parameter_get_bool(
861 cpl_parameterlist_find_const(parlist, param_name));
862 cpl_free(param_name);
871 &(objEntry->cubeBpm), objEntry->cubeHdr);
882 retVal = cpl_error_get_code();
913eris_ifu_jitter_skycorr_from_mask(
struct exposureEntry *objEntry,
914 const cpl_mask*mask_obj,
const int sky_est_method)
924 hdrl_value sky = {0, 0};
925 for (cpl_size zx = skip; zx < size_z - skip; zx++){
934 if(sky_est_method==0) {
948 if(cpl_error_get_code() != CPL_ERROR_NONE) {
950 cpl_msg_error(cpl_func,
"Error found in eris_ifu_jitter_skycorr_from_mask. Exit!");
955 return cpl_error_get_code();
983eris_ifu_jitter_get_split_param_int(
const cpl_parameterlist * parlist,
984 const char* pname,
const int min_x,
const int min_y,
985 const int max_x,
const int max_y,
int* px,
int* py)
988 const cpl_parameter* par = NULL;
990 const char* context =
"eris.eris_ifu_jitter";
992 const char* pname_string_value;
993 param_name = cpl_sprintf(
"%s.%s", context, pname);
994 par = cpl_parameterlist_find_const(parlist, param_name);
995 pname_string_value = cpl_parameter_get_string(par);
996 cpl_free(param_name);
1001 nFields = sscanf(pname_string_value,
"%d,%d%n", px, py, &end);
1003 if (nFields != 2 || end != strlen(pname_string_value)) {
1004 cpl_msg_error(cpl_func,
"The %s parameter must be "
1005 "a list of two integers separated by a comma", pname);
1006 printf(
"Error reading sky-box-center string\n");
1010 cpl_msg_warning(cpl_func,
"%s_x: %d set it to 0",pname, *px);
1014 cpl_msg_warning(cpl_func,
"%s_y: %d set it to 0",pname, *py);
1018 cpl_msg_warning(cpl_func,
"%s_x: %d set it to 10",pname, *px);
1022 cpl_msg_warning(cpl_func,
"%s_y: %d set it to 10", pname, *py);
1030 return cpl_error_get_code();
1063static cpl_error_code
1064eris_ifu_jitter_skycor_from_box(
const cpl_parameterlist * parlist,
1065 struct exposureEntry *objEntry,
const int aj_method)
1068 int sky_box_center_x, sky_box_center_y,
1069 sky_box_width_x, sky_box_width_y,
1070 sky_box_edges_margin_x, sky_box_edges_margin_y;
1072 eris_ifu_jitter_get_split_param_int(parlist,
"sky-box-center", 0, 0, 64, 64,
1073 &sky_box_center_x, &sky_box_center_y);
1074 eris_ifu_jitter_get_split_param_int(parlist,
"sky-box-width", 0, 0, 10, 10,
1075 &sky_box_width_x, &sky_box_width_y);
1076 eris_ifu_jitter_get_split_param_int(parlist,
"sky-box-edges-margin", 0, 0, 10, 10,
1077 &sky_box_edges_margin_x, &sky_box_edges_margin_y);
1080 cpl_msg_info(cpl_func,
"sky_box_center_x: %d sky_box_center_y: %d",
1081 sky_box_center_x, sky_box_center_y);
1082 cpl_msg_info(cpl_func,
"sky_box_width_x: %d sky_box_width_y: %d",
1083 sky_box_width_x, sky_box_width_y);
1084 cpl_msg_info(cpl_func,
"sky_box_edges_margin_x: %d sky_box_edges_margin_y: %d",
1085 sky_box_edges_margin_x, sky_box_edges_margin_y);
1090 int sky_est_method = -1;
1091 const char* context =
"eris.eris_ifu_jitter";
1092 const cpl_parameter* p = NULL;
1094 param_name = cpl_sprintf(
"%s.sky-est-method", context);
1095 p = cpl_parameterlist_find_const(parlist, param_name);
1097 sky_est_method = cpl_parameter_get_int(p);
1099 cpl_free(param_name);
1103 param_name = cpl_sprintf(
"%s.sky-est-niter", context);
1104 p = cpl_parameterlist_find_const(parlist, param_name);
1106 niter = cpl_parameter_get_int(p);
1108 cpl_free(param_name);
1111 param_name = cpl_sprintf(
"%s.sky-est-kappa", context);
1112 p = cpl_parameterlist_find_const(parlist, param_name);
1114 kappa = cpl_parameter_get_double(p);
1116 cpl_free(param_name);
1119 cpl_image* img = NULL;
1120 hdrl_image* himg = NULL;
1121 hdrl_value sky = {0, 0};
1122 cpl_size llx = 0 , urx = 0, lly = 0 , ury = 0 ;
1123 cpl_msg_info(cpl_func,
"llx, lly, urx, ury, [%lld,%lld,%lld,%lld]",
1138 cpl_bivector* xy_pos = NULL;
1139 cpl_vector* sky_data = NULL;
1140 double* x_pos = NULL;
1141 double* y_pos = NULL;
1145 if(aj_method == 5) {
1146 xy_pos = cpl_bivector_new(4);
1147 sky_data = cpl_vector_new(4);
1148 x_pos = cpl_bivector_get_x_data(xy_pos);
1149 y_pos = cpl_bivector_get_y_data(xy_pos);
1151 x_pos[0] = sky_box_edges_margin_x + sky_box_width_x;
1152 y_pos[0] = sky_box_edges_margin_y + sky_box_width_y;
1154 x_pos[1] = sky_box_edges_margin_x + sky_box_width_x;
1155 y_pos[1] = size_y - sky_box_edges_margin_y - sky_box_width_y;
1157 x_pos[2] = size_x - sky_box_edges_margin_x - sky_box_width_x;
1158 y_pos[2] = sky_box_edges_margin_y + sky_box_width_y;
1160 x_pos[3] = size_x - sky_box_edges_margin_x - sky_box_width_x;
1161 y_pos[3] = size_y - sky_box_edges_margin_y - sky_box_width_y;
1165 if(aj_method == 6) {
1166 xy_pos = cpl_bivector_new(8);
1167 sky_data = cpl_vector_new(8);
1168 x_pos = cpl_bivector_get_x_data(xy_pos);
1169 y_pos = cpl_bivector_get_y_data(xy_pos);
1172 x_pos[0] = sky_box_edges_margin_x + sky_box_width_x;
1173 y_pos[0] = sky_box_edges_margin_y + sky_box_width_y;
1175 x_pos[1] = sky_box_edges_margin_x + sky_box_width_x;
1176 y_pos[1] = size_y - sky_box_edges_margin_y - sky_box_width_y;
1178 x_pos[2] = size_x - sky_box_edges_margin_x - sky_box_width_x;
1179 y_pos[2] = sky_box_edges_margin_y + sky_box_width_y;
1181 x_pos[3] = size_x - sky_box_edges_margin_x - sky_box_width_x;
1182 y_pos[3] = size_y - sky_box_edges_margin_y - sky_box_width_y;
1186 x_pos[4] = floor(0.5 * size_x);
1187 y_pos[4] = sky_box_edges_margin_y + sky_box_width_y;
1189 x_pos[5] = sky_box_edges_margin_x + sky_box_width_x;
1190 y_pos[5] = floor(0.5 * size_y);
1192 x_pos[6] = size_x - sky_box_edges_margin_x - sky_box_width_x;
1193 y_pos[6] = floor(0.5 * size_y);
1195 x_pos[7] = floor(0.5 * size_x);
1196 y_pos[7] = size_y - sky_box_edges_margin_y - sky_box_width_y;
1201 double sky_tmp_val = 0;
1202 if(aj_method == 4) {
1203 llx = sky_box_center_x - sky_box_width_x;
1204 urx = sky_box_center_x + sky_box_width_x;
1205 lly = sky_box_center_y - sky_box_width_y;
1206 ury = sky_box_center_y + sky_box_width_y;
1207 for (cpl_size zx = skip; zx < size_z - skip; zx++){
1212 if(sky_est_method==0) {
1213 sky.data = cpl_image_get_median_window(img, llx, lly, urx, ury);
1215 sky.data = cpl_image_get_mean_window(img, llx, lly, urx, ury);
1220 }
else if(aj_method == 5 || aj_method == 6) {
1221 cpl_size xy_pos_size = cpl_bivector_get_size(xy_pos);
1222 double* psky_data = cpl_vector_get_data(sky_data);
1223 for (cpl_size zx = skip; zx < size_z - skip; zx++){
1228 for (cpl_size k = 0; k < xy_pos_size; k++){
1229 llx = ((cpl_size) x_pos[k] - sky_box_width_x);
1230 lly = ((cpl_size) y_pos[k] - sky_box_width_y);
1231 urx = ((cpl_size) x_pos[k] + sky_box_width_x);
1232 ury = ((cpl_size) y_pos[k] + sky_box_width_y);
1234 if(sky_est_method==0) {
1235 sky_tmp_val = cpl_image_get_median_window(img, llx, lly, urx, ury);
1236 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1240 psky_data[k] = sky_tmp_val;
1244 sky_tmp_val = cpl_image_get_mean_window(img, llx, lly, urx, ury);
1245 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1249 psky_data[k] = sky_tmp_val;
1252 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1253 cpl_msg_error(cpl_func,
"Some error during sky modeling: "
1254 "try to use a different region or other aj-method");
1259 if(sky_est_method==0) {
1260 sky.data = cpl_vector_get_median(sky_data);
1262 sky.data = cpl_vector_get_mean(sky_data);
1267 }
else if(aj_method == 7) {
1269 hdrl_image* cube_collapsed = NULL;
1270 cpl_image* cube_cmap = NULL;
1283 cpl_image_delete(cube_cmap);
1285 eris_ifu_jitter_skycorr_from_mask(objEntry, mask_obj, sky_est_method);
1287 cpl_mask_delete(mask_obj);
1288 }
else if(aj_method == 8) {
1289 hdrl_image* cube_mean = NULL;
1290 cpl_image* cube_cmap = NULL;
1295 cpl_image_delete(cube_cmap);
1296 eris_ifu_jitter_skycorr_from_mask(objEntry, mask_obj, sky_est_method);
1297 cpl_mask_delete(mask_obj);
1313 return cpl_error_get_code();
1348 struct stdParamStruct stdParams,
1349 struct paramStruct params,
1350 cpl_frameset *frameset,
1351 const cpl_parameterlist * parlist,
1352 const char* recipe_name,
1355 cpl_error_code retVal = CPL_ERROR_NONE,
1356 err = CPL_ERROR_NONE;
1357 struct exposureEntry *objEntry = NULL,
1359 cpl_mask *tmpMask = NULL;
1360 hdrl_image *tmpImg = NULL;
1361 cpl_size imgSize = 0;
1362 double *pObjErr = NULL,
1364 *pTweakedErr = NULL;
1365 cpl_binary *pObjMask = NULL,
1367 *pTweakedMask = NULL;
1371 cpl_msg_info(cpl_func,
"Process Jitter Cubes: split Obj & Sky, correct Sky as user specified");
1373 for (
int ix = 0; ix < sof->exposureTableCnt; ix++) {
1374 if (!sof->exposureTable[ix].isObject) {
1377 objEntry = &sof->exposureTable[ix];
1378 cpl_frameset* obj_set =
1379 eris_ifu_frameset_extract_obj_set(frameset, sof, ix);
1381 if (params.skyTweak != NONE) {
1382 int skyIndex = objEntry->skyIndex;
1385 "no vaild sky frame found");
1387 skyEntry = &sof->exposureTable[skyIndex];
1389 if (skyEntry->cube == NULL) {
1390 cpl_msg_error(__func__,
1391 "Missing sky image for input frame %s",
1392 cpl_frame_get_filename(objEntry->frame));
1394 cpl_imagelist *dataCubeObj = cpl_imagelist_new(),
1395 *errCubeObj = cpl_imagelist_new(),
1396 *dataCubeSky = cpl_imagelist_new(),
1397 *errCubeSky = cpl_imagelist_new();
1401 dataCubeObj, errCubeObj));
1404 dataCubeSky, errCubeSky));
1406 if (params.skyTweak == DAVIES) {
1407 cpl_imagelist *skycorrObj = NULL,
1412 objEntry->cubeHdr, .3,
1414 params.discard_subband,
1416 params.stretch_degree,
1417 params.stretch_resampling,
1426 skycorrErr = cpl_imagelist_duplicate(errCubeObj));
1428 imgSize = cpl_image_get_size_x(cpl_imagelist_get(skycorrErr, 0)) *
1429 cpl_image_get_size_y(cpl_imagelist_get(skycorrErr, 0));
1431 for (cpl_size tx = 0; tx < cpl_imagelist_get_size(skycorrErr); tx++) {
1432 pObjErr = cpl_image_get_data_double(
1433 cpl_imagelist_get(errCubeObj,tx));
1434 pSkyErr = cpl_image_get_data_double(
1435 cpl_imagelist_get(errCubeSky,tx));
1436 pTweakedErr = cpl_image_get_data_double(
1437 cpl_imagelist_get(skycorrErr,tx));
1438 pObjMask = cpl_mask_get_data(
1439 cpl_image_get_bpm(cpl_imagelist_get(errCubeObj,tx)));
1440 pErrMask = cpl_mask_get_data(
1441 cpl_image_get_bpm(cpl_imagelist_get(errCubeSky,tx)));
1442 pTweakedMask = cpl_mask_get_data(
1443 cpl_image_get_bpm(cpl_imagelist_get(skycorrErr,tx)));
1445 for (cpl_size rx = 0; rx < imgSize; rx++) {
1446 if ((pObjMask[rx] != BAD_PIX) &&
1447 (pErrMask[rx] != BAD_PIX))
1449 pTweakedMask[rx] = GOOD_PIX;
1450 pTweakedErr[rx] = hypot(pObjErr[rx], pSkyErr[rx]);
1452 pTweakedMask[rx] = BAD_PIX;
1470 if ((stdParams.productDepth >= PD_DEBUG) && (skycorrSky != NULL)) {
1471 char *fname = cpl_sprintf(
1472 "eris_ifu_jitter_dbg_skycoorsky_%3.3d.fits", skyIndex);
1473 cpl_imagelist_save(skycorrSky, fname,
1474 CPL_TYPE_FLOAT, NULL, CPL_IO_CREATE);
1481 else if (params.skyTweak == AUSTRIAN) {
1482 cpl_table *objspec = NULL,
1484 cpl_parameterlist *parlist_skycorr = NULL;
1485 double ts = cpl_test_get_walltime();
1493 parlist_skycorr = eris_ifu_skycorr_create_parlist(skyEntry->cubeHdr));
1502 for (cpl_size y = 1; y <= ny; y += 2) {
1503 if (stdParams.productDepth == 3) {
1504 cpl_msg_debug(cpl_func,
">>>>> line %d", (
int)y);
1506 for (cpl_size x = 1; x <= nx; x++) {
1507 int success = CPL_FALSE;
1508 if (stdParams.productDepth == 3) {
1509 cpl_msg_debug(cpl_func,
">>>>> pix (%d/%d)", (
int)x, (
int)y);
1512 objspec = eris_ifu_skycorr_extract_spectrum(objEntry->cube, objEntry->cubeHdr, x, y));
1514 skyspec = eris_ifu_skycorr_extract_spectrum(skyEntry->cube, skyEntry->cubeHdr, x, y));
1516 if (stdParams.productDepth == 3) {
1542 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_1_orig.fits", (
int)x, (
int)y);
1543 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1545 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_1_orig.fits", (
int)x, (
int)y);
1546 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1551 double mean_lambda = 0.5 * (cpl_table_get(objspec,
"lambda", 0, NULL) +
1552 cpl_table_get(objspec,
"lambda", cpl_table_get_nrow(objspec)-1, NULL));
1553 cpl_parameter *p = cpl_parameterlist_find(parlist_skycorr,
"meanlam");
1554 cpl_parameter_set_double(p, mean_lambda);
1556 double mean_obj_flux = cpl_table_get_column_mean(objspec,
"flux"),
1557 mean_sky_flux = cpl_table_get_column_mean(skyspec,
"flux");
1560 if ((fabs(mean_obj_flux) > 0.00001) && (fabs(mean_sky_flux) > 0.00001)) {
1562 int outlier_factor = 10;
1564 eris_ifu_skycorr_flatten_outliers(objspec, skyspec, outlier_factor));
1571 if (stdParams.productDepth == 3) {
1572 char* fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_2_flatten1.fits", (
int)x, (
int)y);
1573 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1575 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_2_flatten1.fits", (
int)x, (
int)y);
1576 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1580 err =
sc_skycorr(parlist_skycorr, objspec, skyspec, stdParams.productDepth);
1581 if (err != CPL_ERROR_NONE) {
1583 cpl_errorstate_set(CPL_ERROR_NONE);
1584 err = CPL_ERROR_NONE;
1590 eris_ifu_skycorr_flatten_outliers(objspec, skyspec, outlier_factor));
1592 if (stdParams.productDepth == 3) {
1593 char* fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_3_flatten2.fits", (
int)x, (
int)y);
1594 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1596 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_3_flatten2.fits", (
int)x, (
int)y);
1597 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1601 err =
sc_skycorr(parlist_skycorr, objspec, skyspec, stdParams.productDepth);
1602 if (err != CPL_ERROR_NONE) {
1604 cpl_errorstate_set(CPL_ERROR_NONE);
1605 err = CPL_ERROR_NONE;
1615 if (success == CPL_FALSE) {
1617 if (stdParams.productDepth == 3) {
1618 cpl_msg_debug(cpl_func,
">>>>> inserted blank spectrum");
1619 char* fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_4_failed.fits", (
int)x, (
int)y);
1620 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1622 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_4_failed.fits", (
int)x, (
int)y);
1623 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1628 objspec = eris_ifu_skycorr_create_nan_spectrum(objEntry->cube));
1631 eris_ifu_skycorr_insert_spectrum(objEntry->cube, objspec, x, y));
1640 double te = cpl_test_get_walltime();
1641 cpl_msg_debug(cpl_func,
">>>>> >>>>> skycorr took %g seconds", te - ts);
1646 if (!cpl_propertylist_has(objEntry->cubeHdr,
"PRODCATG")) {
1647 cpl_propertylist_append_string(objEntry->cubeHdr,
"PRODCATG",
1652 eris_ifu_jitter_save_cpl_cube(frameset, obj_set, objEntry->frame, parlist,
1653 NULL, objEntry->cube, objEntry->cubeBpm, objEntry->cubeHdr,
1654 params, TWEAKED_CUBE, ix, recipe_name));
1656 cpl_frameset_delete(obj_set);
1661 const char* context =
"eris.eris_ifu_jitter";
1662 param_name = cpl_sprintf(
"%s.aj-method", context);
1663 const cpl_parameter* p = NULL;
1664 p = cpl_parameterlist_find_const(parlist, param_name);
1666 aj_method = cpl_parameter_get_int(p);
1668 cpl_free(param_name);
1670 if((objEntry->skyIndex < 0) && (aj_method > 3)) {
1672 eris_ifu_jitter_skycor_from_box(parlist, objEntry, aj_method);
1675 if (params.darCorrection) {
1678 tmpMask = cpl_mask_threshold_image_create(cpl_imagelist_get(objEntry->cubeBpm, zx), params.bpmThreshold, 1.5);;
1686 params.darShiftMethod,
1687 params.darShiftWidth, params.darShiftLength));
1688 cpl_frameset* obj_set2 =
1689 eris_ifu_frameset_extract_obj_set(frameset, sof, ix);
1691 eris_ifu_jitter_save_cpl_cube(frameset, obj_set2,
1692 sof->exposureTable[ix].frame, parlist, NULL,
1693 objEntry->cube, objEntry->cubeBpm, objEntry->cubeHdr,
1694 params, DAR_CUBE, ix, recipe_name);
1695 cpl_frameset_delete(obj_set2);
1699 cubeType sky_type = SKY_OBJECT_CUBE;
1702 char *proCatg = NULL;
1703 char *filenamePrefix = NULL;
1707 cpl_frameset* cube_set;
1709 for(cpl_size i = 0; i < sof->exposureTableCnt; i++) {
1710 if (!cpl_propertylist_has(sof->exposureTable[i].cubeHdr,
"PRODCATG")) {
1711 cpl_propertylist_append_string(sof->exposureTable[i].cubeHdr,
1712 "PRODCATG",
"ANCILLARY.EXPMAP");
1715 if (sof->exposureTable[i].isObject) {
1716 cpl_frameset* obj_set =
1717 eris_ifu_frameset_extract_obj_set(frameset, sof, i);
1719 eris_ifu_jitter_save_cpl_cube(frameset, obj_set,
1720 sof->exposureTable[i].frame,
1721 parlist, NULL, sof->exposureTable[i].cube,
1722 sof->exposureTable[i].cubeBpm,
1723 sof->exposureTable[i].cubeHdr,
1724 params, *obj_type, i, recipe_name);
1725 cpl_frameset_delete(obj_set);
1728 eris_ifu_jitter_save_cpl_cube(frameset, frameset,
1729 sof->exposureTable[i].frame,
1730 parlist, NULL, sof->exposureTable[i].cube,
1731 sof->exposureTable[i].cubeBpm,
1732 sof->exposureTable[i].cubeHdr,
1733 params, sky_type, i, recipe_name);
1741 retVal = cpl_error_get_code();
1774 skyTweakModes sky_tweak,
1776 struct sofStruct *sof,
1777 productDepthType productDepth)
1779 hdrl_image *objImg = NULL;
1780 cpl_mask *inputMask = NULL;
1781 cpl_mask *outputMask = NULL;
1782 cpl_image *dqi = NULL;
1783 char *filename = NULL;
1784 char *filename2 = NULL;
1785 bool darkSkySubtracted =
false;
1787 cpl_ensure(sof != NULL,CPL_ERROR_NULL_INPUT, NULL);
1793 inputMask = cpl_mask_duplicate(
1796 if (sky_tweak == NONE) {
1797 const int skyIdx = sof->exposureTable[objIdx].skyIndex;
1802 darkSkySubtracted =
true;
1804 }
else if (sof->masterDark != NULL) {
1807 darkSkySubtracted =
true;
1811 if (darkSkySubtracted) {
1815 BRK_IF_NULL(dqi = cpl_image_new_from_mask(outputMask));
1816 BRK_IF_ERROR(cpl_image_multiply_scalar(dqi, ERIS_DQI_SKY));
1818 sof->exposureTable[objIdx].dqiImage, dqi));
1819 if (productDepth >= PD_DEBUG) {
1821 filename = cpl_sprintf(
"%s_%3.3d",
1822 ERIS_IFU_PRO_JITTER_DBG_DARK_FN, objIdx));
1824 filename2 = cpl_sprintf(
"%s_%3.3d.fits",
1825 ERIS_IFU_PRO_JITTER_DBG_DARK_FN, objIdx));
1829 cpl_image_save(sof->exposureTable[objIdx].dqiImage,
1830 filename2, CPL_TYPE_INT, NULL, CPL_IO_EXTEND));
1834 cpl_mask_delete(inputMask);
1881 hdrl_image *inputImage,
1883 struct sofStruct *sof,
1884 struct paramStruct params,
1885 bool doVelocityCorrection,
1886 cpl_polynomial *ohLambdaCorrection,
1887 productDepthType productDepth)
1889 hdrl_imagelist *cube = NULL;
1890 cpl_imagelist *dataCube = NULL;
1891 cpl_imagelist *errCube = NULL;
1892 hdrl_image *image1 = NULL;
1893 hdrl_image *image2 = NULL;
1894 hdrl_image *bpmImg1 = NULL;
1895 cpl_image *bpmImg2 = NULL;
1896 hdrl_image *badPixelMaskImg = NULL;
1897 cpl_image *badPixelMaskImg1 = NULL;
1898 cpl_image *badPixelMaskImg2 = NULL;
1900 hdrl_image *waveImg = NULL;
1901 cpl_image *waveDataImg = NULL;
1902 cpl_image *waveErrImg = NULL;
1903 cpl_image *waveMap = NULL;
1904 struct exposureEntry *objEntry;
1907 double velocityCorr;
1910 double minLambda = 0.;
1911 double maxLambda = 0.;
1912 bool buildCubeForOHbasedLambdaCorrection =
false;
1914 cpl_ensure(inputImage != NULL,CPL_ERROR_NULL_INPUT, NULL);
1915 cpl_ensure(sof != NULL,CPL_ERROR_NULL_INPUT, NULL);
1920 if (doVelocityCorrection ==
false && ohLambdaCorrection == NULL) {
1921 buildCubeForOHbasedLambdaCorrection =
true;
1924 objEntry = &sof->exposureTable[sofIdx];
1928 if (sof->masterFlat != NULL) {
1931 if (productDepth >= PD_DEBUG) {
1932 if (buildCubeForOHbasedLambdaCorrection) {
1934 filename = cpl_sprintf(
"%sB_%3.3d",
1935 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN, sofIdx));
1938 filename = cpl_sprintf(
"%s_%3.3d",
1939 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN, sofIdx));
1949 cpl_mask_get_size_x(objEntry->badPixelMask),
1950 cpl_mask_get_size_y(objEntry->badPixelMask)));
1952 badPixelMaskImg1 = cpl_image_new_from_mask(objEntry->badPixelMask));
1954 badPixelMaskImg2 = cpl_image_cast(
1955 badPixelMaskImg1, CPL_TYPE_DOUBLE));
1958 badPixelMaskImg2, NULL, 1, 1));
1962 cpl_msg_info(__func__,
"No. bad pixels: %d", (
int)cpl_image_count_rejected(
hdrl_image_get_image(image1)));
1966 int bpc_iter = params.bpc_iter;
1967 for (
int i = 0; i < bpc_iter; i++){
1970 if (productDepth >= PD_DEBUG) {
1971 if (buildCubeForOHbasedLambdaCorrection) {
1973 filename = cpl_sprintf(
"%sB_%3.3d_%d",
1974 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN
"-corr", sofIdx, i));
1977 filename = cpl_sprintf(
"%s_%3.3d_%d",
1978 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN
"-corr", sofIdx, i));
1988 if (params.derot_corr!=params.derot_corr)
1989 derot_corr = objEntry->derot_corr;
1991 derot_corr = params.derot_corr;
1992 cpl_msg_info(cpl_func,
"First column shifted (derot_corr): %.2f", derot_corr);
1994 for (
int i = 0; i < SLITLET_CNT; i++) {
1995 if (sof->distortion[i] != NULL) {
1997 cpl_polynomial_shift_1d(sof->distortion[i], 0, derot_corr));
2002 if (sof->distortion != NULL) {
2005 sof->distortion, sof->borders));
2008 sof->distortion, sof->borders, productDepth));
2012 sof->poly_u, sof->poly_v));
2015 sof->poly_u, sof->poly_v));
2019 for (
int i = 0; i < SLITLET_CNT; i++) {
2020 if (sof->distortion[i] != NULL) {
2022 cpl_polynomial_shift_1d(sof->distortion[i], 0, -1*derot_corr));
2028 if (productDepth >= PD_DEBUG) {
2029 if (buildCubeForOHbasedLambdaCorrection) {
2031 filename = cpl_sprintf(
"%sB_%3.3d",
2032 ERIS_IFU_PRO_JITTER_DBG_WRAP_FN, sofIdx));
2035 filename = cpl_sprintf(
"%s_%3.3d",
2036 ERIS_IFU_PRO_JITTER_DBG_WRAP_FN, sofIdx));
2039 if (bpmImg1 != NULL) {
2041 filename2 = cpl_sprintf(
"%s.fits", filename));
2044 CPL_TYPE_FLOAT, NULL, CPL_IO_EXTEND));
2050 waveMap = cpl_image_duplicate(sof->waveMap);
2051 lsize = cpl_image_get_size_x(waveMap) * cpl_image_get_size_y(waveMap);
2052 BRK_IF_NULL(pWaveMap = cpl_image_get_data_double(waveMap));
2053 maxLambda = cpl_image_get_max(waveMap);
2054 minLambda = cpl_image_get_min(waveMap);
2057 if (doVelocityCorrection) {
2058 velocityCorr = 1. + params.velocityOffset * 1000. / CPL_PHYS_C;
2059 for (
int ix = 0; ix < lsize; ix++) {
2060 pWaveMap[ix] *= velocityCorr;
2065 if (ohLambdaCorrection != NULL) {
2066 for (
int ix = 0; ix < lsize; ix++) {
2067 pWaveMap[ix] -= cpl_polynomial_eval_1d(
2068 ohLambdaCorrection, pWaveMap[ix], NULL);
2074 cpl_propertylist_delete(objEntry->cubeHdr);
2075 objEntry->cubeHdr = cpl_propertylist_duplicate(objEntry->hdr);
2079 waveMap, sof->band, minLambda, maxLambda,
2080 objEntry->cubeHdr, 3));
2084 waveMap, sof->band, minLambda, maxLambda,
2085 objEntry->cubeHdr, 3));
2090 waveMap, sof->band, minLambda, maxLambda,
2091 objEntry->cubeHdr, 3));
2093 cpl_binary *pImgMask = cpl_mask_get_data(cpl_image_get_bpm(waveDataImg));
2094 float *pDqiData = cpl_image_get_data_float(bpmImg2);
2095 cpl_size size = cpl_image_get_size_x(waveDataImg)
2096 * cpl_image_get_size_y(waveDataImg);
2097 for (cpl_size px = 0; px < size; px++) {
2098 if (pDqiData[px] > params.bpmThreshold) {
2099 pImgMask[px] = BAD_PIX;
2105 if (productDepth >= PD_DEBUG) {
2106 cpl_propertylist *pl2save = cpl_propertylist_duplicate(objEntry->hdr);
2111 waveMap, sof->band, minLambda, maxLambda, pl2save, 2);
2112 if (buildCubeForOHbasedLambdaCorrection) {
2114 filename = cpl_sprintf(
"%sB_%3.3d",
2115 ERIS_IFU_PRO_JITTER_DBG_WAVE_FN, sofIdx));
2118 filename = cpl_sprintf(
"%s_%3.3d",
2119 ERIS_IFU_PRO_JITTER_DBG_WAVE_FN, sofIdx));
2121 cpl_propertylist_erase(pl2save,
"RADECSYS");
2127 waveMap, sof->band, minLambda, maxLambda, pl2save, 2);
2129 filename2 = cpl_sprintf(
"%s.fits", filename));
2131 cpl_image_save(image2save, filename2,
2132 CPL_TYPE_FLOAT, pl2save, CPL_IO_EXTEND));
2143 params.slitletDetectionMode,
2144 params.fineTuneMode,
2148 cpl_image_reject_from_mask(waveErrImg, cpl_image_get_bpm_const(waveDataImg));
2152 params.slitletDetectionMode,
2153 params.fineTuneMode,
2159 cpl_imagelist_delete(dataCube);
2160 cpl_imagelist_delete(errCube);
2161 cpl_propertylist_update_int(objEntry->cubeHdr,NAXIS1,64);
2162 cpl_propertylist_update_int(objEntry->cubeHdr,NAXIS2,64);
2163 cpl_propertylist_update_int(objEntry->cubeHdr,NAXIS3,
2166 if(objEntry->cubeBpm != NULL) {
2167 cpl_imagelist_delete(objEntry->cubeBpm);
2170 cpl_image_multiply_scalar(bpmImg2, 2.0);
2175 params.slitletDetectionMode,
2176 params.fineTuneMode,
2223 cpl_size* min, cpl_size* max)
2225 cpl_size sx = cpl_image_get_size_x(image);
2226 cpl_size sy = cpl_image_get_size_y(image);
2227 float* pdata = cpl_image_get_data(image);
2228 cpl_size rows2check = 200;
2229 cpl_size nan_counter = 0;
2230 double nan_thresh = 0.5;
2233 for(cpl_size j = 0; j < rows2check; j++) {
2235 for(cpl_size i = 0; i < sx; i++) {
2236 if(isnan(pdata[i + j * sx])) {
2241 if(nan_counter > nan_thresh * sx) {
2246 for(cpl_size j = sy-1; j >= sy - rows2check; j--) {
2248 for(cpl_size i = 0; i < sx; i++) {
2249 if(isnan(pdata[i + j * sx])) {
2253 if(nan_counter > nan_thresh * sx) {
2257 cpl_msg_info(cpl_func,
"min: %lld max: %lld", *min, *max);
2259 return cpl_error_get_code();
2297 cpl_image *resampledDetImage,
2298 slitletDetectionModes mode,
2301 cpl_vector *distancesV,
2302 cpl_bivector *positionsVV)
2305 cpl_ensure(resampledDetImage, CPL_ERROR_NULL_INPUT, NULL);
2306 cpl_ensure((mode >= UNSET) && (mode <= GRID), CPL_ERROR_ILLEGAL_INPUT, NULL);
2307 cpl_ensure(fineTuneMode >= -5, CPL_ERROR_ILLEGAL_INPUT, NULL);
2308 cpl_ensure(firstCol >= 0 && firstCol <= ERIS_IFU_DETECTOR_SIZE_X, CPL_ERROR_ILLEGAL_INPUT, NULL);
2312 cpl_imagelist *cube = NULL;
2313 cpl_image *slide = NULL;
2318 int beginCol[SLITLET_CNT] = {0};
2319 double start[SLITLET_CNT] = {0.};
2322 double *distances = NULL;
2325 double *left_edges = NULL;
2326 double *right_edges = NULL;
2329 cpl_binary *mi = NULL;
2330 cpl_binary *mo = NULL;
2340 inx = cpl_image_get_size_x(resampledDetImage);
2341 onx = inx / SLITLET_CNT;
2342 ony = SLITLET_CNT * 2;
2343 onz = cpl_image_get_size_y(resampledDetImage);
2344 cube = cpl_imagelist_new();
2350 if (distancesV == NULL) {
2351 pi = cpl_image_get_data_float(resampledDetImage);
2352 mi = cpl_mask_get_data(cpl_image_get_bpm(resampledDetImage));
2354 for (
int iz=0; iz<onz; iz++) {
2356 slide = cpl_image_new(onx, ony, CPL_TYPE_FLOAT));
2357 po = cpl_image_get_data_float(slide);
2358 mo = cpl_mask_get_data(cpl_image_get_bpm(slide));
2361 for (
int slitlet=0; slitlet<SLITLET_CNT; slitlet++) {
2362 for (
int col=0; col < onx; col++) {
2363 tmp = (float) pi[onx-1-col + slitlet*onx + iz*inx];
2370 po[col + onx*(rowIndices[slitlet]*2)] = tmp;
2371 po[col + onx*(rowIndices[slitlet]*2+1)] = tmp;
2372 if (mi[onx-1-col + slitlet*onx + iz*inx] == BAD_PIX) {
2373 mo[col + onx*(rowIndices[slitlet]*2)] = BAD_PIX;
2374 mo[col + onx*(rowIndices[slitlet]*2+1)] = BAD_PIX;
2381 cpl_imagelist_set(cube, slide, iz));
2384 if (mode == DISTANCES) {
2385 if (distancesV == NULL) {
2387 "missing data about slitlet distances");
2389 if (cpl_vector_get_size(distancesV) != SLITLET_CNT-1) {
2391 "distances vector has wrong number of elements "
2392 "(got %lld but exepected %d)",
2393 cpl_vector_get_size(distancesV), SLITLET_CNT-1);
2395 distances = cpl_vector_get_data(distancesV);
2396 }
else if (mode == EDGES) {
2397 if (positionsVV == NULL) {
2399 "missing data about slitlet positions");
2401 if (cpl_bivector_get_size(positionsVV) != SLITLET_CNT) {
2403 "slit pos bivector has wrong number of elements "
2404 "(got %lld but exepected %d)",
2405 cpl_bivector_get_size(positionsVV), SLITLET_CNT);
2407 left_edges = cpl_vector_get_data(
2408 cpl_bivector_get_x(positionsVV));
2409 right_edges = cpl_vector_get_data(
2410 cpl_bivector_get_y(positionsVV));
2414 for (
int slitlet=0; slitlet<SLITLET_CNT; slitlet++) {
2415 if (mode == DISTANCES) {
2417 start[slitlet] = firstCol;
2419 di += distances[slitlet-1];
2420 start[slitlet] = firstCol + di;
2422 }
else if (mode == EDGES) {
2423 center = (left_edges[slitlet] + right_edges[slitlet]) / 2.;
2424 start[slitlet] = center - (double) (onx -1 )/2.;
2425 }
else if (mode == GRID) {
2426 start[slitlet] = (double) (onx * slitlet);
2429 start[slitlet] > 0 ?
2430 (int)(start[slitlet]+.5) : (int)(start[slitlet]-.5);
2437 xi = cpl_calloc(onx,
sizeof(
double)));
2439 xt = cpl_calloc(onx,
sizeof(
double)));
2441 pt1 = cpl_calloc(onx,
sizeof(
double)));
2443 pt2 = cpl_calloc(onx,
sizeof(
double)));
2444 pi = cpl_image_get_data_float(resampledDetImage);
2446 for (
int iz=0; iz<onz; iz++) {
2448 slide = cpl_image_new(onx, ony, CPL_TYPE_FLOAT));
2449 po = cpl_image_get_data_float(slide);
2451 for (
int slitlet=0; slitlet<SLITLET_CNT; slitlet++) {
2452 for (
int col=0; col < onx; col++) {
2453 xi[col] = (double) (beginCol[slitlet] + col);
2454 xt[col] = start[slitlet] + col;
2455 icol = beginCol[slitlet] + col;
2457 pt1[col] = pi[0 + iz * inx];
2458 }
else if (icol >= inx) {
2459 pt1[col] = pi[(inx - 1) + iz * inx];
2461 pt1[col] = pi[icol + iz * inx];
2464 if (fineTuneMode == 0) {
2465 for (
int col=0; col < onx; col++) {
2466 pt2[col] = pt1[col];
2471 xt, pt2, (
int) onx, fineTuneMode));
2473 for (
int col=0; col < onx; col++) {
2481 tmp = (float) (pt2[col] * 0.5);
2482 po[col + onx*(rowIndices[slitlet]*2)] = tmp;
2483 po[col + onx*(rowIndices[slitlet]*2+1)] = tmp;
2487 cpl_imagelist_set(cube, slide, iz));
2515 char **filenamePrefix)
2517 cpl_ensure_code(proCatg, CPL_ERROR_NULL_INPUT);
2518 cpl_ensure_code(filenamePrefix, CPL_ERROR_NULL_INPUT);
2521 case OBJECT_CUBE_COADD:
2522 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD);
2523 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FN);
2525 case TWEAKED_CUBE_COADD:
2526 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD);
2527 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD_FN);
2529 case DAR_CUBE_COADD:
2530 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE_COADD);
2531 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE_COADD_FN);
2533 case DAR_STD_CUBE_COADD:
2534 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
2535 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FN);
2537 case STD_CUBE_COADD:
2538 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
2539 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FN);
2541 case STD_FLUX_CUBE_COADD:
2542 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD);
2543 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FN);
2545 case STD_FLUX_CUBE_COADD_NOFLAT:
2546 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT);
2547 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT_FN);
2549 case STD_CUBE_COADD_NOFLAT:
2550 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT);
2551 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT_FN);
2553 case PSF_CUBE_COADD:
2554 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
2555 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_FN);
2558 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE);
2559 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE_FN);
2562 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE);
2563 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_FN);
2566 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE);
2567 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_FN);
2569 case STD_CUBE_NOFLAT:
2570 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_NOFLAT);
2571 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_NOFLAT_FN);
2574 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE);
2575 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_FN);
2577 case SKY_OBJECT_CUBE:
2579 case SKY_STD_FLUX_CUBE:
2581 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_SKY_CUBE);
2582 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_SKY_CUBE_FN);
2585 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE);
2586 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE_FN);
2588 case TWEAKED_STD_CUBE:
2589 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE);
2590 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_FN);
2593 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE);
2594 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE_FN);
2597 case DAR_PSF_CUBE_COADD:
2598 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
2599 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_FN);
2603 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE);
2604 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_FN);
2606 case DAR_STD_FLUX_CUBE:
2608 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE);
2609 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_FN);
2613 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE);
2614 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_FN);
2617 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_BPM_CUBE);
2618 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_BPM_CUBE_FN);
2621 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE);
2622 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE_FN);
2625 cpl_msg_warning(cpl_func,
"default case %d",type);
2626 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE);
2627 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE_FN);
2630 cpl_msg_debug(cpl_func,
"proCatg: %s",*proCatg);
2631 cpl_msg_debug(cpl_func,
"filenamePrefix: %s",*filenamePrefix);
2632 return cpl_error_get_code();
2655 const cpl_imagelist *data_in,
2656 const cpl_imagelist *noise_in,
2658 cpl_vector **spec_data_out,
2659 cpl_vector **spec_noise_out)
2661 cpl_error_code ret_error = CPL_ERROR_NONE;
2663 const cpl_image *tmp_img = NULL;
2664 const cpl_mask *bpm = NULL;
2665 const cpl_binary *bpm_data = NULL;
2666 cpl_mask *empty_mask = NULL;
2675 const float *pmask = NULL;
2676 const double *ptmp_img = NULL;
2685 ASSURE((data_in != NULL) &&
2686 (spec_data_out != NULL),
2687 CPL_ERROR_NULL_INPUT,
2688 "Not all input data is provided!");
2691 tmp_img = cpl_imagelist_get_const(data_in, 0));
2693 nx = cpl_image_get_size_x(tmp_img);
2694 ny = cpl_image_get_size_y(tmp_img);
2695 nz = cpl_imagelist_get_size(data_in);
2698 ASSURE((nx == cpl_image_get_size_x(mask)) &&
2699 (ny == cpl_image_get_size_y(mask)),
2700 CPL_ERROR_ILLEGAL_INPUT,
2701 "Data and mask don't have same dimensions!");
2704 pmask = cpl_image_get_data_float_const(mask));
2707 if (noise_in != NULL) {
2708 ASSURE(spec_noise_out != NULL,
2709 CPL_ERROR_NULL_INPUT,
2710 "Not all input data is provided!");
2713 tmp_img = cpl_imagelist_get_const(noise_in, 0));
2715 ASSURE((nx == cpl_image_get_size_x(tmp_img)) &&
2716 (ny == cpl_image_get_size_y(tmp_img)) &&
2717 (nz == cpl_imagelist_get_size(noise_in)),
2718 CPL_ERROR_ILLEGAL_INPUT,
2719 "Data and noise don't have same dimensions!");
2723 *spec_data_out = cpl_vector_new(nz));
2726 pvec = cpl_vector_get_data(*spec_data_out));
2728 if (noise_in != NULL) {
2730 *spec_noise_out = cpl_vector_new(nz));
2733 pvecn = cpl_vector_get_data(*spec_noise_out));
2737 empty_mask = cpl_mask_new(nx,ny));
2740 for (g = 0; g < nz; g++) {
2742 tmp_img = cpl_imagelist_get_const(data_in, g));
2744 ptmp_img = cpl_image_get_data_double_const(tmp_img));
2746 bpm = cpl_image_get_bpm_const(tmp_img);
2751 bpm_data = cpl_mask_get_data_const(bpm));
2756 for (j = 0; j < ny; j++) {
2757 for (i = 0; i < nx; i++) {
2759 if ((bpm_data[i+j*nx] == GOOD_PIX) && isfinite(ptmp_img[i+j*nx])) {
2761 sum += ptmp_img[i+j*nx] * pmask[i+j*nx];
2762 weights += pmask[i+j*nx];
2764 sum += ptmp_img[i+j*nx];
2770 pvec[g] = sum/weights;
2774 if (noise_in != NULL) {
2776 tmp_img = cpl_imagelist_get_const(noise_in, g));
2778 ptmp_img = cpl_image_get_data_double_const(tmp_img));
2782 for (j = 0; j < ny; j++) {
2783 for (i = 0; i < nx; i++) {
2785 if ((bpm_data[i+j*nx] == GOOD_PIX) && isfinite(ptmp_img[i+j*nx])) {
2787 sum += pow(ptmp_img[i+j*nx], 2) * pow(pmask[i+j*nx], 2);
2788 weights += pow(pmask[i+j*nx], 2);
2790 sum += pow(ptmp_img[i+j*nx], 2);
2796 pvecn[g] = sqrt(sum/weights);
2803 ret_error = cpl_error_get_code();
2806 if (empty_mask != NULL) {cpl_mask_delete(empty_mask);}
2832cpl_error_code eris_ifu_jitter_spec_save_products(
2833 cpl_frameset* frames,
2834 const cpl_parameterlist * parlist,
2835 struct esSofStruct sof,
2836 cpl_bivector *spectrum,
2838 cpl_vector *totalFlux,
2839 productDepthType productDepth,
2840 cpl_boolean is_sdp_format,
2841 const char* recipe_name)
2843 cpl_table *pro_tab = NULL;
2844 cpl_propertylist *pl;
2845 cpl_vector *lambda = NULL;
2846 cpl_vector *data = NULL;
2847 cpl_array *waveArray = NULL;
2848 cpl_array *fluxArray = NULL;
2849 cpl_array *errArray = NULL;
2850 cpl_array *totalFluxArray = NULL;
2853 cpl_size spectrumSize;
2857 spectrumSize = cpl_bivector_get_size(spectrum);
2858 BRK_IF_NULL(lambda = cpl_bivector_get_x(spectrum));
2860 firstLambda = cpl_vector_get(lambda,0);
2861 deltaLambda = cpl_vector_get(lambda,1) - firstLambda;
2863 if (productDepth >= PD_AUXILLIARY) {
2864 pl = cpl_propertylist_duplicate(sof.header);
2865 cpl_propertylist_update_string(pl, CPL_DFS_PRO_CATG,
"SPECTRUM");
2866 cpl_propertylist_update_string(pl,
"CTYPE1",
"WAVE");
2867 cpl_propertylist_update_double(pl,
"CRPIX1", 1.);
2868 cpl_propertylist_update_double(pl,
"CRVAL1", firstLambda);
2869 cpl_propertylist_update_double(pl,
"CDELT1", deltaLambda);
2870 cpl_propertylist_erase(pl,
"CTYPE2");
2871 cpl_propertylist_erase(pl,
"CRPIX2");
2872 cpl_propertylist_erase(pl,
"CRVAL2");
2873 cpl_propertylist_erase(pl,
"CDELT2");
2874 cpl_propertylist_erase(pl,
"CTYPE3");
2875 cpl_propertylist_erase(pl,
"CRPIX3");
2876 cpl_propertylist_erase(pl,
"CRVAL3");
2877 cpl_propertylist_erase(pl,
"CDELT3");
2878 cpl_propertylist_update_double(pl,
"CD1_1", 0.);
2879 cpl_propertylist_update_double(pl,
"CD1_2", deltaLambda);
2880 cpl_propertylist_erase(pl,
"CD1_3");
2881 cpl_propertylist_erase(pl,
"CD2_1");
2882 cpl_propertylist_erase(pl,
"CD2_2");
2883 cpl_propertylist_erase(pl,
"CD2_3");
2884 cpl_propertylist_erase(pl,
"CD3_1");
2885 cpl_propertylist_erase(pl,
"CD3_2");
2886 cpl_propertylist_erase(pl,
"CD3_3");
2890 cpl_vector_save(data,
"spectrum_vector.fits",
2891 CPL_TYPE_DOUBLE, pl, CPL_IO_CREATE));
2892 cpl_propertylist_delete(pl);
2894 pl = cpl_propertylist_duplicate(sof.header);
2896 if(strstr(recipe_name,
"no_flat") != NULL) {
2897 cpl_msg_info(cpl_func,
"recipe_name: %s",recipe_name);
2898 cpl_propertylist_update_string(pl, CPL_DFS_PRO_CATG,
2899 ERIS_IFU_PRO_JITTER_SPECTRUM_NOFLAT);
2901 cpl_msg_info(cpl_func,
"recipe_name: %s",recipe_name);
2902 cpl_propertylist_update_string(pl, CPL_DFS_PRO_CATG,
2903 ERIS_IFU_PRO_JITTER_SPECTRUM);
2908 cpl_propertylist_update_string(pl,
"ESO PRO REC1 ID",
"eris_ifu_jitter");
2910 waveArray = cpl_array_wrap_double(cpl_vector_get_data(lambda),
2912 fluxArray = cpl_array_wrap_double(cpl_vector_get_data(data),
2914 errArray = cpl_array_wrap_double(cpl_vector_get_data(error),
2916 if (totalFlux != NULL) {
2917 totalFluxArray = cpl_array_wrap_double(cpl_vector_get_data(totalFlux),
2922 pro_tab = cpl_table_new(1);
2923 cpl_table_new_column_array(pro_tab,
"WAVE",
2924 CPL_TYPE_DOUBLE, spectrumSize);
2925 cpl_table_new_column_array(pro_tab,
"FLUX",
2926 CPL_TYPE_DOUBLE, spectrumSize);
2927 cpl_table_new_column_array(pro_tab,
"ERR",
2928 CPL_TYPE_DOUBLE, spectrumSize);
2929 cpl_table_new_column_array(pro_tab,
"TOT_FLUX",
2930 CPL_TYPE_DOUBLE, spectrumSize);
2931 cpl_table_set_array(pro_tab,
"WAVE", 0, waveArray);
2932 cpl_table_set_array(pro_tab,
"FLUX", 0, fluxArray);
2933 cpl_table_set_array(pro_tab,
"ERR", 0, errArray);
2934 if (totalFlux != NULL) {
2935 cpl_table_set_array(pro_tab,
"TOT_FLUX", 0, totalFluxArray);
2939 pro_tab = cpl_table_new(spectrumSize);
2940 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(lambda),
"WAVE");
2941 if (totalFlux != NULL) {
2942 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(data),
"FLUX");
2944 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(data),
"TOT_FLUX");
2946 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(error),
"ERR");
2947 if (totalFlux != NULL) {
2948 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(totalFlux),
"TOT_FLUX");
2951 char *filename = cpl_sprintf(
"%s_spectrum.fits", recipe_name);
2952 cpl_propertylist_append_string(pl,
"PRODCATG",
"SCIENCE.SPECTRUM");
2953 cpl_dfs_save_table(frames, NULL, parlist, frames, NULL,
2954 pro_tab, NULL, recipe_name, pl,
2955 NULL, PACKAGE
"/" PACKAGE_VERSION, filename);
2958 cpl_propertylist_delete(pl);
2960 cpl_array_unwrap(waveArray);
2961 cpl_array_unwrap(fluxArray);
2962 cpl_array_unwrap(errArray);
2963 if (totalFlux != NULL) {
2964 cpl_array_unwrap(totalFluxArray);
2967 cpl_table_unwrap(pro_tab,
"WAVE");
2968 if (totalFlux != NULL) {
2969 cpl_table_unwrap(pro_tab,
"FLUX");
2971 cpl_table_unwrap(pro_tab,
"TOT_FLUX");
2973 cpl_table_unwrap(pro_tab,
"ERR");
2974 if (totalFlux != NULL) {
2975 cpl_table_unwrap(pro_tab,
"TOT_FLUX");
2978 cpl_table_delete(pro_tab);
2984 return cpl_error_get_code();
3004 const cpl_parameterlist * parlist,
3005 struct esParamStruct *params,
3006 const char* context)
3010 const char* methodString;
3011 char* param_name = NULL;
3013 param_name = cpl_sprintf(
"%s.mask_method", context);
3015 methodString = cpl_parameter_get_string(
3016 cpl_parameterlist_find_const(parlist, param_name));
3017 cpl_free(param_name);
3020 if (strncasecmp(methodString,
"mask", strlen(
"mask")) == 0) {
3021 params->mask_method = MASK;
3022 }
else if (strncasecmp(methodString,
"position", strlen(
"position")) == 0) {
3023 params->mask_method = POSITION;
3024 }
else if (strncasecmp(methodString,
"max", strlen(
"max")) == 0) {
3025 params->mask_method = MAX;
3026 }
else if (strncasecmp(methodString,
"fit", strlen(
"fit")) == 0) {
3027 params->mask_method = FIT;
3028 }
else if (strncasecmp(methodString,
"optimal", strlen(
"optimal")) == 0) {
3029 params->mask_method = OPTIMAL;
3031 cpl_msg_error(cpl_func,
"The maks_method parameter must be one "
3032 "of the list: mask, position, max, fit");
3034 "Error reading recipe parameter, unknown mask method %s",
3040 param_name = cpl_sprintf(
"%s.center", context);
3041 center = cpl_parameter_get_string(
3042 cpl_parameterlist_find_const(parlist, param_name));
3043 cpl_free(param_name);
3047 nFields = sscanf(center,
"%d,%d%n",
3048 ¶ms->center_x, ¶ms->center_y, &end);
3049 if (nFields != 2 || end != (
int)strlen(center)) {
3050 cpl_msg_error(cpl_func,
"The center parameter must be "
3051 "a list of two integers separated by a comma");
3053 "Error reading recipe parameter, cannot properly read center spec %s",
3055 printf(
"Error reading center string\n");
3058 param_name = cpl_sprintf(
"%s.radius", context);
3059 params->radius = cpl_parameter_get_double(
3060 cpl_parameterlist_find_const(parlist, param_name));
3061 cpl_free(param_name);
3063 param_name = cpl_sprintf(
"%s.product_depth", context);
3064 params->productDepth = cpl_parameter_get_int(
3065 cpl_parameterlist_find_const(parlist, param_name));
3066 cpl_free(param_name);
3073 return cpl_error_get_code();
3102 const cpl_parameterlist *parlist,
3105 struct stdParamStruct stdParams,
3106 const char* pipefile_prefix,
3107 const char* context)
3109 double startLambda = 0.,
3112 cpl_frame *frame_cube_coadd = NULL;
3113 cpl_image *mask = NULL;
3114 hdrl_image *collapsedCube = NULL;
3115 cpl_bivector *spectrum = NULL;
3116 cpl_vector *error = NULL;
3117 cpl_vector *totalFlux = NULL;
3118 cpl_vector *qual = NULL;
3119 cpl_propertylist *plist = NULL;
3120 char *fnamePrefix = NULL,
3122 const char *fname = NULL;
3123 struct esParamStruct esParams;
3124 struct esSofStruct esSof;
3127 cpl_msg_info(cpl_func,
"Extracting data source from %s", pcatg);
3129 frame_cube_coadd = cpl_frameset_find(frameset, pcatg);
3130 fname = cpl_frame_get_filename(frame_cube_coadd);
3133 plist = cpl_propertylist_load(fname, 1);
3134 refPixel = cpl_propertylist_get_double(plist,
"CRPIX3");
3135 startLambda = cpl_propertylist_get_double(plist,
"CRVAL3");
3136 if(cpl_propertylist_has(plist,
"CDELT3")) {
3137 deltaLambda = cpl_propertylist_get_double(plist,
"CDELT3");
3139 deltaLambda = cpl_propertylist_get_double(plist,
"CD3_3");
3142 startLambda = startLambda - (refPixel - 1.) * deltaLambda;
3156 cpl_image *contribMap = NULL;
3157 collapsedCube = eris_ifu_extract_spec_collapse(esSof.cube, &contribMap);
3160 char* pro_catg = cpl_sprintf(
"%s_MEDIAN",proCatg);
3162 cpl_free(fnamePrefix);
3163 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG, pro_catg);
3164 char *filename = cpl_sprintf(
"%s_cube_median.fits", pipefile_prefix);
3166 if( strstr(pro_catg,
"STD") != NULL ||
3167 strstr(pro_catg,
"PSF") != NULL ){
3168 cpl_propertylist* qcheader =
3171 cpl_propertylist_append(plist, qcheader);
3172 cpl_propertylist_delete(qcheader);
3178 pipefile_prefix, plist,
"RADECSYS", filename,
3181 rmse, mask_ima, flag16bit, UNIT_ADU);
3182 cpl_image_delete(mask_ima);
3193 mask = eris_ifu_extract_spec_create_mask(esParams, esSof,
3195 esParams.productDepth));
3197 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG,
3198 ERIS_IFU_PRO_JITTER_EXTRACTION_MASK);
3199 filename = cpl_sprintf(
"%s_extraction_mask.fits", pipefile_prefix);
3200 cpl_dfs_save_image(frameset, plist, parlist, frameset, NULL,
3201 mask, CPL_TYPE_FLOAT, pipefile_prefix,
3203 PACKAGE
"/" PACKAGE_VERSION,
3208 if (esParams.mask_method == OPTIMAL) {
3210 spectrum = eris_ifu_optimal_extraction(esSof.cube,
3211 esSof.qualImagelist,
3213 startLambda, deltaLambda,
3214 esParams.productDepth,
3218 spectrum = eris_ifu_extract_spectrum(esSof.cube, mask,
3219 startLambda, deltaLambda,
3220 &error, &totalFlux, &qual));
3223 eris_ifu_jitter_spec_save_products(frameset, parlist, esSof, spectrum,
3224 error, totalFlux, stdParams.productDepth, CPL_TRUE,
3232 if (esSof.mask != mask) {
3236 eris_ifu_extract_free_esSofStruct(&esSof);
3242 return cpl_error_get_code();
3265 cpl_frameset* frames,
3266 struct esParamStruct params,
3267 struct esSofStruct *sof)
3269 cpl_frame *frame = NULL;
3274 if (frames == NULL) {
3276 "missing frameset");
3279 if (cpl_frameset_is_empty(frames)) {
3281 "SOF file is empty or missing");
3288 char *proCatg = NULL;
3289 char *fnamePrefix = NULL;
3291 frame = cpl_frameset_find(frames, proCatg);
3292 cpl_free(fnamePrefix);
3295 if (frame != NULL) {
3298 cpl_frame_get_filename(frame),
3299 &sof->header, &sof->qualImagelist, &sof->qualityType));
3305 "missing \"%s\" tag in the SOF, input data cube",
3312 if (params.mask_method == MASK) {
3313 frame = cpl_frameset_find(frames, ERIS_IFU_UTIL_MASK);
3315 if (frame != NULL) {
3317 sof->mask = cpl_image_load(
3318 cpl_frame_get_filename(frame),
3319 CPL_TYPE_DOUBLE, 0, 0));
3322 "missing \"%s\" tag in the SOF, extraction mask",
3323 ERIS_IFU_UTIL_MASK);
3331 return cpl_error_get_code();
3356 hdrl_imagelist *cube,
3357 cpl_propertylist *hdr,
3363 cpl_ensure_code(cube,CPL_ERROR_NULL_INPUT);
3364 cpl_ensure_code(hdr,CPL_ERROR_NULL_INPUT);
3370 cpl_propertylist_get_double(hdr,
"ESO TEL AIRM START") +
3371 cpl_propertylist_get_double(hdr,
"ESO TEL AIRM END")) / 2.;
3373 cpl_propertylist_get_double(hdr,
"ESO TEL PARANG START") +
3374 cpl_propertylist_get_double(hdr,
"ESO TEL PARANG END")) / 2.;
3376 cpl_propertylist_get_double(hdr,
"ESO ADA POSANG");
3378 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI TEMP");
3380 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI RHUM");
3382 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI PRES START") +
3383 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI PRES END")) / 2.;
3385 cpl_wcs *wcs = cpl_wcs_new_from_propertylist(hdr);
3388 hdrl_parameter *darParams = NULL;
3390 (hdrl_value) {airmass, 0.},
3391 (hdrl_value) {parang, 0.},
3392 (hdrl_value) {posang, 0.},
3393 (hdrl_value) {temp, 0.},
3394 (hdrl_value) {rhum, 0.},
3395 (hdrl_value) {pres, 0.},
3399 cpl_vector *lambdaIn = NULL;
3402 cpl_vector_multiply_scalar(lambdaIn, 10000.);
3403 lambdaRef = cpl_vector_get(lambdaIn, cpl_vector_get_size(lambdaIn)/2);
3404 int naxis3 = cpl_propertylist_get_int(hdr, NAXIS3);
3405 cpl_vector *xShift = cpl_vector_new(naxis3);
3406 cpl_vector *yShift = cpl_vector_new(naxis3);
3407 cpl_vector *xShiftErr = cpl_vector_new(naxis3);
3408 cpl_vector *yShiftErr = cpl_vector_new(naxis3);
3412 (hdrl_value) {lambdaRef, 0.}, lambdaIn,
3413 xShift, yShift, xShiftErr, yShiftErr ));
3414 cpl_msg_info(cpl_func,
"DAR correction shift in X min/max: %.1f/%.1f, "
3415 "in Y min/max: %.1f/%.1f",
3416 cpl_vector_get_min(xShift), cpl_vector_get_max(xShift),
3417 cpl_vector_get_min(yShift), cpl_vector_get_max(yShift));
3420 radius = CPL_KERNEL_DEF_WIDTH;
3423 length = CPL_KERNEL_DEF_SAMPLES;
3426 const char *kernelName[] = {
3436 cpl_msg_info(cpl_func,
"DAR correction: shift method %s, radius %.1f, length %d",
3437 kernelName[method], radius, length);
3439 for (cpl_size sx=0; sx<naxis3; sx++) {
3443 cpl_image *err2Img = cpl_image_duplicate(errImg);
3445 cpl_size nx = cpl_image_get_size_x(inImg);
3446 cpl_size ny = cpl_image_get_size_y(inImg);
3447 cpl_image *outImg = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3448 cpl_image *out2Img = NULL;
3450 double shiftX = cpl_vector_get(xShift, sx);
3451 double shiftY = cpl_vector_get(yShift, sx);
3453 out2Img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3455 method, radius, length));
3456 }
else if (method == 7) {
3458 }
else if (method == 8) {
3461 cpl_image_reject_from_mask(err2Img, cpl_image_get_bpm(outImg));
3470 cpl_image_delete(outImg);
3471 cpl_image_delete(err2Img);
3480 cpl_wcs_delete(wcs);
3485 return cpl_error_get_code();
3510 cpl_kernel kernelType,
3512 cpl_size kernelSize)
3515 cpl_ensure_code(inImg, CPL_ERROR_NULL_INPUT);
3516 cpl_ensure_code(out1Img, CPL_ERROR_NULL_INPUT);
3517 cpl_ensure_code(out2Img, CPL_ERROR_NULL_INPUT);
3522 cpl_vector *xprofile = NULL;
3524 cpl_vector *yprofile = NULL;
3526 cpl_image *correction_map = NULL;
3528 nx = cpl_image_get_size_x(inImg);
3529 ny = cpl_image_get_size_x(inImg);
3530 cpl_image *deltax = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3531 cpl_image *deltay = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3532 cpl_image_add_scalar(deltax, xShift);
3533 cpl_image_add_scalar(deltay, yShift);
3535 xprofile = cpl_vector_new(kernelSize);
3536 cpl_vector_fill_kernel_profile(xprofile, kernelType, width);
3538 yprofile = cpl_vector_new(kernelSize);
3539 cpl_vector_fill_kernel_profile(yprofile, kernelType, width);
3543 cpl_image_warp(out1Img, inImg, deltax, deltay, xprofile, xradius, yprofile, yradius);
3546 correction_map = cpl_image_new(cpl_image_get_size_x(out1Img),
3547 cpl_image_get_size_y(out1Img),
3548 cpl_image_get_type(out1Img));
3549 cpl_image_fill_jacobian(correction_map, deltax, deltay);
3550 cpl_image_copy(out2Img, out1Img, 1, 1);
3551 cpl_image_multiply(out2Img, correction_map);
3565 return cpl_error_get_code();
3591 const gsl_interp2d_type *T)
3599 gsl_set_error_handler_off();
3600 const double xa[] = {
3601 0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,
3602 16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,
3603 31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,
3604 46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,
3607 const double ya[]= {
3608 0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,
3609 16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,
3610 31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,
3611 46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,
3614 double *za = cpl_image_get_data_double(inImg);
3617 nx = cpl_image_get_size_x(outImg);
3618 ny = cpl_image_get_size_y(outImg);
3619 gsl_spline2d *spline = gsl_spline2d_alloc(T, nx, ny);
3620 gsl_interp_accel *xacc = gsl_interp_accel_alloc();
3621 gsl_interp_accel *yacc = gsl_interp_accel_alloc();
3622 gsl_spline2d_init(spline, xa, ya, za, nx, ny);
3626 for (
int i = 0; i < nx; ++i)
3628 double xi = i - xShift;
3630 for (
int j = 0; j < nx; ++j)
3632 double yj = j - yShift;
3633 if (xi > nx-1 || xi < 0 || yj > ny-1 || yj < 0) {
3638 cpl_image_set(outImg, i+1, j+1, z);
3644 gsl_spline2d_free(spline);
3645 gsl_interp_accel_free(xacc);
3646 gsl_interp_accel_free(yacc);
3647 return cpl_error_get_code();
3664 cpl_ensure(sof, CPL_ERROR_NULL_INPUT, -1);
3665 cpl_ensure(tag, CPL_ERROR_NULL_INPUT, -1);
3668 cpl_frameset* loc_sof = cpl_frameset_duplicate(sof);
3669 cpl_frame* frame = cpl_frameset_find(loc_sof, tag);
3672 cpl_frameset_erase_frame(loc_sof, frame);
3673 frame = cpl_frameset_find(loc_sof, tag);
3677 cpl_frameset_delete(loc_sof);
3701 cpl_boolean apply_flat)
3703 cpl_ensure(frameset, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
3704 cpl_ensure(pcatg, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
3707 cpl_frame* frm_tmp = cpl_frameset_find(frameset, pcatg);
3708 cpl_frame* frm_dup = cpl_frame_duplicate(frm_tmp);
3709 const char* fname = cpl_frame_get_filename(frm_tmp);
3710 const char* fname_new = NULL;
3711 cpl_propertylist* plist = cpl_propertylist_load(fname, 0);
3713 if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_OBJ_CUBE) == 0) {
3715 fname_new =
"eris_ifu_jitter_obj_cube_coadd.fits";
3716 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD);
3717 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD);
3718 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_DAR_CUBE) == 0) {
3719 fname_new =
"eris_ifu_jitter_dar_cube_coadd.fits";
3720 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_COADD);
3721 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_COADD);
3722 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_TWK_CUBE) == 0) {
3723 fname_new =
"eris_ifu_jitter_twk_cube_coadd.fits";
3724 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD);
3725 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD);
3726 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_PSF_CUBE) == 0) {
3728 fname_new =
"eris_ifu_stdstar_psf_cube_coadd.fits";
3729 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
3730 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
3731 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_STD_CUBE) == 0){
3734 fname_new =
"eris_ifu_stdstar_std_cube_coadd.fits";
3735 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
3736 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
3738 fname_new =
"eris_ifu_stdstar_no_flat_std_cube_coadd.fits";
3739 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT);
3740 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT);
3742 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE) == 0){
3745 fname_new =
"eris_ifu_stdstar_std_flux_cube_coadd.fits";
3746 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD);
3747 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD);
3749 fname_new =
"eris_ifu_stdstar_no_flat_std_flux_cube_coadd.fits";
3750 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT);
3751 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT);
3755 char* cmd = cpl_sprintf(
"cp %s %s",fname, fname_new);
3756 cpl_msg_debug(cpl_func,
"Copying %s", cmd);
3757 int status = system(cmd);
3759 cpl_msg_warning(cpl_func,
"call to system() failed");
3761 cpl_frame_set_filename(frm_dup, fname_new);
3762 cpl_frame_set_group(frm_dup, CPL_FRAME_GROUP_PRODUCT);
3763 cpl_frame_set_level(frm_dup, CPL_FRAME_LEVEL_FINAL);
3765 cpl_propertylist_save(plist, fname_new, CPL_IO_CREATE);
3766 cpl_propertylist_delete(plist);
3768 plist = cpl_propertylist_load(fname, 1);
3769 cpl_imagelist* data = cpl_imagelist_load(fname,CPL_TYPE_FLOAT, 1);
3770 cpl_imagelist_save(data, fname_new, CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND);
3771 cpl_imagelist_delete(data);
3772 cpl_propertylist_delete(plist);
3774 plist = cpl_propertylist_load(fname, 2);
3775 data = cpl_imagelist_load(fname, CPL_TYPE_FLOAT, 2);
3776 cpl_imagelist_save(data, fname_new, CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND);
3777 cpl_imagelist_delete(data);
3778 cpl_propertylist_delete(plist);
3780 plist = cpl_propertylist_load(fname, 3);
3781 data = cpl_imagelist_load(fname, CPL_TYPE_INT, 3);
3782 cpl_imagelist_save(data, fname_new, CPL_TYPE_INT, plist, CPL_IO_EXTEND);
3783 cpl_imagelist_delete(data);
3784 cpl_propertylist_delete(plist);
3789 cpl_frameset_insert(frameset, frm_dup);
3793 return cpl_error_get_code();
3816 struct sofStruct *sof)
3818 cpl_error_code retval = CPL_ERROR_NONE;
3819 cpl_propertylist *header = NULL;
3833 if (sof->exposureTableCnt < 2) {
3834 return CPL_ERROR_NONE;
3844 for (sx = 0; sx < sof->exposureTableCnt; sx++) {
3845 header = sof->exposureTable[sx].hdr;
3846 cumOffset1 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS1);
3847 cumOffset2 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS2);
3849 if (cumOffset1 == 0.0 && cumOffset2 == 0.0) {
3852 cpl_msg_info(
"update_WCS_with_OCS_keywords",
3853 "%d %s : %f/%f %.1f/%.1f %g %g %g %g",
3854 sx, cpl_frame_get_filename(sof->exposureTable[sx].frame),
3855 cpl_propertylist_get_double(header, FHDR_E_CRVAL1),
3856 cpl_propertylist_get_double(header, FHDR_E_CRVAL2),
3857 cpl_propertylist_get_double(header,
"CRPIX1"),
3858 cpl_propertylist_get_double(header,
"CRPIX2"),
3859 cpl_propertylist_get_double(header,
"CD1_1"),
3860 cpl_propertylist_get_double(header,
"CD1_2"),
3861 cpl_propertylist_get_double(header,
"CD2_1"),
3862 cpl_propertylist_get_double(header,
"CD2_2")
3870 header = sof->exposureTable[rx].hdr;
3871 crval1 = cpl_propertylist_get_double(header, FHDR_E_CRVAL1);
3872 crval2 = cpl_propertylist_get_double(header, FHDR_E_CRVAL2);
3873 cumOffset1 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS1);
3874 cumOffset2 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS2);
3877 crval1Ref = crval1 - cumOffset1 / 3600.;
3878 crval2Ref = crval2 - cumOffset2 / 3600.;
3880 cpl_msg_info(
"update_WCS_with_OCS_keywords",
"ref: %d %f %f",
3881 rx, crval1Ref, crval2Ref);
3883 for (sx = 0; sx < sof->exposureTableCnt; sx++) {
3884 header = sof->exposureTable[sx].hdr;
3885 crval1 = cpl_propertylist_get_double(header, FHDR_E_CRVAL1);
3886 crval2 = cpl_propertylist_get_double(header, FHDR_E_CRVAL2);
3887 cumOffset1 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS1);
3888 cumOffset2 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS2);
3890 crval1New = crval1Ref + cumOffset1 / 3600.;
3891 crval2New = crval2Ref + cumOffset2 / 3600.;
3892 cpl_propertylist_set_double(header, FHDR_E_CRVAL1, crval1New);
3893 cpl_propertylist_set_double(header, FHDR_E_CRVAL2, crval2New);
3896 cpl_msg_info(
"update_WCS_with_OCS_keywords",
3897 "%d %f -> %f (%f) %f -> %f (%f) %f / %f %f / %f %f // %f",
3899 crval1, crval1New, (crval1-crval1New)*3600.,
3900 crval2, crval2New, (crval2-crval2New)*3600.,
3901 cumOffset1, cumOffset2,
3902 (crval1New-crval1Ref)*3600., (crval2New-crval2Ref)*3600.,
3903 (crval1-crval1Ref)*3600., (crval2-crval2Ref)*3600. );
cpl_image * eris_ifu_wave_resampled_arc_image(const cpl_image *arcImg, const cpl_image *waveCalImg, ifsBand band, double minLambda, double maxLambda, cpl_propertylist *plist, int axisNumber)
Resample arc image to uniform wavelength grid.
cpl_error_code eris_ifu_append_qc_float(cpl_propertylist *pl, const char *name, float val, const char *comment)
Append a QC parameter of type FLOAT to a property list.
cpl_error_code eris_ifu_extract_obj_frames(const cpl_frameset *sof, cpl_frameset *obj)
extract object raw frames from frame set and put them in a new one
cpl_frameset * eris_ifu_extract_frameset(const cpl_frameset *in, const char *tag)
Extract frames with a specific tag from a frameset.
hdrl_imagelist * eris_ifu_load_deq_hdrl_imagelist(const char *filename, cpl_propertylist **primaryHeader, cpl_imagelist **qualImagelist, deqQualityType *qualityType)
Load a DEQ-format cube into an HDRL imagelist structure.
cpl_error_code eris_ifu_save_deq_image(cpl_frameset *allframes, cpl_propertylist *header, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_frame *inherit, const char *recipe, const cpl_propertylist *applist, const char *remregexp, const char *filename, const cpl_image *image, const cpl_image *error, deqErrorType errorType, const cpl_image *dataQualityMask, deqQualityType dataQualityType, const char *unit)
Save a DFS-compliant image product with data, error, and quality extensions.
cpl_error_code eris_ifu_save_deq_cube(cpl_frameset *allframes, cpl_propertylist *header, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_frame *inherit, const char *recipe, cpl_propertylist *applist, const char *remregexp, const char *filename, cpl_imagelist *data, cpl_imagelist *error, deqErrorType errorType, const cpl_imagelist *dataQualityMask, deqQualityType qualityType)
Save a DFS-compliant cube product with data, error, and quality extensions.
ifsBand eris_ifu_get_band(const cpl_propertylist *header)
Determine preoptic band.
cpl_error_code eris_ifu_extract_sky_frames(const cpl_frameset *sof, cpl_frameset *sky)
extract sky raw frames from frame set and put them in a new one
cpl_error_code eris_ifu_extract_mst_frames(const cpl_frameset *sof, cpl_frameset *cdb)
extract master and ref frames from input set and put them in a new one
hdrl_image * eris_ifu_dist_warp_bpm(const hdrl_image *bpmIn, cpl_polynomial **poly_u, const cpl_table *borders, productDepthType productDepth)
Warp bad pixel mask using distortion polynomials.
hdrl_image * eris_ifu_dist_warp_image(const hdrl_image *imgIn, cpl_polynomial **poly_u, const cpl_table *borders)
Warp full detector image by warping each slitlet.
#define ASSURE(condition, error,...)
error handling macro (from fors-pipeline)
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define CATCH_MSG()
Displays an error message.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
#define BRK_IF_NULL(function)
If function is or returns a NULL pointer, then the try-block is exited.
#define CATCH_MSGS()
Displays an error message stack.
cpl_error_code eris_ifu_1d_interpolation(double *xIn, double *yIn, int nIn, double *xOut, double *yOut, int nOut, const int interType)
Perform 1D interpolation using GSL routines.
cpl_error_code eris_ifu_bpm_correction(hdrl_image *himg, hdrl_image *badPixelMaskImg)
eris_ifu_bpm_correction
hdrl_image * eris_ifu_warp_polynomial_image(const hdrl_image *hdrlInImg, const cpl_polynomial *poly_u, const cpl_polynomial *poly_v)
Warp an HDRL image using 2D polynomial transformations.
cpl_error_code eris_ifu_jitter_process_cubes(struct sofStruct *sof, struct stdParamStruct stdParams, struct paramStruct params, cpl_frameset *frameset, const cpl_parameterlist *parlist, const char *recipe_name, cubeType *obj_type)
Process and combine data cubes with sky tweaking and DAR correction.
cpl_error_code eris_ifu_dar_gsl_shift(cpl_image *inImg, cpl_image *outImg, double xShift, double yShift, const gsl_interp2d_type *T)
Apply DAR correction using GSL 2D interpolation.
cpl_error_code eris_ifu_jitter_extract_spec_processSof(cubeType obj_type, cpl_frameset *frames, struct esParamStruct params, struct esSofStruct *sof)
Process SOF for spectral extraction.
void eris_ifu_jitter_free_sofStruct(struct sofStruct *sof_struct)
Free and clean up SOF structure and all contained data.
cubeType eris_ifu_jitter_get_sky_type(sofModes mode)
Get sky cube type from SOF observation mode.
cpl_error_code eris_ifu_jitter_extract(cpl_frameset *frameset, const cpl_parameterlist *parlist, cubeType obj_type, const char *pcatg, struct stdParamStruct stdParams, const char *pipefile_prefix, const char *context)
Main spectral extraction function.
cpl_error_code eris_frameset_duplicate_cube_tag(cpl_frameset *frameset, const char *pcatg, cpl_boolean apply_flat)
Duplicate a cube file with different PRODCATG for coadded version.
void eris_ifu_jitter_get_cube_type_string(cubeType type)
Print cube type as string to log.
cpl_error_code eris_ifu_update_wcs_with_OCS_keywords(struct sofStruct *sof)
Update WCS coordinates from OCS cumulative offset keywords.
cpl_error_code eris_image_get_valid_data_range(cpl_image *image, cpl_size *min, cpl_size *max)
Determine valid data range in spectral direction (find NaN-dominated rows)
#define ERIS_IFU_SKIP_SKY_CORR_PLANES
*static */void
cpl_error_code eris_ifu_extract_spec(const cpl_imagelist *data_in, const cpl_imagelist *noise_in, cpl_image *mask, cpl_vector **spec_data_out, cpl_vector **spec_noise_out)
Extract a spectrum from 3D data cube.
cpl_error_code eris_ifu_jitter_get_procatg_and_filename(cubeType type, char **proCatg, char **filenamePrefix)
Get the value of the PRO.CATG and the filename as function of the type of cube.
hdrl_image * eris_ifu_jitter_subtract_background(skyTweakModes sky_tweak, int objIdx, struct sofStruct *sof, productDepthType productDepth)
Subtract sky or dark background from raw exposure image.
cubeType eris_ifu_jitter_get_obj_type(sofModes mode)
Get object cube type from SOF observation mode.
cpl_imagelist * eris_ifu_jitter_reconstruct_cube(cpl_image *resampledDetImage, slitletDetectionModes mode, int fineTuneMode, double firstCol, cpl_vector *distancesV, cpl_bivector *positionsVV)
Function to create a 3D-data cube from a re-sampled image.
cpl_error_code eris_ifu_jitter_process_exposures(struct sofStruct *sof, struct stdParamStruct stdParams, struct paramStruct params, cpl_frameset *frameset, const cpl_parameterlist *parlist, const char *recipe_name, const char *context)
Process all raw exposures into calibrated 3D data cubes.
cpl_error_code eris_ifu_dar_cpl_shift(cpl_image *inImg, cpl_image *out1Img, cpl_image *out2Img, double xShift, double yShift, cpl_kernel kernelType, double width, cpl_size kernelSize)
Apply DAR correction using CPL image shifting.
hdrl_imagelist * eris_ifu_jitter_build_cube(hdrl_image *inputImage, int sofIdx, struct sofStruct *sof, struct paramStruct params, bool doVelocityCorrection, cpl_polynomial *ohLambdaCorrection, productDepthType productDepth)
Build 3D data cube from 2D detector image.
int eris_frameset_count_tag(cpl_frameset *sof, const char *tag)
Count frames with specified tag in frameset.
cpl_error_code eris_ifu_dar_correction(hdrl_imagelist *cube, cpl_propertylist *hdr, int method, double radius, int length)
Apply Differential Atmospheric Refraction (DAR) correction.
cpl_error_code eris_ifu_extract_spec_fetch_params(const cpl_parameterlist *parlist, struct esParamStruct *params, const char *context)
Fetch spectral extraction parameters from parameter list.
cubeType eris_ifu_jitter_get_coadd_obj_type(cubeType type)
Convert cube type to corresponding coadded cube type.
cpl_polynomial * eris_ifu_lcorr_get(cpl_imagelist *cube, hdrl_imagelist *hdrlCube, const cpl_propertylist *header, cpl_vector *peaks, const int pfit_order)
Create wavelength correction polynomial from IFU cube using OH lines.
cpl_vector * eris_ifu_lcorr_create_lambda_vector(const cpl_propertylist *header)
Create wavelength vector from FITS header WCS keywords.
cpl_imagelist * eris_ifu_sky_tweak(cpl_imagelist *obj, cpl_imagelist *sky, const cpl_propertylist *header, float min_frac, int tbsub, int skip_last, int stretch, int stretch_degree, int stretch_resampling, int plot, cpl_imagelist **new_sky)
Main sky tweaking and subtraction function.
cpl_error_code eris_ifu_save_imagelist(cpl_frameset *fs, cpl_frame *inherit, const cpl_propertylist *plist, const cpl_parameterlist *parlist, const char *recipe, const char *procatg, const char *filename, cpl_type type, const cpl_imagelist *imglist)
Save imagelist with DFS compliance.
void eris_ifu_free_propertylist(cpl_propertylist **item)
Free memory and set pointer to null.
void eris_ifu_free_string(char **item)
Free memory and set pointer to null.
void eris_ifu_free_vector(cpl_vector **item)
Free memory and set pointer to null.
void eris_ifu_free_table(cpl_table **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_split_hdrl_imagelist(hdrl_imagelist *cube, cpl_imagelist *dataCube, cpl_imagelist *errorCube)
extract from hdrl_imagelist the data and error information
cpl_error_code eris_ifu_get_plane_cut_min_max(ifsBand band, cpl_size *zmin, cpl_size *zmax)
Get band-specific plane indices for NaN trimming.
void eris_ifu_free_polynomial(cpl_polynomial **item)
Free memory and set pointer to null.
cpl_propertylist * eris_compute_psf_qc(hdrl_image *hima, const cpl_parameterlist *parlist, const char *context)
compute QC parameters on a PSF STD image
cpl_mask * eris_ifu_hima_get_obj_mask_percent(hdrl_image *hima, const double percent)
find mask flagging pixels above percent(%) pixels with lower intensity
void eris_ifu_free_imagelist(cpl_imagelist **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_mask_nans_in_cube(cpl_imagelist *cube)
Mask NaNs and Infs in CPL imagelist (cube)
void eris_ifu_free_hdrl_imagelist(hdrl_imagelist **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_save_hdrl_image_dbg(const hdrl_image *hdrl_img, const char *filename, int singlefile, const cpl_propertylist *pl)
Save HDRL image for debugging (data + error + mask)
void eris_ifu_free_hdrl_image(hdrl_image **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_cube_trim_nans(const cpl_size zmin, const cpl_size zmax, hdrl_imagelist **iml, cpl_imagelist **bpm, cpl_propertylist *header)
Trim NaN-dominated planes from cube edges.
cpl_imagelist * eris_ifu_interpolatedMask_to_maskZero(cpl_imagelist *bpmCube, double threshold)
return cube flagging (as 1) pixels above a given threshold
void eris_ifu_free_image(cpl_image **item)
Free memory and set pointer to null.
void eris_ifu_free_mask(cpl_mask **item)
Free memory and set pointer to null.
void eris_ifu_free_parameterlist(cpl_parameterlist **item)
Free memory and set pointer to null.
void eris_ifu_free_bivector(cpl_bivector **item)
Free memory and set pointer to null.
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
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
cpl_error_code hdrl_dar_compute(const hdrl_parameter *params, const hdrl_value lambdaRef, const cpl_vector *lambdaIn, cpl_vector *xShift, cpl_vector *yShift, cpl_vector *xShiftErr, cpl_vector *yShiftErr)
Correct the pixel coordinates of all pixels of a given pixel table for differential atmospheric refra...
hdrl_parameter * hdrl_dar_parameter_create(hdrl_value airmass, hdrl_value parang, hdrl_value posang, hdrl_value temp, hdrl_value rhum, hdrl_value pres, cpl_wcs *wcs)
Creates DAR parameters object with the values in the header.
cpl_error_code hdrl_image_sub_image(hdrl_image *self, const hdrl_image *other)
Subtract two images, store the result in the first image.
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
hdrl_value hdrl_image_get_median(const hdrl_image *self)
computes the median and associated error of an image.
cpl_error_code hdrl_image_div_image(hdrl_image *self, const hdrl_image *other)
Divide two images, store the result in the first image.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
cpl_mask * hdrl_image_get_mask(hdrl_image *himg)
get cpl bad pixel mask from image
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
hdrl_value hdrl_image_get_mean(const hdrl_image *self)
computes mean pixel value and associated error of an image.
cpl_error_code hdrl_image_insert(hdrl_image *self, const cpl_image *image, const cpl_image *error, cpl_size xpos, cpl_size ypos)
Copy cpl images into an hdrl 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
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
cpl_error_code hdrl_image_sub_scalar(hdrl_image *self, hdrl_value value)
Elementwise subtraction of a scalar from an image.
cpl_error_code hdrl_image_accept_all(hdrl_image *self)
Accept all pixels in an image.
cpl_error_code hdrl_imagelist_collapse_mean(const hdrl_imagelist *himlist, hdrl_image **out, cpl_image **contrib)
Mean collapsing of image list.
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
cpl_size hdrl_imagelist_get_size_y(const hdrl_imagelist *himlist)
Get number of rows of images in the imagelist.
hdrl_imagelist * hdrl_imagelist_create(cpl_imagelist *imlist, cpl_imagelist *errlist)
Create an hdrl_imagelist out of 2 cpl_imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
cpl_size hdrl_imagelist_get_size_x(const hdrl_imagelist *himlist)
Get number of colums of images in the imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
cpl_error_code sc_skycorr(cpl_parameterlist *parlist, cpl_table *scispec, cpl_table *skyspec, int product_depth)