29#include "eris_ifu_error.h"
30#include "eris_ifu_utils.h"
31#include "eris_ifu_dfs.h"
32#include "eris_ifu_debug.h"
33#include "eris_ifu_flat_static.h"
34#include "eris_ifu_dark_static.h"
35#include "eris_ifu_functions.h"
36#include "eris_utils.h"
80cpl_error_code eris_ifu_flat_static(cpl_frameset *fs,
81 const cpl_parameterlist *parlist,
85 const char *recipe_name,
86 const char *procatg_prefix,
87 const char *instrument,
88 cpl_propertylist **qc_list,
89 hdrl_image **masterFlatHdrlImg_lo,
90 cpl_image **qualityImage)
92 cpl_error_code ret = CPL_ERROR_NONE;
93 cpl_image *contrib_map = NULL;
94 cpl_mask *bpm2dMask = NULL,
96 hdrl_image *masterFlatHdrlImg_hi = NULL;
97 hdrl_imagelist *hdrl_imglist_on = NULL,
98 *hdrl_imglist_off = NULL;
99 const char *fn = NULL;
102 double cleanmean = 0.,
105 cpl_ensure_code(fs, CPL_ERROR_NULL_INPUT);
106 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
107 cpl_ensure_code(procatg, CPL_ERROR_NULL_INPUT);
108 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
109 cpl_ensure_code(qc_list, CPL_ERROR_NULL_INPUT);
110 cpl_ensure_code(masterFlatHdrlImg_lo, CPL_ERROR_NULL_INPUT);
111 cpl_ensure_code(qualityImage, CPL_ERROR_NULL_INPUT);
116 double gain = 0., exptime = 0.;
117 eris_ifu_flat_load_frames(fs,
122 *qc_list = cpl_propertylist_new();
124 cpl_propertylist_append_string(*qc_list, CPL_DFS_PRO_CATG,
128 eris_ifu_flat_calc_qc_pre(parlist,
138 cpl_frame* raw_flat_lamp = NULL;
140 if (NULL != cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_LAMP)){
141 raw_flat_lamp = cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_LAMP);
143 }
else if (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_LAMP_ON) > 0) {
145 raw_flat_lamp = cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_LAMP_ON);
147 }
else if (NULL != cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_LAMP_ON)){
148 raw_flat_lamp = cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_LAMP_ON);
150 }
else if (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_NS_ON) > 0) {
152 raw_flat_lamp = cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_NS_ON);
154 raw_flat_lamp = cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_NS);
156 const char* fname = cpl_frame_get_filename(raw_flat_lamp);
157 cpl_propertylist* header = cpl_propertylist_load(fname, 0);
159 cpl_propertylist_delete(header);
160 eris_ifu_calc_flat(parlist,
167 masterFlatHdrlImg_lo,
168 &masterFlatHdrlImg_hi,
171 if (productDepth & 4) {
173 tmp_str = cpl_sprintf(
"%s_dbg_flat_masterflat.fits", recipe_name));
175 "eris_ifu_distortion_dbg_flat_02_masterflat",
181 if (mode != FLAT_MODE_SEGMENT) {
206 if (strcmp(recipe_name, REC_NAME_DISTORTION) == 0)
209 double maxcut = 50000.,
211 char *band_name = NULL;
212 cpl_frame *fr = NULL;
214 cpl_propertylist *plist = NULL;
216 fr = cpl_frameset_find(fs, ERIS_IFU_RAW_FLAT_NS);
217 fn = cpl_frame_get_filename(fr);
218 plist = cpl_propertylist_load(fn, 0);
220 if (strcmp(instrument, INSTRUMENT_ERIS) == 0) {
222 const char *tmp_band = NULL;
223 tmp_band = cpl_propertylist_get_string(plist,
225 band_name = cpl_sprintf(
"%c", tmp_band[0]);
228 band_name = cpl_sprintf(
"%s", cpl_propertylist_get_string(plist,
229 FHDR_S_FILTER_NAME));
242 hdrl_image **med = NULL,
255 mjd_obs = cpl_propertylist_get_double(plist, FHDR_MJD_OBS);
260 if ((strcmp(band_name,
"J") == 0) && (mjd_obs > 58150.)) {
266 if (productDepth & 4) {
268 "eris_ifu_distortion_dbg_flat_03_bad_medIm",
275 eris_ifu_flat_thresh_mask(*masterFlatHdrlImg_lo,
278 if (productDepth & 4) {
280 "eris_ifu_distortion_dbg_flat_04_bad_medIm_cut",
284 eris_ifu_column_tilt(*masterFlatHdrlImg_lo, sigma);
286 if (productDepth & 4) {
288 "eris_ifu_distortion_dbg_flat_05_bad_colImage",
291 eris_ifu_flat_stats_rectangle(*masterFlatHdrlImg_lo,
298 eris_ifu_flat_thresh_mask(*masterFlatHdrlImg_lo,
299 cleanmean - meanfactor*cleanstdev,
300 cleanmean + meanfactor*cleanstdev);
301 if (productDepth & 4) {
303 "eris_ifu_distortion_dbg_flat_06_bad_threshIm",
307 med = (hdrl_image**)cpl_calloc(n_iter,
sizeof(hdrl_image*));
309 med[0] = eris_ifu_flat_median_image(*masterFlatHdrlImg_lo,
310 -meanfactor*cleanstdev);
312 for (
int i = 0; i< n_iter-1; i++) {
313 med[i+1] = eris_ifu_flat_median_image(med[i],
314 -meanfactor*cleanstdev);
318 eris_ifu_sinfo_compare_images(*masterFlatHdrlImg_lo,
321 if (productDepth & 4) {
323 "eris_ifu_distortion_dbg_flat_07_bad_compImage",
328 *masterFlatHdrlImg_lo = original;
330 for (
int i = 0; i< n_iter; i++) {
333 cpl_free(med); med = NULL;
340 *masterFlatHdrlImg_lo,
342 &bpm2dMask, &bpm3dMask);
345 eris_ifu_flat_thresh_mask(*masterFlatHdrlImg_lo,
356 *masterFlatHdrlImg_lo,
358 &bpm2dMask, &bpm3dMask);
363 eris_ifu_flat_calc_qc_post(parlist,
367 masterFlatHdrlImg_hi,
368 *masterFlatHdrlImg_lo,
382 ret = cpl_error_get_code();
412double eris_ifu_getThreshold(hdrl_image *img) {
413 cpl_ensure(img != NULL, CPL_ERROR_ILLEGAL_INPUT, NAN);
435int eris_ifu_matchRow(
int blocksize,
int rx) {
436 cpl_ensure(blocksize > 0, CPL_ERROR_ILLEGAL_INPUT, -1);
437 cpl_ensure(rx >= 0, CPL_ERROR_ILLEGAL_INPUT, -1);
438 cpl_ensure(rx < ERIS_IFU_DETECTOR_SIZE_X, CPL_ERROR_ILLEGAL_INPUT, -1);
442 val = (int)((rx-4)/blocksize + 0.5);
461void eris_ifu_free_structFlatData(
struct structFlatData* sfd) {
464 if(sfd->ry != NULL) cpl_vector_delete(sfd->ry);
465 if(sfd->borderAleft != NULL) cpl_vector_delete(sfd->borderAleft);
466 if(sfd->borderAright != NULL) cpl_vector_delete(sfd->borderAright);
467 if(sfd->borderBleft != NULL) cpl_vector_delete(sfd->borderBleft);
468 if(sfd->borderBright != NULL) cpl_vector_delete(sfd->borderBright);
469 if(sfd->borderCleft != NULL) cpl_vector_delete(sfd->borderCleft);
470 if(sfd->borderCright != NULL) cpl_vector_delete(sfd->borderCright);
471 if(sfd->borderDleft != NULL) cpl_vector_delete(sfd->borderDleft);
472 if(sfd->borderDright != NULL) cpl_vector_delete(sfd->borderDright);
499cpl_error_code eris_ifu_calc_flat(
const cpl_parameterlist *parlist,
500 const char *recipe_name,
502 const hdrl_imagelist *hdrl_imglist_on,
503 const hdrl_imagelist *hdrl_imglist_off,
506 hdrl_image **masterFlatHdrlImg_lo,
507 hdrl_image **masterFlatHdrlImg_hi,
508 cpl_image **contrib_map)
510 cpl_error_code ret = CPL_ERROR_NONE;
511 cpl_image *noiseImage = NULL;
512 hdrl_image *fastFlatImg = NULL;
513 hdrl_parameter *pHdrlCollapse = NULL,
514 *pHdrlFlat_lo = NULL,
515 *pHdrlFlat_hi = NULL;
516 hdrl_imagelist *tmp_hdrl_imglist = NULL,
517 *tmp_hdrl_imglist2 = NULL;
518 char *tmp_str = NULL;
520 cpl_ensure_code(hdrl_imglist_on, CPL_ERROR_NULL_INPUT);
521 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
522 cpl_ensure_code(hdrl_imglist_off, CPL_ERROR_NULL_INPUT);
523 cpl_ensure_code(masterFlatHdrlImg_lo, CPL_ERROR_NULL_INPUT);
524 cpl_ensure_code(contrib_map, CPL_ERROR_NULL_INPUT);
528 cpl_msg_info(cpl_func,
"Generating master flat image...");
531 tmp_str = cpl_sprintf(
"eris.%s.collapse", recipe_name);
536 if (mode == FLAT_MODE_FAST) {
538 cpl_msg_info(cpl_func,
" Fast-mode");
549 masterFlatHdrlImg_lo,
555 cpl_image *tmpFilteredImg = cpl_image_new(
560 cpl_matrix *filterKernel = cpl_matrix_new(5,3);
561 cpl_matrix_set(filterKernel, 0, 1 ,1.0);
562 cpl_matrix_set(filterKernel, 1, 1 ,2.0);
563 cpl_matrix_set(filterKernel, 2, 1 ,3.0);
564 cpl_matrix_set(filterKernel, 3, 1 ,2.0);
565 cpl_matrix_set(filterKernel, 4, 1 ,1.0);
566 cpl_matrix_set(filterKernel, 2, 0 ,1.5);
567 cpl_matrix_set(filterKernel, 2, 2 ,1.5);
568 cpl_image_filter(tmpFilteredImg,
570 filterKernel, CPL_FILTER_LINEAR, CPL_BORDER_FILTER);
571 cpl_image_reject_from_mask(tmpFilteredImg,
578 *masterFlatHdrlImg_lo = fastFlatImg;
580 if (productDepth & 4) {
581 tmp_str = cpl_sprintf(
"%s_dbg_flat_fast.fits", recipe_name);
591 }
else if (mode == FLAT_MODE_HDRL) {
594 cpl_msg_info(cpl_func,
" HDRL-mode");
597 tmp_str = cpl_sprintf(
"eris.%s.flat_lo", recipe_name);
611 cpl_msg_warning(cpl_func,
"#off and #on frames isn't the same! "
612 "So no off-frames are subtracted at all.");
615 if (productDepth & 1) {
617 tmp_str = cpl_sprintf(
"eris.%s.flat_hi", recipe_name);
624 pHdrlCollapse, pHdrlFlat_hi,
625 masterFlatHdrlImg_hi, contrib_map);
630 if (productDepth & 4) {
631 tmp_str = cpl_sprintf(
"eris_ifu_%s_dbg_flat_01_sub", recipe_name);
639 cpl_msg_severity level = cpl_msg_get_level();
640 cpl_msg_set_level(CPL_MSG_ERROR);
644 pHdrlCollapse, pHdrlFlat_lo,
645 masterFlatHdrlImg_lo, contrib_map);
646 cpl_msg_set_level(level);
652 }
else if (mode == FLAT_MODE_SEGMENT) {
654 cpl_msg_info(cpl_func,
" Segment-mode");
656 hdrl_image *masterFlat = NULL,
675 double columnThreshold = .70,
679 *pdnewcleanRowBC = NULL,
682 const double *pcleanRow = NULL;
683 cpl_vector *cleanRow = NULL,
684 *dnewcleanRowBC = NULL,
690 struct structFlatData Data;
695 columnThreshold = .65;
706 eris_ifu_flat_data_init(&Data, blockSize);
712 for(
int ry = ERIS_IFU_DETECTOR_BP_BORDER;
713 ry < ERIS_IFU_DETECTOR_SIZE_Y-ERIS_IFU_DETECTOR_BP_BORDER;
718 ERIS_IFU_DETECTOR_SIZE_X,
722 pcleanRow = cpl_vector_get_data_const(cleanRow);
733 thresholdA = medianA.data * columnThreshold;
735 for (
int cx = 920; cx <= 1100; cx++) {
736 if (pcleanRow[cx] < thresholdA) {
737 if (nLower == 0) rightEdgeA = cx;
739 if (nLower > 1)
break;
748 for (
int cx = 60; cx >= 4; cx--) {
749 if (pcleanRow[cx] < thresholdA) {
750 if (nLower == 0) leftEdgeA = cx;
752 if (nLower > 3)
break;
763 Dright+1, blockSize);
766 thresholdD = medianD.data * columnThreshold;
769 for (
int cx = 1980; cx <= 2047; cx++) {
770 if (pcleanRow[cx] < thresholdD) {
771 if (nLower == 0) rightEdgeD = cx;
773 if (nLower > 6)
break;
782 for (
int cx = 1140; cx >= 1000; cx--) {
783 if (pcleanRow[cx] < thresholdD) {
784 if (nLower == 0) leftEdgeD = cx;
786 if (nLower > 3)
break;
796 dnewcleanRowBC = cpl_vector_new(ERIS_IFU_DETECTOR_SIZE_X);
797 pdnewcleanRowBC = cpl_vector_get_data(dnewcleanRowBC);
798 for (
int i = 0; i < ERIS_IFU_DETECTOR_SIZE_X-1; i++) {
799 pdnewcleanRowBC[i] = pcleanRow[i+1]- pcleanRow[i];
802 int start = rightEdgeA + 1;
803 sample = cpl_vector_extract(dnewcleanRowBC, start, leftEdgeD-1, 1);
804 sample2 = cpl_vector_extract(sample, 40, cpl_vector_get_size(sample)-1, 1);
805 leftEdgeC = cpl_vector_get_maxpos(sample2) + offset + 1;
808 sample2 = cpl_vector_extract(sample, 0, leftEdgeC-10-1, 1);
809 leftEdgeB = cpl_vector_get_maxpos(sample2) - 4;
811 rightEdgeC = cpl_vector_get_minpos(sample);
812 rightEdgeB = leftEdgeC - 2;
818 eris_ifu_flat_data_setBorders(&Data, ry,
819 leftEdgeA, rightEdgeA,
820 leftEdgeB, rightEdgeB,
821 leftEdgeC, rightEdgeC,
822 leftEdgeD, rightEdgeD);
835 for(
int ry = ERIS_IFU_DETECTOR_BP_BORDER;
836 ry < ERIS_IFU_DETECTOR_SIZE_Y-ERIS_IFU_DETECTOR_BP_BORDER;
841 ERIS_IFU_DETECTOR_SIZE_X,
845 borders = eris_ifu_flat_data_getBorderInterpolated(&Data, ry);
846 pborders = cpl_vector_get_data(borders);
848 leftEdgeA = pborders[0];
849 rightEdgeA = pborders[1];
850 leftEdgeB = pborders[2];
851 rightEdgeB = pborders[3];
852 leftEdgeC = pborders[4];
853 rightEdgeC = pborders[5];
854 leftEdgeD = pborders[6];
855 rightEdgeD = pborders[7];
860 if (4+1 <= leftEdgeA+1) {
861 for (
int x = 4; x <= leftEdgeA; x++) {
862 for (
int y = 0; y < sy; y++) {
869 for (
int x = rightEdgeA; x < leftEdgeB; x++) {
870 for (
int y = 0; y < sy; y++) {
876 for (
int x = rightEdgeB; x < leftEdgeC; x++) {
877 for (
int y = 0; y < sy; y++) {
883 for (
int x = rightEdgeC; x < leftEdgeD; x++) {
884 for (
int y = 0; y < sy; y++) {
890 if (rightEdgeD+1<=2044) {
891 for (
int x = rightEdgeD; x < 2044; x++) {
892 for (
int y = 0; y < sy; y++) {
902 coldThreshold = eris_ifu_getThreshold(tmpImg);
903 for (
int x = leftEdgeA; x < rightEdgeA+1; x++) {
904 for (
int y = 0; y < sy; y++) {
905 if (psubImg[x+y*sx] < coldThreshold) {
914 coldThreshold = eris_ifu_getThreshold(tmpImg);
915 for (
int x = leftEdgeB; x < rightEdgeB+1; x++) {
916 for (
int y = 0; y < sy; y++) {
917 if (psubImg[x+y*sx] < coldThreshold) {
926 coldThreshold = eris_ifu_getThreshold(tmpImg);
927 for (
int x = leftEdgeC; x < rightEdgeC+1; x++) {
928 for (
int y = 0; y < sy; y++) {
929 if (psubImg[x+y*sx] < coldThreshold) {
938 coldThreshold = eris_ifu_getThreshold(tmpImg);
939 for (
int x = leftEdgeD; x < rightEdgeD+1; x++) {
940 for (
int y = 0; y < sy; y++) {
941 if (psubImg[x+y*sx] < coldThreshold) {
950 for (
int x = 1; x <= ERIS_IFU_DETECTOR_SIZE_X; x++) {
952 for (
int y = ry+1; y <= ry+1+blockSize-1; y++) {
969 const double *pleftA = cpl_vector_get_data_const(Data.borderAleft),
970 *prightD = cpl_vector_get_data_const(Data.borderDright);
971 for (
int rx = 4; rx < 2044; rx++) {
972 bool lineCheck =
false;
975 rowIndex = eris_ifu_matchRow(blockSize, rx);
977 for (
int colx = pleftA[rowIndex]; colx < prightD[rowIndex]+1; colx++) {
979 if (rx_left > 2044) {
990 if (lineCheck ==
false) {
1002 if ((fabs(cPix - cPixBefore) < thresh) &&
1003 (fabs(cPix - cPixAfter) < thresh))
1008 for (
int ax = startPos; ax < colx; ax++) {
1026 *masterFlatHdrlImg_lo = masterFlat;
1027 eris_ifu_free_structFlatData(&Data);
1036 if (productDepth & 1) {
1039 ret = cpl_error_get_code();
1070cpl_error_code eris_ifu_flat_load_frames(
const cpl_frameset *fs,
1073 hdrl_imagelist **hdrl_imglist_on,
1074 hdrl_imagelist **hdrl_imglist_off)
1076 cpl_error_code err = CPL_ERROR_NONE;
1077 cpl_frameset *fs_extracted = NULL;
1078 cpl_frameset *fs_off = NULL;
1079 hdrl_image *tmp_img = NULL;
1080 cpl_propertylist *plist = NULL;
1081 cpl_mask *bpm_dark = NULL,
1084 const cpl_frame *fr = NULL;
1085 const char *fn = NULL;
1087 bool first_on =
false;
1091 cpl_ensure_code(fs, CPL_ERROR_NULL_INPUT);
1092 cpl_ensure_code(hdrl_imglist_on, CPL_ERROR_NULL_INPUT);
1093 cpl_ensure_code(hdrl_imglist_off, CPL_ERROR_NULL_INPUT);
1094 cpl_ensure_code(gain, CPL_ERROR_NULL_INPUT);
1095 cpl_ensure_code(exptime, CPL_ERROR_NULL_INPUT);
1105 if (bpm_dark != NULL) {
1106 if (cpl_frameset_count_tags(fs, ERIS_IFU_PRO_DIST_BPM) == 1) {
1108 ERIS_IFU_PRO_DIST_BPM, 0);
1109 cpl_mask_or(bpm_dark, bpm_dist);
1112 if (cpl_frameset_count_tags(fs, ERIS_IFU_PRO_DETLIN_BPM) == 1) {
1114 ERIS_IFU_PRO_DETLIN_BPM, 0);
1115 cpl_mask_or(bpm_dark, bpm_detlin);
1119 cpl_msg_info(cpl_func,
"Loading all flat frames...");
1122 if (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_LAMP) > 0) {
1123 tag = cpl_sprintf(
"%s", ERIS_IFU_RAW_FLAT_LAMP);
1125 }
else if ( (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_LAMP_ON) > 0) &&
1126 (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_LAMP_OFF) > 0) ) {
1132 cpl_frameset_join(fs_extracted, fs_off);
1133 tag = cpl_sprintf(
"%s", ERIS_IFU_RAW_FLAT_LAMP_ON);
1134 }
else if (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_NS) > 0) {
1135 tag = cpl_sprintf(
"%s", ERIS_IFU_RAW_FLAT_NS);
1137 }
else if ( (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_NS_ON) > 0) &&
1138 (cpl_frameset_count_tags(fs, ERIS_IFU_RAW_FLAT_NS_OFF) > 0) ) {
1144 cpl_frameset_join(fs_extracted, fs_off);
1145 tag = cpl_sprintf(
"%s", ERIS_IFU_RAW_FLAT_NS_ON);
1150 "Neither FLAT_LAMP or FLAT_NS "
1154 if (cpl_frameset_get_size(fs_extracted) < 1) {
1156 "Not enough FLAT RAW frames!");
1166 fr = cpl_frameset_find_const(fs_extracted, tag);
1167 cpl_size frameCnt = cpl_frameset_get_size(fs_extracted);
1170 for (cpl_size i = 0 ; i < frameCnt ; i++) {
1171 fr = cpl_frameset_get_position_const(fs_extracted, i) ;
1172 fn = cpl_frame_get_filename(fr);
1177 if (cpl_frame_get_tag(fr) != NULL) {
1179 if (bpm_dark != NULL) {
1193 plist = cpl_propertylist_load(fn, 0));
1194 if (cpl_propertylist_has(plist, FHDR_DET_CHIP_GAIN)) {
1195 *gain = cpl_propertylist_get_double(plist,
1196 FHDR_DET_CHIP_GAIN);
1200 if (cpl_propertylist_has(plist, FHDR_EXPTIME)) {
1201 *exptime = cpl_propertylist_get_double(plist,
1216 cpl_msg_info(cpl_func,
"nr_on: %d nr_off: %d",nr_on, nr_off);
1217 if (nr_on != nr_off) {
1218 cpl_msg_warning(cpl_func,
1219 "Number obj/off frames differs (#obj= %d #off= %d)!",
1226 "No ON raw frame in input, something wrong!");
1231 "input object list's size 0. Check"
1232 " your input data!");
1241 err = cpl_error_get_code();
1247 cpl_mask_delete(bpm_dark);
1248 cpl_mask_delete(bpm_dist);
1249 cpl_mask_delete(bpm_detlin);
1275cpl_error_code eris_ifu_flat_calc_qc_pre(
1276 const cpl_parameterlist *parlist,
1277 const char *recipe_name,
1278 const hdrl_imagelist *hdrl_imglist_on,
1279 const hdrl_imagelist *hdrl_imglist_off,
1280 cpl_propertylist *qc_list)
1282 cpl_error_code err = CPL_ERROR_NONE;
1284 cpl_vector *vec_off = NULL;
1285 cpl_vector *vec_diff = NULL;
1286 const cpl_parameter *p =NULL;
1287 hdrl_parameter *param = NULL;
1288 const hdrl_image *img_on_const = NULL;
1289 const hdrl_image *img_off_const = NULL;
1290 hdrl_image *img_on = NULL;
1291 hdrl_image *img_off = NULL;
1292 hdrl_image *img = NULL;
1293 cpl_image *contrib = NULL;
1305 double fpn_stdev1 = 0.;
1306 double fpn_stdev2 = 0.;
1307 char *tmp_str = NULL;
1309 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
1310 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
1311 cpl_ensure_code(hdrl_imglist_on, CPL_ERROR_NULL_INPUT);
1312 cpl_ensure_code(hdrl_imglist_off, CPL_ERROR_NULL_INPUT);
1313 cpl_ensure_code(qc_list, CPL_ERROR_NULL_INPUT);
1318 qc_sat = eris_ifu_get_qc_saturated(hdrl_imglist_on);
1322 "nr. saturated pixels of master flat");
1328 nr_fr = (nr_on <= nr_off) ? nr_on : nr_off;
1330 if (nr_on != nr_off) {
1331 cpl_msg_warning(cpl_func,
1332 "Number obj/off frames differs (#obj= %d #off= %d)!",
1336 vec_off = cpl_vector_new(nr_fr);
1337 vec_diff = cpl_vector_new(nr_fr);
1339 for (
int i = 0; i < nr_fr; i++) {
1354 cpl_vector_get_mean(vec_off),
1355 "[ADU] average flux off frames");
1357 cpl_vector_get_mean(vec_diff),
1358 "[ADU] average counts");
1361 cpl_vector_get_stdev(vec_diff),
1362 "[ADU] stdev counts");
1366 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.xmin1", recipe_name);
1367 p = cpl_parameterlist_find_const(parlist, tmp_str);
1368 xmin1 = cpl_parameter_get_int(p);
1372 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.xmax1", recipe_name);
1373 p = cpl_parameterlist_find_const(parlist, tmp_str);
1374 xmax1 = cpl_parameter_get_int(p);
1378 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.ymin1", recipe_name);
1379 p = cpl_parameterlist_find_const(parlist, tmp_str);
1380 ymin1 = cpl_parameter_get_int(p);
1384 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.ymax1", recipe_name);
1385 p = cpl_parameterlist_find_const(parlist, tmp_str);
1386 ymax1 = cpl_parameter_get_int(p);
1390 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.xmin2", recipe_name);
1391 p = cpl_parameterlist_find_const(parlist, tmp_str);
1392 xmin2 = cpl_parameter_get_int(p);
1396 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.xmax2", recipe_name);
1397 p = cpl_parameterlist_find_const(parlist, tmp_str);
1398 xmax2 = cpl_parameter_get_int(p);
1402 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.ymin2", recipe_name);
1403 p = cpl_parameterlist_find_const(parlist, tmp_str);
1404 ymin2 = cpl_parameter_get_int(p);
1408 tmp_str = cpl_sprintf(
"eris.%s.qc.fpn.ymax2", recipe_name);
1409 p = cpl_parameterlist_find_const(parlist, tmp_str);
1410 ymax2 = cpl_parameter_get_int(p);
1414 tmp_str = cpl_sprintf(
"eris.%s.collapse", recipe_name);
1434 xmin1, ymin1, xmax1, ymax1);
1438 xmin2, ymin2, xmax2, ymax2);
1444 "[ADU] Fixed Pattern Noise of combined frames");
1447 "[ADU] Fixed Pattern Noise of combined frames");
1452 err = cpl_error_get_code();
1492cpl_error_code eris_ifu_flat_calc_qc_post(
const cpl_parameterlist *parlist,
1493 const char *recipe_name,
1494 const int productDepth,
1495 const char *procatg_prefix,
1496 const hdrl_image *masterFlatHdrlImg_hi,
1497 const hdrl_image *masterFlatHdrlImg_lo,
1498 const hdrl_imagelist *hdrl_imglist_on,
1499 const hdrl_imagelist *hdrl_imglist_off,
1500 const cpl_image *contrib_map,
1503 const cpl_mask *bpm2dMask,
1504 const cpl_mask *bpm3dMask,
1506 cpl_propertylist *qc_list,
1507 cpl_image **qualityImage)
1509 cpl_error_code err = CPL_ERROR_NONE;
1515 const cpl_mask *bp_mask_flat = NULL;
1516 cpl_image *tmpImg = NULL,
1523 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
1524 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
1525 cpl_ensure_code(procatg_prefix, CPL_ERROR_NULL_INPUT);
1527 cpl_ensure_code(masterFlatHdrlImg_lo, CPL_ERROR_NULL_INPUT);
1528 cpl_ensure_code(hdrl_imglist_on, CPL_ERROR_NULL_INPUT);
1529 cpl_ensure_code(hdrl_imglist_off, CPL_ERROR_NULL_INPUT);
1530 cpl_ensure_code(contrib_map, CPL_ERROR_NULL_INPUT);
1535 cpl_ensure_code(fs, CPL_ERROR_NULL_INPUT);
1536 cpl_ensure_code(qc_list, CPL_ERROR_NULL_INPUT);
1537 cpl_ensure_code(qualityImage, CPL_ERROR_NULL_INPUT);
1545 *qualityImage = cpl_image_new_from_mask(bp_mask_flat);
1548 cpl_image_multiply_scalar(*qualityImage, ERIS_DQI_BP);
1553 double stdev = cpl_image_get_stdev(ima);
1554 double mean = cpl_image_get_mean(ima);
1555 double median = cpl_image_get_median(ima);
1560 key_name = cpl_sprintf(
"ESO QC FLAT STDDEV");
1561 key_comm = cpl_sprintf(
"[ADU] Std deviation on flat image");
1562 cpl_propertylist_append_double(qc_list,key_name, stdev);
1563 cpl_propertylist_set_comment(qc_list, key_name, key_comm);
1568 key_name = cpl_sprintf(
"ESO QC FLAT MEAN");
1569 key_comm = cpl_sprintf(
"[ADU] Mean value on flat image");
1570 cpl_propertylist_append_double(qc_list,key_name, mean);
1571 cpl_propertylist_set_comment(qc_list, key_name, key_comm);
1575 key_name = cpl_sprintf(
"ESO QC FLAT MEDIAN");
1576 key_comm = cpl_sprintf(
"[ADU] Median value on flat image");
1577 cpl_propertylist_append_double(qc_list,key_name, median);
1578 cpl_propertylist_set_comment(qc_list, key_name, key_comm);
1583 if (bpm2dMask != NULL) {
1584 bpm2dImg = cpl_image_new_from_mask(bpm2dMask);
1585 tmpImg = cpl_image_duplicate(bpm2dImg);
1587 cpl_image_multiply_scalar(tmpImg, ERIS_DQI_BP_BPM2D);
1588 cpl_image_add(*qualityImage, tmpImg);
1591 if (bpm3dMask != NULL) {
1592 bpm3dImg = cpl_image_new_from_mask(bpm3dMask);
1593 tmpImg = cpl_image_duplicate(bpm3dImg);
1595 cpl_image_multiply_scalar(tmpImg, ERIS_DQI_BP_BPM3D);
1596 cpl_image_add(*qualityImage, tmpImg);
1601 if ((hdrl_imglist_on != NULL) && ((productDepth & 2) != 0)) {
1602 fn = cpl_sprintf(
"%s%s", recipe_name,
1603 ERIS_IFU_PRO_FLAT_DBG_CUBE_ON_FN);
1608 if ((hdrl_imglist_off != NULL) && ((productDepth & 2) != 0)) {
1609 fn = cpl_sprintf(
"%s%s", recipe_name,
1610 ERIS_IFU_PRO_FLAT_DBG_CUBE_OFF_FN);
1615 if ((contrib_map != NULL) && ((productDepth & 1) != 0)) {
1616 fn = cpl_sprintf(
"%s%s", recipe_name,
1617 ERIS_IFU_PRO_FLAT_DBG_CONTRIBMAP_FN);
1618 pc = cpl_sprintf(
"%s%s", procatg_prefix,
1619 ERIS_IFU_PRO_FLAT_DBG_CONTRIBMAP);
1621 pc, fn, CPL_TYPE_USHORT, contrib_map);
1626 if ((masterFlatHdrlImg_hi != NULL) && ((productDepth & 1) != 0)) {
1627 fn = cpl_sprintf(
"%s%s", recipe_name,
1628 ERIS_IFU_PRO_FLAT_DBG_HI_FN);
1629 pc = cpl_sprintf(
"%s%s", procatg_prefix,
1630 ERIS_IFU_PRO_FLAT_DBG_HI);
1632 pc, fn, CPL_TYPE_DOUBLE,
1638 if ((bpm2dMask != NULL) && ((productDepth & 1) != 0)) {
1641 fn = cpl_sprintf(
"%s%s", recipe_name,
1642 ERIS_IFU_PRO_FLAT_DBG_BPM2D_FN);
1643 pc = cpl_sprintf(
"%s%s", procatg_prefix,
1644 ERIS_IFU_PRO_FLAT_DBG_BPM2D);
1646 pc, fn, CPL_TYPE_USHORT, bpm2dImg);
1651 if ((bpm3dMask != NULL) && ((productDepth & 1) != 0)) {
1654 fn = cpl_sprintf(
"%s%s", recipe_name,
1655 ERIS_IFU_PRO_FLAT_DBG_BPM3D_FN);
1656 pc = cpl_sprintf(
"%s%s", procatg_prefix,
1657 ERIS_IFU_PRO_FLAT_DBG_BPM3D);
1659 pc, fn, CPL_TYPE_USHORT, bpm3dImg);
1666 cpl_propertylist_update_string(qc_list, CPL_DFS_PRO_CATG,
"");
1671 err = cpl_error_get_code();
1692int eris_ifu_get_qc_saturated(
const hdrl_imagelist *dataHdrl)
1694 int saturated_pixels = 0,
1699 sat_min = ERIS_IFU_FLAT_SAT_MIN;
1700 double threshold = ERIS_IFU_FLAT_SATURATED;
1701 const hdrl_image *curHdrlImg = NULL;
1702 const cpl_image *curImg = NULL;
1703 const double *pcur_img = NULL;
1705 cpl_ensure_code(dataHdrl, CPL_ERROR_NULL_INPUT);
1709 ASSURE((threshold > 0.0) &&
1711 CPL_ERROR_ILLEGAL_INPUT,
1712 "threshold and sat_min must be greater than zero!");
1721 if (nz >= sat_min) {
1723 int ix = 0, iy = 0, iz = 0;
1724 for (iy = 0; iy < ny; iy++) {
1725 for (ix = 0; ix < nx; ix++) {
1727 for (iz = 0; iz < nz; iz++) {
1730 pcur_img = cpl_image_get_data_double_const(curImg);
1732 if (!cpl_image_is_rejected(curImg, ix+1, iy+1) &&
1733 (pcur_img[ix+iy*nx] > threshold)) {
1738 if (tmp_sat >= sat_min) {
1748 saturated_pixels = -1;
1751 return saturated_pixels;
1780cpl_error_code eris_ifu_column_tilt(hdrl_image *hdrl_img,
double sigma)
1782 cpl_error_code err = CPL_ERROR_NONE;
1783 cpl_image *img = NULL;
1784 cpl_binary *pmask = NULL;
1785 cpl_mask *mask = NULL;
1809 cpl_ensure_code(hdrl_img, CPL_ERROR_NULL_INPUT);
1810 cpl_ensure_code(sigma > 0., CPL_ERROR_ILLEGAL_INPUT);
1821 pimg = cpl_image_get_data_double(img);
1822 pmask = cpl_mask_get_data(mask);
1825 for (
int i = ERIS_IFU_DETECTOR_BP_BORDER;
1826 i < ERIS_IFU_DETECTOR_SIZE_X-ERIS_IFU_DETECTOR_BP_BORDER ;
1831 column = (
double*)cpl_calloc(ny,
sizeof(
double*));
1832 sig = (
double*)cpl_calloc(ny,
sizeof(
double*));
1833 dat = (
double*)cpl_calloc(ny,
sizeof(
double*));
1836 for(
int j = 0; j < ny; j++) {
1837 if (pmask[i + j*nx] != BAD_PIX) {
1838 column[j] = pimg[i + j*nx];
1846 for(
int j = 0; j < ny; j++) {
1847 pmask[i + j*nx] = BAD_PIX;
1854 eris_ifu_flat_pixel_qsort(column, col_nr);
1856 for (
int j = 0.1*col_nr + 1; j <= 0.9*col_nr; j++) {
1858 sum2 += column[j] * column[j];
1863 noise = sigma * 1000.;
1865 mean = sum/(double)npix;
1866 noise = sqrt((sum2 - sum*mean)/(
double)(npix -1));
1875 if ((col_nr % 2 == 1) || (col_nr == 0)) {
1876 sinfo_median = column[col_nr/2];
1878 sinfo_median = (column[col_nr/2 - 1] + column[col_nr/2])/2.;
1883 for (
int j = 0; j < ny; j++) {
1884 if ((pmask[i + j*nx] != BAD_PIX) &&
1885 (fabs((pimg[i+j*nx])-sinfo_median) <= noise))
1887 column[col_nr] = pimg[i+j*nx];
1888 dat[col_nr] = (double)j;
1899 eris_ifu_my_fit(dat, column, col_nr, sig, mwt, &a,
1900 &b, &siga, &sigb, &chi2, &q);
1903 if ((fabs(b) >= slope) || (fabs(a) >= saturation) ||
1904 isnan(b) || isnan(a))
1906 cpl_msg_warning(cpl_func,
"linear fit: slope is greater than "
1907 "limit: %f saturation level is "
1908 "reached: %f in column number %d ",
1913 for (
int j = 0; j < ny; j++) {
1914 if ((pmask[i + j*nx] != BAD_PIX) &&
1915 (fabs(b) < slope) &&
1916 (fabs(a) < saturation))
1918 pimg[i+j*nx] = pimg[i+j*nx] - (a + b*(double)j);
1919 }
else if (pmask[i + j*nx] == BAD_PIX) {
1920 pimg[i+j*nx] = NAN ;
1921 }
else if (((fabs(b) >= slope) ||
1922 (fabs(a) >= saturation) ||
1923 isnan(a) || isnan(b)) &&
1924 (pmask[i + j*nx] != BAD_PIX))
1926 pimg[i+j*nx] -= sinfo_median;
1928 cpl_msg_error(cpl_func,
" case is not possible! %f %f",
1941 err = cpl_error_get_code();
1960cpl_error_code eris_ifu_flat_thresh_mask(hdrl_image* hdrl_img,
1966 const double *pimg = NULL;
1967 cpl_image *img = NULL;
1968 cpl_mask *mask = NULL;
1969 cpl_binary *pmask = NULL;
1970 cpl_error_code err = CPL_ERROR_NONE;
1972 cpl_ensure_code(hdrl_img, CPL_ERROR_NULL_INPUT);
1983 pimg = cpl_image_get_data_double_const(img);
1984 pmask = cpl_mask_get_data(mask);
1986 for (
int x = ERIS_IFU_DETECTOR_BP_BORDER; x < nx-ERIS_IFU_DETECTOR_BP_BORDER; x++) {
1987 for (
int y = ERIS_IFU_DETECTOR_BP_BORDER; y < ny-ERIS_IFU_DETECTOR_BP_BORDER; y++) {
1988 if ((pmask[x+nx*y] == GOOD_PIX) &&
1989 ((pimg[x+nx*y] > hi_cut) || (pimg[x+nx*y] < lo_cut)))
1991 pmask[x+nx*y] = BAD_PIX;
1999 err = cpl_error_get_code();
2018#define PIX_SWAP(a,b) { double temp=(a); (a)=(b); (b)=temp; }
2019#define PIX_STACK_SIZE 50
2021cpl_error_code eris_ifu_flat_pixel_qsort(
double *pix_arr,
int npix)
2023 int i, ir, j, k, l, j_stack;
2024 int i_stack[PIX_STACK_SIZE *
sizeof(double)];
2027 cpl_error_code ret = CPL_ERROR_NONE;
2029 cpl_ensure_code(pix_arr, CPL_ERROR_NULL_INPUT);
2038 for (j = l + 1; j <= ir; j++) {
2040 for (i = j - 1; i >= 1; i--) {
2041 if (pix_arr[i - 1] <= a)
2043 pix_arr[i] = pix_arr[i - 1];
2049 ir = i_stack[j_stack-- - 1];
2050 l = i_stack[j_stack-- - 1];
2053 PIX_SWAP(pix_arr[k - 1], pix_arr[l])
2054 if (pix_arr[l] > pix_arr[ir - 1]) {
2055 PIX_SWAP(pix_arr[l], pix_arr[ir - 1])
2057 if (pix_arr[l - 1] > pix_arr[ir - 1]) {
2058 PIX_SWAP(pix_arr[l - 1], pix_arr[ir - 1])
2060 if (pix_arr[l] > pix_arr[l - 1]) {
2061 PIX_SWAP(pix_arr[l], pix_arr[l - 1])
2069 while (pix_arr[i - 1] < a);
2072 while (pix_arr[j - 1] > a);
2075 PIX_SWAP(pix_arr[i - 1], pix_arr[j - 1]);
2077 pix_arr[l - 1] = pix_arr[j - 1];
2080 if (j_stack > PIX_STACK_SIZE) {
2082 "stack too small : aborting");
2084 if (ir - i + 1 >= j - l) {
2085 i_stack[j_stack - 1] = ir;
2086 i_stack[j_stack - 2] = i;
2089 i_stack[j_stack - 1] = j - 1;
2090 i_stack[j_stack - 2] = l;
2100 ret = cpl_error_get_code();
2105#undef PIX_STACK_SIZE
2126void eris_ifu_my_fit(
double x[],
double y[],
int ndata,
double sig[],
int mwt,
2127 double *a,
double *b,
double *siga,
double *sigb,
double *chi2,
2140 for (
int i = 0; i < ndata; i++) {
2141 double wt = 1./pow(sig[i], 2);
2147 for (
int i = 0; i < ndata; i++) {
2156 for (
int i = 0; i < ndata; i++) {
2157 t = (x[i] - sxoss)/sig[i];
2159 *b += t*y[i]/sig[i];
2162 for (
int i = 0; i < ndata; i++) {
2170 *a = (sy - sx*(*b))/ss;
2171 *siga = sqrt ((1.0 + sx*sx/(ss*st2))/ss);
2172 *sigb = sqrt (1.0/st2);
2175 for (
int i = 0 ; i < ndata ; i++) {
2176 *chi2 += pow((y[i] - (*a) - (*b)*x[i]), 2);
2183 double sigdat = sqrt ((*chi2)/(ndata - 2));
2187 for (
int i = 0; i < ndata; i++) {
2188 *chi2 += pow(((y[i] - (*a) - (*b) * x[i])/sig[i]),2);
2211cpl_error_code eris_ifu_flat_stats_rectangle(
const hdrl_image *hdrl_img,
2221 cpl_error_code ret = CPL_ERROR_NONE;
2222 const cpl_image *img = NULL;
2229 const double *pimg = NULL;
2230 double *pix_array = NULL,
2234 cpl_ensure_code(hdrl_img, CPL_ERROR_NULL_INPUT);
2239 cpl_ensure_code(loReject+hiReject < 100., CPL_ERROR_ILLEGAL_INPUT);
2240 cpl_ensure_code(loReject >= 0., CPL_ERROR_ILLEGAL_INPUT);
2241 cpl_ensure_code(loReject < 100., CPL_ERROR_ILLEGAL_INPUT);
2242 cpl_ensure_code(hiReject >= 0., CPL_ERROR_ILLEGAL_INPUT);
2243 cpl_ensure_code(hiReject < 100., CPL_ERROR_ILLEGAL_INPUT);
2244 cpl_ensure_code((llx >= 0) && (lly >= 0), CPL_ERROR_ILLEGAL_INPUT);
2245 cpl_ensure_code((urx >= 0) && (ury >= 0), CPL_ERROR_ILLEGAL_INPUT);
2246 cpl_ensure_code((llx < nx) && (lly < ny), CPL_ERROR_ILLEGAL_INPUT);
2247 cpl_ensure_code((urx < nx) && (ury < ny), CPL_ERROR_ILLEGAL_INPUT);
2248 cpl_ensure_code((ury > lly) && (urx > llx), CPL_ERROR_ILLEGAL_INPUT);
2253 npix = (urx-llx+1) * (ury-lly+1);
2254 pix_array = (
double*)cpl_calloc(npix,
sizeof(
double));
2258 pimg = cpl_image_get_data_double_const(img);
2260 for (
int row = lly; row <= ury; row++) {
2261 for (
int col = llx; col <= urx; col++) {
2262 if (!isnan(pimg[col + row*nx])) {
2263 pix_array[n] = pimg[col + row*nx];
2272 eris_ifu_flat_clean_mean(pix_array, npix, loReject, hiReject,
2277 lo_n = (int)(loReject / 100. * (
double)npix);
2278 hi_n = (int)(hiReject / 100. * (
double)npix);
2282 for (
int i = lo_n; i <= npix - hi_n; i++) {
2283 pix_sum += (double)pix_array[i];
2284 sqr_sum += ((double)pix_array[i] * (
double)pix_array[i]);
2291 "number of clean pixels is zero!");
2294 pix_sum /= (double)n;
2295 sqr_sum /= (double)n;
2296 *cleanstdev = sqrt(sqr_sum - pix_sum*pix_sum);
2302 ret = cpl_error_get_code();
2304 *cleanmean = -DBL_MAX;
2305 *cleanstdev = -DBL_MAX;
2308 cpl_free(pix_array);
2329cpl_error_code eris_ifu_flat_clean_mean(
double *array,
2331 double throwaway_low,
2332 double throwaway_high,
2335 cpl_error_code ret = CPL_ERROR_NONE;
2341 cpl_ensure_code(array, CPL_ERROR_NULL_INPUT);
2342 cpl_ensure_code(n_elements > 0, CPL_ERROR_ILLEGAL_INPUT);
2343 cpl_ensure_code(throwaway_low > 0., CPL_ERROR_ILLEGAL_INPUT);
2344 cpl_ensure_code(throwaway_high > 0., CPL_ERROR_ILLEGAL_INPUT);
2345 cpl_ensure_code(throwaway_low + throwaway_high < 100.,
2346 CPL_ERROR_ILLEGAL_INPUT);
2350 lo_n = (int)(throwaway_low * (
double)n_elements / 100.);
2351 hi_n = (int)(throwaway_high * (
double)n_elements / 100.);
2354 eris_ifu_flat_pixel_qsort(array, n_elements);
2356 for (
int i = lo_n; i < n_elements - hi_n; i++) {
2357 if (!isnan(array[i])) {
2366 *cleanmean = sum/(double)n;
2373 ret = cpl_error_get_code();
2375 *cleanmean = -DBL_MAX;
2404hdrl_image* eris_ifu_flat_median_image(
const hdrl_image *hdrl_img_in,
2407 hdrl_image *hdrl_img_out = NULL;
2408 const cpl_image *img_in = NULL;
2409 cpl_image *img_out = NULL;
2410 const cpl_mask *mask_in = NULL;
2411 cpl_mask *mask_out = NULL;
2412 const cpl_binary *pmask_in = NULL;
2413 cpl_binary *pmask_out = NULL;
2414 int *position = NULL,
2419 double *value = NULL,
2422 const double *pimg_in = NULL;
2424 cpl_ensure(hdrl_img_in, CPL_ERROR_NULL_INPUT, NULL);
2435 pimg_in = cpl_image_get_data_double_const(img_in);
2436 pmask_in = cpl_mask_get_data_const(mask_in);
2441 pimg_out = cpl_image_get_data_double(img_out);
2442 pmask_out = cpl_mask_get_data(mask_out);
2445 for (
int i = 0; i < im_size; i++) {
2447 if (pmask_in[i] == BAD_PIX) {
2452 value = (
double*)cpl_calloc(8,
sizeof(
double*));
2453 position = (
int*)cpl_calloc(8,
sizeof(
int*));
2457 position[0] = i + nx - 1 ;
2458 position[1] = i + nx ;
2459 position[2] = i + nx + 1 ;
2460 position[3] = i + 1 ;
2461 position[4] = i - nx + 1 ;
2462 position[5] = i - nx ;
2463 position[6] = i - nx - 1 ;
2464 position[7] = i - 1 ;
2470 if ((i >= 0) && (i < nx)) {
2472 position[4] += 2*nx;
2473 position[5] += 2*nx;
2474 position[6] += 2*nx;
2475 }
else if ((i >= ((
int)nx*ny - nx)) && (i < (int) nx*ny)) {
2477 position[0] -= 2*nx;
2478 position[1] -= 2*nx;
2479 position[2] -= 2*nx;
2480 }
else if (i % nx == 0) {
2485 }
else if ((i % nx) == (nx - 1)) {
2497 for (
int j = 0; j < nposition; j++) {
2498 if((position[j] > -1) && (position[j] < im_size)) {
2499 if (pmask_in[position[j]] == GOOD_PIX) {
2500 value[n] = pimg_in[position[j]];
2509 pmask_out[i] = BAD_PIX;
2517 eris_ifu_flat_pixel_qsort(value, nposition));
2519 if (nposition % 2 == 1) {
2520 my_med = value[nposition/2];
2522 my_med = (value [nposition/2 - 1] + value [nposition/2]) / 2.;
2538 pimg_out[i] = my_med;
2539 }
else if ((fmedian < 0) && (fabs(my_med-pimg_in[i]) >= -fmedian)) {
2540 pimg_out[i] = my_med;
2541 }
else if ((fmedian > 0) &&
2542 (fabs(my_med-pimg_in[i]) >=
2543 fmedian*sqrt(fabs(my_med))))
2545 pimg_out[i] = my_med;
2564 return hdrl_img_out;
2580cpl_error_code eris_ifu_sinfo_compare_images(
const hdrl_image *hdrl_img1,
2581 const hdrl_image *hdrl_img2,
2582 hdrl_image *hdrl_img_orig)
2584 const cpl_image *img1 = NULL,
2586 const double *pimg1 = NULL;
2587 const double *pimg2 = NULL;
2588 const cpl_mask *mask_img1 = NULL,
2590 cpl_mask *mask_orig = NULL;
2591 const cpl_binary *pmask_img1 = NULL,
2593 cpl_binary *pmask_orig = NULL;
2594 cpl_error_code err = CPL_ERROR_NONE;
2600 cpl_ensure_code(hdrl_img1, CPL_ERROR_NULL_INPUT);
2601 cpl_ensure_code(hdrl_img2, CPL_ERROR_NULL_INPUT);
2602 cpl_ensure_code(hdrl_img_orig, CPL_ERROR_NULL_INPUT);
2609 cpl_ensure_code(nx1 == nx2, CPL_ERROR_ILLEGAL_INPUT);
2610 cpl_ensure_code(ny1 == ny2, CPL_ERROR_ILLEGAL_INPUT);
2616 pimg1=cpl_image_get_data_double_const(img1);
2617 pimg2=cpl_image_get_data_double_const(img2);
2622 pmask_img1 = cpl_mask_get_data_const(mask_img1);
2623 pmask_img2 = cpl_mask_get_data_const(mask_img2);
2624 pmask_orig = cpl_mask_get_data(mask_orig);
2626 for (
int i = 0; i < nx1*ny1; i++) {
2627 if ((pmask_img1[i] == BAD_PIX) ||
2628 (pmask_img2[i] == BAD_PIX) ||
2629 (pimg1[i] != pimg2[i]))
2631 pmask_orig[i] = BAD_PIX;
2638 err = cpl_error_get_code();
2653cpl_error_code eris_ifu_flat_fast_bpm(hdrl_image *master_flat,
2654 const cpl_parameterlist *parlist,
2661 cpl_error_code err = CPL_ERROR_NONE;
2662 cpl_mask *bpm = NULL;
2663 cpl_image *img = NULL;
2664 const cpl_image *data = NULL;
2665 cpl_binary *pbpm = NULL;
2667 cpl_ensure_code(master_flat, CPL_ERROR_NULL_INPUT);
2668 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
2675 pbpm = cpl_mask_get_data(bpm);
2681 urx = ERIS_IFU_DETECTOR_BP_BORDER+SLITLET_WIDTH,
2682 ury = ERIS_IFU_DETECTOR_SIZE_Y;
2685 img = cpl_image_extract(data, llx, lly, urx, ury));
2691 cpl_vector *profile_x = NULL;
2692 double left_edge_pos = 0.,
2693 right_edge_pos = 0.,
2700 for (
int i = 0; i < nr_values; i++) {
2702 center_y = ERIS_IFU_DETECTOR_BP_BORDER + i*height + height/2;
2704 img, center_y, height);
2708 pprofile_x = cpl_vector_get_data(profile_x);
2710 cpl_image *imgg=NULL;
2711 imgg = cpl_image_wrap_double(cpl_vector_get_size(profile_x),1,
2714 imgg = cpl_image_wrap_double(cpl_image_get_size_x(img), 1,
2723 if (status == CPL_ERROR_EOL) {
2726 }
else if (status != CPL_ERROR_NONE) {
2731 for (
int y = center_y-height/2; y < center_y+height/2; y++) {
2732 for (
int x = 0; x <= (int)(left_edge_pos+.5); x++) {
2733 pbpm[x+y*ERIS_IFU_DETECTOR_SIZE_X] = BAD_PIX;
2741 for (
int y = 2020; y < 2045; y++) {
2742 for (
int x = 0; x <= (int)(left_edge_pos+.5); x++) {
2743 pbpm[x+y*ERIS_IFU_DETECTOR_SIZE_X] = BAD_PIX;
2752 err = cpl_error_get_code();
2759cpl_error_code eris_ifu_flat_data_init(
struct structFlatData *self,
int blocksize) {
2760 cpl_error_code err = CPL_ERROR_NONE;
2762 cpl_ensure_code(blocksize > 0, CPL_ERROR_ILLEGAL_INPUT);
2767 self->blocksize = blocksize;
2768 int nr = ERIS_IFU_DETECTOR_SIZE_Y/blocksize;
2769 self->ry = cpl_vector_new(nr);
2770 self->borderAleft = cpl_vector_new(nr);
2771 self->borderAright = cpl_vector_new(nr);
2772 self->borderBleft = cpl_vector_new(nr);
2773 self->borderBright = cpl_vector_new(nr);
2774 self->borderCleft = cpl_vector_new(nr);
2775 self->borderCright = cpl_vector_new(nr);
2776 self->borderDleft = cpl_vector_new(nr);
2777 self->borderDright = cpl_vector_new(nr);
2782 err = cpl_error_get_code();
2788cpl_error_code eris_ifu_flat_data_setBorders(
struct structFlatData *self,
int ry,
2789 int leftEdgeA,
int rightEdgeA,
2790 int leftEdgeB,
int rightEdgeB,
2791 int leftEdgeC,
int rightEdgeC,
2792 int leftEdgeD,
int rightEdgeD)
2794 cpl_error_code err = CPL_ERROR_NONE;
2798 cpl_vector_set(self->ry, self->cnt, ry);
2799 cpl_vector_set(self->borderAleft, self->cnt, leftEdgeA);
2800 cpl_vector_set(self->borderAright, self->cnt, rightEdgeA);
2801 cpl_vector_set(self->borderBleft, self->cnt, leftEdgeB);
2802 cpl_vector_set(self->borderBright, self->cnt, rightEdgeB);
2803 cpl_vector_set(self->borderCleft, self->cnt, leftEdgeC);
2804 cpl_vector_set(self->borderCright, self->cnt, rightEdgeC);
2805 cpl_vector_set(self->borderDleft, self->cnt, leftEdgeD);
2806 cpl_vector_set(self->borderDright, self->cnt, rightEdgeD);
2812 err = cpl_error_get_code();
2818cpl_vector* eris_ifu_flat_data_getBorderInterpolated(
struct structFlatData *self,
2821 cpl_vector *borders = NULL,
2825 double *pfit_par = NULL,
2829 rowx = row + self->blocksize/2.;
2831 borders = cpl_vector_new(8);
2832 pborders = cpl_vector_get_data(borders);
2835 pfit_par = cpl_vector_get_data(fit_par);
2836 pborders[0] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
2840 pfit_par = cpl_vector_get_data(fit_par);
2841 pborders[1] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
2845 pfit_par = cpl_vector_get_data(fit_par);
2846 pborders[2] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
2850 pfit_par = cpl_vector_get_data(fit_par);
2851 pborders[3] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
2855 pfit_par = cpl_vector_get_data(fit_par);
2856 pborders[4] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
2860 pfit_par = cpl_vector_get_data(fit_par);
2861 pborders[5] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
2865 pfit_par = cpl_vector_get_data(fit_par);
2866 pborders[6] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
2870 pfit_par = cpl_vector_get_data(fit_par);
2871 pborders[7] = (int)(pfit_par[0] + pfit_par[1] * rowx + pfit_par[2] * pow(rowx, 2) + 0.5);
cpl_error_code eris_ifu_append_qc_double(cpl_propertylist *pl, const char *name, double val, const char *comment)
Append a QC parameter of type DOUBLE to a property list.
bool eris_ifu_frame_is_sky(const cpl_frame *fr)
Determine if a frame is a sky frame.
ifsBand eris_ifu_get_band(const cpl_propertylist *header)
Determine preoptic band.
cpl_error_code eris_ifu_append_qc_int(cpl_propertylist *pl, const char *name, int val, const char *comment)
Append a QC parameter of type INT to a property list.
bool eris_ifu_frame_is_on(const cpl_frame *fr)
Determine if a frame has calibration lamps ON or OFF.
#define ASSURE(condition, error,...)
error handling macro (from fors-pipeline)
#define ERIS_IFU_TRY_EXIT(void)
The try-block is exited.
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#define RECOVER(void)
Recover the error state which was present during TRY (at the beginning of the try-block).
#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_slitpos_gauss(const cpl_image *profile_x, double *left_edge_pos, double *right_edge_pos, int llx, int productDepth)
eris_ifu_dist_slitpos_gauss
cpl_vector * eris_ifu_calc_centers_collapse_chunk(const cpl_image *img, int chunk_center, int height)
cpl_vector * eris_ifu_image_collapse(const cpl_image *img)
cpl_error_code eris_ifu_calc_bpm(const cpl_parameterlist *pl, const char *recipe_name, hdrl_image *master_img, const hdrl_imagelist *imglist_on, cpl_mask **bpm2dMask, cpl_mask **bpm3dMask)
Create 2D and/or 3D bad pixel masks using HDRL algorithms.
cpl_error_code eris_ifu_add_badpix_border(cpl_image *data, cpl_boolean add_ones, cpl_image *dqi)
Flag detector border pixels as bad in image and optionally set to 1.
cpl_vector * eris_ifu_polyfit_1d(const cpl_vector *x, const cpl_vector *y, const int degree)
Fit a 1D polynomial to vector data.
hdrl_image * eris_ifu_load_exposure_file(const char *filename, int exposureCorrectionMode, cpl_image *dqi)
Load a raw detector exposure from file with corrections and noise.
void eris_ifu_free_frameset(cpl_frameset **item)
Free memory and set pointer to null.
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_double_array(double **item)
Free memory and set pointer to null.
void eris_ifu_free_vector(cpl_vector **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_save_image_dbg(const cpl_image *img, const char *filename, int create, const cpl_propertylist *pl)
Save image for debugging (quick, no DFS overhead)
cpl_mask * eris_ifu_load_badpixel_mask(const cpl_frameset *frameset, const char *category, int ext)
**
cpl_error_code eris_ifu_file_exists(const char *filename)
**
void eris_ifu_free_int_array(int **item)
Free memory and set pointer to null.
void eris_ifu_free_hdrl_imagelist(hdrl_imagelist **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_save_hdrl_imagelist_dbg(const hdrl_imagelist *hdrl_img_list, const char *filename, int singlefile)
Save HDRL imagelist for debugging (data + error + mask planes)
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_get_badpix_qc_from_mask(const cpl_mask *bp_mask, cpl_propertylist *qc_list, const char *prefix)
compute QC keyword with number of bad pixels and fraction to total
void eris_ifu_free_image(cpl_image **item)
Free memory and set pointer to null.
void eris_ifu_free_matrix(cpl_matrix **item)
Free memory and set pointer to null.
void eris_ifu_free_mask(cpl_mask **item)
Free memory and set pointer to null.
cpl_frameset * eris_ifu_get_frameset_by_tag(const cpl_frameset *frameset, const char *tag)
Get frames with given tag from frameset.
cpl_error_code eris_ifu_save_image(cpl_frameset *fs, const cpl_propertylist *plist, const cpl_parameterlist *parlist, const char *recipe, const char *procatg, const char *filename, cpl_type type, const cpl_image *image)
Save image with DFS compliance.
void eris_ifu_free_hdrl_parameter(hdrl_parameter **item)
Free memory and set pointer to null.
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
hdrl_parameter * hdrl_collapse_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
parse parameterlist for imagelist reduction method
cpl_error_code hdrl_flat_compute(hdrl_imagelist *hdrl_data, const cpl_mask *stat_mask, const hdrl_parameter *collapse_params, hdrl_parameter *flat_params, hdrl_image **master, cpl_image **contrib_map)
compute high or low frequency master flat with median filtering
hdrl_parameter * hdrl_flat_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse a parameterlist to create input parameters for the FLAT.
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
int hdrl_image_is_rejected(hdrl_image *self, cpl_size xpos, cpl_size ypos)
return if pixel is marked bad
cpl_error_code hdrl_image_set_pixel(hdrl_image *self, cpl_size xpos, cpl_size ypos, hdrl_value value)
set pixel values of hdrl_image
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
cpl_error_code hdrl_image_div_scalar(hdrl_image *self, hdrl_value value)
Elementwise division of an image with a scalar.
hdrl_value hdrl_image_get_median(const hdrl_image *self)
computes the median and associated error of an image.
hdrl_image * hdrl_image_sub_image_create(const hdrl_image *self, const hdrl_image *other)
Subtract two images.
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
hdrl_image * hdrl_image_extract(const hdrl_image *self, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury)
extract copy of window 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_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
const cpl_mask * hdrl_image_get_mask_const(const hdrl_image *himg)
get cpl bad pixel mask from image
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of 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
cpl_error_code hdrl_image_reject(hdrl_image *self, cpl_size xpos, cpl_size ypos)
mark pixel as bad
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
const hdrl_image * hdrl_imagelist_get_const(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
cpl_error_code hdrl_imagelist_collapse(const hdrl_imagelist *himlist, const hdrl_parameter *param, hdrl_image **out, cpl_image **contrib)
collapsing of image list
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
cpl_error_code hdrl_imagelist_sub_imagelist(hdrl_imagelist *himlist1, const hdrl_imagelist *himlist2)
Subtract two image lists, the first one is replaced by the result.
hdrl_imagelist * hdrl_imagelist_duplicate(const hdrl_imagelist *himlist)
Duplicate an image list.