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"
71#define ERIS_IFU_SKIP_SKY_CORR_PLANES 75
72void eris_ifu_jitter_free_sofStruct(
struct sofStruct* sof_struct){
75 if(sof_struct != NULL) {
76 if(sof_struct->exposureTable != NULL) {
77 for(cpl_size i = 0; i < sof_struct->exposureTableCnt; i++) {
78 if (sof_struct->exposureTable != NULL) {
80 if(sof_struct->exposureTable[i].frame != NULL) {
83 if(sof_struct->exposureTable[i].hdr != NULL) {
84 cpl_propertylist_delete(sof_struct->exposureTable[i].hdr);
86 if(sof_struct->exposureTable[i].rawImage != NULL) {
89 if(sof_struct->exposureTable[i].cube != NULL){
92 if(sof_struct->exposureTable[i].cubeBpm != NULL){
93 cpl_imagelist_delete(sof_struct->exposureTable[i].cubeBpm);
95 if(sof_struct->exposureTable[i].cubeHdr != NULL) {
96 cpl_propertylist_delete(sof_struct->exposureTable[i].cubeHdr);
98 if(sof_struct->exposureTable[i].badPixelMask != NULL) {
99 cpl_mask_delete(sof_struct->exposureTable[i].badPixelMask);
101 if(sof_struct->exposureTable[i].darkSubtrImage != NULL){
104 if(sof_struct->exposureTable[i].skySubtrImage != NULL){
114 if(sof_struct->waveMap != NULL) cpl_image_delete(sof_struct->waveMap);
115 if(sof_struct->badPixelMask != NULL) cpl_mask_delete(sof_struct->badPixelMask);
116 if(sof_struct->distortion != NULL) {
117 for (
int sx = 0; sx < SLITLET_CNT; sx++) {
118 cpl_polynomial_delete(sof_struct->distortion[sx]);
120 cpl_free(sof_struct->distortion);
122 if(sof_struct->dqi != NULL) {
123 cpl_image_delete(sof_struct->dqi);
125 if(sof_struct->oh_ref_peaks != NULL) cpl_vector_delete(sof_struct->oh_ref_peaks);
126 if(sof_struct->oh_ref_frame != NULL) cpl_frame_delete(sof_struct->oh_ref_frame);
127 if(sof_struct->borders != NULL) cpl_table_delete(sof_struct->borders);
128 if(sof_struct->poly_u != NULL) cpl_polynomial_delete(sof_struct->poly_u);
129 if(sof_struct->poly_v != NULL) cpl_polynomial_delete(sof_struct->poly_v);
130 if(sof_struct->distances != NULL) cpl_vector_delete(sof_struct->distances);
131 if(sof_struct->positions != NULL) cpl_bivector_delete(sof_struct->positions);
139eris_ifu_jitter_get_cube_type_string(cubeType type)
144 cpl_msg_info(cpl_func,
"type: OBJECT_CUBE");
147 cpl_msg_info(cpl_func,
"type: STD_CUBE");
150 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE");
152 case STD_CUBE_NOFLAT:
153 cpl_msg_info(cpl_func,
"type: STD_CUBE_NOFLAT");
155 case STD_FLUX_CUBE_NOFLAT:
156 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE_NOFLAT");
159 cpl_msg_info(cpl_func,
"type: PSF_CUBE");
161 case SKY_OBJECT_CUBE:
162 cpl_msg_info(cpl_func,
"type: SKY_OBJECT_CUBE");
165 cpl_msg_info(cpl_func,
"type: SKY_STD_CUBE");
167 case SKY_STD_FLUX_CUBE:
168 cpl_msg_info(cpl_func,
"type: SKY_STD_FLUX_CUBE");
171 cpl_msg_info(cpl_func,
"type: SKY_PSF_CUBE");
174 cpl_msg_info(cpl_func,
"type: TWEAKED_CUBE");
177 cpl_msg_info(cpl_func,
"type: DAR_CUBE");
180 cpl_msg_info(cpl_func,
"type: JITTER_CUBE");
183 cpl_msg_info(cpl_func,
"type: BPM_CUBE");
185 case OBJECT_CUBE_COADD:
186 cpl_msg_info(cpl_func,
"type: OBJECT_CUBE_COADD");
189 cpl_msg_info(cpl_func,
"type: STD_CUBE_COADD");
192 cpl_msg_info(cpl_func,
"type: PSF_CUBE_COADD");
194 case STD_FLUX_CUBE_COADD:
195 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE_COADD");
197 case DAR_STD_FLUX_CUBE:
198 cpl_msg_info(cpl_func,
"type: DAR_STD_FLUX_CUBE");
200 case TWEAKED_CUBE_COADD:
201 cpl_msg_info(cpl_func,
"type: TWEAKED_CUBE_COADD");
204 cpl_msg_info(cpl_func,
"type: DAR_CUBE_COADD");
206 case STD_FLUX_CUBE_COADD_NOFLAT:
207 cpl_msg_info(cpl_func,
"type: STD_FLUX_CUBE_COADD_NOFLAT");
209 case STD_CUBE_COADD_NOFLAT:
210 cpl_msg_info(cpl_func,
"type: STD_CUBE_COADD_NOFLAT");
213 cpl_msg_info(cpl_func,
"type: DEFAULT %d",type);
220eris_ifu_jitter_get_coadd_obj_type(cubeType type)
225 coadd_type = OBJECT_CUBE_COADD;
227 case OBJECT_CUBE_COADD:
228 coadd_type = OBJECT_CUBE_COADD;
231 coadd_type = DAR_CUBE_COADD;
234 coadd_type = STD_CUBE_COADD;
237 coadd_type = STD_CUBE_COADD;
240 coadd_type = STD_FLUX_CUBE_COADD;
242 case STD_FLUX_CUBE_COADD:
243 coadd_type = STD_FLUX_CUBE_COADD;
245 case STD_FLUX_CUBE_COADD_NOFLAT:
246 coadd_type = STD_FLUX_CUBE_COADD_NOFLAT;
248 case STD_CUBE_NOFLAT:
249 coadd_type = STD_CUBE_COADD_NOFLAT;
251 case STD_CUBE_COADD_NOFLAT:
252 coadd_type = STD_CUBE_COADD_NOFLAT;
255 coadd_type = PSF_CUBE_COADD;
258 coadd_type = DAR_CUBE_COADD;
260 case DAR_STD_CUBE_COADD:
261 coadd_type = STD_CUBE_COADD;
263 case TWEAKED_CUBE_COADD:
264 coadd_type = TWEAKED_CUBE_COADD;
267 cpl_msg_warning(cpl_func,
"case %d not found switch to default case",type);
268 coadd_type = OBJECT_CUBE_COADD;
275eris_ifu_jitter_get_obj_type(sofModes mode)
286 type = STD_FLUX_CUBE;
299eris_ifu_jitter_get_sky_type(sofModes mode)
304 type = SKY_OBJECT_CUBE;
310 type = SKY_STD_FLUX_CUBE;
316 type = SKY_OBJECT_CUBE;
325eris_ifu_jitter_save_cpl_cube(
326 cpl_frameset *allframes,
327 cpl_frameset *usedframes,
329 const cpl_parameterlist * parlist,
331 hdrl_imagelist *hdrlCube,
332 cpl_imagelist *bpmCube,
333 cpl_propertylist *hdr,
334 struct paramStruct params,
337 const char* recipe_name)
339 cpl_error_code retVal = CPL_ERROR_NONE;
340 char *proCatg = NULL;
341 char *filenamePrefix = NULL;
342 char *filename = NULL;
346 ASSURE(cube != NULL || hdrlCube != NULL,
347 CPL_ERROR_ILLEGAL_INPUT,
"One of cube or hdrlCube must be not NULL");
348 ASSURE(!(cube != NULL && hdrlCube != NULL),
349 CPL_ERROR_ILLEGAL_INPUT,
"One of cube or hdrlCube must be NULL");
350 eris_ifu_jitter_get_procatg_and_filename(type,&proCatg,&filenamePrefix);
353 filename = cpl_sprintf(
"%s_%s_%3.3d.fits", recipe_name, filenamePrefix, counter);
355 filename = cpl_sprintf(
"%s_%s.fits", recipe_name, filenamePrefix);
357 cpl_propertylist_erase(hdr,
"RADECSYS");
368 if (bpmCube != NULL) {
369 cpl_imagelist_save(bpmCube, filename, CPL_TYPE_INT,
374 cpl_imagelist *datacube = cpl_imagelist_new();
375 cpl_imagelist *errorcube = cpl_imagelist_new();
376 cpl_propertylist *applist = NULL;
379 applist = cpl_propertylist_duplicate(hdr);
380 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG, proCatg);
383 cpl_propertylist_update_string(applist, CPL_DFS_PRO_TYPE,
"CUBE");
384 cpl_propertylist_update_string(applist, CPL_DFS_PRO_TECH,
"CUBE");
388 cpl_imagelist *bpmMaskZero;
390 bpmCube, params.bpmThreshold);
422 cpl_imagelist_delete(datacube);
423 cpl_imagelist_delete(errorcube);
424 cpl_propertylist_delete(applist);
425 cpl_imagelist_delete(bpmMaskZero);
430 retVal = cpl_error_get_code();
453eris_ifu_frameset_extract_obj_set(
const cpl_frameset* set,
struct sofStruct* sof,
457 cpl_ensure(set, CPL_ERROR_NULL_INPUT, NULL);
458 cpl_ensure(sof, CPL_ERROR_NULL_INPUT, NULL);
459 cpl_ensure(ix >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
462 cpl_frameset * obj_set = NULL;
463 cpl_frameset * sky_set = NULL;
464 cpl_frameset * cdb_set = NULL;
465 cpl_frameset * out_set = NULL;
468 obj_set = cpl_frameset_new();
473 sky_set = cpl_frameset_new();
478 cdb_set = cpl_frameset_new();
482 cpl_frame* frame = sof->exposureTable[ix].frame;
486 out_set = cpl_frameset_new();
487 cpl_frameset_insert(out_set, cpl_frame_duplicate(frame));
488 cpl_frameset_join(out_set, sky_set);
489 cpl_frameset_join(out_set, cdb_set);
493 cpl_frameset_delete(obj_set);
494 cpl_frameset_delete(sky_set);
495 cpl_frameset_delete(cdb_set);
501cpl_error_code eris_ifu_jitter_process_exposures(
struct sofStruct *sof,
502 struct stdParamStruct stdParams,
503 struct paramStruct params,
504 cpl_frameset *frameset,
505 const cpl_parameterlist * parlist,
506 const char* recipe_name,
509 cpl_error_code retVal = CPL_ERROR_NONE;
510 hdrl_image *objImg = NULL;
511 hdrl_image *tmpImg = NULL;
512 struct exposureEntry *objEntry;
513 cpl_polynomial *ohLambdaCorrection = NULL;
514 productDepthType productDepth = stdParams.productDepth;
515 bool doOHbasedLambdaCorrection = FALSE;
516 cubeType type = OBJECT_CUBE;
517 const char *expType = NULL;
519 double centralLambda = 0.0;
525 cpl_msg_info(cpl_func,
"Build OBJ and SKY data cubes, may correct wavecal by OH lines, subtract sky background");
527 if ((sof->oh_ref_frame != NULL) && !params.skip_oh_align && !(isSky && params.skip_sky_oh_align)) {
528 doOHbasedLambdaCorrection = TRUE;
530 doOHbasedLambdaCorrection = FALSE;
532 cpl_msg_debug(cpl_func,
"doOHbasedLambdaCorrection: %d, isSky: %d, "
533 "params.skip_sky_oh_align: %d, params.skip_oh_align: %d",
534 doOHbasedLambdaCorrection, isSky,
535 params.skip_sky_oh_align, params.skip_oh_align);
537 if (getenv(
"USE_OCS") != NULL) {
538 eris_ifu_update_wcs_with_OCS_keywords(sof);
541 for (
int ix=0; ix < sof->exposureTableCnt; ix++) {
542 if (sof->exposureTable[ix].isObject) {
545 type = eris_ifu_jitter_get_obj_type(sof->mode);
549 type = eris_ifu_jitter_get_sky_type(sof->mode);
551 cpl_msg_info(__func__,
"Process exposure #\%3.3d %s %s", ix, expType,
552 cpl_frame_get_filename(sof->exposureTable[ix].frame));
554 objEntry = &sof->exposureTable[ix];
555 objImg = objEntry->rawImage;
559 objEntry->cube = eris_ifu_jitter_build_cube(
560 objImg, ix, sof, params,
false,
561 ohLambdaCorrection, productDepth));
566 if (doOHbasedLambdaCorrection) {
573 char* param_name = cpl_sprintf(
"%s.oh_align_poly_order", context);
574 cpl_msg_info(cpl_func,
"pname: %s",param_name);
575 pfit_order = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, param_name));
576 cpl_free(param_name);
580 objEntry->cube, objEntry->cubeHdr, sof->oh_ref_peaks, pfit_order));
582 cdelt = cpl_propertylist_get_double(objEntry->cubeHdr,
"CDELT3");
583 centralLambda = cpl_propertylist_get_double(
584 objEntry->cubeHdr,
"CRVAL3") +
586 shift = cpl_polynomial_eval_1d(
587 ohLambdaCorrection, centralLambda, NULL);
588 cpl_msg_info(__func__,
589 "Overall shift of wavelength due OH lambda correction: %f [micron] %f [pixel]",
594 tmpImg = eris_ifu_jitter_subtract_background(
595 params.skyTweak, ix, sof, productDepth);
597 objEntry->cube = eris_ifu_jitter_build_cube(
598 tmpImg, ix, sof, params,
true,
599 ohLambdaCorrection, productDepth);
604 objEntry->cubeHdr,
"LAMBDA SHIFT UM", shift,
605 "[um] OH based lambda shift"));
607 objEntry->cubeHdr,
"LAMBDA SHIFT PIXEL", shift/cdelt,
608 "[px] OH based lambda shift"));
610 if (params.skip_oh_align && (ix == 0)) {
611 cpl_msg_warning(cpl_func,
" |------------------------------------------------------|");
612 cpl_msg_warning(cpl_func,
" | WARNING: with parameter --sky_oh_align the spectral |");
613 cpl_msg_warning(cpl_func,
" | calibration of the outputs is expected to |");
614 cpl_msg_warning(cpl_func,
" | be off for several pixels due to flexure of |");
615 cpl_msg_warning(cpl_func,
" | the instrument |");
616 cpl_msg_warning(cpl_func,
" |------------------------------------------------------|");
620 if (productDepth >= PD_AUXILLIARY) {
644 cpl_frameset* obj_set =
645 eris_ifu_frameset_extract_obj_set(frameset, sof, ix);
646 eris_ifu_jitter_save_cpl_cube(frameset, obj_set, objEntry->frame, parlist,
647 NULL, objEntry->cube, objEntry->cubeBpm, objEntry->cubeHdr, params, type, ix, recipe_name);
648 eris_ifu_jitter_save_cpl_cube(frameset, obj_set, objEntry->frame, parlist,
649 objEntry->cubeBpm, NULL, NULL, objEntry->cubeHdr, params, BPM_CUBE, ix, recipe_name);
650 cpl_frameset_delete(obj_set);
654 cpl_boolean chop_nan = CPL_FALSE;
655 char* param_name = cpl_sprintf(
"%s.chop-nan", context);
657 chop_nan = cpl_parameter_get_bool(
658 cpl_parameterlist_find_const(parlist, param_name));
659 cpl_free(param_name);
668 &(objEntry->cubeBpm), objEntry->cubeHdr);
679 retVal = cpl_error_get_code();
687eris_ifu_jitter_skycorr_from_mask(
struct exposureEntry *objEntry,
688 const cpl_mask*mask_obj,
const int sky_est_method)
695 cpl_size skip = ERIS_IFU_SKIP_SKY_CORR_PLANES;
698 hdrl_value sky = {0, 0};
699 for (cpl_size zx = skip; zx < size_z - skip; zx++){
708 if(sky_est_method==0) {
722 if(cpl_error_get_code() != CPL_ERROR_NONE) {
724 cpl_msg_error(cpl_func,
"Error found in eris_ifu_jitter_skycorr_from_mask. Exit!");
729 return cpl_error_get_code();
733eris_ifu_jitter_get_split_param_int(
const cpl_parameterlist * parlist,
734 const char* pname,
const int min_x,
const int min_y,
735 const int max_x,
const int max_y,
int* px,
int* py)
738 const cpl_parameter* par = NULL;
740 const char* context =
"eris.eris_ifu_jitter";
742 const char* pname_string_value;
743 param_name = cpl_sprintf(
"%s.%s", context, pname);
744 par = cpl_parameterlist_find_const(parlist, param_name);
745 pname_string_value = cpl_parameter_get_string(par);
746 cpl_free(param_name);
751 nFields = sscanf(pname_string_value,
"%d,%d%n", px, py, &end);
753 if (nFields != 2 || end != strlen(pname_string_value)) {
754 cpl_msg_error(cpl_func,
"The %s parameter must be "
755 "a list of two integers separated by a comma", pname);
756 printf(
"Error reading sky-box-center string\n");
760 cpl_msg_warning(cpl_func,
"%s_x: %d set it to 0",pname, *px);
764 cpl_msg_warning(cpl_func,
"%s_y: %d set it to 0",pname, *py);
768 cpl_msg_warning(cpl_func,
"%s_x: %d set it to 10",pname, *px);
772 cpl_msg_warning(cpl_func,
"%s_y: %d set it to 10", pname, *py);
780 return cpl_error_get_code();
784eris_ifu_jitter_skycor_from_box(
const cpl_parameterlist * parlist,
785 struct exposureEntry *objEntry,
const int aj_method)
788 int sky_box_center_x, sky_box_center_y,
789 sky_box_width_x, sky_box_width_y,
790 sky_box_edges_margin_x, sky_box_edges_margin_y;
792 eris_ifu_jitter_get_split_param_int(parlist,
"sky-box-center", 0, 0, 64, 64,
793 &sky_box_center_x, &sky_box_center_y);
794 eris_ifu_jitter_get_split_param_int(parlist,
"sky-box-width", 0, 0, 10, 10,
795 &sky_box_width_x, &sky_box_width_y);
796 eris_ifu_jitter_get_split_param_int(parlist,
"sky-box-edges-margin", 0, 0, 10, 10,
797 &sky_box_edges_margin_x, &sky_box_edges_margin_y);
800 cpl_msg_info(cpl_func,
"sky_box_center_x: %d sky_box_center_y: %d",
801 sky_box_center_x, sky_box_center_y);
802 cpl_msg_info(cpl_func,
"sky_box_width_x: %d sky_box_width_y: %d",
803 sky_box_width_x, sky_box_width_y);
804 cpl_msg_info(cpl_func,
"sky_box_edges_margin_x: %d sky_box_edges_margin_y: %d",
805 sky_box_edges_margin_x, sky_box_edges_margin_y);
810 int sky_est_method = -1;
811 const char* context =
"eris.eris_ifu_jitter";
812 const cpl_parameter* p = NULL;
814 param_name = cpl_sprintf(
"%s.sky-est-method", context);
815 p = cpl_parameterlist_find_const(parlist, param_name);
817 sky_est_method = cpl_parameter_get_int(p);
819 cpl_free(param_name);
823 param_name = cpl_sprintf(
"%s.sky-est-niter", context);
824 p = cpl_parameterlist_find_const(parlist, param_name);
826 niter = cpl_parameter_get_int(p);
828 cpl_free(param_name);
831 param_name = cpl_sprintf(
"%s.sky-est-kappa", context);
832 p = cpl_parameterlist_find_const(parlist, param_name);
834 kappa = cpl_parameter_get_double(p);
836 cpl_free(param_name);
839 cpl_image* img = NULL;
840 hdrl_image* himg = NULL;
841 hdrl_value sky = {0, 0};
842 cpl_size llx = 0 , urx = 0, lly = 0 , ury = 0 ;
843 cpl_msg_info(cpl_func,
"llx, lly, urx, ury, [%lld,%lld,%lld,%lld]",
846 cpl_size skip = ERIS_IFU_SKIP_SKY_CORR_PLANES;
858 cpl_bivector* xy_pos = NULL;
859 cpl_vector* sky_data = NULL;
860 double* x_pos = NULL;
861 double* y_pos = NULL;
866 xy_pos = cpl_bivector_new(4);
867 sky_data = cpl_vector_new(4);
868 x_pos = cpl_bivector_get_x_data(xy_pos);
869 y_pos = cpl_bivector_get_y_data(xy_pos);
871 x_pos[0] = sky_box_edges_margin_x + sky_box_width_x;
872 y_pos[0] = sky_box_edges_margin_y + sky_box_width_y;
874 x_pos[1] = sky_box_edges_margin_x + sky_box_width_x;
875 y_pos[1] = size_y - sky_box_edges_margin_y - sky_box_width_y;
877 x_pos[2] = size_x - sky_box_edges_margin_x - sky_box_width_x;
878 y_pos[2] = sky_box_edges_margin_y + sky_box_width_y;
880 x_pos[3] = size_x - sky_box_edges_margin_x - sky_box_width_x;
881 y_pos[3] = size_y - sky_box_edges_margin_y - sky_box_width_y;
886 xy_pos = cpl_bivector_new(8);
887 sky_data = cpl_vector_new(8);
888 x_pos = cpl_bivector_get_x_data(xy_pos);
889 y_pos = cpl_bivector_get_y_data(xy_pos);
892 x_pos[0] = sky_box_edges_margin_x + sky_box_width_x;
893 y_pos[0] = sky_box_edges_margin_y + sky_box_width_y;
895 x_pos[1] = sky_box_edges_margin_x + sky_box_width_x;
896 y_pos[1] = size_y - sky_box_edges_margin_y - sky_box_width_y;
898 x_pos[2] = size_x - sky_box_edges_margin_x - sky_box_width_x;
899 y_pos[2] = sky_box_edges_margin_y + sky_box_width_y;
901 x_pos[3] = size_x - sky_box_edges_margin_x - sky_box_width_x;
902 y_pos[3] = size_y - sky_box_edges_margin_y - sky_box_width_y;
906 x_pos[4] = floor(0.5 * size_x);
907 y_pos[4] = sky_box_edges_margin_y + sky_box_width_y;
909 x_pos[5] = sky_box_edges_margin_x + sky_box_width_x;
910 y_pos[5] = floor(0.5 * size_y);
912 x_pos[6] = size_x - sky_box_edges_margin_x - sky_box_width_x;
913 y_pos[6] = floor(0.5 * size_y);
915 x_pos[7] = floor(0.5 * size_x);
916 y_pos[7] = size_y - sky_box_edges_margin_y - sky_box_width_y;
921 double sky_tmp_val = 0;
923 llx = sky_box_center_x - sky_box_width_x;
924 urx = sky_box_center_x + sky_box_width_x;
925 lly = sky_box_center_y - sky_box_width_y;
926 ury = sky_box_center_y + sky_box_width_y;
927 for (cpl_size zx = skip; zx < size_z - skip; zx++){
932 if(sky_est_method==0) {
933 sky.data = cpl_image_get_median_window(img, llx, lly, urx, ury);
935 sky.data = cpl_image_get_mean_window(img, llx, lly, urx, ury);
940 }
else if(aj_method == 5 || aj_method == 6) {
941 cpl_size xy_pos_size = cpl_bivector_get_size(xy_pos);
942 double* psky_data = cpl_vector_get_data(sky_data);
943 for (cpl_size zx = skip; zx < size_z - skip; zx++){
948 for (cpl_size k = 0; k < xy_pos_size; k++){
949 llx = ((cpl_size) x_pos[k] - sky_box_width_x);
950 lly = ((cpl_size) y_pos[k] - sky_box_width_y);
951 urx = ((cpl_size) x_pos[k] + sky_box_width_x);
952 ury = ((cpl_size) y_pos[k] + sky_box_width_y);
954 if(sky_est_method==0) {
955 sky_tmp_val = cpl_image_get_median_window(img, llx, lly, urx, ury);
956 if(cpl_error_get_code() != CPL_ERROR_NONE) {
960 psky_data[k] = sky_tmp_val;
964 sky_tmp_val = cpl_image_get_mean_window(img, llx, lly, urx, ury);
965 if(cpl_error_get_code() != CPL_ERROR_NONE) {
969 psky_data[k] = sky_tmp_val;
972 if(cpl_error_get_code() != CPL_ERROR_NONE) {
973 cpl_msg_error(cpl_func,
"Some error during sky modeling: "
974 "try to use a different region or other aj-method");
979 if(sky_est_method==0) {
980 sky.data = cpl_vector_get_median(sky_data);
982 sky.data = cpl_vector_get_mean(sky_data);
987 }
else if(aj_method == 7) {
989 hdrl_image* cube_collapsed = NULL;
990 cpl_image* cube_cmap = NULL;
1003 cpl_image_delete(cube_cmap);
1005 eris_ifu_jitter_skycorr_from_mask(objEntry, mask_obj, sky_est_method);
1007 cpl_mask_delete(mask_obj);
1008 }
else if(aj_method == 8) {
1009 hdrl_image* cube_mean = NULL;
1010 cpl_image* cube_cmap = NULL;
1015 cpl_image_delete(cube_cmap);
1016 eris_ifu_jitter_skycorr_from_mask(objEntry, mask_obj, sky_est_method);
1017 cpl_mask_delete(mask_obj);
1033 return cpl_error_get_code();
1037cpl_error_code eris_ifu_jitter_process_cubes(
struct sofStruct *sof,
1038 struct stdParamStruct stdParams,
1039 struct paramStruct params,
1040 cpl_frameset *frameset,
1041 const cpl_parameterlist * parlist,
1042 const char* recipe_name,
1045 cpl_error_code retVal = CPL_ERROR_NONE,
1046 err = CPL_ERROR_NONE;
1047 struct exposureEntry *objEntry = NULL,
1049 cpl_mask *tmpMask = NULL;
1050 hdrl_image *tmpImg = NULL;
1051 cpl_size imgSize = 0;
1052 double *pObjErr = NULL,
1054 *pTweakedErr = NULL;
1055 cpl_binary *pObjMask = NULL,
1057 *pTweakedMask = NULL;
1061 cpl_msg_info(cpl_func,
"Process Jitter Cubes: split Obj & Sky, correct Sky as user specified");
1063 for (
int ix = 0; ix < sof->exposureTableCnt; ix++) {
1064 if (!sof->exposureTable[ix].isObject) {
1067 objEntry = &sof->exposureTable[ix];
1068 cpl_frameset* obj_set =
1069 eris_ifu_frameset_extract_obj_set(frameset, sof, ix);
1071 if (params.skyTweak != NONE) {
1072 int skyIndex = objEntry->skyIndex;
1075 "no vaild sky frame found");
1077 skyEntry = &sof->exposureTable[skyIndex];
1079 if (skyEntry->cube == NULL) {
1080 cpl_msg_error(__func__,
1081 "Missing sky image for input frame %s",
1082 cpl_frame_get_filename(objEntry->frame));
1084 cpl_imagelist *dataCubeObj = cpl_imagelist_new(),
1085 *errCubeObj = cpl_imagelist_new(),
1086 *dataCubeSky = cpl_imagelist_new(),
1087 *errCubeSky = cpl_imagelist_new();
1091 dataCubeObj, errCubeObj));
1094 dataCubeSky, errCubeSky));
1096 if (params.skyTweak == DAVIES) {
1097 cpl_imagelist *skycorrObj = NULL,
1102 objEntry->cubeHdr, .3,
1104 params.discard_subband,
1106 params.stretch_degree,
1107 params.stretch_resampling,
1116 skycorrErr = cpl_imagelist_duplicate(errCubeObj));
1118 imgSize = cpl_image_get_size_x(cpl_imagelist_get(skycorrErr, 0)) *
1119 cpl_image_get_size_y(cpl_imagelist_get(skycorrErr, 0));
1121 for (cpl_size tx = 0; tx < cpl_imagelist_get_size(skycorrErr); tx++) {
1122 pObjErr = cpl_image_get_data_double(
1123 cpl_imagelist_get(errCubeObj,tx));
1124 pSkyErr = cpl_image_get_data_double(
1125 cpl_imagelist_get(errCubeSky,tx));
1126 pTweakedErr = cpl_image_get_data_double(
1127 cpl_imagelist_get(skycorrErr,tx));
1128 pObjMask = cpl_mask_get_data(
1129 cpl_image_get_bpm(cpl_imagelist_get(errCubeObj,tx)));
1130 pErrMask = cpl_mask_get_data(
1131 cpl_image_get_bpm(cpl_imagelist_get(errCubeSky,tx)));
1132 pTweakedMask = cpl_mask_get_data(
1133 cpl_image_get_bpm(cpl_imagelist_get(skycorrErr,tx)));
1135 for (cpl_size rx = 0; rx < imgSize; rx++) {
1136 if ((pObjMask[rx] != BAD_PIX) &&
1137 (pErrMask[rx] != BAD_PIX))
1139 pTweakedMask[rx] = GOOD_PIX;
1140 pTweakedErr[rx] = hypot(pObjErr[rx], pSkyErr[rx]);
1142 pTweakedMask[rx] = BAD_PIX;
1160 if ((stdParams.productDepth >= PD_DEBUG) && (skycorrSky != NULL)) {
1161 char *fname = cpl_sprintf(
1162 "eris_ifu_jitter_dbg_skycoorsky_%3.3d.fits", skyIndex);
1163 cpl_imagelist_save(skycorrSky, fname,
1164 CPL_TYPE_FLOAT, NULL, CPL_IO_CREATE);
1171 else if (params.skyTweak == AUSTRIAN) {
1172 cpl_table *objspec = NULL,
1174 cpl_parameterlist *parlist_skycorr = NULL;
1175 double ts = cpl_test_get_walltime();
1183 parlist_skycorr = eris_ifu_skycorr_create_parlist(skyEntry->cubeHdr));
1192 for (cpl_size y = 1; y <= ny; y += 2) {
1193 if (stdParams.productDepth == 3) {
1194 cpl_msg_debug(cpl_func,
">>>>> line %d", (
int)y);
1196 for (cpl_size x = 1; x <= nx; x++) {
1197 int success = CPL_FALSE;
1198 if (stdParams.productDepth == 3) {
1199 cpl_msg_debug(cpl_func,
">>>>> pix (%d/%d)", (
int)x, (
int)y);
1202 objspec = eris_ifu_skycorr_extract_spectrum(objEntry->cube, objEntry->cubeHdr, x, y));
1204 skyspec = eris_ifu_skycorr_extract_spectrum(skyEntry->cube, skyEntry->cubeHdr, x, y));
1206 if (stdParams.productDepth == 3) {
1232 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_1_orig.fits", (
int)x, (
int)y);
1233 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1235 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_1_orig.fits", (
int)x, (
int)y);
1236 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1241 double mean_lambda = 0.5 * (cpl_table_get(objspec,
"lambda", 0, NULL) +
1242 cpl_table_get(objspec,
"lambda", cpl_table_get_nrow(objspec)-1, NULL));
1243 cpl_parameter *p = cpl_parameterlist_find(parlist_skycorr,
"meanlam");
1244 cpl_parameter_set_double(p, mean_lambda);
1246 double mean_obj_flux = cpl_table_get_column_mean(objspec,
"flux"),
1247 mean_sky_flux = cpl_table_get_column_mean(skyspec,
"flux");
1250 if ((fabs(mean_obj_flux) > 0.00001) && (fabs(mean_sky_flux) > 0.00001)) {
1252 int outlier_factor = 10;
1254 eris_ifu_skycorr_flatten_outliers(objspec, skyspec, outlier_factor));
1261 if (stdParams.productDepth == 3) {
1262 char* fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_2_flatten1.fits", (
int)x, (
int)y);
1263 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1265 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_2_flatten1.fits", (
int)x, (
int)y);
1266 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1270 err =
sc_skycorr(parlist_skycorr, objspec, skyspec, stdParams.productDepth);
1271 if (err != CPL_ERROR_NONE) {
1273 cpl_errorstate_set(CPL_ERROR_NONE);
1274 err = CPL_ERROR_NONE;
1280 eris_ifu_skycorr_flatten_outliers(objspec, skyspec, outlier_factor));
1282 if (stdParams.productDepth == 3) {
1283 char* fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_3_flatten2.fits", (
int)x, (
int)y);
1284 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1286 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_3_flatten2.fits", (
int)x, (
int)y);
1287 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1291 err =
sc_skycorr(parlist_skycorr, objspec, skyspec, stdParams.productDepth);
1292 if (err != CPL_ERROR_NONE) {
1294 cpl_errorstate_set(CPL_ERROR_NONE);
1295 err = CPL_ERROR_NONE;
1305 if (success == CPL_FALSE) {
1307 if (stdParams.productDepth == 3) {
1308 cpl_msg_debug(cpl_func,
">>>>> inserted blank spectrum");
1309 char* fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_objspec_4_failed.fits", (
int)x, (
int)y);
1310 cpl_table_save(objspec, NULL, objEntry->cubeHdr, fn, CPL_IO_CREATE);
1312 fn = cpl_sprintf(
"%d_%d_eris_ifu_jitter_dbg_skyspec_4_failed.fits", (
int)x, (
int)y);
1313 cpl_table_save(skyspec, NULL, skyEntry->cubeHdr, fn, CPL_IO_CREATE);
1318 objspec = eris_ifu_skycorr_create_nan_spectrum(objEntry->cube));
1321 eris_ifu_skycorr_insert_spectrum(objEntry->cube, objspec, x, y));
1330 double te = cpl_test_get_walltime();
1331 cpl_msg_debug(cpl_func,
">>>>> >>>>> skycorr took %g seconds", te - ts);
1336 if (!cpl_propertylist_has(objEntry->cubeHdr,
"PRODCATG")) {
1337 cpl_propertylist_append_string(objEntry->cubeHdr,
"PRODCATG",
1342 eris_ifu_jitter_save_cpl_cube(frameset, obj_set, objEntry->frame, parlist,
1343 NULL, objEntry->cube, objEntry->cubeBpm, objEntry->cubeHdr,
1344 params, TWEAKED_CUBE, ix, recipe_name));
1346 cpl_frameset_delete(obj_set);
1351 const char* context =
"eris.eris_ifu_jitter";
1352 param_name = cpl_sprintf(
"%s.aj-method", context);
1353 const cpl_parameter* p = NULL;
1354 p = cpl_parameterlist_find_const(parlist, param_name);
1356 aj_method = cpl_parameter_get_int(p);
1358 cpl_free(param_name);
1360 if((objEntry->skyIndex < 0) && (aj_method > 3)) {
1362 eris_ifu_jitter_skycor_from_box(parlist, objEntry, aj_method);
1365 if (params.darCorrection) {
1368 tmpMask = cpl_mask_threshold_image_create(cpl_imagelist_get(objEntry->cubeBpm, zx), params.bpmThreshold, 1.5);;
1374 eris_ifu_dar_correction(objEntry->cube,
1376 params.darShiftMethod,
1377 params.darShiftWidth, params.darShiftLength));
1378 cpl_frameset* obj_set2 =
1379 eris_ifu_frameset_extract_obj_set(frameset, sof, ix);
1381 eris_ifu_jitter_save_cpl_cube(frameset, obj_set2,
1382 sof->exposureTable[ix].frame, parlist, NULL,
1383 objEntry->cube, objEntry->cubeBpm, objEntry->cubeHdr,
1384 params, DAR_CUBE, ix, recipe_name);
1385 cpl_frameset_delete(obj_set2);
1389 cubeType sky_type = SKY_OBJECT_CUBE;
1392 char *proCatg = NULL;
1393 char *filenamePrefix = NULL;
1394 *obj_type = eris_ifu_jitter_get_obj_type(sof->mode);
1395 eris_ifu_jitter_get_procatg_and_filename(*obj_type, &proCatg, &filenamePrefix);
1397 cpl_frameset* cube_set;
1399 for(cpl_size i = 0; i < sof->exposureTableCnt; i++) {
1400 if (!cpl_propertylist_has(sof->exposureTable[i].cubeHdr,
"PRODCATG")) {
1401 cpl_propertylist_append_string(sof->exposureTable[i].cubeHdr,
1402 "PRODCATG",
"ANCILLARY.EXPMAP");
1405 if (sof->exposureTable[i].isObject) {
1406 cpl_frameset* obj_set =
1407 eris_ifu_frameset_extract_obj_set(frameset, sof, i);
1408 *obj_type = eris_ifu_jitter_get_obj_type(sof->mode);
1409 eris_ifu_jitter_save_cpl_cube(frameset, obj_set,
1410 sof->exposureTable[i].frame,
1411 parlist, NULL, sof->exposureTable[i].cube,
1412 sof->exposureTable[i].cubeBpm,
1413 sof->exposureTable[i].cubeHdr,
1414 params, *obj_type, i, recipe_name);
1415 cpl_frameset_delete(obj_set);
1417 sky_type = eris_ifu_jitter_get_sky_type(sof->mode);
1418 eris_ifu_jitter_save_cpl_cube(frameset, frameset,
1419 sof->exposureTable[i].frame,
1420 parlist, NULL, sof->exposureTable[i].cube,
1421 sof->exposureTable[i].cubeBpm,
1422 sof->exposureTable[i].cubeHdr,
1423 params, sky_type, i, recipe_name);
1431 retVal = cpl_error_get_code();
1439hdrl_image *eris_ifu_jitter_subtract_background(
1440 skyTweakModes sky_tweak,
1442 struct sofStruct *sof,
1443 productDepthType productDepth)
1445 hdrl_image *objImg = NULL;
1446 cpl_mask *inputMask = NULL;
1447 cpl_mask *outputMask = NULL;
1448 cpl_image *dqi = NULL;
1449 char *filename = NULL;
1450 char *filename2 = NULL;
1451 bool darkSkySubtracted =
false;
1453 cpl_ensure(sof != NULL,CPL_ERROR_NULL_INPUT, NULL);
1459 inputMask = cpl_mask_duplicate(
1462 if (sky_tweak == NONE) {
1463 const int skyIdx = sof->exposureTable[objIdx].skyIndex;
1468 darkSkySubtracted =
true;
1470 }
else if (sof->masterDark != NULL) {
1473 darkSkySubtracted =
true;
1477 if (darkSkySubtracted) {
1481 BRK_IF_NULL(dqi = cpl_image_new_from_mask(outputMask));
1482 BRK_IF_ERROR(cpl_image_multiply_scalar(dqi, ERIS_DQI_SKY));
1484 sof->exposureTable[objIdx].dqiImage, dqi));
1485 if (productDepth >= PD_DEBUG) {
1487 filename = cpl_sprintf(
"%s_%3.3d",
1488 ERIS_IFU_PRO_JITTER_DBG_DARK_FN, objIdx));
1490 filename2 = cpl_sprintf(
"%s_%3.3d.fits",
1491 ERIS_IFU_PRO_JITTER_DBG_DARK_FN, objIdx));
1495 cpl_image_save(sof->exposureTable[objIdx].dqiImage,
1496 filename2, CPL_TYPE_INT, NULL, CPL_IO_EXTEND));
1500 cpl_mask_delete(inputMask);
1524hdrl_imagelist *eris_ifu_jitter_build_cube(
1525 hdrl_image *inputImage,
1527 struct sofStruct *sof,
1528 struct paramStruct params,
1529 bool doVelocityCorrection,
1530 cpl_polynomial *ohLambdaCorrection,
1531 productDepthType productDepth)
1533 hdrl_imagelist *cube = NULL;
1534 cpl_imagelist *dataCube = NULL;
1535 cpl_imagelist *errCube = NULL;
1536 hdrl_image *image1 = NULL;
1537 hdrl_image *image2 = NULL;
1538 hdrl_image *bpmImg1 = NULL;
1539 cpl_image *bpmImg2 = NULL;
1540 hdrl_image *badPixelMaskImg = NULL;
1541 cpl_image *badPixelMaskImg1 = NULL;
1542 cpl_image *badPixelMaskImg2 = NULL;
1544 hdrl_image *waveImg = NULL;
1545 cpl_image *waveDataImg = NULL;
1546 cpl_image *waveErrImg = NULL;
1547 cpl_image *waveMap = NULL;
1548 struct exposureEntry *objEntry;
1551 double velocityCorr;
1554 double minLambda = 0.;
1555 double maxLambda = 0.;
1556 bool buildCubeForOHbasedLambdaCorrection =
false;
1558 cpl_ensure(inputImage != NULL,CPL_ERROR_NULL_INPUT, NULL);
1559 cpl_ensure(sof != NULL,CPL_ERROR_NULL_INPUT, NULL);
1564 if (doVelocityCorrection ==
false && ohLambdaCorrection == NULL) {
1565 buildCubeForOHbasedLambdaCorrection =
true;
1568 objEntry = &sof->exposureTable[sofIdx];
1572 if (sof->masterFlat != NULL) {
1575 if (productDepth >= PD_DEBUG) {
1576 if (buildCubeForOHbasedLambdaCorrection) {
1578 filename = cpl_sprintf(
"%sB_%3.3d",
1579 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN, sofIdx));
1582 filename = cpl_sprintf(
"%s_%3.3d",
1583 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN, sofIdx));
1593 cpl_mask_get_size_x(objEntry->badPixelMask),
1594 cpl_mask_get_size_y(objEntry->badPixelMask)));
1596 badPixelMaskImg1 = cpl_image_new_from_mask(objEntry->badPixelMask));
1598 badPixelMaskImg2 = cpl_image_cast(
1599 badPixelMaskImg1, CPL_TYPE_DOUBLE));
1602 badPixelMaskImg2, NULL, 1, 1));
1606 cpl_msg_info(__func__,
"No. bad pixels: %d", (
int)cpl_image_count_rejected(
hdrl_image_get_image(image1)));
1610 int bpc_iter = params.bpc_iter;
1611 for (
int i = 0; i < bpc_iter; i++){
1614 if (productDepth >= PD_DEBUG) {
1615 if (buildCubeForOHbasedLambdaCorrection) {
1617 filename = cpl_sprintf(
"%sB_%3.3d_%d",
1618 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN
"-corr", sofIdx, i));
1621 filename = cpl_sprintf(
"%s_%3.3d_%d",
1622 ERIS_IFU_PRO_JITTER_DBG_FLAT_FN
"-corr", sofIdx, i));
1632 if (params.derot_corr!=params.derot_corr)
1633 derot_corr = objEntry->derot_corr;
1635 derot_corr = params.derot_corr;
1636 cpl_msg_info(cpl_func,
"First column shifted (derot_corr): %.2f", derot_corr);
1638 for (
int i = 0; i < SLITLET_CNT; i++) {
1639 if (sof->distortion[i] != NULL) {
1641 cpl_polynomial_shift_1d(sof->distortion[i], 0, derot_corr));
1646 if (sof->distortion != NULL) {
1648 image2 = eris_ifu_dist_warp_image(image1,
1649 sof->distortion, sof->borders));
1651 bpmImg1 = eris_ifu_dist_warp_bpm(badPixelMaskImg,
1652 sof->distortion, sof->borders, productDepth));
1656 sof->poly_u, sof->poly_v));
1659 sof->poly_u, sof->poly_v));
1663 for (
int i = 0; i < SLITLET_CNT; i++) {
1664 if (sof->distortion[i] != NULL) {
1666 cpl_polynomial_shift_1d(sof->distortion[i], 0, -1*derot_corr));
1672 if (productDepth >= PD_DEBUG) {
1673 if (buildCubeForOHbasedLambdaCorrection) {
1675 filename = cpl_sprintf(
"%sB_%3.3d",
1676 ERIS_IFU_PRO_JITTER_DBG_WRAP_FN, sofIdx));
1679 filename = cpl_sprintf(
"%s_%3.3d",
1680 ERIS_IFU_PRO_JITTER_DBG_WRAP_FN, sofIdx));
1683 if (bpmImg1 != NULL) {
1685 filename2 = cpl_sprintf(
"%s.fits", filename));
1688 CPL_TYPE_FLOAT, NULL, CPL_IO_EXTEND));
1694 waveMap = cpl_image_duplicate(sof->waveMap);
1695 lsize = cpl_image_get_size_x(waveMap) * cpl_image_get_size_y(waveMap);
1696 BRK_IF_NULL(pWaveMap = cpl_image_get_data_double(waveMap));
1697 maxLambda = cpl_image_get_max(waveMap);
1698 minLambda = cpl_image_get_min(waveMap);
1701 if (doVelocityCorrection) {
1702 velocityCorr = 1. + params.velocityOffset * 1000. / CPL_PHYS_C;
1703 for (
int ix = 0; ix < lsize; ix++) {
1704 pWaveMap[ix] *= velocityCorr;
1709 if (ohLambdaCorrection != NULL) {
1710 for (
int ix = 0; ix < lsize; ix++) {
1711 pWaveMap[ix] -= cpl_polynomial_eval_1d(
1712 ohLambdaCorrection, pWaveMap[ix], NULL);
1718 cpl_propertylist_delete(objEntry->cubeHdr);
1719 objEntry->cubeHdr = cpl_propertylist_duplicate(objEntry->hdr);
1721 waveDataImg = eris_ifu_wave_resampled_arc_image(
1723 waveMap, sof->band, minLambda, maxLambda,
1724 objEntry->cubeHdr, 3));
1726 waveErrImg = eris_ifu_wave_resampled_arc_image(
1728 waveMap, sof->band, minLambda, maxLambda,
1729 objEntry->cubeHdr, 3));
1732 bpmImg2 = eris_ifu_wave_resampled_arc_image(
1734 waveMap, sof->band, minLambda, maxLambda,
1735 objEntry->cubeHdr, 3));
1737 cpl_binary *pImgMask = cpl_mask_get_data(cpl_image_get_bpm(waveDataImg));
1738 float *pDqiData = cpl_image_get_data_float(bpmImg2);
1739 cpl_size size = cpl_image_get_size_x(waveDataImg)
1740 * cpl_image_get_size_y(waveDataImg);
1741 for (cpl_size px = 0; px < size; px++) {
1742 if (pDqiData[px] > params.bpmThreshold) {
1743 pImgMask[px] = BAD_PIX;
1749 if (productDepth >= PD_DEBUG) {
1750 cpl_propertylist *pl2save = cpl_propertylist_duplicate(objEntry->hdr);
1753 cpl_image *image2save = eris_ifu_wave_resampled_arc_image(
1755 waveMap, sof->band, minLambda, maxLambda, pl2save, 2);
1756 if (buildCubeForOHbasedLambdaCorrection) {
1758 filename = cpl_sprintf(
"%sB_%3.3d",
1759 ERIS_IFU_PRO_JITTER_DBG_WAVE_FN, sofIdx));
1762 filename = cpl_sprintf(
"%s_%3.3d",
1763 ERIS_IFU_PRO_JITTER_DBG_WAVE_FN, sofIdx));
1765 cpl_propertylist_erase(pl2save,
"RADECSYS");
1769 image2save = eris_ifu_wave_resampled_arc_image(
1771 waveMap, sof->band, minLambda, maxLambda, pl2save, 2);
1773 filename2 = cpl_sprintf(
"%s.fits", filename));
1775 cpl_image_save(image2save, filename2,
1776 CPL_TYPE_FLOAT, pl2save, CPL_IO_EXTEND));
1785 dataCube = eris_ifu_jitter_reconstruct_cube(
1787 params.slitletDetectionMode,
1788 params.fineTuneMode,
1792 cpl_image_reject_from_mask(waveErrImg, cpl_image_get_bpm_const(waveDataImg));
1794 errCube = eris_ifu_jitter_reconstruct_cube(
1796 params.slitletDetectionMode,
1797 params.fineTuneMode,
1803 cpl_imagelist_delete(dataCube);
1804 cpl_imagelist_delete(errCube);
1805 cpl_propertylist_update_int(objEntry->cubeHdr,NAXIS1,64);
1806 cpl_propertylist_update_int(objEntry->cubeHdr,NAXIS2,64);
1807 cpl_propertylist_update_int(objEntry->cubeHdr,NAXIS3,
1810 if(objEntry->cubeBpm != NULL) {
1811 cpl_imagelist_delete(objEntry->cubeBpm);
1814 cpl_image_multiply_scalar(bpmImg2, 2.0);
1817 objEntry->cubeBpm = eris_ifu_jitter_reconstruct_cube(
1819 params.slitletDetectionMode,
1820 params.fineTuneMode,
1850eris_image_get_valid_data_range(cpl_image* image,
1851 cpl_size* min, cpl_size* max)
1853 cpl_size sx = cpl_image_get_size_x(image);
1854 cpl_size sy = cpl_image_get_size_y(image);
1855 float* pdata = cpl_image_get_data(image);
1856 cpl_size rows2check = 200;
1857 cpl_size nan_counter = 0;
1858 double nan_thresh = 0.5;
1861 for(cpl_size j = 0; j < rows2check; j++) {
1863 for(cpl_size i = 0; i < sx; i++) {
1864 if(isnan(pdata[i + j * sx])) {
1869 if(nan_counter > nan_thresh * sx) {
1874 for(cpl_size j = sy-1; j >= sy - rows2check; j--) {
1876 for(cpl_size i = 0; i < sx; i++) {
1877 if(isnan(pdata[i + j * sx])) {
1881 if(nan_counter > nan_thresh * sx) {
1885 cpl_msg_info(cpl_func,
"min: %lld max: %lld", *min, *max);
1887 return cpl_error_get_code();
1910cpl_imagelist * eris_ifu_jitter_reconstruct_cube(
1911 cpl_image *resampledDetImage,
1912 slitletDetectionModes mode,
1915 cpl_vector *distancesV,
1916 cpl_bivector *positionsVV)
1919 cpl_ensure(resampledDetImage, CPL_ERROR_NULL_INPUT, NULL);
1920 cpl_ensure((mode >= UNSET) && (mode <= GRID), CPL_ERROR_ILLEGAL_INPUT, NULL);
1921 cpl_ensure(fineTuneMode >= -5, CPL_ERROR_ILLEGAL_INPUT, NULL);
1922 cpl_ensure(firstCol >= 0 && firstCol <= ERIS_IFU_DETECTOR_SIZE_X, CPL_ERROR_ILLEGAL_INPUT, NULL);
1926 cpl_imagelist *cube = NULL;
1927 cpl_image *slide = NULL;
1932 int beginCol[SLITLET_CNT] = {0};
1933 double start[SLITLET_CNT] = {0.};
1936 double *distances = NULL;
1939 double *left_edges = NULL;
1940 double *right_edges = NULL;
1943 cpl_binary *mi = NULL;
1944 cpl_binary *mo = NULL;
1954 inx = cpl_image_get_size_x(resampledDetImage);
1955 onx = inx / SLITLET_CNT;
1956 ony = SLITLET_CNT * 2;
1957 onz = cpl_image_get_size_y(resampledDetImage);
1958 cube = cpl_imagelist_new();
1964 if (distancesV == NULL) {
1965 pi = cpl_image_get_data_float(resampledDetImage);
1966 mi = cpl_mask_get_data(cpl_image_get_bpm(resampledDetImage));
1968 for (
int iz=0; iz<onz; iz++) {
1970 slide = cpl_image_new(onx, ony, CPL_TYPE_FLOAT));
1971 po = cpl_image_get_data_float(slide);
1972 mo = cpl_mask_get_data(cpl_image_get_bpm(slide));
1975 for (
int slitlet=0; slitlet<SLITLET_CNT; slitlet++) {
1976 for (
int col=0; col < onx; col++) {
1977 tmp = (float) pi[onx-1-col + slitlet*onx + iz*inx];
1984 po[col + onx*(rowIndices[slitlet]*2)] = tmp;
1985 po[col + onx*(rowIndices[slitlet]*2+1)] = tmp;
1986 if (mi[onx-1-col + slitlet*onx + iz*inx] == BAD_PIX) {
1987 mo[col + onx*(rowIndices[slitlet]*2)] = BAD_PIX;
1988 mo[col + onx*(rowIndices[slitlet]*2+1)] = BAD_PIX;
1995 cpl_imagelist_set(cube, slide, iz));
1998 if (mode == DISTANCES) {
1999 if (distancesV == NULL) {
2001 "missing data about slitlet distances");
2003 if (cpl_vector_get_size(distancesV) != SLITLET_CNT-1) {
2005 "distances vector has wrong number of elements "
2006 "(got %lld but exepected %d)",
2007 cpl_vector_get_size(distancesV), SLITLET_CNT-1);
2009 distances = cpl_vector_get_data(distancesV);
2010 }
else if (mode == EDGES) {
2011 if (positionsVV == NULL) {
2013 "missing data about slitlet positions");
2015 if (cpl_bivector_get_size(positionsVV) != SLITLET_CNT) {
2017 "slit pos bivector has wrong number of elements "
2018 "(got %lld but exepected %d)",
2019 cpl_bivector_get_size(positionsVV), SLITLET_CNT);
2021 left_edges = cpl_vector_get_data(
2022 cpl_bivector_get_x(positionsVV));
2023 right_edges = cpl_vector_get_data(
2024 cpl_bivector_get_y(positionsVV));
2028 for (
int slitlet=0; slitlet<SLITLET_CNT; slitlet++) {
2029 if (mode == DISTANCES) {
2031 start[slitlet] = firstCol;
2033 di += distances[slitlet-1];
2034 start[slitlet] = firstCol + di;
2036 }
else if (mode == EDGES) {
2037 center = (left_edges[slitlet] + right_edges[slitlet]) / 2.;
2038 start[slitlet] = center - (double) (onx -1 )/2.;
2039 }
else if (mode == GRID) {
2040 start[slitlet] = (double) (onx * slitlet);
2043 start[slitlet] > 0 ?
2044 (int)(start[slitlet]+.5) : (int)(start[slitlet]-.5);
2051 xi = cpl_calloc(onx,
sizeof(
double)));
2053 xt = cpl_calloc(onx,
sizeof(
double)));
2055 pt1 = cpl_calloc(onx,
sizeof(
double)));
2057 pt2 = cpl_calloc(onx,
sizeof(
double)));
2058 pi = cpl_image_get_data_float(resampledDetImage);
2060 for (
int iz=0; iz<onz; iz++) {
2062 slide = cpl_image_new(onx, ony, CPL_TYPE_FLOAT));
2063 po = cpl_image_get_data_float(slide);
2065 for (
int slitlet=0; slitlet<SLITLET_CNT; slitlet++) {
2066 for (
int col=0; col < onx; col++) {
2067 xi[col] = (double) (beginCol[slitlet] + col);
2068 xt[col] = start[slitlet] + col;
2069 icol = beginCol[slitlet] + col;
2071 pt1[col] = pi[0 + iz * inx];
2072 }
else if (icol >= inx) {
2073 pt1[col] = pi[(inx - 1) + iz * inx];
2075 pt1[col] = pi[icol + iz * inx];
2078 if (fineTuneMode == 0) {
2079 for (
int col=0; col < onx; col++) {
2080 pt2[col] = pt1[col];
2085 xt, pt2, (
int) onx, fineTuneMode));
2087 for (
int col=0; col < onx; col++) {
2095 tmp = (float) (pt2[col] * 0.5);
2096 po[col + onx*(rowIndices[slitlet]*2)] = tmp;
2097 po[col + onx*(rowIndices[slitlet]*2+1)] = tmp;
2101 cpl_imagelist_set(cube, slide, iz));
2120eris_ifu_jitter_get_procatg_and_filename(cubeType type,
char **proCatg,
2121 char **filenamePrefix)
2123 cpl_ensure_code(proCatg, CPL_ERROR_NULL_INPUT);
2124 cpl_ensure_code(filenamePrefix, CPL_ERROR_NULL_INPUT);
2127 case OBJECT_CUBE_COADD:
2128 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD);
2129 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FN);
2131 case TWEAKED_CUBE_COADD:
2132 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD);
2133 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD_FN);
2135 case DAR_CUBE_COADD:
2136 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE_COADD);
2137 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE_COADD_FN);
2139 case DAR_STD_CUBE_COADD:
2140 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
2141 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FN);
2143 case STD_CUBE_COADD:
2144 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
2145 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FN);
2147 case STD_FLUX_CUBE_COADD:
2148 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD);
2149 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FN);
2151 case STD_FLUX_CUBE_COADD_NOFLAT:
2152 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT);
2153 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT_FN);
2155 case STD_CUBE_COADD_NOFLAT:
2156 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT);
2157 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT_FN);
2159 case PSF_CUBE_COADD:
2160 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
2161 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_FN);
2164 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE);
2165 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_OBJ_CUBE_FN);
2168 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE);
2169 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_FN);
2172 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE);
2173 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_FN);
2175 case STD_CUBE_NOFLAT:
2176 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_NOFLAT);
2177 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_NOFLAT_FN);
2180 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE);
2181 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_FN);
2183 case SKY_OBJECT_CUBE:
2185 case SKY_STD_FLUX_CUBE:
2187 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_SKY_CUBE);
2188 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_SKY_CUBE_FN);
2191 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE);
2192 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_TWK_CUBE_FN);
2194 case TWEAKED_STD_CUBE:
2195 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE);
2196 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_FN);
2199 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE);
2200 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_DAR_CUBE_FN);
2203 case DAR_PSF_CUBE_COADD:
2204 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
2205 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD_FN);
2209 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE);
2210 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_CUBE_FN);
2212 case DAR_STD_FLUX_CUBE:
2214 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE);
2215 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_FN);
2219 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE);
2220 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_PSF_CUBE_FN);
2223 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_BPM_CUBE);
2224 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_BPM_CUBE_FN);
2227 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE);
2228 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE_FN);
2231 cpl_msg_warning(cpl_func,
"default case %d",type);
2232 *proCatg = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE);
2233 *filenamePrefix = cpl_sprintf(ERIS_IFU_PRO_JITTER_CUBE_FN);
2236 cpl_msg_debug(cpl_func,
"proCatg: %s",*proCatg);
2237 cpl_msg_debug(cpl_func,
"filenamePrefix: %s",*filenamePrefix);
2238 return cpl_error_get_code();
2253cpl_error_code eris_ifu_extract_spec(
2254 const cpl_imagelist *data_in,
2255 const cpl_imagelist *noise_in,
2257 cpl_vector **spec_data_out,
2258 cpl_vector **spec_noise_out)
2260 cpl_error_code ret_error = CPL_ERROR_NONE;
2262 const cpl_image *tmp_img = NULL;
2263 const cpl_mask *bpm = NULL;
2264 const cpl_binary *bpm_data = NULL;
2265 cpl_mask *empty_mask = NULL;
2274 const float *pmask = NULL;
2275 const double *ptmp_img = NULL;
2284 ASSURE((data_in != NULL) &&
2285 (spec_data_out != NULL),
2286 CPL_ERROR_NULL_INPUT,
2287 "Not all input data is provided!");
2290 tmp_img = cpl_imagelist_get_const(data_in, 0));
2292 nx = cpl_image_get_size_x(tmp_img);
2293 ny = cpl_image_get_size_y(tmp_img);
2294 nz = cpl_imagelist_get_size(data_in);
2297 ASSURE((nx == cpl_image_get_size_x(mask)) &&
2298 (ny == cpl_image_get_size_y(mask)),
2299 CPL_ERROR_ILLEGAL_INPUT,
2300 "Data and mask don't have same dimensions!");
2303 pmask = cpl_image_get_data_float_const(mask));
2306 if (noise_in != NULL) {
2307 ASSURE(spec_noise_out != NULL,
2308 CPL_ERROR_NULL_INPUT,
2309 "Not all input data is provided!");
2312 tmp_img = cpl_imagelist_get_const(noise_in, 0));
2314 ASSURE((nx == cpl_image_get_size_x(tmp_img)) &&
2315 (ny == cpl_image_get_size_y(tmp_img)) &&
2316 (nz == cpl_imagelist_get_size(noise_in)),
2317 CPL_ERROR_ILLEGAL_INPUT,
2318 "Data and noise don't have same dimensions!");
2322 *spec_data_out = cpl_vector_new(nz));
2325 pvec = cpl_vector_get_data(*spec_data_out));
2327 if (noise_in != NULL) {
2329 *spec_noise_out = cpl_vector_new(nz));
2332 pvecn = cpl_vector_get_data(*spec_noise_out));
2336 empty_mask = cpl_mask_new(nx,ny));
2339 for (g = 0; g < nz; g++) {
2341 tmp_img = cpl_imagelist_get_const(data_in, g));
2343 ptmp_img = cpl_image_get_data_double_const(tmp_img));
2345 bpm = cpl_image_get_bpm_const(tmp_img);
2350 bpm_data = cpl_mask_get_data_const(bpm));
2355 for (j = 0; j < ny; j++) {
2356 for (i = 0; i < nx; i++) {
2358 if ((bpm_data[i+j*nx] == GOOD_PIX) && isfinite(ptmp_img[i+j*nx])) {
2360 sum += ptmp_img[i+j*nx] * pmask[i+j*nx];
2361 weights += pmask[i+j*nx];
2363 sum += ptmp_img[i+j*nx];
2369 pvec[g] = sum/weights;
2373 if (noise_in != NULL) {
2375 tmp_img = cpl_imagelist_get_const(noise_in, g));
2377 ptmp_img = cpl_image_get_data_double_const(tmp_img));
2381 for (j = 0; j < ny; j++) {
2382 for (i = 0; i < nx; i++) {
2384 if ((bpm_data[i+j*nx] == GOOD_PIX) && isfinite(ptmp_img[i+j*nx])) {
2386 sum += pow(ptmp_img[i+j*nx], 2) * pow(pmask[i+j*nx], 2);
2387 weights += pow(pmask[i+j*nx], 2);
2389 sum += pow(ptmp_img[i+j*nx], 2);
2395 pvecn[g] = sqrt(sum/weights);
2402 ret_error = cpl_error_get_code();
2405 if (empty_mask != NULL) {cpl_mask_delete(empty_mask);}
2426cpl_error_code eris_ifu_jitter_spec_save_products(
2427 cpl_frameset* frames,
2428 const cpl_parameterlist * parlist,
2429 struct esSofStruct sof,
2430 cpl_bivector *spectrum,
2432 cpl_vector *totalFlux,
2433 productDepthType productDepth,
2434 cpl_boolean is_sdp_format,
2435 const char* recipe_name)
2437 cpl_table *pro_tab = NULL;
2438 cpl_propertylist *pl;
2439 cpl_vector *lambda = NULL;
2440 cpl_vector *data = NULL;
2441 cpl_array *waveArray = NULL;
2442 cpl_array *fluxArray = NULL;
2443 cpl_array *errArray = NULL;
2444 cpl_array *totalFluxArray = NULL;
2447 cpl_size spectrumSize;
2451 spectrumSize = cpl_bivector_get_size(spectrum);
2452 BRK_IF_NULL(lambda = cpl_bivector_get_x(spectrum));
2454 firstLambda = cpl_vector_get(lambda,0);
2455 deltaLambda = cpl_vector_get(lambda,1) - firstLambda;
2457 if (productDepth >= PD_AUXILLIARY) {
2458 pl = cpl_propertylist_duplicate(sof.header);
2459 cpl_propertylist_update_string(pl, CPL_DFS_PRO_CATG,
"SPECTRUM");
2460 cpl_propertylist_update_string(pl,
"CTYPE1",
"WAVE");
2461 cpl_propertylist_update_double(pl,
"CRPIX1", 1.);
2462 cpl_propertylist_update_double(pl,
"CRVAL1", firstLambda);
2463 cpl_propertylist_update_double(pl,
"CDELT1", deltaLambda);
2464 cpl_propertylist_erase(pl,
"CTYPE2");
2465 cpl_propertylist_erase(pl,
"CRPIX2");
2466 cpl_propertylist_erase(pl,
"CRVAL2");
2467 cpl_propertylist_erase(pl,
"CDELT2");
2468 cpl_propertylist_erase(pl,
"CTYPE3");
2469 cpl_propertylist_erase(pl,
"CRPIX3");
2470 cpl_propertylist_erase(pl,
"CRVAL3");
2471 cpl_propertylist_erase(pl,
"CDELT3");
2472 cpl_propertylist_update_double(pl,
"CD1_1", 0.);
2473 cpl_propertylist_update_double(pl,
"CD1_2", deltaLambda);
2474 cpl_propertylist_erase(pl,
"CD1_3");
2475 cpl_propertylist_erase(pl,
"CD2_1");
2476 cpl_propertylist_erase(pl,
"CD2_2");
2477 cpl_propertylist_erase(pl,
"CD2_3");
2478 cpl_propertylist_erase(pl,
"CD3_1");
2479 cpl_propertylist_erase(pl,
"CD3_2");
2480 cpl_propertylist_erase(pl,
"CD3_3");
2484 cpl_vector_save(data,
"spectrum_vector.fits",
2485 CPL_TYPE_DOUBLE, pl, CPL_IO_CREATE));
2486 cpl_propertylist_delete(pl);
2488 pl = cpl_propertylist_duplicate(sof.header);
2490 if(strstr(recipe_name,
"no_flat") != NULL) {
2491 cpl_msg_info(cpl_func,
"recipe_name: %s",recipe_name);
2492 cpl_propertylist_update_string(pl, CPL_DFS_PRO_CATG,
2493 ERIS_IFU_PRO_JITTER_SPECTRUM_NOFLAT);
2495 cpl_msg_info(cpl_func,
"recipe_name: %s",recipe_name);
2496 cpl_propertylist_update_string(pl, CPL_DFS_PRO_CATG,
2497 ERIS_IFU_PRO_JITTER_SPECTRUM);
2502 cpl_propertylist_update_string(pl,
"ESO PRO REC1 ID",
"eris_ifu_jitter");
2504 waveArray = cpl_array_wrap_double(cpl_vector_get_data(lambda),
2506 fluxArray = cpl_array_wrap_double(cpl_vector_get_data(data),
2508 errArray = cpl_array_wrap_double(cpl_vector_get_data(error),
2510 if (totalFlux != NULL) {
2511 totalFluxArray = cpl_array_wrap_double(cpl_vector_get_data(totalFlux),
2516 pro_tab = cpl_table_new(1);
2517 cpl_table_new_column_array(pro_tab,
"WAVE",
2518 CPL_TYPE_DOUBLE, spectrumSize);
2519 cpl_table_new_column_array(pro_tab,
"FLUX",
2520 CPL_TYPE_DOUBLE, spectrumSize);
2521 cpl_table_new_column_array(pro_tab,
"ERR",
2522 CPL_TYPE_DOUBLE, spectrumSize);
2523 cpl_table_new_column_array(pro_tab,
"TOT_FLUX",
2524 CPL_TYPE_DOUBLE, spectrumSize);
2525 cpl_table_set_array(pro_tab,
"WAVE", 0, waveArray);
2526 cpl_table_set_array(pro_tab,
"FLUX", 0, fluxArray);
2527 cpl_table_set_array(pro_tab,
"ERR", 0, errArray);
2528 if (totalFlux != NULL) {
2529 cpl_table_set_array(pro_tab,
"TOT_FLUX", 0, totalFluxArray);
2533 pro_tab = cpl_table_new(spectrumSize);
2534 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(lambda),
"WAVE");
2535 if (totalFlux != NULL) {
2536 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(data),
"FLUX");
2538 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(data),
"TOT_FLUX");
2540 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(error),
"ERR");
2541 if (totalFlux != NULL) {
2542 cpl_table_wrap_double(pro_tab, cpl_vector_get_data(totalFlux),
"TOT_FLUX");
2545 char *filename = cpl_sprintf(
"%s_spectrum.fits", recipe_name);
2546 cpl_propertylist_append_string(pl,
"PRODCATG",
"SCIENCE.SPECTRUM");
2547 cpl_dfs_save_table(frames, NULL, parlist, frames, NULL,
2548 pro_tab, NULL, recipe_name, pl,
2549 NULL, PACKAGE
"/" PACKAGE_VERSION, filename);
2552 cpl_propertylist_delete(pl);
2554 cpl_array_unwrap(waveArray);
2555 cpl_array_unwrap(fluxArray);
2556 cpl_array_unwrap(errArray);
2557 if (totalFlux != NULL) {
2558 cpl_array_unwrap(totalFluxArray);
2561 cpl_table_unwrap(pro_tab,
"WAVE");
2562 if (totalFlux != NULL) {
2563 cpl_table_unwrap(pro_tab,
"FLUX");
2565 cpl_table_unwrap(pro_tab,
"TOT_FLUX");
2567 cpl_table_unwrap(pro_tab,
"ERR");
2568 if (totalFlux != NULL) {
2569 cpl_table_unwrap(pro_tab,
"TOT_FLUX");
2572 cpl_table_delete(pro_tab);
2578 return cpl_error_get_code();
2591cpl_error_code eris_ifu_extract_spec_fetch_params(
2592 const cpl_parameterlist * parlist,
2593 struct esParamStruct *params,
2594 const char* context)
2598 const char* methodString;
2599 char* param_name = NULL;
2601 param_name = cpl_sprintf(
"%s.mask_method", context);
2603 methodString = cpl_parameter_get_string(
2604 cpl_parameterlist_find_const(parlist, param_name));
2605 cpl_free(param_name);
2608 if (strncasecmp(methodString,
"mask", strlen(
"mask")) == 0) {
2609 params->mask_method = MASK;
2610 }
else if (strncasecmp(methodString,
"position", strlen(
"position")) == 0) {
2611 params->mask_method = POSITION;
2612 }
else if (strncasecmp(methodString,
"max", strlen(
"max")) == 0) {
2613 params->mask_method = MAX;
2614 }
else if (strncasecmp(methodString,
"fit", strlen(
"fit")) == 0) {
2615 params->mask_method = FIT;
2616 }
else if (strncasecmp(methodString,
"optimal", strlen(
"optimal")) == 0) {
2617 params->mask_method = OPTIMAL;
2619 cpl_msg_error(cpl_func,
"The maks_method parameter must be one "
2620 "of the list: mask, position, max, fit");
2622 "Error reading recipe parameter, unknown mask method %s",
2628 param_name = cpl_sprintf(
"%s.center", context);
2629 center = cpl_parameter_get_string(
2630 cpl_parameterlist_find_const(parlist, param_name));
2631 cpl_free(param_name);
2635 nFields = sscanf(center,
"%d,%d%n",
2636 ¶ms->center_x, ¶ms->center_y, &end);
2637 if (nFields != 2 || end != (
int)strlen(center)) {
2638 cpl_msg_error(cpl_func,
"The center parameter must be "
2639 "a list of two integers separated by a comma");
2641 "Error reading recipe parameter, cannot properly read center spec %s",
2643 printf(
"Error reading center string\n");
2646 param_name = cpl_sprintf(
"%s.radius", context);
2647 params->radius = cpl_parameter_get_double(
2648 cpl_parameterlist_find_const(parlist, param_name));
2649 cpl_free(param_name);
2651 param_name = cpl_sprintf(
"%s.product_depth", context);
2652 params->productDepth = cpl_parameter_get_int(
2653 cpl_parameterlist_find_const(parlist, param_name));
2654 cpl_free(param_name);
2661 return cpl_error_get_code();
2677eris_ifu_jitter_extract(cpl_frameset * frameset,
2678 const cpl_parameterlist *parlist,
2681 struct stdParamStruct stdParams,
2682 const char* pipefile_prefix,
2683 const char* context)
2685 double startLambda = 0.,
2688 cpl_frame *frame_cube_coadd = NULL;
2689 cpl_image *mask = NULL;
2690 hdrl_image *collapsedCube = NULL;
2691 cpl_bivector *spectrum = NULL;
2692 cpl_vector *error = NULL;
2693 cpl_vector *totalFlux = NULL;
2694 cpl_vector *qual = NULL;
2695 cpl_propertylist *plist = NULL;
2696 char *fnamePrefix = NULL,
2698 const char *fname = NULL;
2699 struct esParamStruct esParams;
2700 struct esSofStruct esSof;
2703 cpl_msg_info(cpl_func,
"Extracting data source from %s", pcatg);
2705 frame_cube_coadd = cpl_frameset_find(frameset, pcatg);
2706 fname = cpl_frame_get_filename(frame_cube_coadd);
2709 plist = cpl_propertylist_load(fname, 1);
2710 refPixel = cpl_propertylist_get_double(plist,
"CRPIX3");
2711 startLambda = cpl_propertylist_get_double(plist,
"CRVAL3");
2712 if(cpl_propertylist_has(plist,
"CDELT3")) {
2713 deltaLambda = cpl_propertylist_get_double(plist,
"CDELT3");
2715 deltaLambda = cpl_propertylist_get_double(plist,
"CD3_3");
2718 startLambda = startLambda - (refPixel - 1.) * deltaLambda;
2721 eris_ifu_extract_spec_fetch_params(parlist, &esParams, context));
2724 cubeType coadd_obj_type = eris_ifu_jitter_get_coadd_obj_type(obj_type);
2725 eris_ifu_jitter_get_cube_type_string(coadd_obj_type);
2727 eris_ifu_jitter_extract_spec_processSof(obj_type, frameset,
2730 eris_ifu_jitter_get_procatg_and_filename(obj_type, &proCatg, &fnamePrefix);
2732 cpl_image *contribMap = NULL;
2733 collapsedCube = eris_ifu_extract_spec_collapse(esSof.cube, &contribMap);
2736 char* pro_catg = cpl_sprintf(
"%s_MEDIAN",proCatg);
2738 cpl_free(fnamePrefix);
2739 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG, pro_catg);
2740 char *filename = cpl_sprintf(
"%s_cube_median.fits", pipefile_prefix);
2742 if( strstr(pro_catg,
"STD") != NULL ||
2743 strstr(pro_catg,
"PSF") != NULL ){
2744 cpl_propertylist* qcheader =
2747 cpl_propertylist_append(plist, qcheader);
2748 cpl_propertylist_delete(qcheader);
2754 pipefile_prefix, plist,
"RADECSYS", filename,
2757 rmse, mask_ima, flag16bit, UNIT_ADU);
2758 cpl_image_delete(mask_ima);
2769 mask = eris_ifu_extract_spec_create_mask(esParams, esSof,
2771 esParams.productDepth));
2773 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG,
2774 ERIS_IFU_PRO_JITTER_EXTRACTION_MASK);
2775 filename = cpl_sprintf(
"%s_extraction_mask.fits", pipefile_prefix);
2776 cpl_dfs_save_image(frameset, plist, parlist, frameset, NULL,
2777 mask, CPL_TYPE_FLOAT, pipefile_prefix,
2779 PACKAGE
"/" PACKAGE_VERSION,
2784 if (esParams.mask_method == OPTIMAL) {
2786 spectrum = eris_ifu_optimal_extraction(esSof.cube,
2787 esSof.qualImagelist,
2789 startLambda, deltaLambda,
2790 esParams.productDepth,
2794 spectrum = eris_ifu_extract_spectrum(esSof.cube, mask,
2795 startLambda, deltaLambda,
2796 &error, &totalFlux, &qual));
2799 eris_ifu_jitter_spec_save_products(frameset, parlist, esSof, spectrum,
2800 error, totalFlux, stdParams.productDepth, CPL_TRUE,
2808 if (esSof.mask != mask) {
2812 eris_ifu_extract_free_esSofStruct(&esSof);
2818 return cpl_error_get_code();
2831eris_ifu_jitter_extract_spec_processSof(
2833 cpl_frameset* frames,
2834 struct esParamStruct params,
2835 struct esSofStruct *sof)
2837 cpl_frame *frame = NULL;
2842 if (frames == NULL) {
2844 "missing frameset");
2847 if (cpl_frameset_is_empty(frames)) {
2849 "SOF file is empty or missing");
2856 char *proCatg = NULL;
2857 char *fnamePrefix = NULL;
2858 eris_ifu_jitter_get_procatg_and_filename(obj_type, &proCatg, &fnamePrefix);
2859 frame = cpl_frameset_find(frames, proCatg);
2860 cpl_free(fnamePrefix);
2863 if (frame != NULL) {
2866 cpl_frame_get_filename(frame),
2867 &sof->header, &sof->qualImagelist, &sof->qualityType));
2873 "missing \"%s\" tag in the SOF, input data cube",
2880 if (params.mask_method == MASK) {
2881 frame = cpl_frameset_find(frames, ERIS_IFU_UTIL_MASK);
2883 if (frame != NULL) {
2885 sof->mask = cpl_image_load(
2886 cpl_frame_get_filename(frame),
2887 CPL_TYPE_DOUBLE, 0, 0));
2890 "missing \"%s\" tag in the SOF, extraction mask",
2891 ERIS_IFU_UTIL_MASK);
2899 return cpl_error_get_code();
2913cpl_error_code eris_ifu_dar_correction(
2914 hdrl_imagelist *cube,
2915 cpl_propertylist *hdr,
2921 cpl_ensure_code(cube,CPL_ERROR_NULL_INPUT);
2922 cpl_ensure_code(hdr,CPL_ERROR_NULL_INPUT);
2928 cpl_propertylist_get_double(hdr,
"ESO TEL AIRM START") +
2929 cpl_propertylist_get_double(hdr,
"ESO TEL AIRM END")) / 2.;
2931 cpl_propertylist_get_double(hdr,
"ESO TEL PARANG START") +
2932 cpl_propertylist_get_double(hdr,
"ESO TEL PARANG END")) / 2.;
2934 cpl_propertylist_get_double(hdr,
"ESO ADA POSANG");
2936 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI TEMP");
2938 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI RHUM");
2940 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI PRES START") +
2941 cpl_propertylist_get_double(hdr,
"ESO TEL AMBI PRES END")) / 2.;
2943 cpl_wcs *wcs = cpl_wcs_new_from_propertylist(hdr);
2946 hdrl_parameter *darParams = NULL;
2948 (hdrl_value) {airmass, 0.},
2949 (hdrl_value) {parang, 0.},
2950 (hdrl_value) {posang, 0.},
2951 (hdrl_value) {temp, 0.},
2952 (hdrl_value) {rhum, 0.},
2953 (hdrl_value) {pres, 0.},
2957 cpl_vector *lambdaIn = NULL;
2960 cpl_vector_multiply_scalar(lambdaIn, 10000.);
2961 lambdaRef = cpl_vector_get(lambdaIn, cpl_vector_get_size(lambdaIn)/2);
2962 int naxis3 = cpl_propertylist_get_int(hdr, NAXIS3);
2963 cpl_vector *xShift = cpl_vector_new(naxis3);
2964 cpl_vector *yShift = cpl_vector_new(naxis3);
2965 cpl_vector *xShiftErr = cpl_vector_new(naxis3);
2966 cpl_vector *yShiftErr = cpl_vector_new(naxis3);
2970 (hdrl_value) {lambdaRef, 0.}, lambdaIn,
2971 xShift, yShift, xShiftErr, yShiftErr ));
2972 cpl_msg_info(cpl_func,
"DAR correction shift in X min/max: %.1f/%.1f, "
2973 "in Y min/max: %.1f/%.1f",
2974 cpl_vector_get_min(xShift), cpl_vector_get_max(xShift),
2975 cpl_vector_get_min(yShift), cpl_vector_get_max(yShift));
2978 radius = CPL_KERNEL_DEF_WIDTH;
2981 length = CPL_KERNEL_DEF_SAMPLES;
2984 const char *kernelName[] = {
2994 cpl_msg_info(cpl_func,
"DAR correction: shift method %s, radius %.1f, length %d",
2995 kernelName[method], radius, length);
2997 for (cpl_size sx=0; sx<naxis3; sx++) {
3001 cpl_image *err2Img = cpl_image_duplicate(errImg);
3003 cpl_size nx = cpl_image_get_size_x(inImg);
3004 cpl_size ny = cpl_image_get_size_y(inImg);
3005 cpl_image *outImg = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3006 cpl_image *out2Img = NULL;
3008 double shiftX = cpl_vector_get(xShift, sx);
3009 double shiftY = cpl_vector_get(yShift, sx);
3011 out2Img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3012 BRK_IF_ERROR(eris_ifu_dar_cpl_shift(inImg, outImg, out2Img, shiftX, shiftY,
3013 method, radius, length));
3014 }
else if (method == 7) {
3015 eris_ifu_dar_gsl_shift(inImg, outImg, shiftX, shiftY, gsl_interp2d_bilinear);
3016 }
else if (method == 8) {
3017 eris_ifu_dar_gsl_shift(inImg, outImg, shiftX, shiftY, gsl_interp2d_bicubic);
3019 cpl_image_reject_from_mask(err2Img, cpl_image_get_bpm(outImg));
3028 cpl_image_delete(outImg);
3029 cpl_image_delete(err2Img);
3038 cpl_wcs_delete(wcs);
3043 return cpl_error_get_code();
3045cpl_error_code eris_ifu_dar_cpl_shift(
3051 cpl_kernel kernelType,
3053 cpl_size kernelSize)
3056 cpl_ensure_code(inImg, CPL_ERROR_NULL_INPUT);
3057 cpl_ensure_code(out1Img, CPL_ERROR_NULL_INPUT);
3058 cpl_ensure_code(out2Img, CPL_ERROR_NULL_INPUT);
3063 cpl_vector *xprofile = NULL;
3065 cpl_vector *yprofile = NULL;
3067 cpl_image *correction_map = NULL;
3069 nx = cpl_image_get_size_x(inImg);
3070 ny = cpl_image_get_size_x(inImg);
3071 cpl_image *deltax = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3072 cpl_image *deltay = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
3073 cpl_image_add_scalar(deltax, xShift);
3074 cpl_image_add_scalar(deltay, yShift);
3076 xprofile = cpl_vector_new(kernelSize);
3077 cpl_vector_fill_kernel_profile(xprofile, kernelType, width);
3079 yprofile = cpl_vector_new(kernelSize);
3080 cpl_vector_fill_kernel_profile(yprofile, kernelType, width);
3084 cpl_image_warp(out1Img, inImg, deltax, deltay, xprofile, xradius, yprofile, yradius);
3087 correction_map = cpl_image_new(cpl_image_get_size_x(out1Img),
3088 cpl_image_get_size_y(out1Img),
3089 cpl_image_get_type(out1Img));
3090 cpl_image_fill_jacobian(correction_map, deltax, deltay);
3091 cpl_image_copy(out2Img, out1Img, 1, 1);
3092 cpl_image_multiply(out2Img, correction_map);
3106 return cpl_error_get_code();
3109cpl_error_code eris_ifu_dar_gsl_shift(
3114 const gsl_interp2d_type *T)
3122 gsl_set_error_handler_off();
3123 const double xa[] = {
3124 0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,
3125 16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,
3126 31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,
3127 46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,
3130 const double ya[]= {
3131 0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,
3132 16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,
3133 31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,
3134 46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,
3137 double *za = cpl_image_get_data_double(inImg);
3140 nx = cpl_image_get_size_x(outImg);
3141 ny = cpl_image_get_size_y(outImg);
3142 gsl_spline2d *spline = gsl_spline2d_alloc(T, nx, ny);
3143 gsl_interp_accel *xacc = gsl_interp_accel_alloc();
3144 gsl_interp_accel *yacc = gsl_interp_accel_alloc();
3145 gsl_spline2d_init(spline, xa, ya, za, nx, ny);
3149 for (
int i = 0; i < nx; ++i)
3151 double xi = i - xShift;
3153 for (
int j = 0; j < nx; ++j)
3155 double yj = j - yShift;
3156 if (xi > nx-1 || xi < 0 || yj > ny-1 || yj < 0) {
3161 cpl_image_set(outImg, i+1, j+1, z);
3167 gsl_spline2d_free(spline);
3168 gsl_interp_accel_free(xacc);
3169 gsl_interp_accel_free(yacc);
3170 return cpl_error_get_code();
3179eris_frameset_count_tag(cpl_frameset * sof,
const char* tag)
3182 cpl_ensure(sof, CPL_ERROR_NULL_INPUT, -1);
3183 cpl_ensure(tag, CPL_ERROR_NULL_INPUT, -1);
3186 cpl_frameset* loc_sof = cpl_frameset_duplicate(sof);
3187 cpl_frame* frame = cpl_frameset_find(loc_sof, tag);
3190 cpl_frameset_erase_frame(loc_sof, frame);
3191 frame = cpl_frameset_find(loc_sof, tag);
3195 cpl_frameset_delete(loc_sof);
3206eris_frameset_duplicate_cube_tag(cpl_frameset* frameset,
const char* pcatg,
3207 cpl_boolean apply_flat)
3209 cpl_ensure(frameset, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
3210 cpl_ensure(pcatg, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
3213 cpl_frame* frm_tmp = cpl_frameset_find(frameset, pcatg);
3214 cpl_frame* frm_dup = cpl_frame_duplicate(frm_tmp);
3215 const char* fname = cpl_frame_get_filename(frm_tmp);
3216 const char* fname_new = NULL;
3217 cpl_propertylist* plist = cpl_propertylist_load(fname, 0);
3219 if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_OBJ_CUBE) == 0) {
3221 fname_new =
"eris_ifu_jitter_obj_cube_coadd.fits";
3222 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD);
3223 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD);
3224 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_DAR_CUBE) == 0) {
3225 fname_new =
"eris_ifu_jitter_dar_cube_coadd.fits";
3226 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_COADD);
3227 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_COADD);
3228 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_TWK_CUBE) == 0) {
3229 fname_new =
"eris_ifu_jitter_twk_cube_coadd.fits";
3230 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD);
3231 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_TWK_CUBE_COADD);
3232 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_PSF_CUBE) == 0) {
3234 fname_new =
"eris_ifu_stdstar_psf_cube_coadd.fits";
3235 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
3236 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_PSF_CUBE_COADD);
3237 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_STD_CUBE) == 0){
3240 fname_new =
"eris_ifu_stdstar_std_cube_coadd.fits";
3241 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
3242 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD);
3244 fname_new =
"eris_ifu_stdstar_no_flat_std_cube_coadd.fits";
3245 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT);
3246 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_NOFLAT);
3248 }
else if(strcmp(pcatg,ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE) == 0){
3251 fname_new =
"eris_ifu_stdstar_std_flux_cube_coadd.fits";
3252 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD);
3253 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD);
3255 fname_new =
"eris_ifu_stdstar_no_flat_std_flux_cube_coadd.fits";
3256 cpl_propertylist_update_string(plist, FHDR_PRO_CATG, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT);
3257 cpl_frame_set_tag(frm_dup, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_NOFLAT);
3261 char* cmd = cpl_sprintf(
"cp %s %s",fname, fname_new);
3262 cpl_msg_debug(cpl_func,
"Copying %s", cmd);
3263 int status = system(cmd);
3265 cpl_msg_warning(cpl_func,
"call to system() failed");
3267 cpl_frame_set_filename(frm_dup, fname_new);
3268 cpl_frame_set_group(frm_dup, CPL_FRAME_GROUP_PRODUCT);
3269 cpl_frame_set_level(frm_dup, CPL_FRAME_LEVEL_FINAL);
3271 cpl_propertylist_save(plist, fname_new, CPL_IO_CREATE);
3272 cpl_propertylist_delete(plist);
3274 plist = cpl_propertylist_load(fname, 1);
3275 cpl_imagelist* data = cpl_imagelist_load(fname,CPL_TYPE_FLOAT, 1);
3276 cpl_imagelist_save(data, fname_new, CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND);
3277 cpl_imagelist_delete(data);
3278 cpl_propertylist_delete(plist);
3280 plist = cpl_propertylist_load(fname, 2);
3281 data = cpl_imagelist_load(fname, CPL_TYPE_FLOAT, 2);
3282 cpl_imagelist_save(data, fname_new, CPL_TYPE_FLOAT, plist, CPL_IO_EXTEND);
3283 cpl_imagelist_delete(data);
3284 cpl_propertylist_delete(plist);
3286 plist = cpl_propertylist_load(fname, 3);
3287 data = cpl_imagelist_load(fname, CPL_TYPE_INT, 3);
3288 cpl_imagelist_save(data, fname_new, CPL_TYPE_INT, plist, CPL_IO_EXTEND);
3289 cpl_imagelist_delete(data);
3290 cpl_propertylist_delete(plist);
3295 cpl_frameset_insert(frameset, frm_dup);
3299 return cpl_error_get_code();
3302cpl_error_code eris_ifu_update_wcs_with_OCS_keywords(
3303 struct sofStruct *sof)
3305 cpl_error_code retval = CPL_ERROR_NONE;
3306 cpl_propertylist *header = NULL;
3320 if (sof->exposureTableCnt < 2) {
3321 return CPL_ERROR_NONE;
3331 for (sx = 0; sx < sof->exposureTableCnt; sx++) {
3332 header = sof->exposureTable[sx].hdr;
3333 cumOffset1 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS1);
3334 cumOffset2 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS2);
3336 if (cumOffset1 == 0.0 && cumOffset2 == 0.0) {
3339 cpl_msg_info(
"update_WCS_with_OCS_keywords",
3340 "%d %s : %f/%f %.1f/%.1f %g %g %g %g",
3341 sx, cpl_frame_get_filename(sof->exposureTable[sx].frame),
3342 cpl_propertylist_get_double(header, FHDR_E_CRVAL1),
3343 cpl_propertylist_get_double(header, FHDR_E_CRVAL2),
3344 cpl_propertylist_get_double(header,
"CRPIX1"),
3345 cpl_propertylist_get_double(header,
"CRPIX2"),
3346 cpl_propertylist_get_double(header,
"CD1_1"),
3347 cpl_propertylist_get_double(header,
"CD1_2"),
3348 cpl_propertylist_get_double(header,
"CD2_1"),
3349 cpl_propertylist_get_double(header,
"CD2_2")
3357 header = sof->exposureTable[rx].hdr;
3358 crval1 = cpl_propertylist_get_double(header, FHDR_E_CRVAL1);
3359 crval2 = cpl_propertylist_get_double(header, FHDR_E_CRVAL2);
3360 cumOffset1 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS1);
3361 cumOffset2 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS2);
3364 crval1Ref = crval1 - cumOffset1 / 3600.;
3365 crval2Ref = crval2 - cumOffset2 / 3600.;
3367 cpl_msg_info(
"update_WCS_with_OCS_keywords",
"ref: %d %f %f",
3368 rx, crval1Ref, crval2Ref);
3370 for (sx = 0; sx < sof->exposureTableCnt; sx++) {
3371 header = sof->exposureTable[sx].hdr;
3372 crval1 = cpl_propertylist_get_double(header, FHDR_E_CRVAL1);
3373 crval2 = cpl_propertylist_get_double(header, FHDR_E_CRVAL2);
3374 cumOffset1 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS1);
3375 cumOffset2 = cpl_propertylist_get_double(header, FHDR_E_CUMOFFS2);
3377 crval1New = crval1Ref + cumOffset1 / 3600.;
3378 crval2New = crval2Ref + cumOffset2 / 3600.;
3379 cpl_propertylist_set_double(header, FHDR_E_CRVAL1, crval1New);
3380 cpl_propertylist_set_double(header, FHDR_E_CRVAL2, crval2New);
3383 cpl_msg_info(
"update_WCS_with_OCS_keywords",
3384 "%d %f -> %f (%f) %f -> %f (%f) %f / %f %f / %f %f // %f",
3386 crval1, crval1New, (crval1-crval1New)*3600.,
3387 crval2, crval2New, (crval2-crval2New)*3600.,
3388 cumOffset1, cumOffset2,
3389 (crval1New-crval1Ref)*3600., (crval2New-crval2Ref)*3600.,
3390 (crval1-crval1Ref)*3600., (crval2-crval2Ref)*3600. );
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 the frames with the given tag from a frameset.
hdrl_imagelist * eris_ifu_load_deq_hdrl_imagelist(const char *filename, cpl_propertylist **primaryHeader, cpl_imagelist **qualImagelist, deqQualityType *qualityType)
Function to load an HDRL imagelist with quality extensions.
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)
Write DFS pipeline product with image, error and data qual.
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)
Write DFS pipeline product with image, error and data qual.
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
#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)
eris_ifu_warp_polynomial_image
cpl_polynomial * eris_ifu_lcorr_get(cpl_imagelist *cube, hdrl_imagelist *hdrlCube, const cpl_propertylist *header, cpl_vector *peaks, const int pfit_order)
Main function to create the lcal-correction.
cpl_vector * eris_ifu_lcorr_create_lambda_vector(const cpl_propertylist *header)
Creates a wavelength vector from an input cube.
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 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
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)
eris_ifu_get_plane_cut_min_max
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 in input data 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 imagelist for debugging purposes
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)
remove planes from input iml and bpm in the range [0, zmin), (zmax,sz]
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)