28#include <eris_utils.h>
29#include "eris_ifu_error.h"
30#include "eris_ifu_utils.h"
31#include "eris_ifu_functions.h"
32#include "eris_ifu_dfs.h"
33#include "eris_ifu_wavecal_static.h"
34#include "eris_ifu_debug.h"
36cpl_error_code eris_ifu_wave_get_arc_images (
37 cpl_frameset *arcFrames,
38 int exposureCorrectionMode,
40 hdrl_imagelist **arcImages,
43 ifsPreopticsScale *scale,
44 ifsInstrument *instrument,
45 double saturation_threshold,
48 cpl_error_code err = CPL_ERROR_NONE;
49 hdrl_imagelist *arcImagesLocal = NULL;
50 int *lampStatesLocal = NULL;
51 hdrl_image *image = NULL;
52 cpl_table *arcFrameTable = NULL;
53 cpl_table *darkTable = NULL;
54 cpl_table *litTable = NULL;
55 const cpl_frame *frame = NULL;
57 cpl_propertylist *header = NULL;
63 ifsPreopticsScale currScale;
65 const int MaxLampStateSetSize = 16;
71 "Null frameset (ARC frames)!");
73 ASSURE(arcImages != NULL, CPL_ERROR_NULL_INPUT,
"Null arcImages!");
75 ASSURE(qclog != NULL, CPL_ERROR_NULL_INPUT,
"Null qclog!");
76 int frameCnt = (int) cpl_frameset_get_size(arcFrames);
79 "input frameset (ARC frames) is empty");
82 lampStatesLocal = cpl_calloc(MaxLampStateSetSize,
sizeof(
int));
83 *lampStates = lampStatesLocal;
84 *band = UNDEFINED_BAND;
85 *instrument = UNSET_INSTRUMENT;
89 arcFrameTable = cpl_table_new(frameCnt));
90 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAMR_IDX,
92 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAME_LAMP,
94 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAME_DIT,
96 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAME_FILE,
100 for (
int i=0 ; i<frameCnt ; i++) {
101 frame = cpl_frameset_get_position_const(arcFrames, i);
102 cpl_msg_info(
"wavecal",
"Tag is %s",cpl_frame_get_tag(frame));
104 filename = cpl_frame_get_filename(frame));
106 header = cpl_propertylist_load(filename, 0));
109 if (*band == UNDEFINED_BAND) {
113 if (*band != currBand) {
115 "different instrument band settings"
119 if (*scale == UNDEFINED_SCALE) {
123 if (*scale != currScale) {
125 "different instrument pre-optics settings"
129 if (*instrument == UNSET_INSTRUMENT) {
133 cpl_table_set_int(arcFrameTable, ERIS_IFU_ARCFRAMR_IDX, i, i);
134 cpl_table_set_int(arcFrameTable, ERIS_IFU_ARCFRAME_LAMP, i, lamps);
135 cpl_table_set_float(arcFrameTable, ERIS_IFU_ARCFRAME_DIT, i, dit);
136 cpl_table_set_string(arcFrameTable, ERIS_IFU_ARCFRAME_FILE, i, filename);
141 cpl_propertylist *refList = NULL;
143 refList = cpl_propertylist_new());
145 cpl_propertylist_append_bool(refList,ERIS_IFU_ARCFRAME_LAMP,0));
147 cpl_propertylist_append_bool(refList,ERIS_IFU_ARCFRAME_DIT,0));
149 cpl_table_sort(arcFrameTable, refList));
150 cpl_propertylist_delete(refList);
151 cpl_msg_debug(cpl_func,
"Input arc/dark frames sorted by lamps/dit");
152 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
153 cpl_table_dump(arcFrameTable, 0, frameCnt, stdout);
158 cpl_table_unselect_all(arcFrameTable));
159 cpl_size nDarks = cpl_table_or_selected_int(arcFrameTable, ERIS_IFU_ARCFRAME_LAMP,
162 darkTable = cpl_table_extract_selected(arcFrameTable));
163 nLits = cpl_table_not_selected(arcFrameTable);
165 litTable = cpl_table_extract_selected(arcFrameTable));
166 cpl_table_dump(darkTable, 0, nDarks, stdout);
167 cpl_table_dump(litTable, 0, nLits, stdout);
175 cpl_table* qc_log_tmp;
177 for (
int i=0 ; i<nLits ; i++) {
178 lLampState = cpl_table_get_int(litTable, ERIS_IFU_ARCFRAME_LAMP, i, &isNull);
179 lDit = cpl_table_get_float(litTable, ERIS_IFU_ARCFRAME_DIT, i, &isNull);
180 if (lDit != nDit || lLampState != nLampState) {
181 nLampState = lLampState;
184 cpl_msg_info(cpl_func,
"New lamp/dit state: %d (%s) %f",
185 nLampState, lampString, nDit);
188 image = eris_ifu_wave_collapse_arc_images(
189 darkTable, litTable, lLampState, lDit,
190 exposureCorrectionMode, saturation_threshold, &qc_log_tmp));
194 *lampStatesLocal = lLampState;
197 cpl_size size = cpl_table_get_nrow(*qclog);
198 cpl_table_insert(*qclog, qc_log_tmp, size);
199 cpl_table_delete(qc_log_tmp);
206 err = cpl_error_get_code();
214 *arcImages = arcImagesLocal;
218hdrl_image *eris_ifu_wave_collapse_arc_images(
219 cpl_table *darkTable,
223 int exposureCorrectionMode,
227 hdrl_image *arcImage = NULL;
228 hdrl_image *tmpImage = NULL;
229 hdrl_image *litImage = NULL;
230 hdrl_image *darkImage = NULL;
231 hdrl_imagelist *litImageList = NULL;
232 hdrl_imagelist *darkImageList = NULL;
233 cpl_image *contribMap = NULL;
237 const char *filename;
238 hdrl_value mean = {0., 0.};
239 hdrl_value median = {0., 0.};
243 cpl_image* image = NULL;
250 ASSURE((darkTable != NULL) && (litTable != NULL),
251 CPL_ERROR_NULL_INPUT,
252 "One or both input tables are NULL");
254 cpl_table_unselect_all(darkTable));
256 cpl_table_unselect_all(litTable));
257 nDarks = cpl_table_or_selected_float(darkTable, ERIS_IFU_ARCFRAME_DIT,
259 nLits = cpl_table_or_selected_float(litTable, ERIS_IFU_ARCFRAME_DIT,
261 nLits = cpl_table_and_selected_int(litTable, ERIS_IFU_ARCFRAME_LAMP,
262 CPL_EQUAL_TO, lampState);
265 CPL_ERROR_DATA_NOT_FOUND,
266 "No frames with the lamp-on pattern %d found", lampState);
271 for (
int ix=0; ix<cpl_table_get_nrow(litTable); ix++) {
272 if (cpl_table_is_selected(litTable, ix)) {
273 filename = cpl_table_get_string(litTable, ERIS_IFU_ARCFRAME_FILE, ix);
276 exposureCorrectionMode, NULL));
282 cpl_image_threshold(image, threshold, threshold, 0, 1);
283 npixsat = (int) cpl_image_get_flux(image);
285 name = cpl_sprintf(
"QC FRMON%d MEANFLUX",ix);
287 cpl_free(name); name = cpl_sprintf(
"QC FRMON%d MEDIANFLUX",ix);
289 cpl_free(name); name = cpl_sprintf(
"QC FRMON%d MAXFLUX",ix);
291 cpl_free(name); name = cpl_sprintf(
"QC FRMON%d NPIXSAT",ix);
293 cpl_free(name); name = NULL;
298 cpl_image_delete(image);
303 for (
int ix=0; ix<cpl_table_get_nrow(darkTable); ix++) {
304 if (cpl_table_is_selected(darkTable, ix)) {
305 filename = cpl_table_get_string(darkTable, ERIS_IFU_ARCFRAME_FILE, ix);
314 exposureCorrectionMode, NULL));
320 cpl_image_threshold(image, threshold, threshold, 0, 1);
321 npixsat = (int) cpl_image_get_flux(image);
323 name = cpl_sprintf(
"QC FRMOFF%d MEANFLUX",ix);
325 cpl_free(name); name = cpl_sprintf(
"QC FRMOFF%d MEDIANFLUX",ix);
327 cpl_free(name); name = cpl_sprintf(
"QC FRMOFF%d MAXFLUX",ix);
329 cpl_free(name); name = cpl_sprintf(
"QC FRMOFF%d NPIXSAT",ix);
331 cpl_free(name); name = NULL;
335 cpl_image_delete(image);
343 }
else if (nLits >= 3) {
346 litImageList, &litImage, &contribMap));
350 litImageList, &litImage, &contribMap));
360 }
else if (nDarks >= 3) {
363 darkImageList, &darkImage, &contribMap));
367 darkImageList, &darkImage, &contribMap));
376 cpl_image_threshold(image, threshold, threshold, 0, 1);
377 npixsat = (int) cpl_image_get_flux(image);
379 name = cpl_sprintf(
"QC FRMDIFF MEANFLUX");
381 cpl_free(name); name = cpl_sprintf(
"QC FRMDIFF MEDIANFLUX");
383 cpl_free(name); name = cpl_sprintf(
"QC FRMDIFF MAXFLUX");
385 cpl_free(name); name = cpl_sprintf(
"QC FRMDIFF NPIXSAT");
387 cpl_free(name); name = NULL;
388 cpl_image_delete(image);
396 cpl_table_delete(*qclog);
488cpl_image * eris_ifu_wave_get_calImg(
490 hdrl_imagelist *arcImages,
493 ifsInstrument instrument,
494 struct waveSetupStruct waveSetup,
495 const char* refLineTableFileName,
496 const char* firstFitTableFileName,
497 cpl_bivector *slitPos,
498 struct waveTablesStruct *tables,
501 const cpl_parameterlist* parlist,
505 cpl_image *waveCalImg = NULL;
506 const cpl_image **dataImg = NULL;
507 cpl_bivector **refLines = NULL;
508 hdrl_image *arcImg = NULL;
510 double *slitletStart;
512 cpl_image **collapsedSpectra = NULL;
513 cpl_vector *collapsedSpectrum = NULL;
517 cpl_polynomial *firstFit = NULL;
518 cpl_table *firstFitTable = NULL;
519 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y];
520 const hdrl_image *tmpImg;
521 enum multiArcModes {SUPERIMPOSE, SEPARATE};
522 int multiArcMode = SEPARATE;
526 for (
int ix=0; ix<ERIS_IFU_DETECTOR_SIZE_Y; ix++) {
539 if (multiArcMode == SUPERIMPOSE) {
542 arcImgCnt = arcImagesCnt;
546 dataImg = cpl_calloc(arcImgCnt,
sizeof(cpl_image *)));
548 refLines = cpl_calloc(arcImgCnt,
sizeof(cpl_bivector *)));
550 collapsedSpectra = cpl_calloc(arcImgCnt,
sizeof(cpl_image *)));
552 if (multiArcMode == SUPERIMPOSE) {
555 lampStatus = lampStates[0];
556 for (
int aix = 1; aix< arcImgCnt; aix++) {
557 lampStatus = lampStatus | lampStates[aix];
563 lampStates[0] = lampStatus;
569 for (
int ix = 0; ix < arcImgCnt; ix++) {
577 char* pipe_id = cpl_sprintf(
"%s%s%s", PACKAGE,
"/", PACKAGE_VERSION);
578 cpl_propertylist *applist = cpl_propertylist_new();
580 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG,
581 ERIS_IFU_PRO_WAVE_LAMP_STACKED);
582 cpl_dfs_save_propertylist(fs, NULL, parlist, fs, NULL,
583 "eris_ifu_wavecal", applist, NULL,
584 pipe_id, ERIS_IFU_PRO_WAVE_LAMP_STACKED_FN);
589 for (
int ix = 0; ix < arcImgCnt; ix++) {
591 refLines[ix] = eris_ifu_wave_get_refLines(
592 refLineTableFileName, instrument, lampStates[ix]));
595 ERIS_IFU_PRO_WAVE_LAMP_STACKED_FN,
596 CPL_IO_EXTEND, NULL);
598 cpl_propertylist_delete(applist);
600 nRows = cpl_image_get_size_y(dataImg[0]);
601 if (slitPos == NULL) {
603 slitletStart = cpl_calloc(SLITLET_CNT,
sizeof(
double)));
605 slitletEnd = cpl_calloc(SLITLET_CNT,
sizeof(
double)));
606 for (
int mx = 0; mx <SLITLET_CNT; mx++){
607 double tmp = (double) (SLITLET_WIDTH * mx);
608 slitletStart[mx] = tmp;
609 slitletEnd[mx] = tmp + SLITLET_WIDTH -1;
613 slitletStart = cpl_bivector_get_x_data(slitPos));
615 slitletEnd = cpl_bivector_get_y_data(slitPos));
618 for (
int aIdx = 0; aIdx < arcImgCnt; aIdx++) {
619 for (
int sIdx = 0; sIdx < SLITLET_CNT; sIdx++) {
622 (slitletEnd[sIdx] - slitletStart[sIdx]) / 2.);
623 collapsedSpectrum = eris_ifu_wave_collapse_slitlet(
624 dataImg[aIdx], center);
625 eris_ifu_wave_save_spectrum(collapsedSpectra, aIdx,
626 collapsedSpectrum, sIdx, nRows,
627 lampStates[aIdx], band, instrument,
628 refLines[aIdx], productDepth);
634 firstFitTable = eris_ifu_wave_get_firstFitTable(
635 firstFitTableFileName, instrument, band));
636 cpl_msg_debug(cpl_func,
"First fit table:");
637 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
638 cpl_table_dump(firstFitTable, 0,
639 cpl_table_get_nrow(firstFitTable), stdout);
643 int firstFitMasterOffset;
645 firstFit = eris_ifu_get_first_fit(collapsedSpectra,
646 lampStates, arcImgCnt, 16, 0, &firstFitMasterOffset,
647 waveSetup, firstFitTable,
648 tables->slitletFitting, tables->slitletCoeff));
649 cpl_msg_info(__func__,
"FirstFit Master Offset %d", firstFitMasterOffset);
651 for (
int sIdx = 0; sIdx < SLITLET_CNT; sIdx++) {
652 cpl_polynomial_delete(firstFit);
654 firstFit = eris_ifu_get_first_fit(collapsedSpectra,
655 lampStates, arcImgCnt, sIdx, firstFitMasterOffset, &firstFitOffset,
656 waveSetup, firstFitTable,
657 tables->slitletFitting, tables->slitletCoeff));
659 eris_ifu_fit_all_lines(REC_NAME_WAVECAL, sIdx, slitletStart, slitletEnd,
660 arcImgCnt, dataImg, refLines,
661 waveSetup, firstFit, allFits,
662 tables->columnFitting, tables->columnCoeffRaw,
663 tables->columnCoeffSmoothed, tables->smoothingCoeff);
666 cpl_free(slitletEnd);
667 cpl_free(slitletStart);
672 waveCalImg = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
673 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_DOUBLE));
674 cpl_image* waveCalErr = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
675 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_DOUBLE);
678 for (
int col=0; col<ERIS_IFU_DETECTOR_SIZE_X; col++) {
679 for (
int row=0; row<ERIS_IFU_DETECTOR_SIZE_Y; row++) {
680 wave = cpl_polynomial_eval_1d(allFits[col], row, &errs);
682 cpl_image_set(waveCalImg, col+1, row+1, wave));
683 cpl_image_set(waveCalErr, col+1, row+1, errs);
687 cpl_image* img = cpl_image_extract(waveCalImg,1,1024,2048,1024);
689 cpl_image* err = cpl_image_extract(waveCalErr,1,1024,2048,1024);
691 double wcen = cpl_image_get_mean(img);
692 double werr = fabs(cpl_image_get_mean(err));
693 cpl_msg_warning(cpl_func,
"Central wave: %g, %g", wcen, werr);
694 cpl_image_delete(img);
695 cpl_image_delete(err);
696 char* key_name = NULL;
697 char* key_help = NULL;
698 key_name = cpl_sprintf(
"QC WCEN VALUE");
699 key_help = cpl_sprintf(
"[um] Central wavelength value");
705 key_name = cpl_sprintf(
"QC WCEN ERR");
706 key_help = cpl_sprintf(
"[um] Error on central wavelength value");
713 cpl_image_delete(waveCalErr);
715 eris_ifu_save_resampled_arc_images(
720 lampStates, fs, parlist);
724 eris_ifu_wave_pos_err(allFits, tables->columnFitting, band));
733 for (
int ix=0; ix<ERIS_IFU_DETECTOR_SIZE_Y; ix++) {
736 if (dataImg != NULL) {
739 if (refLines != NULL) {
740 for (
int ix=0; ix < arcImgCnt; ix++) {
745 if (collapsedSpectra != NULL) {
746 for (
int ix=0; ix < arcImgCnt; ix++) {
749 cpl_free(collapsedSpectra);
757cpl_bivector *eris_ifu_wave_get_refLines(
758 const char * refLineTableFileName,
759 ifsInstrument instrument,
762 cpl_bivector *refLines = NULL;
763 cpl_propertylist *header = NULL;
765 const char *instrumentHdr;
767 const char *instrString;
768 char lampString[9] =
"";
769 cpl_vector *wavelength = NULL;
770 cpl_vector *intensity = NULL;
771 cpl_table *refLineTable = NULL;
777 cpl_ensure(refLineTableFileName, CPL_ERROR_NULL_INPUT, NULL);
778 if (access(refLineTableFileName, F_OK)) {
779 cpl_msg_error(cpl_func,
"File %s was not found",
780 refLineTableFileName);
781 cpl_error_set(cpl_func, CPL_ERROR_FILE_NOT_FOUND);
782 cpl_ensure(CPL_FALSE, CPL_ERROR_FILE_NOT_FOUND, NULL);
788 instrString = ERIS_IFU_REFTABLE_SPIFFIER_VAL;
791 instrString = ERIS_IFU_REFTABLE_SPIFFI_VAL;
797 if ((lampState & AR_LAMP) != 0) {
798 strcat(lampString, ERIS_IFU_REFTABLE_ARGON_VAL);
800 if ((lampState & NE_LAMP) != 0) {
801 strcat(lampString, ERIS_IFU_REFTABLE_NEON_VAL);
803 if ((lampState & KR_LAMP) != 0) {
804 strcat(lampString, ERIS_IFU_REFTABLE_KRYPTON_VAL);
806 if ((lampState & XE_LAMP) != 0) {
807 strcat(lampString, ERIS_IFU_REFTABLE_XEON_VAL);
809 exCnt = cpl_fits_count_extensions(refLineTableFileName);
811 for (
int ex=1; ex<exCnt+1; ex++) {
813 header = cpl_propertylist_load(refLineTableFileName, ex));
815 instrumentHdr = cpl_propertylist_get_string(
816 header, ERIS_IFU_REFTABLE_INSTR_HDR));
818 lampHdr = cpl_propertylist_get_string(
819 header, ERIS_IFU_REFTABLE_LAMPS_HDR));
820 if ((strcmp(instrumentHdr, instrString) == 0) &&
821 (strcmp(lampHdr, lampString) == 0)) {
824 refLineTable = cpl_table_load(refLineTableFileName, ex, 0));
825 nRows = cpl_table_get_nrow(refLineTable);
827 wavelength = cpl_vector_new(nRows));
829 intensity = cpl_vector_new(nRows));
830 for (
int rx=0; rx<nRows; rx++) {
831 ignored = cpl_table_get_int(
832 refLineTable, ERIS_IFU_REFTABLE_IGNORED_COLUMN,
835 tmp = cpl_table_get_double(
836 refLineTable, ERIS_IFU_REFTABLE_LAMBDA_COLUMN, rx,
843 cpl_vector_set(wavelength, vx, tmp));
845 tmp = cpl_table_get_double(
846 refLineTable, ERIS_IFU_REFTABLE_INTENSITY_COLUMN,
850 cpl_vector_set(intensity, vx, tmp));
860 if (wavelength == NULL) {
862 "There is no extension in reference lines file %s "
863 "for instrument %s and lamps %s",
864 refLineTableFileName, instrString, lampString);
869 refLines = cpl_bivector_wrap_vectors(
870 cpl_vector_extract(wavelength, 0, vx-1, 1),
871 cpl_vector_extract(intensity, 0, vx-1, 1)));
886cpl_vector * eris_ifu_wave_collapse_slitlet(
const cpl_image *dataImg,
889 cpl_vector *spec = NULL;
891 cpl_vector *slitletRow = NULL;
892 double *slitletRowData = NULL;
898 const int halfWidth = 10;
900 startCol = center - halfWidth;
901 endCol = center + halfWidth;
904 nRows = cpl_image_get_size_y(dataImg);
906 spec = cpl_vector_new(nRows));
909 slitletRow = cpl_vector_new(halfWidth * 2 + 1));
911 slitletRowData = cpl_vector_get_data(slitletRow));
913 for (
int row=0; row<nRows; row++) {
914 for (
int col=startCol; col<endCol+1; col++) {
915 tmpData = cpl_image_get(dataImg, col+1, row+1, &isValid);
920 slitletRowData[col-startCol] = tmpData;
922 tmpData = cpl_vector_get_median(slitletRow);
924 cpl_vector_set(spec, row, tmpData));
935cpl_polynomial * eris_ifu_get_first_fit(
942 struct waveSetupStruct waveSetup,
943 cpl_table *firstFitTable,
944 cpl_table *fittingDumpTable,
945 cpl_table *coeffDumpTable)
947 cpl_polynomial *fit = NULL;
948 cpl_table *blockTable = NULL;
949 cpl_table *tmpTable = NULL;
951 cpl_vector *spectrum = NULL;
955 const int fitLength = 40;
956 double xData[fitLength];
957 double yData[fitLength];
959 struct gaussParStruct gaussPar;
961 double ffOffsets = 0.;
964 const int slitlet2collapsed[SLITLET_CNT] = {
965 0, 15, 1, 16, 2, 17, 3, 18, 4, 19, 5, 20, 6, 21, 7,
967 22, 8, 23, 9, 24, 10, 25, 11, 26, 12, 27, 13, 28, 14, 29};
972 cpl_table_unselect_all(firstFitTable));
974 rowCnt = cpl_table_or_selected_int(firstFitTable,
975 ERIS_IFU_FIRSTFIT_BLOCK, CPL_EQUAL_TO, slitlet_block[slitlet]);
979 "no records found in firstFits table with block %d",
980 slitlet_block[slitlet]);
982 blockTable = cpl_table_extract_selected(firstFitTable);
986 for (
int aIdx = 0; aIdx < spectrumCnt; aIdx++) {
989 cpl_table_unselect_all(blockTable));
991 rowCnt = cpl_table_or_selected_string(blockTable,
992 ERIS_IFU_FIRSTFIT_LAMPS, CPL_EQUAL_TO, lampString);
993 cpl_free(lampString);
994 tmpTable = cpl_table_extract_selected(blockTable);
995 dumpRow = cpl_table_get_nrow(fittingDumpTable);
996 cpl_table_set_size(fittingDumpTable, dumpRow+rowCnt);
1002 spectrum = cpl_vector_new_from_image_column(
1003 spectra[aIdx], slitlet2collapsed[slitlet]+1));
1005 for (
int rx = 0; rx < rowCnt; rx++) {
1006 position = cpl_table_get_int(tmpTable,
1007 ERIS_IFU_FIRSTFIT_POSITION, rx, &isValid);
1008 wavelength = cpl_table_get_double(tmpTable,
1009 ERIS_IFU_FIRSTFIT_WAVELENGTH, rx, &isValid);
1011 if (CPL_ERROR_NONE == eris_ifu_line_gauss_fit(
1012 spectrum, position+ffOffsetIn, waveSetup.s_range, &gaussPar)) {
1013 if ((gaussPar.x0 != 0.) &&
1014 (gaussPar.sigma < 3. || gaussPar.peak > 8000.)){
1015 if (fx < fitLength) {
1016 if (wavelength > 100.) {
1017 wavelength /= 1000.;
1019 xData[fx] = wavelength;
1020 yData[fx] = gaussPar.x0;
1023 ffOffsets += gaussPar.x0 - position;
1026 int range = waveSetup.s_range;
1027 int start = position-(range/2);
1028 if (range <= GAUSS_PAR_RANGE_MAX) {
1029 gaussPar.range = range;
1030 for (
int ix=0; ix<range; ix++) {
1031 gaussPar.xdata[ix] = start+ix;
1032 gaussPar.ydata[ix] = cpl_vector_get(spectrum,start+ix);
1036 const char *lamp = cpl_table_get_string(tmpTable,
1037 ERIS_IFU_FIRSTFIT_LAMPS, rx);
1038 cpl_msg_warning(__func__,
1039 "First line fit failed for "
1040 "slitlet %d at row %d wavelength %.3f for lamp %s",
1041 slitlet, position, wavelength, lamp);
1045 eris_ifu_wave_fill_fitting_table(fittingDumpTable,
1047 slitlet, slitlet_block[slitlet], aIdx,
1048 position, wavelength,
1054 *ffOffsetOut = (int) (ffOffsets/ffOffsetCnt + .5);
1057 fit = eris_ifu_1d_polynomial_fit(fx, xData, yData,
1059 eris_ifu_wave_fill_coeff_table(coeffDumpTable, slitlet, slitlet, fx,
1071 cpl_table_unselect_all(firstFitTable));
1075cpl_error_code eris_ifu_fit_all_lines(
1076 const char *recipe_name,
1078 const double *slitletStart,
1079 const double *slitletEnd,
1081 const cpl_image **dataImg,
1082 cpl_bivector **refLines,
1083 struct waveSetupStruct waveSetup,
1084 cpl_polynomial *firstFit,
1085 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y],
1086 cpl_table *dumpTable,
1087 cpl_table *columnCoeffRawTable,
1088 cpl_table *columnCoeffSmoothedTable,
1089 cpl_table *smoothingCoeffTable)
1091 cpl_error_code err = CPL_ERROR_NONE;
1093 double s1, s2, e1, e2;
1094 cpl_vector *spectrum = NULL;
1095 double *refLinelambda;
1099 cpl_error_code fitErr;
1100 struct gaussParStruct gaussPar;
1101 cpl_size dumpRow = 0;
1102 const int fitLength = 2048;
1103 double xData[fitLength];
1104 double yData[fitLength];
1107 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
1111 if (strcmp(recipe_name, REC_NAME_DISTORTION) == 0) {
1112 start = (int) slitletStart[sIdx];
1113 end = (int) slitletEnd[sIdx];
1115 s2 = slitletStart[sIdx];
1119 s1 = slitletEnd[sIdx-1];
1121 e1 = slitletEnd[sIdx];
1122 if (sIdx == SLITLET_CNT-1) {
1125 e2 = slitletStart[sIdx+1];
1132 start = (int) (((s1 + s2) / 2.0) + .5) + 1;
1134 if (sIdx == SLITLET_CNT-1) {
1137 end = (int) (((e1 + e2) / 2.0) + .5);
1139 cpl_msg_debug(cpl_func,
1140 "Slitlet %2d: start: %4d end: %4d (%7.2f - %7.2f ... %7.2f - %7.2f)",
1141 sIdx, start, end, s1, s2, e1, e2);
1144 for (
int cx = start; cx <= end; cx++) {
1146 for (
int ax = 0; ax< arcImgCnt; ax++) {
1147 nRefLines = cpl_bivector_get_size(refLines[ax]);
1148 refLinelambda = cpl_bivector_get_x_data(refLines[ax]);
1150 dumpRow = cpl_table_get_nrow(dumpTable);
1151 cpl_table_set_size(dumpTable, dumpRow + nRefLines);
1154 spectrum = cpl_vector_new_from_image_column(dataImg[ax], cx+1));
1155 nSpectrum = cpl_vector_get_size(spectrum);
1156 for (
int rx=0; rx<nRefLines; rx++) {
1157 firstGuessPos = (int) (0.5 +
1158 cpl_polynomial_eval_1d(firstFit, refLinelambda[rx], NULL));
1159 if (firstGuessPos > 4+waveSetup.c_range/2 &&
1160 firstGuessPos < (nSpectrum - 4 - waveSetup.c_range/2)) {
1161 fitErr = eris_ifu_line_gauss_fit(
1162 spectrum, firstGuessPos, waveSetup.c_range, &gaussPar);
1163 if ((fitErr == CPL_ERROR_NONE) &&
1164 (gaussPar.offset > -10. - gaussPar.peak / 300. ) &&
1165 (gaussPar.sigma < waveSetup.sigma) &&
1166 (fabs(gaussPar.x0 - firstGuessPos) < 5.01)) {
1167 yData[fx] = refLinelambda[rx];
1168 xData[fx] = gaussPar.x0;
1171 if (fitErr == CPL_ERROR_NONE) {
1172 gaussPar.errorCode = -2;
1177 gaussPar.errorCode = -1;
1179 gaussPar.sigma = 0.;
1181 gaussPar.offset = 0.;
1186 if (gaussPar.errorCode != -1) {
1188 eris_ifu_wave_fill_fitting_table(dumpTable, (
int) dumpRow,
1189 sIdx, cx, ax, firstGuessPos, refLinelambda[rx],
1195 cpl_table_set_size(dumpTable, dumpRow);
1197 if (fx > COLUMN_FIT_DEGREE+1) {
1200 allFits[cx] = eris_ifu_1d_polynomial_fit(fx, xData, yData,
1201 COLUMN_FIT_DEGREE));
1203 cpl_msg_warning(cpl_func,
1204 "Number of found lines (=%d) too small for column %d",
1207 allFits[cx] = cpl_polynomial_new(1);
1208 cpl_size tmpPower = 0;
1209 cpl_polynomial_set_coeff(allFits[cx], &tmpPower, 0.0);
1211 eris_ifu_wave_fill_coeff_table(columnCoeffRawTable, cx, cx,
1218 eris_ifu_wave_smooth_coeffs(sIdx, start, end,
1219 COLUMN_FIT_DEGREE, allFits,
1220 columnCoeffSmoothedTable, smoothingCoeffTable));
1229cpl_error_code eris_ifu_wave_smooth_coeffs(
1234 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y],
1235 cpl_table *columnCoeffSmoothedTable,
1236 cpl_table *smoothingCoeffTable)
1238 cpl_error_code retVal = CPL_ERROR_NONE;
1240 const int fitLength = 2048;
1241 double cData[fitLength];
1242 double xData[fitLength];
1243 double yData[fitLength];
1244 cpl_polynomial *smoothFit = NULL;
1245 cpl_size firstCoeff = 0;
1250 for (
int cx = start; cx <= end; cx++) {
1251 if (cpl_polynomial_get_coeff(allFits[cx], &firstCoeff) != 0.) {
1252 cData[nc] = cx + .1;
1253 yData[nc] = cpl_polynomial_eval_1d( allFits[cx], 1024., NULL);
1258 cpl_vector *xVec = cpl_vector_wrap(nc, cData);
1259 cpl_vector *yVec = cpl_vector_wrap(nc, yData);
1260 cpl_bivector *biVec = cpl_bivector_wrap_vectors(xVec, yVec);
1261 cpl_bivector_sort(biVec, biVec, CPL_SORT_ASCENDING, CPL_SORT_BY_Y);
1262 cpl_bivector_unwrap_vectors(biVec);
1263 cpl_vector_unwrap(xVec);
1264 cpl_vector_unwrap(yVec);
1266 for (cpl_size power = 0; power <= fitDegree; power++) {
1267 for (
int ix = 0; ix < nc; ix++) {
1268 int cx = (int) cData[ix];
1270 yData[ix] = cpl_polynomial_get_coeff(allFits[cx], &power);
1273 smoothFit = eris_ifu_1d_polynomial_fit(nc - 4, &xData[2], &yData[2],
1275 eris_ifu_wave_fill_coeff_table(smoothingCoeffTable,
1276 (COLUMN_FIT_DEGREE + 1) * sIdx + (
int) power,
1277 sIdx, (
int) power, smoothFit);
1278 for (
int cx = start; cx <= end; cx++) {
1279 cpl_polynomial_set_coeff(allFits[cx], &power,
1280 cpl_polynomial_eval_1d(smoothFit, (
double) cx, NULL));
1285 for (
int cx = start; cx <= end; cx++) {
1286 eris_ifu_wave_fill_coeff_table(columnCoeffSmoothedTable, cx, cx, 0,
1296cpl_error_code eris_ifu_wave_pos_err(
1297 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y],
1298 cpl_table *fitTable,
1301 cpl_error_code retVal = CPL_ERROR_NONE;
1309 for (cpl_size row=0; row<cpl_table_get_nrow(fitTable); row++) {
1310 if (cpl_table_get_int(fitTable, ERIS_IFU_FITTABLE_ERRORCODE, row, NULL) != 0) {
1313 col = cpl_table_get_int(fitTable,
"index", row, NULL);
1314 val = cpl_table_get_double(fitTable,
"x0", row, NULL);
1315 wave = cpl_polynomial_eval_1d(allFits[col], val, NULL);
1316 waveError = cpl_table_get_double(fitTable, ERIS_IFU_FITTABLE_WAVELENGTH, row, NULL)-
1318 cpl_table_set_double(fitTable,
"wavelengthFit", row, wave);
1319 cpl_table_set_double(fitTable,
"wavelengthError", row, waveError);
1323 eris_ifu_get_dispersion(band, &dispersion);
1324 double convFactor = 2. * sqrt(2. * log(2.));
1325 cpl_table_duplicate_column(fitTable,
"resol",fitTable,
"wavelengthFit");
1326 cpl_table_divide_columns(fitTable,
"resol",
"sigma");
1327 cpl_table_divide_scalar(fitTable,
"resol", dispersion);
1328 cpl_table_divide_scalar(fitTable,
"resol", convFactor);
1337void eris_ifu_wave_save_spectrum(
1338 cpl_image **collapsedSpectra,
1340 cpl_vector *collapsedSpectrum,
1345 ifsInstrument instrument,
1346 cpl_bivector *refLines,
1349 const double *collapsedSpectrumData = NULL;
1350 static int slitletBlockIdx[SLITLET_BLOCK_CNT];
1364 if((productDepth & 1)) {
1365 cpl_image_save(NULL, ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1366 CPL_TYPE_DOUBLE,NULL,CPL_IO_CREATE);
1370 for (
int i=0; i<SLITLET_BLOCK_CNT; i++) {
1371 slitletBlockIdx[i] = 0;
1374 collapsedSpectra[aIdx] = cpl_image_new(SLITLET_CNT, nRows,
1377 collapsedSpectrumData =
1378 cpl_vector_get_data_const(collapsedSpectrum);
1379 switch (slitlet_block[sIdx]) {
1381 columnIdx = slitletBlockIdx[0];
1384 columnIdx = slitletBlockIdx[1] +
1388 columnIdx = slitletBlockIdx[2] +
1389 SLITLET_BLOCK0_CNT + SLITLET_BLOCK1_CNT;
1392 columnIdx = slitletBlockIdx[3] +
1393 SLITLET_BLOCK0_CNT + SLITLET_BLOCK1_CNT +SLITLET_BLOCK2_CNT;
1399 slitletBlockIdx[slitlet_block[sIdx]]++;
1400 for (
int row=0; row<nRows; row++) {
1402 cpl_image_set(collapsedSpectra[aIdx], columnIdx+1, row+1,
1403 collapsedSpectrumData[row]));
1405 if ((sIdx >= SLITLET_CNT-1) && ((productDepth & 1) != 0)) {
1406 const char *instrumentString;
1408 if (instrument == SPIFFI) {
1409 instrumentString =
"SINFONI";
1411 instrumentString =
"ERIS";
1413 cpl_propertylist *hdr = cpl_propertylist_new();
1415 cpl_propertylist_update_string(hdr, CPL_DFS_PRO_CATG,
1416 ERIS_IFU_PRO_WAVE_COLLAP_SPECTR ));
1417 cpl_propertylist_append_string(hdr,
"INSTRUME", instrumentString);
1419 cpl_propertylist_append_string(hdr,
"LAMPS", lampString);
1420 cpl_propertylist_append_string(hdr,
"BAND",
1422 cpl_image_save(collapsedSpectra[aIdx], ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1423 CPL_TYPE_UNSPECIFIED, hdr, CPL_IO_EXTEND);
1425 cpl_free(lampString);
1426 cpl_vector_save(cpl_bivector_get_x(refLines), ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1427 CPL_TYPE_DOUBLE, NULL, CPL_IO_EXTEND);
1428 cpl_vector_save(cpl_bivector_get_y(refLines), ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1429 CPL_TYPE_DOUBLE, NULL, CPL_IO_EXTEND);
1439cpl_table *eris_ifu_wave_get_firstFitTable(
1440 const char* firstFitTableFileName,
1441 ifsInstrument instrument,
1445 cpl_table *firstFitTable = NULL;
1446 cpl_table *fullTable = NULL;
1448 const char *instrumentString;
1449 const char* bandString;
1453 if (instrument == SPIFFI) {
1454 instrumentString =
"SINFONI";
1456 instrumentString =
"ERIS";
1461 fullTable = cpl_table_load(firstFitTableFileName, 1, 0));
1463 rowCnt = cpl_table_and_selected_string(fullTable,
1464 ERIS_IFU_FIRSTFIT_INSTRUMENT, CPL_EQUAL_TO, instrumentString);
1468 "no records found in firstFits table with instrument %s",
1472 char *regExp = cpl_sprintf(
"^%s$", bandString);
1473 rowCnt = cpl_table_and_selected_string(fullTable,
1474 ERIS_IFU_FIRSTFIT_BAND, CPL_EQUAL_TO, regExp);
1479 "no records found in firstFits table with band %s",
1482 firstFitTable = cpl_table_extract_selected(fullTable);
1489 return firstFitTable;
1493eris_ifu_get_dispersion(ifsBand band,
double* dispersion)
1498 *dispersion = DISPERSION_J_SPIFFI;
1501 *dispersion = DISPERSION_H_SPIFFI;
1504 *dispersion = DISPERSION_K_SPIFFI;
1507 *dispersion = DISPERSION_HK_SPIFFI;
1510 *dispersion = DISPERSION_J_LOW;
1513 *dispersion = DISPERSION_J_SHORT;
1516 *dispersion = DISPERSION_J_MIDDLE;
1519 *dispersion = DISPERSION_J_LONG;
1522 *dispersion = DISPERSION_H_LOW;
1525 *dispersion = DISPERSION_H_SHORT;
1528 *dispersion = DISPERSION_H_MIDDLE;
1531 *dispersion = DISPERSION_H_LONG;
1534 *dispersion = DISPERSION_K_LOW;
1537 *dispersion = DISPERSION_K_SHORT;
1540 *dispersion = DISPERSION_K_MIDDLE;
1543 *dispersion = DISPERSION_K_LONG;
1550 return cpl_error_get_code();
1554eris_ifu_get_central_lambda(ifsBand band,
double* centralLambda)
1559 *centralLambda = CENTRALLAMBDA_J_SPIFFI;
1562 *centralLambda = CENTRALLAMBDA_H_SPIFFI;
1565 *centralLambda = CENTRALLAMBDA_K_SPIFFI;
1568 *centralLambda = CENTRALLAMBDA_HK_SPIFFI;
1571 *centralLambda = CENTRALLAMBDA_J_LOW;
1574 *centralLambda = CENTRALLAMBDA_J_SHORT;
1577 *centralLambda = CENTRALLAMBDA_J_MIDDLE;
1580 *centralLambda = CENTRALLAMBDA_J_LONG;
1583 *centralLambda = CENTRALLAMBDA_H_LOW;
1586 *centralLambda = CENTRALLAMBDA_H_SHORT;
1589 *centralLambda = CENTRALLAMBDA_H_MIDDLE;
1592 *centralLambda = CENTRALLAMBDA_H_LONG;
1595 *centralLambda = CENTRALLAMBDA_K_LOW;
1598 *centralLambda = CENTRALLAMBDA_K_SHORT;
1601 *centralLambda = CENTRALLAMBDA_K_MIDDLE;
1604 *centralLambda = CENTRALLAMBDA_K_LONG;
1611 return cpl_error_get_code();
1615cpl_image *eris_ifu_wave_resampled_arc_image(
1616 const cpl_image *arcImg,
1617 const cpl_image *waveCalImg,
1621 cpl_propertylist *plist,
1624 cpl_image *resampledImage = NULL;
1625 cpl_vector *arcImgCol = NULL;
1626 cpl_vector *calImgCol = NULL;
1627 double dispersion =0;
1628 double centralLambda = 0;
1629 double *lambdaIn = NULL;
1630 double *lambdaOut = NULL;
1631 double *aduIn = NULL;
1632 double *aduOut = NULL;
1635 char *propName = NULL;
1640 CPL_ERROR_NULL_INPUT,
"no arc image provided");
1641 ASSURE(waveCalImg != NULL,
1642 CPL_ERROR_NULL_INPUT,
"no wavelength calibration image provided");
1643 origNx = cpl_image_get_size_x(arcImg);
1644 origNy = cpl_image_get_size_y(arcImg);
1645 ASSURE(cpl_image_get_size_x(waveCalImg) == origNx,
1646 CPL_ERROR_INCOMPATIBLE_INPUT,
1647 "arc and wavecal image have different size");
1648 ASSURE(cpl_image_get_size_y(waveCalImg) == origNy,
1649 CPL_ERROR_INCOMPATIBLE_INPUT,
1650 "arc and wavecal image have different size");
1652 eris_ifu_get_dispersion(band, &dispersion);
1653 eris_ifu_get_central_lambda(band, ¢ralLambda);
1655 cpl_size nRows = (cpl_size) ((maxLambda - minLambda) / dispersion + .5);
1656 cpl_size centerRow = nRows / 2;
1657 double startLambda = centralLambda - dispersion * (double) centerRow;
1660 resampledImage = cpl_image_new(origNx, nRows, CPL_TYPE_FLOAT));
1662 lambdaIn = cpl_malloc(
sizeof(
double) * origNy));
1664 aduIn = cpl_malloc(
sizeof(
double) * origNy));
1666 lambdaOut = cpl_malloc(
sizeof(
double) * nRows));
1668 aduOut = cpl_malloc(
sizeof(
double) * nRows));
1671 for (
int rx=0; rx<nRows; rx++) {
1672 lambdaOut[rx] = startLambda + dispersion * (double) rx;
1675 cpl_errorstate errorState;
1676 bool errorHappend =
false;
1678 for (
int cx=0; cx<origNx; cx++) {
1680 arcImgCol = cpl_vector_new_from_image_column(arcImg, cx+1);
1681 calImgCol = cpl_vector_new_from_image_column(waveCalImg, cx+1);
1682 double *arcImgColData = cpl_vector_get_data(arcImgCol);
1683 double *calImgColData = cpl_vector_get_data(calImgCol);
1684 for (
int rx=0; rx<origNy; rx++) {
1685 lambdaIn[rx] = calImgColData[origNy-rx-1];
1686 aduIn[rx] = arcImgColData[origNy-rx-1];
1695 errorState = cpl_errorstate_get();
1697 lambdaOut, aduOut, (
int) nRows, nDegree)
1698 != CPL_ERROR_NONE) {
1699 errorHappend =
true;
1700 cpl_errorstate_set(errorState);
1702 for (
int rx = 0; rx < nRows; rx++) {
1703 cpl_image_set(resampledImage, cx + 1, rx + 1, aduOut[rx]);
1709 cpl_msg_error(__func__,
1710 "One or more columns of the arc images could not be resampled");
1713 propName = cpl_sprintf(
"CTYPE%d", axisNumber);
1714 cpl_propertylist_update_string(plist, propName,
"WAVE");
1716 propName = cpl_sprintf(
"CUNIT%d", axisNumber);
1717 cpl_propertylist_update_string(plist, propName,
"um");
1719 propName = cpl_sprintf(
"CRPIX%d", axisNumber);
1720 cpl_propertylist_update_double(plist, propName, 1.);
1722 propName = cpl_sprintf(
"CRVAL%d", axisNumber);
1723 cpl_propertylist_update_double(plist, propName, lambdaOut[0]);
1725 propName = cpl_sprintf(
"CDELT%d", axisNumber);
1726 cpl_propertylist_update_double(plist, propName, dispersion);
1728 for (
int ix=1; ix<=axisNumber; ix++) {
1729 propName = cpl_sprintf(
"CD%d_%d", axisNumber, ix);
1730 if (ix == axisNumber) {
1731 cpl_propertylist_update_double(plist, propName, dispersion);
1733 cpl_propertylist_update_double(plist, propName, 0.);
1744 resampledImage = NULL;
1750 return resampledImage;
1752cpl_error_code eris_ifu_save_resampled_arc_images(
1754 const cpl_image **dataImg,
1755 const cpl_image *waveCalImg,
1758 cpl_frameset* frameset,
1759 const cpl_parameterlist* parlist) {
1761 cpl_error_code retVal = CPL_ERROR_NONE;
1762 cpl_propertylist *plist = NULL;
1763 cpl_image *resampledImg = NULL;
1764 cpl_image *tmpImg = NULL;
1765 double minLambda = 0.;
1766 double maxLambda = 0.;
1771 plist = cpl_propertylist_new());
1773 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG,
1774 ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED));
1783 tmpImg = cpl_image_new(1, 1, CPL_TYPE_INT));
1785 char* pipe_id = cpl_sprintf(
"%s%s%s", PACKAGE,
"/", PACKAGE_VERSION);
1786 cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, tmpImg,
1787 CPL_TYPE_UNSPECIFIED, REC_NAME_WAVECAL, plist,
"RADECSYS",
1788 pipe_id, ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED_FN);
1790 maxLambda = cpl_image_get_max(waveCalImg);
1791 minLambda = cpl_image_get_min(waveCalImg);
1793 for (
int ix = 0; ix < arcImgCnt; ix++) {
1798 eris_ifu_wave_resampled_arc_image(dataImg[ix],
1799 waveCalImg, band, minLambda, maxLambda, plist, 2));
1801 cpl_propertylist_update_string(plist,
"CTYPE1",
"PIXEL");
1802 cpl_propertylist_update_string(plist,
"CUNIT1",
"PIXEL");
1803 cpl_propertylist_update_double(plist,
"CRPIX1", 1.);
1804 cpl_propertylist_update_double(plist,
"CRVAL1", 1.);
1805 cpl_propertylist_update_double(plist,
"CDELT1", 1.);
1807 cpl_propertylist_update_string(plist,
"LAMPS",lamp_string);
1808 cpl_free(lamp_string);
1810 ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED_FN, CPL_IO_EXTEND,plist);
1817 retVal = cpl_error_get_code();
1830cpl_error_code eris_ifu_read_wave_setup(
1831 const char* filename,
1833 struct waveSetupStruct *waveSetup)
1835 cpl_error_code retVal = CPL_ERROR_NONE;
1836 cpl_table *table = NULL;
1838 const char* bandName;
1839 const char* rowBandName;
1841 bool invalidColumnFound = FALSE;
1847 (void)memset(waveSetup, 0,
sizeof(*waveSetup));
1850 table = cpl_table_load(filename, 1, 0));
1851 for (row = 0; row<cpl_table_get_nrow(table); row++) {
1852 rowBandName = cpl_table_get_string(table,
"band", row);
1854 if (strcmp(bandName, rowBandName) == 0){
1857 "There are more than row in the WAVE_SETUP with "
1858 "the same band name %s", bandName);
1862 cpl_table_get_double(table,
"fwhm", row, &n);
1864 invalidColumnFound = TRUE;
1866 waveSetup->s_range =
1867 cpl_table_get_int(table,
"s_range", row, &n);
1869 invalidColumnFound = TRUE;
1871 waveSetup->c_range =
1872 cpl_table_get_int(table,
"c_range", row, &n);
1874 invalidColumnFound = TRUE;
1876 waveSetup->ri_dispersion =
1877 cpl_table_get_double(table,
"ri_dispersion", row, &n);
1879 invalidColumnFound = TRUE;
1881 waveSetup->ri_centralLambda =
1882 cpl_table_get_double(table,
"ri_centrallambda", row,&n);
1884 double convFactor = 2. * sqrt(2. * log(2.));
1885 waveSetup->sigma = waveSetup->fwhm / convFactor;
1890 "There is no row in the WAVE_SETUP with the band name %s",
1893 if (invalidColumnFound) {
1895 "There is an invalid column in the WAVE_SETUP "
1896 "with the band name %s",
1907cpl_error_code eris_ifu_wave_init_tables(
1908 struct waveTablesStruct *tables)
1910 cpl_ensure_code(tables, CPL_ERROR_NULL_INPUT);
1911 cpl_error_code retVal = CPL_ERROR_NONE;
1915 tables->slitletFitting = NULL;
1916 tables->columnFitting = NULL;
1917 tables->slitletCoeff = NULL;
1918 tables->columnCoeffRaw = NULL;
1919 tables->columnCoeffSmoothed = NULL;
1920 tables->smoothingCoeff = NULL;
1922 tables->slitletFitting = eris_ifu_wave_create_fitting_table();
1923 tables->columnFitting = eris_ifu_wave_create_fitting_table();
1924 tables->slitletCoeff = eris_ifu_wave_create_coeff_table(
1925 SLITLET_CNT, FIRST_FIT_DEGREE);
1926 tables->columnCoeffRaw = eris_ifu_wave_create_coeff_table(
1927 ERIS_IFU_DETECTOR_SIZE_X, COLUMN_FIT_DEGREE);
1928 tables->columnCoeffSmoothed = eris_ifu_wave_create_coeff_table(
1929 ERIS_IFU_DETECTOR_SIZE_X, COLUMN_FIT_DEGREE);
1930 tables->smoothingCoeff = eris_ifu_wave_create_coeff_table(
1931 SLITLET_CNT * (COLUMN_FIT_DEGREE + 1), SMOOTH_FIT_DEGREE);
1941cpl_table *eris_ifu_wave_create_fitting_table(
void)
1944 cpl_table *table = NULL;
1949 table = cpl_table_new(0));
1950 cpl_table_new_column(table, ERIS_IFU_FITTABLE_SLITLET, CPL_TYPE_INT);
1951 cpl_table_new_column(table, ERIS_IFU_FITTABLE_INDEX, CPL_TYPE_INT);
1952 cpl_table_new_column(table,
"imgIdx", CPL_TYPE_INT);
1953 cpl_table_new_column(table, ERIS_IFU_FITTABLE_POSITION, CPL_TYPE_INT);
1954 cpl_table_new_column(table, ERIS_IFU_FITTABLE_WAVELENGTH, CPL_TYPE_DOUBLE);
1955 cpl_table_new_column(table, ERIS_IFU_FITTABLE_ERRORCODE, CPL_TYPE_INT);
1956 cpl_table_new_column(table,
"x0", CPL_TYPE_DOUBLE);
1957 cpl_table_new_column(table,
"sigma", CPL_TYPE_DOUBLE);
1958 cpl_table_new_column(table,
"area", CPL_TYPE_DOUBLE);
1959 cpl_table_new_column(table,
"offset", CPL_TYPE_DOUBLE);
1960 cpl_table_new_column(table,
"mse", CPL_TYPE_DOUBLE);
1961 cpl_table_new_column(table,
"wavelengthFit", CPL_TYPE_DOUBLE);
1962 cpl_table_new_column(table,
"wavelengthError", CPL_TYPE_DOUBLE);
1963 cpl_table_new_column(table,
"range", CPL_TYPE_INT);
1964 cpl_table_new_column_array(table,
"xdata", CPL_TYPE_DOUBLE,
1965 GAUSS_PAR_RANGE_MAX);
1966 cpl_table_new_column_array(table,
"ydata", CPL_TYPE_DOUBLE,
1967 GAUSS_PAR_RANGE_MAX);
1978cpl_error_code eris_ifu_wave_fill_fitting_table(
1986 struct gaussParStruct *gaussPar)
1988 cpl_error_code retVal = CPL_ERROR_NONE;
1994 cpl_table_set_int(table, ERIS_IFU_FITTABLE_SLITLET, row, slitlet);
1995 cpl_table_set_int(table, ERIS_IFU_FITTABLE_INDEX, row, index);
1996 cpl_table_set_int(table,
"imgIdx", row, arcImgIdx);
1997 cpl_table_set_int(table, ERIS_IFU_FITTABLE_POSITION, row, position);
1998 cpl_table_set_double(table, ERIS_IFU_FITTABLE_WAVELENGTH, row, wavelength);
1999 cpl_table_set_int(table, ERIS_IFU_FITTABLE_ERRORCODE, row, gaussPar->errorCode);
2000 cpl_table_set_double(table,
"x0", row, gaussPar->x0);
2001 cpl_table_set_double(table,
"sigma", row, gaussPar->sigma);
2002 cpl_table_set_double(table,
"area", row, gaussPar->area);
2003 cpl_table_set_double(table,
"offset", row, gaussPar->offset);
2004 cpl_table_set_double(table,
"mse", row, gaussPar->mse);
2005 cpl_table_set_int(table,
"range", row, gaussPar->range);
2008 for (
int ix=gaussPar->range; ix<GAUSS_PAR_RANGE_MAX; ix++) {
2009 gaussPar->xdata[ix] = 0.0;
2010 gaussPar->ydata[ix] = 0.0;
2013 xArray = cpl_array_wrap_double(gaussPar->xdata,
2014 GAUSS_PAR_RANGE_MAX));
2016 yArray = cpl_array_wrap_double(gaussPar->ydata,
2017 GAUSS_PAR_RANGE_MAX));
2018 cpl_table_set_array(table,
"xdata", row, xArray);
2019 cpl_table_set_array(table,
"ydata", row, yArray);
2020 cpl_array_unwrap(xArray);
2021 cpl_array_unwrap(yArray);
2030cpl_table *eris_ifu_wave_create_coeff_table(
2031 int size,
int polynomialDegree)
2034 cpl_table *table = NULL;
2039 table = cpl_table_new(size));
2040 cpl_table_new_column(table,
"slitlet", CPL_TYPE_INT);
2041 cpl_table_new_column(table,
"nlines", CPL_TYPE_INT);
2042 cpl_table_new_column(table,
"degree", CPL_TYPE_INT);
2043 cpl_table_new_column_array(table,
"coeffs", CPL_TYPE_DOUBLE,
2044 polynomialDegree+1);
2056cpl_error_code eris_ifu_wave_fill_coeff_table(
2061 cpl_polynomial *polynomial)
2063 cpl_error_code retVal = CPL_ERROR_NONE;
2070 degree = cpl_polynomial_get_degree(polynomial);
2071 arrayDim = cpl_table_get_column_dimension (table,
"coeffs", 0);
2072 array = cpl_array_new(arrayDim, CPL_TYPE_DOUBLE);
2075 cpl_table_set_int(table,
"slitlet", row, idx);
2076 cpl_table_set_int(table,
"nlines", row, nLines);
2077 cpl_table_set_int(table,
"degree", row, (
int) degree);
2078 for (cpl_size ix=0; ix<=degree; ix++) {
2079 cpl_array_set_double(array, ix,
2080 cpl_polynomial_get_coeff(polynomial, &ix));
2082 cpl_table_set_array(table,
"coeffs", row, array);
2083 cpl_array_delete(array);
2091cpl_error_code eris_ifu_wave_save_fitting_tables(
2092 struct waveTablesStruct *tables,
2093 ifsInstrument instrument,
2095 struct waveSetupStruct waveSetup,
2096 cpl_frameset* frameset,
2097 const cpl_parameterlist* parlist,
2098 const char* recipe_name)
2100 cpl_error_code retVal = CPL_ERROR_NONE;
2101 cpl_propertylist *phdr = NULL;
2102 cpl_propertylist *hdr = NULL;
2103 const char* filename = ERIS_IFU_PRO_WAVE_FIT_TABLES_FN;
2104 const char* extname =
"EXTNAME";
2105 const char *instrString;
2106 const char *bandString;
2107 int ioMode = CPL_IO_CREATE;
2111 switch (instrument) {
2113 instrString =
"ERIS";
2116 instrString =
"SINFONI";
2119 instrString =
"UNKNOWN";
2125 hdr = cpl_propertylist_new());
2127 phdr = cpl_propertylist_new());
2129 cpl_propertylist_update_string(phdr, CPL_DFS_PRO_CATG,
2130 ERIS_IFU_PRO_WAVE_FIT_TABLES));
2132 cpl_propertylist_update_string(phdr,
"INSTRUME", instrString));
2134 cpl_propertylist_update_string(phdr,
"BAND", bandString));
2136 cpl_propertylist_update_int(phdr,
"SRANGE", waveSetup.s_range));
2138 cpl_propertylist_update_int(phdr,
"CRANGE", waveSetup.c_range));
2140 eris_setup_product_header(filename, ERIS_IFU_PRO_WAVE_FIT_TABLES,
2141 CPL_FRAME_TYPE_IMAGE, recipe_name,
2142 frameset, parlist, phdr);
2144 if (tables->slitletFitting != NULL) {
2146 cpl_propertylist_update_string(
2147 hdr, extname,
"slitletFittingTable"));
2149 cpl_table_name_column(tables->slitletFitting,
"index",
"block"));
2151 cpl_table_save(tables->slitletFitting,
2152 phdr, hdr, filename, ioMode));
2153 ioMode = CPL_IO_EXTEND;
2156 if (tables->columnFitting != NULL) {
2158 cpl_propertylist_update_string(
2159 hdr, extname,
"columnFittingTable"));
2161 cpl_table_name_column(tables->columnFitting,
"index",
"column"));
2163 cpl_table_save(tables->columnFitting,
2164 phdr, hdr, filename, ioMode));
2165 ioMode = CPL_IO_EXTEND;
2168 if (tables->columnCoeffRaw != NULL) {
2170 cpl_propertylist_update_string(
2171 hdr, extname,
"slitletCoeff"));
2173 cpl_table_save(tables->slitletCoeff,
2174 phdr, hdr, filename, ioMode));
2177 cpl_propertylist_update_string(
2178 hdr, extname,
"columnCoeffRaw"));
2180 cpl_table_save(tables->columnCoeffRaw,
2181 phdr, hdr, filename, ioMode));
2182 ioMode = CPL_IO_EXTEND;
2185 if (tables->columnCoeffSmoothed != NULL) {
2187 cpl_propertylist_update_string(
2188 hdr, extname,
"columnCoeffSmoothed"));
2190 cpl_table_name_column(tables->columnCoeffSmoothed,
"nlines",
"dummy"));
2192 cpl_table_save(tables->columnCoeffSmoothed,
2193 phdr, hdr, filename, ioMode));
2194 ioMode = CPL_IO_EXTEND;
2197 if (tables->smoothingCoeff != NULL) {
2199 cpl_propertylist_update_string(
2200 hdr, extname,
"smoothingCoeff"));
2202 cpl_table_name_column(tables->smoothingCoeff,
"nlines",
"order"));
2204 cpl_table_save(tables->smoothingCoeff,
2205 phdr, hdr, filename, ioMode));
2206 ioMode = CPL_IO_EXTEND;
2210 if (ioMode == CPL_IO_CREATE) {
2213 cpl_image_save(NULL, filename, CPL_TYPE_FLOAT, phdr, ioMode));
2226void eris_ifu_wave_free_tables(
2227 struct waveTablesStruct *tables)
2238void eris_ifu_wave_clear_tables(
2239 struct waveTablesStruct *tables)
2241 tables->slitletFitting = NULL;
2242 tables->columnFitting = NULL;
2243 tables->slitletCoeff = NULL;
2244 tables->columnCoeffRaw = NULL;
2245 tables->columnCoeffSmoothed = NULL;
2246 tables->smoothingCoeff = NULL;
ifsPreopticsScale eris_ifu_get_preopticsScale(cpl_propertylist *header)
Return the the pre-optics scaling.
float eris_ifu_get_dit(cpl_propertylist *header)
Determine if a frame is a Sky frame or not.
ifsInstrument eris_ifu_get_instrument(const cpl_propertylist *header)
Return the used instrument of the FITS file header.
int eris_ifu_get_callamp_status(cpl_propertylist *header)
Return a bit mask indicating which calibration lamps are turned on.
ifsBand eris_ifu_get_band(const cpl_propertylist *header)
Determine preoptic band.
#define ASSURE(condition, error,...)
error handling macro (from fors-pipeline)
#define SET_ERROR_MSG(code, msg)
Set a new error code together with a custom error message.
#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_1d_interpolation(double *xIn, double *yIn, int nIn, double *xOut, double *yOut, int nOut, const int interType)
Perform 1D interpolation using GSL routines.
hdrl_image * eris_ifu_load_exposure_file(const char *filename, int exposureCorrectionMode, cpl_image *dqi)
Read a raw detector exposure, perform some correction, add noise data.
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
char * eris_ifu_get_lampString(int lampStatus)
eris_ifu_get_lampString
void eris_ifu_free_double_array(double **item)
free memory and set pointer to null
cpl_table * eris_qclog_init(void)
Initialize QC table.
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)
eris_ifu_save_image_dbg
void eris_ifu_free_table(cpl_table **item)
free memory and set pointer to null
const char * eris_ifu_get_bandString(ifsBand band)
eris_ifu_get_bandString
cpl_error_code eris_pfits_put_qc(cpl_propertylist *plist, cpl_table *qclog)
convert table with QC parameter information to a propertylist
void eris_ifu_free_polynomial(cpl_polynomial **item)
free memory and set pointer to null
cpl_error_code eris_qclog_add_double(cpl_table *table, const char *key_name, const double value, const char *key_help)
add QC double info to table
void eris_ifu_free_hdrl_imagelist(hdrl_imagelist **item)
free memory and set pointer to null
cpl_error_code eris_qclog_add_int(cpl_table *table, const char *key_name, const int value, const char *key_help)
add QC int info to table
void eris_ifu_free_hdrl_image(hdrl_image **item)
free memory and set pointer to null
void eris_ifu_free_image(cpl_image **item)
free memory and set pointer to null
void eris_ifu_free_bivector(cpl_bivector **item)
free memory and set pointer to null
cpl_error_code hdrl_image_sub_image(hdrl_image *self, const hdrl_image *other)
Subtract two images, store the result in the first 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_add_image(hdrl_image *self, const hdrl_image *other)
Add two images, store the result in the first image.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
hdrl_value hdrl_image_get_mean(const hdrl_image *self)
computes mean pixel value and associated error of an image.
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
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_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.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
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.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
cpl_error_code hdrl_imagelist_collapse_median(const hdrl_imagelist *himlist, hdrl_image **out, cpl_image **contrib)
Median collapsing of image list.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.