ERIS Pipeline Reference Manual 1.9.2
eris_ifu_wavecal_static.c
Go to the documentation of this file.
1/* $Id$
2 *
3 * This file is part of the ERIS Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
44#ifdef HAVE_CONFIG_H
45#include <config.h>
46#endif
47
48#include <stdbool.h>
49#include <string.h>
50#include <math.h>
51#include <eris_utils.h>
52#include "eris_ifu_error.h"
53#include "eris_ifu_utils.h"
54#include "eris_ifu_functions.h"
55#include "eris_ifu_dfs.h"
56#include "eris_ifu_wavecal_static.h"
57#include "eris_ifu_debug.h"
58
85 cpl_frameset *arcFrames,
86 int exposureCorrectionMode,
87 int *arcImgCnt,
88 hdrl_imagelist **arcImages,
89 int **lampStates,
90 ifsBand *band,
91 ifsPreopticsScale *scale,
92 ifsInstrument *instrument,
93 double saturation_threshold,
94 cpl_table** qclog)
95{
96 cpl_error_code err = CPL_ERROR_NONE;
97 hdrl_imagelist *arcImagesLocal = NULL;
98 int *lampStatesLocal = NULL;
99 hdrl_image *image = NULL;
100 cpl_table *arcFrameTable = NULL;
101 cpl_table *darkTable = NULL;
102 cpl_table *litTable = NULL;
103 const cpl_frame *frame = NULL;
104 const char *filename;
105 cpl_propertylist *header = NULL;
106 int lamps = 0;
107 float dit;
108// cpl_size nDarks;
109 cpl_size nLits;
110 ifsBand currBand;
111 ifsPreopticsScale currScale;
112 // four different lamps make a maximum number of 16 different states
113 const int MaxLampStateSetSize = 16;
114
115 TRY
116 {
117 ASSURE(arcFrames != NULL,
118 CPL_ERROR_NULL_INPUT,
119 "Null frameset (ARC frames)!");
120
121 ASSURE(arcImages != NULL, CPL_ERROR_NULL_INPUT, "Null arcImages!");
122
123 ASSURE(qclog != NULL, CPL_ERROR_NULL_INPUT, "Null qclog!");
124 int frameCnt = (int) cpl_frameset_get_size(arcFrames);
125 if (frameCnt == 0) {
126 SET_ERROR_MSG(CPL_ERROR_NULL_INPUT,
127 "input frameset (ARC frames) is empty");
128 }
129 BRK_IF_NULL(arcImagesLocal = hdrl_imagelist_new());
130 lampStatesLocal = cpl_calloc(MaxLampStateSetSize, sizeof(int));
131 *lampStates = lampStatesLocal;
132 *band = UNDEFINED_BAND;
133 *instrument = UNSET_INSTRUMENT;
134
135 // Create table
137 arcFrameTable = cpl_table_new(frameCnt));
138 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAMR_IDX,
139 CPL_TYPE_INT);
140 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAME_LAMP,
141 CPL_TYPE_INT);
142 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAME_DIT,
143 CPL_TYPE_FLOAT);
144 cpl_table_new_column(arcFrameTable, ERIS_IFU_ARCFRAME_FILE,
145 CPL_TYPE_STRING);
147
148 for (int i=0 ; i<frameCnt ; i++) {
149 frame = cpl_frameset_get_position_const(arcFrames, i);
150 cpl_msg_info("wavecal","Tag is %s",cpl_frame_get_tag(frame));
152 filename = cpl_frame_get_filename(frame));
154 header = cpl_propertylist_load(filename, 0));
155 lamps = eris_ifu_get_callamp_status(header);
156 dit = eris_ifu_get_dit(header);
157 if (*band == UNDEFINED_BAND) {
158 *band = eris_ifu_get_band(header);
159 } else {
160 currBand = eris_ifu_get_band(header);
161 if (*band != currBand) {
162 BRK_WITH_ERROR_MSG(CPL_ERROR_BAD_FILE_FORMAT,
163 "different instrument band settings"
164 " in ARC frames");
165 }
166 }
167 if (*scale == UNDEFINED_SCALE) {
168 *scale = eris_ifu_get_preopticsScale(header);
169 } else {
170 currScale = eris_ifu_get_preopticsScale(header);
171 if (*scale != currScale) {
172 BRK_WITH_ERROR_MSG(CPL_ERROR_BAD_FILE_FORMAT,
173 "different instrument pre-optics settings"
174 " in ARC frames");
175 }
176 }
177 if (*instrument == UNSET_INSTRUMENT) {
178 *instrument = eris_ifu_get_instrument(header);
179 }
181 cpl_table_set_int(arcFrameTable, ERIS_IFU_ARCFRAMR_IDX, i, i);
182 cpl_table_set_int(arcFrameTable, ERIS_IFU_ARCFRAME_LAMP, i, lamps);
183 cpl_table_set_float(arcFrameTable, ERIS_IFU_ARCFRAME_DIT, i, dit);
184 cpl_table_set_string(arcFrameTable, ERIS_IFU_ARCFRAME_FILE, i, filename);
187 }
188
189 cpl_propertylist *refList = NULL;
191 refList = cpl_propertylist_new());
193 cpl_propertylist_append_bool(refList,ERIS_IFU_ARCFRAME_LAMP,0));
195 cpl_propertylist_append_bool(refList,ERIS_IFU_ARCFRAME_DIT,0));
197 cpl_table_sort(arcFrameTable, refList));
198 cpl_propertylist_delete(refList);
199 cpl_msg_debug(cpl_func, "Input arc/dark frames sorted by lamps/dit");
200 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
201 cpl_table_dump(arcFrameTable, 0, frameCnt, stdout);
202 }
204
206 cpl_table_unselect_all(arcFrameTable));
207 cpl_size nDarks = cpl_table_or_selected_int(arcFrameTable, ERIS_IFU_ARCFRAME_LAMP,
208 CPL_EQUAL_TO, 0);
210 darkTable = cpl_table_extract_selected(arcFrameTable));
211 nLits = cpl_table_not_selected(arcFrameTable);
213 litTable = cpl_table_extract_selected(arcFrameTable));
214 cpl_table_dump(darkTable, 0, nDarks, stdout);
215 cpl_table_dump(litTable, 0, nLits, stdout);
217
218 float nDit = -1.;
219 float lDit;
220 int nLampState = 0;
221 int lLampState;
222 int isNull;
223 cpl_table* qc_log_tmp;
224 *qclog = eris_qclog_init();
225 for (int i=0 ; i<nLits ; i++) {
226 lLampState = cpl_table_get_int(litTable, ERIS_IFU_ARCFRAME_LAMP, i, &isNull);
227 lDit = cpl_table_get_float(litTable, ERIS_IFU_ARCFRAME_DIT, i, &isNull);
228 if (lDit != nDit || lLampState != nLampState) {
229 nLampState = lLampState;
230 nDit = lDit;
231 char *lampString = eris_ifu_get_lampString(nLampState);
232 cpl_msg_info(cpl_func,"New lamp/dit state: %d (%s) %f",
233 nLampState, lampString, nDit);
234 eris_ifu_free_string(&lampString);
237 darkTable, litTable, lLampState, lDit,
238 exposureCorrectionMode, saturation_threshold, &qc_log_tmp));
240 hdrl_imagelist_set(arcImagesLocal, image,
241 hdrl_imagelist_get_size(arcImagesLocal)));
242 *lampStatesLocal = lLampState;
243 lampStatesLocal++;
244
245 cpl_size size = cpl_table_get_nrow(*qclog);
246 cpl_table_insert(*qclog, qc_log_tmp, size);
247 cpl_table_delete(qc_log_tmp);
248 }
249 }
250 //hdrl_imagelist_delete(arcImagesLocal);
251 }
252 CATCH
253 {
254 err = cpl_error_get_code();
256 hdrl_imagelist_delete(arcImagesLocal);
257 }
258 eris_ifu_free_table(&arcFrameTable);
259 eris_ifu_free_table(&darkTable);
260 eris_ifu_free_table(&litTable);
261
262 *arcImages = arcImagesLocal;
263 *arcImgCnt = (int) hdrl_imagelist_get_size(arcImagesLocal);
264 return err;
265}
266
289 cpl_table *darkTable,
290 cpl_table *litTable,
291 int lampState,
292 float dit,
293 int exposureCorrectionMode,
294 double threshold,
295 cpl_table** qclog)
296{
297 hdrl_image *arcImage = NULL;
298 hdrl_image *tmpImage = NULL;
299 hdrl_image *litImage = NULL;
300 hdrl_image *darkImage = NULL;
301 hdrl_imagelist *litImageList = NULL;
302 hdrl_imagelist *darkImageList = NULL;
303 cpl_image *contribMap = NULL;
304 char* name = NULL;
305 cpl_size nDarks;
306 cpl_size nLits;
307 const char *filename;
308 hdrl_value mean = {0., 0.};
309 hdrl_value median = {0., 0.};
310 double maximum = 0.;
311 int npixsat = 0;
312 //double threshold = 18000.;
313 cpl_image* image = NULL;
314
315
316
317 TRY
318 {
319 *qclog = NULL;
320 ASSURE((darkTable != NULL) && (litTable != NULL),
321 CPL_ERROR_NULL_INPUT,
322 "One or both input tables are NULL");
324 cpl_table_unselect_all(darkTable));
326 cpl_table_unselect_all(litTable));
327 nDarks = cpl_table_or_selected_float(darkTable, ERIS_IFU_ARCFRAME_DIT,
328 CPL_EQUAL_TO, dit);
329 nLits = cpl_table_or_selected_float(litTable, ERIS_IFU_ARCFRAME_DIT,
330 CPL_EQUAL_TO, dit);
331 nLits = cpl_table_and_selected_int(litTable, ERIS_IFU_ARCFRAME_LAMP,
332 CPL_EQUAL_TO, lampState);
334 ASSURE(nLits != 0,
335 CPL_ERROR_DATA_NOT_FOUND,
336 "No frames with the lamp-on pattern %d found", lampState);
337
339 litImageList = hdrl_imagelist_new());
340 *qclog = eris_qclog_init();
341 for (int ix=0; ix<cpl_table_get_nrow(litTable); ix++) {
342 if (cpl_table_is_selected(litTable, ix)) {
343 filename = cpl_table_get_string(litTable, ERIS_IFU_ARCFRAME_FILE, ix);
345 tmpImage = eris_ifu_load_exposure_file(filename,
346 exposureCorrectionMode, NULL));
347
348 mean = hdrl_image_get_mean(tmpImage);
349 median = hdrl_image_get_median(tmpImage);
350 maximum = cpl_image_get_max(hdrl_image_get_image(tmpImage));
351 image = cpl_image_duplicate(hdrl_image_get_image(tmpImage));
352 cpl_image_threshold(image, threshold, threshold, 0, 1);
353 npixsat = (int) cpl_image_get_flux(image);
354
355 name = cpl_sprintf("QC FRMON%d MEANFLUX",ix);
356 eris_qclog_add_double(*qclog, name, mean.data, "[ADU] Average of flux");
357 cpl_free(name); name = cpl_sprintf("QC FRMON%d MEDIANFLUX",ix);
358 eris_qclog_add_double(*qclog, name, median.data, "[ADU] Median of flux");
359 cpl_free(name); name = cpl_sprintf("QC FRMON%d MAXFLUX",ix);
360 eris_qclog_add_double(*qclog, name, maximum, "[ADU] Max of flux");
361 cpl_free(name); name = cpl_sprintf("QC FRMON%d NPIXSAT",ix);
362 eris_qclog_add_int(*qclog, name, npixsat, "Number of saturated pixels");
363 cpl_free(name); name = NULL;
364
366 hdrl_imagelist_set(litImageList, tmpImage,
367 hdrl_imagelist_get_size(litImageList)));
368 cpl_image_delete(image);
369 }
370 }
372 darkImageList = hdrl_imagelist_new());
373 for (int ix=0; ix<cpl_table_get_nrow(darkTable); ix++) {
374 if (cpl_table_is_selected(darkTable, ix)) {
375 filename = cpl_table_get_string(darkTable, ERIS_IFU_ARCFRAME_FILE, ix);
376/*
377 BRK_IF_NULL(
378 image = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, 0));
379 BRK_IF_NULL(
380 tmpImage = eris_ifu_raw_hdrl_image(image));
381*/
383 tmpImage = eris_ifu_load_exposure_file(filename,
384 exposureCorrectionMode, NULL));
385
386 mean = hdrl_image_get_mean(tmpImage);
387 median = hdrl_image_get_median(tmpImage);
388 maximum = cpl_image_get_max(hdrl_image_get_image(tmpImage));
389 image = cpl_image_duplicate(hdrl_image_get_image(tmpImage));
390 cpl_image_threshold(image, threshold, threshold, 0, 1);
391 npixsat = (int) cpl_image_get_flux(image);
392
393 name = cpl_sprintf("QC FRMOFF%d MEANFLUX",ix);
394 eris_qclog_add_double(*qclog, name, mean.data, "[ADU] Average of flux");
395 cpl_free(name); name = cpl_sprintf("QC FRMOFF%d MEDIANFLUX",ix);
396 eris_qclog_add_double(*qclog, name, median.data, "[ADU] Median of flux");
397 cpl_free(name); name = cpl_sprintf("QC FRMOFF%d MAXFLUX",ix);
398 eris_qclog_add_double(*qclog, name, maximum, "[ADU] Max of flux");
399 cpl_free(name); name = cpl_sprintf("QC FRMOFF%d NPIXSAT",ix);
400 eris_qclog_add_int(*qclog, name, npixsat, "Number of saturated pixels");
401 cpl_free(name); name = NULL;
403 hdrl_imagelist_set(darkImageList, tmpImage,
404 hdrl_imagelist_get_size(darkImageList)));
405 cpl_image_delete(image);
406 }
407 }
408
409 if (nLits == 1) {
411 litImage = hdrl_image_duplicate(
412 hdrl_imagelist_get(litImageList, 0)));
413 } else if (nLits >= 3) {
416 litImageList, &litImage, &contribMap));
417 } else {
420 litImageList, &litImage, &contribMap));
421 }
422
423 arcImage = litImage;
424 litImage = NULL;
425 if (nDarks != 0) {
426 if (nDarks == 1) {
428 darkImage = hdrl_image_duplicate(
429 hdrl_imagelist_get(darkImageList, 0)));
430 } else if (nDarks >= 3) {
433 darkImageList, &darkImage, &contribMap));
434 } else {
437 darkImageList, &darkImage, &contribMap));
438 }
440 hdrl_image_sub_image(arcImage, darkImage));
441
442 mean = hdrl_image_get_mean(arcImage);
443 median = hdrl_image_get_median(arcImage);
444 maximum = cpl_image_get_max(hdrl_image_get_image(arcImage));
445 image = cpl_image_duplicate(hdrl_image_get_image(arcImage));
446 cpl_image_threshold(image, threshold, threshold, 0, 1);
447 npixsat = (int) cpl_image_get_flux(image);
448
449 name = cpl_sprintf("QC FRMDIFF MEANFLUX");
450 eris_qclog_add_double(*qclog, name, mean.data, "[ADU] Average of flux");
451 cpl_free(name); name = cpl_sprintf("QC FRMDIFF MEDIANFLUX");
452 eris_qclog_add_double(*qclog, name, median.data, "[ADU] Median of flux");
453 cpl_free(name); name = cpl_sprintf("QC FRMDIFF MAXFLUX");
454 eris_qclog_add_double(*qclog, name, maximum, "[ADU] Max of flux");
455 cpl_free(name); name = cpl_sprintf("QC FRMDIFF NPIXSAT");
456 eris_qclog_add_int(*qclog, name, npixsat, "Number of saturated pixels");
457 cpl_free(name); name = NULL;
458 cpl_image_delete(image);
459 }
460
461 }
462 CATCH
463 {
464 cpl_free(name);
465 hdrl_image_delete(litImage);
466 cpl_table_delete(*qclog);
467 *qclog = NULL;
468 hdrl_image_delete(arcImage);
469 arcImage = NULL;
470 }
471 eris_ifu_free_hdrl_imagelist(&litImageList);
472 eris_ifu_free_hdrl_imagelist(&darkImageList);
473 eris_ifu_free_hdrl_image(&darkImage);
474 return arcImage;
475}
476
477//static cpl_error_code
478//eris_compute_residuals_fit(cpl_table* tab, cpl_table* qclog)
479//{
480// /* compute QC parameters */
481// cpl_table* xtab = NULL;
482// double mean = 0;
483// double median = 0;
484// double stddev = 0;
485// double min = 0;
486// double max = 0;
487// const char* key_name;
488// const char* key_help;
489
490// for (int sIdx = 0; sIdx < SLITLET_CNT; sIdx++) {
491// cpl_table_and_selected_int(tab, "slitlet", CPL_EQUAL_TO, sIdx );
492// xtab = cpl_table_extract_selected(tab);
493
494// mean = cpl_table_get_column_mean(xtab, "wavelengthError");
495// key_name = cpl_sprintf("QC WFIT SLICE%d MEAN",sIdx);
496// key_help = cpl_sprintf("[um] Mean error of wave fit for slice %d",sIdx);
497// eris_qclog_add_double(qclog, key_name, mean, key_help);
498
499
500// median = cpl_table_get_column_median(xtab, "wavelengthError");
501// key_name = cpl_sprintf("QC WFIT SLICE%d MEDIAN",sIdx);
502// key_help = cpl_sprintf("[um] Median error of wave fit for slice %d",sIdx);
503// eris_qclog_add_double(qclog, key_name, median, key_help);
504
505// stddev = cpl_table_get_column_stdev(xtab, "wavelengthError");
506// key_name = cpl_sprintf("QC WFIT SLICE%d STDEV",sIdx);
507// key_help = cpl_sprintf("[um] Stdev error of wave fit for slice %d",sIdx);
508// eris_qclog_add_double(qclog, key_name, stddev, key_help);
509
510
511// min = cpl_table_get_column_min(xtab, "wavelengthError");
512// key_name = cpl_sprintf("QC WFIT SLICE%d MIN",sIdx);
513// key_help = cpl_sprintf("[um] Minimum error of wave fit for slice %d",sIdx);
514// eris_qclog_add_double(qclog, key_name, min, key_help);
515
516
517// max = cpl_table_get_column_max(xtab, "wavelengthError");
518// key_name = cpl_sprintf("QC WFIT SLICE%d MAX",sIdx);
519// key_help = cpl_sprintf("[um] Maximum error of wave fit for slice %d",sIdx);
520// eris_qclog_add_double(qclog, key_name, max, key_help);
521
522// cpl_table_select_all(tab);
523// cpl_table_delete(xtab);
524
525// }
526// cpl_table_select_all(tab);
527// mean = cpl_table_get_column_mean(tab, "wavelengthError");
528// key_name = cpl_sprintf("QC WFIT MEAN");
529// key_help = cpl_sprintf("[um] Mean error of wave fit");
530// eris_qclog_add_double(qclog, key_name, mean, key_help);
531
532
533// median = cpl_table_get_column_median(tab, "wavelengthError");
534// key_name = cpl_sprintf("QC WFIT MEDIAN");
535// key_help = cpl_sprintf("[um] Median error of wave fit");
536// eris_qclog_add_double(qclog, key_name, median, key_help);
537
538
539// stddev = cpl_table_get_column_stdev(tab, "wavelengthError");
540// key_name = cpl_sprintf("QC WFIT STDEV");
541// key_help = cpl_sprintf("[um] Stdev error of wave fit");
542// eris_qclog_add_double(qclog, key_name, stddev, key_help);
543
544// min = cpl_table_get_column_min(tab, "wavelengthError");
545// key_name = cpl_sprintf("QC WFIT MIN");
546// key_help = cpl_sprintf("[um] Minimum error of wave fit");
547// eris_qclog_add_double(qclog, key_name, min, key_help);
548
549// max = cpl_table_get_column_max(tab, "wavelengthError");
550// key_name = cpl_sprintf("QC WFIT MAX");
551// key_help = cpl_sprintf("[um] Maximum error of wave fit");
552// eris_qclog_add_double(qclog, key_name, max, key_help);
553// cpl_table_save(qclog,NULL, NULL, "qclog.fits", CPL_IO_CREATE);
554
555// return cpl_error_get_code();
556//}
557
594 int arcImagesCnt,
595 hdrl_imagelist *arcImages,
596 int *lampStates,
597 ifsBand band,
598 ifsInstrument instrument,
599 struct waveSetupStruct waveSetup,
600 const char* refLineTableFileName,
601 const char* firstFitTableFileName,
602 cpl_bivector *slitPos,
603 struct waveTablesStruct *tables,
604 int productDepth,
605 cpl_frameset *fs,
606 const cpl_parameterlist* parlist,
607 cpl_table* qclog)
608{
609 int arcImgCnt;
610 cpl_image *waveCalImg = NULL;
611 const cpl_image **dataImg = NULL;
612 cpl_bivector **refLines = NULL;
613 hdrl_image *arcImg = NULL;
614 int lampStatus = 0;
615 double *slitletStart;
616 double *slitletEnd;
617 cpl_image **collapsedSpectra = NULL;
618 cpl_vector *collapsedSpectrum = NULL;
619// const double *collapsedSpectrumData;
620 cpl_size nRows;
621 int center;
622 cpl_polynomial *firstFit = NULL;
623 cpl_table *firstFitTable = NULL;
624 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y];
625 const hdrl_image *tmpImg;
626 enum multiArcModes {SUPERIMPOSE, SEPARATE};
627 int multiArcMode = SEPARATE;
628
629 TRY
630 {
631 for (int ix=0; ix<ERIS_IFU_DETECTOR_SIZE_Y; ix++) {
632 allFits[ix] = NULL;
633 }
634
635
636 // If there are more than one arc images two possibilities exist:
637 // a) superimpose all arc images as they were illuminated by a
638 // combination of all lamp states. This can be used if the
639 // different lamps intensities need different DITs but no severe
640 // line blending occurs.
641 // b) work on each arc image independent and combine the lambda/pos
642 // fits at the end.
643
644 if (multiArcMode == SUPERIMPOSE) {
645 arcImgCnt = 1;
646 } else { // SEPARATE
647 arcImgCnt = arcImagesCnt;
648 }
649
651 dataImg = cpl_calloc(arcImgCnt, sizeof(cpl_image *)));
653 refLines = cpl_calloc(arcImgCnt, sizeof(cpl_bivector *)));
655 collapsedSpectra = cpl_calloc(arcImgCnt, sizeof(cpl_image *)));
656
657 if (multiArcMode == SUPERIMPOSE) { //option a)
659 arcImg = hdrl_imagelist_get(arcImages, 0));
660 lampStatus = lampStates[0];
661 for (int aix = 1; aix< arcImgCnt; aix++) {
662 lampStatus = lampStatus | lampStates[aix];
664 tmpImg = hdrl_imagelist_get_const(arcImages, aix));
666 hdrl_image_add_image(arcImg, tmpImg));
667 }
668 lampStates[0] = lampStatus;
669
671 dataImg[0] = hdrl_image_get_image(arcImg));
672
673 } else { // SEPARATE
674 for (int ix = 0; ix < arcImgCnt; ix++) {
676 tmpImg = hdrl_imagelist_get_const(arcImages, ix));
678 dataImg[ix] = hdrl_image_get_image_const(tmpImg));
679 }
680 }
681
682 char* pipe_id = cpl_sprintf("%s%s%s", PACKAGE, "/", PACKAGE_VERSION);
683 cpl_propertylist *applist = cpl_propertylist_new();
684 eris_pfits_put_qc(applist, qclog);
685 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG,
686 ERIS_IFU_PRO_WAVE_LAMP_STACKED);
687 cpl_dfs_save_propertylist(fs, NULL, parlist, fs, NULL,
688 "eris_ifu_wavecal", applist, NULL,
689 pipe_id, ERIS_IFU_PRO_WAVE_LAMP_STACKED_FN);
690
691 //BRK_IF_ERROR(
692 // cpl_image_save(NULL,ERIS_IFU_PRO_WAVE_LAMP_STACKED_FN,
693 // CPL_TYPE_DOUBLE,NULL,CPL_IO_CREATE));
694 for (int ix = 0; ix < arcImgCnt; ix++) {
696 refLines[ix] = eris_ifu_wave_get_refLines(
697 refLineTableFileName, instrument, lampStates[ix]));
698 /* AMo: save as final product as requested by QC: PIPE-10189 */
699 eris_ifu_save_image_dbg(dataImg[ix],
700 ERIS_IFU_PRO_WAVE_LAMP_STACKED_FN,
701 CPL_IO_EXTEND, NULL);
702 }
703 cpl_propertylist_delete(applist);
704 cpl_free(pipe_id);
705 nRows = cpl_image_get_size_y(dataImg[0]);
706 if (slitPos == NULL) {
708 slitletStart = cpl_calloc(SLITLET_CNT, sizeof(double)));
710 slitletEnd = cpl_calloc(SLITLET_CNT, sizeof(double)));
711 for (int mx = 0; mx <SLITLET_CNT; mx++){
712 double tmp = (double) (SLITLET_WIDTH * mx);
713 slitletStart[mx] = tmp;
714 slitletEnd[mx] = tmp + SLITLET_WIDTH -1;
715 }
716 } else {
718 slitletStart = cpl_bivector_get_x_data(slitPos));
720 slitletEnd = cpl_bivector_get_y_data(slitPos));
721 }
722
723 for (int aIdx = 0; aIdx < arcImgCnt; aIdx++) {
724 for (int sIdx = 0; sIdx < SLITLET_CNT; sIdx++) {
725 center = (int) (
726 slitletStart[sIdx] +
727 (slitletEnd[sIdx] - slitletStart[sIdx]) / 2.);
728 collapsedSpectrum = eris_ifu_wave_collapse_slitlet(
729 dataImg[aIdx], center);
730 eris_ifu_wave_save_spectrum(collapsedSpectra, aIdx,
731 collapsedSpectrum, sIdx, nRows,
732 lampStates[aIdx], band, instrument,
733 refLines[aIdx], productDepth);
734 eris_ifu_free_vector(&collapsedSpectrum);
735 }
736 }
737
739 firstFitTable = eris_ifu_wave_get_firstFitTable(
740 firstFitTableFileName, instrument, band));
741 cpl_msg_debug(cpl_func, "First fit table:");
742 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
743 cpl_table_dump(firstFitTable, 0,
744 cpl_table_get_nrow(firstFitTable), stdout);
745 }
746
747 int firstFitOffset;
748 int firstFitMasterOffset;
750 firstFit = eris_ifu_get_first_fit(collapsedSpectra,
751 lampStates, arcImgCnt, 16, 0, &firstFitMasterOffset,
752 waveSetup, firstFitTable,
753 tables->slitletFitting, tables->slitletCoeff));
754 cpl_msg_info(__func__,"FirstFit Master Offset %d", firstFitMasterOffset);
755
756 for (int sIdx = 0; sIdx < SLITLET_CNT; sIdx++) {
757 cpl_polynomial_delete(firstFit);
759 firstFit = eris_ifu_get_first_fit(collapsedSpectra,
760 lampStates, arcImgCnt, sIdx, firstFitMasterOffset, &firstFitOffset,
761 waveSetup, firstFitTable,
762 tables->slitletFitting, tables->slitletCoeff));
763
764 eris_ifu_fit_all_lines(REC_NAME_WAVECAL, sIdx, slitletStart, slitletEnd,
765 arcImgCnt, dataImg, refLines,
766 waveSetup, firstFit, allFits,
767 tables->columnFitting, tables->columnCoeffRaw,
768 tables->columnCoeffSmoothed, tables->smoothingCoeff);
769
770 }
771 cpl_free(slitletEnd);
772 cpl_free(slitletStart);
773 BRK_IF_NULL(firstFitTable);
774
775 // create wave cal image
777 waveCalImg = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
778 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_DOUBLE));
779 cpl_image* waveCalErr = cpl_image_new(ERIS_IFU_DETECTOR_SIZE_X,
780 ERIS_IFU_DETECTOR_SIZE_Y, CPL_TYPE_DOUBLE);
781 double errs = 0;
782 double wave = 0;
783 for (int col=0; col<ERIS_IFU_DETECTOR_SIZE_X; col++) {
784 for (int row=0; row<ERIS_IFU_DETECTOR_SIZE_Y; row++) {
785 wave = cpl_polynomial_eval_1d(allFits[col], row, &errs);
787 cpl_image_set(waveCalImg, col+1, row+1, wave));
788 cpl_image_set(waveCalErr, col+1, row+1, errs);
789 }
790 }
791
792 cpl_image* img = cpl_image_extract(waveCalImg,1,1024,2048,1024);
793
794 cpl_image* err = cpl_image_extract(waveCalErr,1,1024,2048,1024);
795
796 double wcen = cpl_image_get_mean(img);
797 double werr = fabs(cpl_image_get_mean(err));
798 cpl_msg_warning(cpl_func,"Central wave: %g, %g", wcen, werr);
799 cpl_image_delete(img);
800 cpl_image_delete(err);
801 char* key_name = NULL;
802 char* key_help = NULL;
803 key_name = cpl_sprintf("QC WCEN VALUE");
804 key_help = cpl_sprintf("[um] Central wavelength value");
805 eris_qclog_add_double(qclog, key_name, wcen, key_help);
806
807 cpl_free(key_name);
808 cpl_free(key_help);
809
810 key_name = cpl_sprintf("QC WCEN ERR");
811 key_help = cpl_sprintf("[um] Error on central wavelength value");
812 eris_qclog_add_double(qclog, key_name, werr, key_help);
813 cpl_free(key_name);
814 cpl_free(key_help);
815
816
817 //cpl_image_save(waveCalErr,"waveCalErr.fits",CPL_TYPE_DOUBLE,NULL,CPL_IO_DEFAULT);
818 cpl_image_delete(waveCalErr);
819 /* AMo: save as final product as requested by QC: PIPE-10189 */
821 arcImgCnt,
822 dataImg,
823 waveCalImg,
824 band,
825 lampStates, fs, parlist);
826
827 // calculate position errors and store them in FIT table
829 eris_ifu_wave_pos_err(allFits, tables->columnFitting, band));
830 /* TODO: temporarily commented out as seems same infor is computed elsewhere
831 eris_compute_residuals_fit(tables->columnFitting,qclog);
832 */
833 }
834 CATCH
835 {
836 waveCalImg = NULL;
837 }
838 for (int ix=0; ix<ERIS_IFU_DETECTOR_SIZE_Y; ix++) {
839 eris_ifu_free_polynomial(&allFits[ix]);
840 }
841 if (dataImg != NULL) {
842 cpl_free(dataImg);
843 }
844 if (refLines != NULL) {
845 for (int ix=0; ix < arcImgCnt; ix++) {
846 eris_ifu_free_bivector(&refLines[ix]);
847 }
848 cpl_free(refLines);
849 }
850 if (collapsedSpectra != NULL) {
851 for (int ix=0; ix < arcImgCnt; ix++) {
852 eris_ifu_free_image(&collapsedSpectra[ix]);
853 }
854 cpl_free(collapsedSpectra);
855 }
856 eris_ifu_free_vector(&collapsedSpectrum);
857 eris_ifu_free_polynomial(&firstFit);
858 eris_ifu_free_table(&firstFitTable);
859 return waveCalImg;
860}
861
880 const char * refLineTableFileName,
881 ifsInstrument instrument,
882 int lampState)
883{
884 cpl_bivector *refLines = NULL;
885 cpl_propertylist *header = NULL;
886 cpl_size exCnt = 0;
887 const char *instrumentHdr;
888 const char *lampHdr;
889 const char *instrString;
890 char lampString[9] = "";
891 cpl_vector *wavelength = NULL;
892 cpl_vector *intensity = NULL;
893 cpl_table *refLineTable = NULL;
894 cpl_size nRows;
895 int ignored;
896 int vx=0;
897 double tmp;
898
899 cpl_ensure(refLineTableFileName, CPL_ERROR_NULL_INPUT, NULL);
900 if (access(refLineTableFileName, F_OK)) {
901 cpl_msg_error(cpl_func, "File %s was not found",
902 refLineTableFileName);
903 cpl_error_set(cpl_func, CPL_ERROR_FILE_NOT_FOUND);
904 cpl_ensure(CPL_FALSE, CPL_ERROR_FILE_NOT_FOUND, NULL);
905 }
906 TRY
907 {
908 switch(instrument) {
909 case SPIFFIER:
910 instrString = ERIS_IFU_REFTABLE_SPIFFIER_VAL;
911 break;
912 case SPIFFI:
913 instrString = ERIS_IFU_REFTABLE_SPIFFI_VAL;
914 break;
915 default:
916 instrString = "";
917 break;
918 }
919 if ((lampState & AR_LAMP) != 0) {
920 strcat(lampString, ERIS_IFU_REFTABLE_ARGON_VAL);
921 }
922 if ((lampState & NE_LAMP) != 0) {
923 strcat(lampString, ERIS_IFU_REFTABLE_NEON_VAL);
924 }
925 if ((lampState & KR_LAMP) != 0) {
926 strcat(lampString, ERIS_IFU_REFTABLE_KRYPTON_VAL);
927 }
928 if ((lampState & XE_LAMP) != 0) {
929 strcat(lampString, ERIS_IFU_REFTABLE_XEON_VAL);
930 }
931 exCnt = cpl_fits_count_extensions(refLineTableFileName);
933 for (int ex=1; ex<exCnt+1; ex++) {
935 header = cpl_propertylist_load(refLineTableFileName, ex));
937 instrumentHdr = cpl_propertylist_get_string(
938 header, ERIS_IFU_REFTABLE_INSTR_HDR));
940 lampHdr = cpl_propertylist_get_string(
941 header, ERIS_IFU_REFTABLE_LAMPS_HDR));
942 if ((strcmp(instrumentHdr, instrString) == 0) &&
943 (strcmp(lampHdr, lampString) == 0)) {
944
946 refLineTable = cpl_table_load(refLineTableFileName, ex, 0));
947 nRows = cpl_table_get_nrow(refLineTable);
949 wavelength = cpl_vector_new(nRows));
951 intensity = cpl_vector_new(nRows));
952 for (int rx=0; rx<nRows; rx++) {
953 ignored = cpl_table_get_int(
954 refLineTable, ERIS_IFU_REFTABLE_IGNORED_COLUMN,
955 rx, NULL);
956 if (ignored == 0) {
957 tmp = cpl_table_get_double(
958 refLineTable, ERIS_IFU_REFTABLE_LAMBDA_COLUMN, rx,
959 NULL);
961 if (tmp > 100.) {
962 tmp /= 1000.;
963 }
965 cpl_vector_set(wavelength, vx, tmp));
966
967 tmp = cpl_table_get_double(
968 refLineTable, ERIS_IFU_REFTABLE_INTENSITY_COLUMN,
969 rx, NULL);
972 cpl_vector_set(intensity, vx, tmp));
973
974 vx++;
975 }
976 }
978 break;
979 }
981 }
982 if (wavelength == NULL) {
983 BRK_WITH_ERROR_MSG(CPL_ERROR_BAD_FILE_FORMAT,
984 "There is no extension in reference lines file %s "
985 "for instrument %s and lamps %s",
986 refLineTableFileName, instrString, lampString);
987
988 }
989 if (vx > 0) {
991 refLines = cpl_bivector_wrap_vectors(
992 cpl_vector_extract(wavelength, 0, vx-1, 1),
993 cpl_vector_extract(intensity, 0, vx-1, 1)));
994 }
995 }
996 CATCH
997 {
998 refLines = NULL;
1000 }
1001 eris_ifu_free_vector(&wavelength);
1002 eris_ifu_free_vector(&intensity);
1003 eris_ifu_free_table(&refLineTable);
1004
1005 return refLines;
1006}
1007
1023cpl_vector * eris_ifu_wave_collapse_slitlet(const cpl_image *dataImg,
1024 int center)
1025{
1026 cpl_vector *spec = NULL;
1027 cpl_size nRows;
1028 cpl_vector *slitletRow = NULL;
1029 double *slitletRowData = NULL;
1030 int isValid;
1031 int startCol;
1032 int endCol;
1033 double tmpData;
1034
1035 const int halfWidth = 10;
1036
1037 startCol = center - halfWidth;
1038 endCol = center + halfWidth;
1039 TRY
1040 {
1041 nRows = cpl_image_get_size_y(dataImg);
1043 spec = cpl_vector_new(nRows));
1044
1046 slitletRow = cpl_vector_new(halfWidth * 2 + 1));
1048 slitletRowData = cpl_vector_get_data(slitletRow));
1049
1050 for (int row=0; row<nRows; row++) {
1051 for (int col=startCol; col<endCol+1; col++) {
1052 tmpData = cpl_image_get(dataImg, col+1, row+1, &isValid);
1054 if (isValid != 0) {
1055 tmpData = 0;
1056 }
1057 slitletRowData[col-startCol] = tmpData;
1058 }
1059 tmpData = cpl_vector_get_median(slitletRow);
1061 cpl_vector_set(spec, row, tmpData));
1062 }
1063 }
1064 CATCH
1065 {
1066 spec = NULL;
1067 }
1068 eris_ifu_free_vector(&slitletRow);
1069 return spec;
1070}
1071
1099cpl_polynomial * eris_ifu_get_first_fit(
1100 cpl_image** spectra,
1101 int *lampStates,
1102 int spectrumCnt,
1103 int slitlet,
1104 int ffOffsetIn,
1105 int *ffOffsetOut,
1106 struct waveSetupStruct waveSetup,
1107 cpl_table *firstFitTable,
1108 cpl_table *fittingDumpTable,
1109 cpl_table *coeffDumpTable)
1110{
1111 cpl_polynomial *fit = NULL;
1112 cpl_table *blockTable = NULL;
1113 cpl_table *tmpTable = NULL;
1114 cpl_size rowCnt;
1115 cpl_vector *spectrum = NULL;
1116 int isValid;
1117 int position;
1118 double wavelength;
1119 const int fitLength = 40;
1120 double xData[fitLength];
1121 double yData[fitLength];
1122 int fx;
1123 struct gaussParStruct gaussPar;
1124 cpl_size dumpRow;
1125 double ffOffsets = 0.;
1126 int ffOffsetCnt = 0;
1127
1128 const int slitlet2collapsed[SLITLET_CNT] = {
1129 0, 15, 1, 16, 2, 17, 3, 18, 4, 19, 5, 20, 6, 21, 7,
1130 30, 31,
1131 22, 8, 23, 9, 24, 10, 25, 11, 26, 12, 27, 13, 28, 14, 29};
1132
1133 TRY
1134 {
1136 cpl_table_unselect_all(firstFitTable));
1137
1138 rowCnt = cpl_table_or_selected_int(firstFitTable,
1139 ERIS_IFU_FIRSTFIT_BLOCK, CPL_EQUAL_TO, slitlet_block[slitlet]);
1141 if (rowCnt < 1) {
1142 BRK_WITH_ERROR_MSG(CPL_ERROR_DATA_NOT_FOUND,
1143 "no records found in firstFits table with block %d",
1144 slitlet_block[slitlet]);
1145 }
1146 blockTable = cpl_table_extract_selected(firstFitTable);
1147
1148 fx = 0;
1149
1150 for (int aIdx = 0; aIdx < spectrumCnt; aIdx++) {
1151
1153 cpl_table_unselect_all(blockTable));
1154 char* lampString = eris_ifu_get_lampString(lampStates[aIdx]);
1155 rowCnt = cpl_table_or_selected_string(blockTable,
1156 ERIS_IFU_FIRSTFIT_LAMPS, CPL_EQUAL_TO, lampString);
1157 cpl_free(lampString);
1158 tmpTable = cpl_table_extract_selected(blockTable);
1159 dumpRow = cpl_table_get_nrow(fittingDumpTable);
1160 cpl_table_set_size(fittingDumpTable, dumpRow+rowCnt);
1161
1162 if (slitlet < 15) {
1163
1164 }
1166 spectrum = cpl_vector_new_from_image_column(
1167 spectra[aIdx], slitlet2collapsed[slitlet]+1));
1168
1169 for (int rx = 0; rx < rowCnt; rx++) {
1170 position = cpl_table_get_int(tmpTable,
1171 ERIS_IFU_FIRSTFIT_POSITION, rx, &isValid);
1172 wavelength = cpl_table_get_double(tmpTable,
1173 ERIS_IFU_FIRSTFIT_WAVELENGTH, rx, &isValid);
1174
1175 if (CPL_ERROR_NONE == eris_ifu_line_gauss_fit(
1176 spectrum, position+ffOffsetIn, waveSetup.s_range, &gaussPar)) {
1177 if ((gaussPar.x0 != 0.) &&
1178 (gaussPar.sigma < 3. || gaussPar.peak > 8000.)){
1179 if (fx < fitLength) {
1180 if (wavelength > 100.) {
1181 wavelength /= 1000.;
1182 }
1183 xData[fx] = wavelength;
1184 yData[fx] = gaussPar.x0;
1185 fx++;
1186 }
1187 ffOffsets += gaussPar.x0 - position;
1188 ffOffsetCnt++;
1189 } else {
1190 int range = waveSetup.s_range;
1191 int start = position-(range/2);
1192 if (range <= GAUSS_PAR_RANGE_MAX) {
1193 gaussPar.range = range;
1194 for (int ix=0; ix<range; ix++) {
1195 gaussPar.xdata[ix] = start+ix;
1196 gaussPar.ydata[ix] = cpl_vector_get(spectrum,start+ix);
1197 }
1198 }
1199
1200 const char *lamp = cpl_table_get_string(tmpTable,
1201 ERIS_IFU_FIRSTFIT_LAMPS, rx);
1202 cpl_msg_warning(__func__,
1203 "First line fit failed for "
1204 "slitlet %d at row %d wavelength %.3f for lamp %s",
1205 slitlet, position, wavelength, lamp);
1206 }
1207 }
1209 eris_ifu_wave_fill_fitting_table(fittingDumpTable,
1210 (int) dumpRow,
1211 slitlet, slitlet_block[slitlet], aIdx,
1212 position, wavelength,
1213 &gaussPar));
1214 dumpRow++;
1215 }
1216 eris_ifu_free_vector(&spectrum);
1217 eris_ifu_free_table(&tmpTable);
1218 *ffOffsetOut = (int) (ffOffsets/ffOffsetCnt + .5);
1219 }
1221 fit = eris_ifu_1d_polynomial_fit(fx, xData, yData,
1222 FIRST_FIT_DEGREE));
1223 eris_ifu_wave_fill_coeff_table(coeffDumpTable, slitlet, slitlet, fx,
1224 fit);
1225 }
1226
1227 CATCH
1228 {
1229 fit = NULL;
1230 }
1231 eris_ifu_free_table(&tmpTable);
1232 eris_ifu_free_table(&blockTable);
1233 eris_ifu_free_vector(&spectrum);
1235 cpl_table_unselect_all(firstFitTable));
1236 return fit;
1237}
1238
1275 const char *recipe_name,
1276 int sIdx,
1277 const double *slitletStart,
1278 const double *slitletEnd,
1279 int arcImgCnt,
1280 const cpl_image **dataImg,
1281 cpl_bivector **refLines,
1282 struct waveSetupStruct waveSetup,
1283 cpl_polynomial *firstFit,
1284 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y],
1285 cpl_table *dumpTable,
1286 cpl_table *columnCoeffRawTable,
1287 cpl_table *columnCoeffSmoothedTable,
1288 cpl_table *smoothingCoeffTable)
1289{
1290 cpl_error_code err = CPL_ERROR_NONE;
1291 int start, end;
1292 double s1, s2, e1, e2;
1293 cpl_vector *spectrum = NULL;
1294 double *refLinelambda;
1295 int firstGuessPos;
1296 cpl_size nRefLines;
1297 cpl_size nSpectrum;
1298 cpl_error_code fitErr;
1299 struct gaussParStruct gaussPar;
1300 cpl_size dumpRow = 0;
1301 const int fitLength = 2048;
1302 double xData[fitLength];
1303 double yData[fitLength];
1304 int fx;
1305
1306 cpl_ensure_code(recipe_name, CPL_ERROR_NULL_INPUT);
1307
1308 TRY
1309 {
1310 if (strcmp(recipe_name, REC_NAME_DISTORTION) == 0) {
1311 start = (int) slitletStart[sIdx];
1312 end = (int) slitletEnd[sIdx];
1313 } else {
1314 s2 = slitletStart[sIdx];
1315 if (sIdx == 0) {
1316 s1 = -.5;
1317 } else {
1318 s1 = slitletEnd[sIdx-1];
1319 }
1320 e1 = slitletEnd[sIdx];
1321 if (sIdx == SLITLET_CNT-1) {
1322 e2 = 2047.;
1323 } else {
1324 e2 = slitletStart[sIdx+1];
1325 }
1326 // start = 1 + (int) floor(((s1 + s2) /2.0));
1327 // end = (int) ((e1 + e2) /2.0);
1328 if (sIdx == 0) {
1329 start = 0;
1330 } else {
1331 start = (int) (((s1 + s2) / 2.0) + .5) + 1;
1332 }
1333 if (sIdx == SLITLET_CNT-1) {
1334 end = 2047;
1335 } else {
1336 end = (int) (((e1 + e2) / 2.0) + .5);
1337 }
1338 cpl_msg_debug(cpl_func,
1339 "Slitlet %2d: start: %4d end: %4d (%7.2f - %7.2f ... %7.2f - %7.2f)",
1340 sIdx, start, end, s1, s2, e1, e2);
1341 }
1342
1343 for (int cx = start; cx <= end; cx++) {
1344 fx = 0;
1345 for (int ax = 0; ax< arcImgCnt; ax++) {
1346 nRefLines = cpl_bivector_get_size(refLines[ax]);
1347 refLinelambda = cpl_bivector_get_x_data(refLines[ax]);
1348
1349 dumpRow = cpl_table_get_nrow(dumpTable);
1350 cpl_table_set_size(dumpTable, dumpRow + nRefLines);
1351
1353 spectrum = cpl_vector_new_from_image_column(dataImg[ax], cx+1));
1354 nSpectrum = cpl_vector_get_size(spectrum);
1355 for (int rx=0; rx<nRefLines; rx++) {
1356 firstGuessPos = (int) (0.5 +
1357 cpl_polynomial_eval_1d(firstFit, refLinelambda[rx], NULL));
1358 if (firstGuessPos > 4+waveSetup.c_range/2 &&
1359 firstGuessPos < (nSpectrum - 4 - waveSetup.c_range/2)) {
1360 fitErr = eris_ifu_line_gauss_fit(
1361 spectrum, firstGuessPos, waveSetup.c_range, &gaussPar);
1362 if ((fitErr == CPL_ERROR_NONE) &&
1363 (gaussPar.offset > -10. - gaussPar.peak / 300. ) &&
1364 (gaussPar.sigma < waveSetup.sigma) &&
1365 (fabs(gaussPar.x0 - firstGuessPos) < 5.01)) {
1366 yData[fx] = refLinelambda[rx];
1367 xData[fx] = gaussPar.x0;
1368 fx++;
1369 } else {
1370 if (fitErr == CPL_ERROR_NONE) { //wierd looking fit
1371 gaussPar.errorCode = -2; //for dump table only
1372 }
1373 }
1374 } else {
1375 // search outside spectra
1376 gaussPar.errorCode = -1;
1377 gaussPar.x0 = 0.;
1378 gaussPar.sigma = 0.;
1379 gaussPar.area = 0.;
1380 gaussPar.offset = 0.;
1381 gaussPar.peak = 0.;
1382 gaussPar.mse = 0.;
1383 gaussPar.range = 0;
1384 }
1385 if (gaussPar.errorCode != -1) {
1387 eris_ifu_wave_fill_fitting_table(dumpTable, (int) dumpRow,
1388 sIdx, cx, ax, firstGuessPos, refLinelambda[rx],
1389 &gaussPar));
1390 dumpRow++;
1391 }
1392 }
1393 eris_ifu_free_vector(&spectrum);
1394 cpl_table_set_size(dumpTable, dumpRow);
1395 }
1396 if (fx > COLUMN_FIT_DEGREE+1) {
1397 //if (fx > (/2)) {
1399 allFits[cx] = eris_ifu_1d_polynomial_fit(fx, xData, yData,
1400 COLUMN_FIT_DEGREE));
1401 } else {
1402 cpl_msg_warning(cpl_func,
1403 "Number of found lines (=%d) too small for column %d",
1404 fx, cx);
1405 //mark fit as failed
1406 allFits[cx] = cpl_polynomial_new(1);
1407 cpl_size tmpPower = 0;
1408 cpl_polynomial_set_coeff(allFits[cx], &tmpPower, 0.0);
1409 }
1410 eris_ifu_wave_fill_coeff_table(columnCoeffRawTable, cx, cx,
1411 fx, allFits[cx]);
1412
1413 eris_ifu_free_vector(&spectrum);
1414 }
1415
1417 eris_ifu_wave_smooth_coeffs(sIdx, start, end,
1418 COLUMN_FIT_DEGREE, allFits,
1419 columnCoeffSmoothedTable, smoothingCoeffTable));
1420 }
1421 CATCH
1422 {
1423 }
1424 return err;
1425
1426}
1427
1456 int sIdx,
1457 int start,
1458 int end,
1459 int fitDegree,
1460 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y],
1461 cpl_table *columnCoeffSmoothedTable,
1462 cpl_table *smoothingCoeffTable)
1463{
1464 cpl_error_code retVal = CPL_ERROR_NONE;
1465 int nc;
1466 const int fitLength = 2048;
1467 double cData[fitLength];
1468 double xData[fitLength];
1469 double yData[fitLength];
1470 cpl_polynomial *smoothFit = NULL;
1471 cpl_size firstCoeff = 0;
1472
1473 TRY
1474 {
1475 nc = 0;
1476 for (int cx = start; cx <= end; cx++) {
1477 if (cpl_polynomial_get_coeff(allFits[cx], &firstCoeff) != 0.) {
1478 cData[nc] = cx + .1;
1479 yData[nc] = cpl_polynomial_eval_1d( allFits[cx], 1024., NULL);
1480 nc++;
1481 }
1482 }
1483 //sort cData/yData pairs by yData values
1484 cpl_vector *xVec = cpl_vector_wrap(nc, cData);
1485 cpl_vector *yVec = cpl_vector_wrap(nc, yData);
1486 cpl_bivector *biVec = cpl_bivector_wrap_vectors(xVec, yVec);
1487 cpl_bivector_sort(biVec, biVec, CPL_SORT_ASCENDING, CPL_SORT_BY_Y);
1488 cpl_bivector_unwrap_vectors(biVec);
1489 cpl_vector_unwrap(xVec);
1490 cpl_vector_unwrap(yVec);
1491
1492 for (cpl_size power = 0; power <= fitDegree; power++) {
1493 for (int ix = 0; ix < nc; ix++) {
1494 int cx = (int) cData[ix];
1495 xData[ix] = cx;
1496 yData[ix] = cpl_polynomial_get_coeff(allFits[cx], &power);
1497 }
1498 // reject outliers
1499 smoothFit = eris_ifu_1d_polynomial_fit(nc - 4, &xData[2], &yData[2],
1500 SMOOTH_FIT_DEGREE);
1501 eris_ifu_wave_fill_coeff_table(smoothingCoeffTable,
1502 (COLUMN_FIT_DEGREE + 1) * sIdx + (int) power,
1503 sIdx, (int) power, smoothFit);
1504 for (int cx = start; cx <= end; cx++) {
1505 cpl_polynomial_set_coeff(allFits[cx], &power,
1506 cpl_polynomial_eval_1d(smoothFit, (double) cx, NULL));
1507 }
1508 eris_ifu_free_polynomial(&smoothFit);
1509 }
1510
1511 for (int cx = start; cx <= end; cx++) {
1512 eris_ifu_wave_fill_coeff_table(columnCoeffSmoothedTable, cx, cx, 0,
1513 allFits[cx]);
1514 }
1515 }
1516 CATCH {
1517 }
1518
1519 return retVal;
1520}
1521
1544 cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y],
1545 cpl_table *fitTable,
1546 ifsBand band)
1547{
1548 cpl_error_code retVal = CPL_ERROR_NONE;
1549 int col;
1550 double val;
1551 double wave;
1552 double waveError;
1553
1554 TRY
1555 {
1556 for (cpl_size row=0; row<cpl_table_get_nrow(fitTable); row++) {
1557 if (cpl_table_get_int(fitTable, ERIS_IFU_FITTABLE_ERRORCODE, row, NULL) != 0) {
1558 continue;
1559 }
1560 col = cpl_table_get_int(fitTable, "index", row, NULL);
1561 val = cpl_table_get_double(fitTable, "x0", row, NULL);
1562 wave = cpl_polynomial_eval_1d(allFits[col], val, NULL);
1563 waveError = cpl_table_get_double(fitTable, ERIS_IFU_FITTABLE_WAVELENGTH, row, NULL)-
1564 wave;
1565 cpl_table_set_double(fitTable, "wavelengthFit", row, wave);
1566 cpl_table_set_double(fitTable, "wavelengthError", row, waveError);
1568 }
1569 double dispersion;
1570 eris_ifu_get_dispersion(band, &dispersion);
1571 double convFactor = 2. * sqrt(2. * log(2.));
1572 cpl_table_duplicate_column(fitTable,"resol",fitTable,"wavelengthFit");
1573 cpl_table_divide_columns(fitTable,"resol","sigma");
1574 cpl_table_divide_scalar(fitTable,"resol", dispersion);
1575 cpl_table_divide_scalar(fitTable,"resol", convFactor);
1576
1577 }
1578 CATCH {
1579 }
1580 return retVal;
1581
1582}
1583
1608 cpl_image **collapsedSpectra,
1609 int aIdx,
1610 cpl_vector *collapsedSpectrum,
1611 int sIdx,
1612 cpl_size nRows,
1613 int lampStatus,
1614 ifsBand band,
1615 ifsInstrument instrument,
1616 cpl_bivector *refLines,
1617 int productDepth)
1618{
1619 const double *collapsedSpectrumData = NULL;
1620 static int slitletBlockIdx[SLITLET_BLOCK_CNT];
1621 int columnIdx = 0;
1622
1623 TRY
1624 {
1625 if (aIdx == 0) {
1626 /* TODO: One should save product in standard way.
1627 * But this is not yet working
1628 *
1629 cpl_dfs_save_propertylist(fs, NULL, parlist, fs,
1630 NULL, "eris_ifu_wavecal", NULL, NULL,
1631 PACKAGE "/" PACKAGE_VERSION,
1632 ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN);
1633 */
1634 if((productDepth & 1)) {
1635 cpl_image_save(NULL, ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1636 CPL_TYPE_DOUBLE,NULL,CPL_IO_CREATE);
1637 }
1638 }
1639 if (sIdx == 0) {
1640 for (int i=0; i<SLITLET_BLOCK_CNT; i++) {
1641 slitletBlockIdx[i] = 0;
1642 }
1644 collapsedSpectra[aIdx] = cpl_image_new(SLITLET_CNT, nRows,
1645 CPL_TYPE_DOUBLE));
1646 }
1647 collapsedSpectrumData =
1648 cpl_vector_get_data_const(collapsedSpectrum);
1649 switch (slitlet_block[sIdx]) {
1650 case 0:
1651 columnIdx = slitletBlockIdx[0];
1652 break;
1653 case 1:
1654 columnIdx = slitletBlockIdx[1] +
1655 SLITLET_BLOCK0_CNT;
1656 break;
1657 case 2:
1658 columnIdx = slitletBlockIdx[2] +
1659 SLITLET_BLOCK0_CNT + SLITLET_BLOCK1_CNT;
1660 break;
1661 case 3:
1662 columnIdx = slitletBlockIdx[3] +
1663 SLITLET_BLOCK0_CNT + SLITLET_BLOCK1_CNT +SLITLET_BLOCK2_CNT;
1664 break;
1665 default:
1666 columnIdx = -1;
1667 break;
1668 }
1669 slitletBlockIdx[slitlet_block[sIdx]]++;
1670 for (int row=0; row<nRows; row++) {
1672 cpl_image_set(collapsedSpectra[aIdx], columnIdx+1, row+1,
1673 collapsedSpectrumData[row]));
1674 }
1675 if ((sIdx >= SLITLET_CNT-1) && ((productDepth & 1) != 0)) {
1676 const char *instrumentString;
1677 char *lampString;
1678 if (instrument == SPIFFI) {
1679 instrumentString = "SINFONI";
1680 } else {
1681 instrumentString = "ERIS";
1682 }
1683 cpl_propertylist *hdr = cpl_propertylist_new();
1685 cpl_propertylist_update_string(hdr, CPL_DFS_PRO_CATG,
1686 ERIS_IFU_PRO_WAVE_COLLAP_SPECTR ));
1687 cpl_propertylist_append_string(hdr,"INSTRUME", instrumentString);
1688 lampString = eris_ifu_get_lampString(lampStatus);
1689 cpl_propertylist_append_string(hdr,"LAMPS", lampString);
1690 cpl_propertylist_append_string(hdr,"BAND",
1692 cpl_image_save(collapsedSpectra[aIdx], ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1693 CPL_TYPE_UNSPECIFIED, hdr, CPL_IO_EXTEND);
1695 cpl_free(lampString);
1696 cpl_vector_save(cpl_bivector_get_x(refLines), ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1697 CPL_TYPE_DOUBLE, NULL, CPL_IO_EXTEND);
1698 cpl_vector_save(cpl_bivector_get_y(refLines), ERIS_IFU_PRO_WAVE_COLLAP_SPECTR_FN,
1699 CPL_TYPE_DOUBLE, NULL, CPL_IO_EXTEND);
1700 }
1701 }
1702 CATCH
1703 {
1704
1705 }
1706 return;
1707}
1708
1727 const char* firstFitTableFileName,
1728 ifsInstrument instrument,
1729// int lampStatus,
1730 ifsBand band)
1731{
1732 cpl_table *firstFitTable = NULL;
1733 cpl_table *fullTable = NULL;
1734 cpl_size rowCnt;
1735 const char *instrumentString;
1736 const char* bandString;
1737
1738 TRY
1739 {
1740 if (instrument == SPIFFI) {
1741 instrumentString = "SINFONI";
1742 } else {
1743 instrumentString = "ERIS";
1744 }
1745 bandString = eris_ifu_get_bandString(band);
1746
1748 fullTable = cpl_table_load(firstFitTableFileName, 1, 0));
1749
1750 rowCnt = cpl_table_and_selected_string(fullTable,
1751 ERIS_IFU_FIRSTFIT_INSTRUMENT, CPL_EQUAL_TO, instrumentString);
1753 if (rowCnt < 1) {
1754 BRK_WITH_ERROR_MSG(CPL_ERROR_DATA_NOT_FOUND,
1755 "no records found in firstFits table with instrument %s",
1756 instrumentString);
1757 }
1758
1759 char *regExp = cpl_sprintf("^%s$", bandString);
1760 rowCnt = cpl_table_and_selected_string(fullTable,
1761 ERIS_IFU_FIRSTFIT_BAND, CPL_EQUAL_TO, regExp);
1763 eris_ifu_free_string(&regExp);
1764 if (rowCnt < 1) {
1765 BRK_WITH_ERROR_MSG(CPL_ERROR_DATA_NOT_FOUND,
1766 "no records found in firstFits table with band %s",
1767 bandString);
1768 }
1769 firstFitTable = cpl_table_extract_selected(fullTable);
1770 }
1771 CATCH
1772 {
1773 }
1774 eris_ifu_free_table(&fullTable);
1775
1776 return firstFitTable;
1777}
1778
1793cpl_error_code
1794eris_ifu_get_dispersion(ifsBand band, double* dispersion)
1795{
1796
1797 switch (band) {
1798 case J_SPIFFI:
1799 *dispersion = DISPERSION_J_SPIFFI;
1800 break;
1801 case H_SPIFFI:
1802 *dispersion = DISPERSION_H_SPIFFI;
1803 break;
1804 case K_SPIFFI:
1805 *dispersion = DISPERSION_K_SPIFFI;
1806 break;
1807 case HK_SPIFFI:
1808 *dispersion = DISPERSION_HK_SPIFFI;
1809 break;
1810 case J_LOW:
1811 *dispersion = DISPERSION_J_LOW;
1812 break;
1813 case J_SHORT:
1814 *dispersion = DISPERSION_J_SHORT;
1815 break;
1816 case J_MIDDLE:
1817 *dispersion = DISPERSION_J_MIDDLE;
1818 break;
1819 case J_LONG:
1820 *dispersion = DISPERSION_J_LONG;
1821 break;
1822 case H_LOW:
1823 *dispersion = DISPERSION_H_LOW;
1824 break;
1825 case H_SHORT:
1826 *dispersion = DISPERSION_H_SHORT;
1827 break;
1828 case H_MIDDLE:
1829 *dispersion = DISPERSION_H_MIDDLE;
1830 break;
1831 case H_LONG:
1832 *dispersion = DISPERSION_H_LONG;
1833 break;
1834 case K_LOW:
1835 *dispersion = DISPERSION_K_LOW;
1836 break;
1837 case K_SHORT:
1838 *dispersion = DISPERSION_K_SHORT;
1839 break;
1840 case K_MIDDLE:
1841 *dispersion = DISPERSION_K_MIDDLE;
1842 break;
1843 case K_LONG:
1844 *dispersion = DISPERSION_K_LONG;
1845 break;
1846 default:
1847
1848 break;
1849 }
1850
1851 return cpl_error_get_code();
1852}
1853
1854cpl_error_code
1855eris_ifu_get_central_lambda(ifsBand band, double* centralLambda)
1856{
1857
1858 switch (band) {
1859 case J_SPIFFI:
1860 *centralLambda = CENTRALLAMBDA_J_SPIFFI;
1861 break;
1862 case H_SPIFFI:
1863 *centralLambda = CENTRALLAMBDA_H_SPIFFI;
1864 break;
1865 case K_SPIFFI:
1866 *centralLambda = CENTRALLAMBDA_K_SPIFFI;
1867 break;
1868 case HK_SPIFFI:
1869 *centralLambda = CENTRALLAMBDA_HK_SPIFFI;
1870 break;
1871 case J_LOW:
1872 *centralLambda = CENTRALLAMBDA_J_LOW;
1873 break;
1874 case J_SHORT:
1875 *centralLambda = CENTRALLAMBDA_J_SHORT;
1876 break;
1877 case J_MIDDLE:
1878 *centralLambda = CENTRALLAMBDA_J_MIDDLE;
1879 break;
1880 case J_LONG:
1881 *centralLambda = CENTRALLAMBDA_J_LONG;
1882 break;
1883 case H_LOW:
1884 *centralLambda = CENTRALLAMBDA_H_LOW;
1885 break;
1886 case H_SHORT:
1887 *centralLambda = CENTRALLAMBDA_H_SHORT;
1888 break;
1889 case H_MIDDLE:
1890 *centralLambda = CENTRALLAMBDA_H_MIDDLE;
1891 break;
1892 case H_LONG:
1893 *centralLambda = CENTRALLAMBDA_H_LONG;
1894 break;
1895 case K_LOW:
1896 *centralLambda = CENTRALLAMBDA_K_LOW;
1897 break;
1898 case K_SHORT:
1899 *centralLambda = CENTRALLAMBDA_K_SHORT;
1900 break;
1901 case K_MIDDLE:
1902 *centralLambda = CENTRALLAMBDA_K_MIDDLE;
1903 break;
1904 case K_LONG:
1905 *centralLambda = CENTRALLAMBDA_K_LONG;
1906 break;
1907 default:
1908
1909 break;
1910 }
1911
1912 return cpl_error_get_code();
1913}
1914
1915
1946 const cpl_image *arcImg,
1947 const cpl_image *waveCalImg,
1948 ifsBand band,
1949 double minLambda,
1950 double maxLambda,
1951 cpl_propertylist *plist,
1952 int axisNumber)
1953{
1954 cpl_image *resampledImage = NULL;
1955 cpl_vector *arcImgCol = NULL;
1956 cpl_vector *calImgCol = NULL;
1957 double dispersion =0;
1958 double centralLambda = 0;
1959 double *lambdaIn = NULL;
1960 double *lambdaOut = NULL;
1961 double *aduIn = NULL;
1962 double *aduOut = NULL;
1963 cpl_size origNx;
1964 cpl_size origNy;
1965 char *propName = NULL;
1966
1967 TRY
1968 {
1969 ASSURE(arcImg != NULL,
1970 CPL_ERROR_NULL_INPUT, "no arc image provided");
1971 ASSURE(waveCalImg != NULL,
1972 CPL_ERROR_NULL_INPUT, "no wavelength calibration image provided");
1973 origNx = cpl_image_get_size_x(arcImg);
1974 origNy = cpl_image_get_size_y(arcImg);
1975 ASSURE(cpl_image_get_size_x(waveCalImg) == origNx,
1976 CPL_ERROR_INCOMPATIBLE_INPUT,
1977 "arc and wavecal image have different size");
1978 ASSURE(cpl_image_get_size_y(waveCalImg) == origNy,
1979 CPL_ERROR_INCOMPATIBLE_INPUT,
1980 "arc and wavecal image have different size");
1981
1982 eris_ifu_get_dispersion(band, &dispersion);
1983 eris_ifu_get_central_lambda(band, &centralLambda);
1984
1985 cpl_size nRows = (cpl_size) ((maxLambda - minLambda) / dispersion + .5);
1986 cpl_size centerRow = nRows / 2;
1987 double startLambda = centralLambda - dispersion * (double) centerRow;
1988
1990 resampledImage = cpl_image_new(origNx, nRows, CPL_TYPE_FLOAT));
1992 lambdaIn = cpl_malloc(sizeof(double) * origNy));
1994 aduIn = cpl_malloc(sizeof(double) * origNy));
1996 lambdaOut = cpl_malloc(sizeof(double) * nRows));
1998 aduOut = cpl_malloc(sizeof(double) * nRows));
1999
2000 // populate wavelength axis for resampled image
2001 for (int rx=0; rx<nRows; rx++) {
2002 lambdaOut[rx] = startLambda + dispersion * (double) rx;
2003 }
2004
2005 cpl_errorstate errorState;
2006 bool errorHappend = false;
2007
2008 for (int cx=0; cx<origNx; cx++) {
2009 // copy arc and wavecal columns and swap the columns
2010 arcImgCol = cpl_vector_new_from_image_column(arcImg, cx+1);
2011 calImgCol = cpl_vector_new_from_image_column(waveCalImg, cx+1);
2012 double *arcImgColData = cpl_vector_get_data(arcImgCol);
2013 double *calImgColData = cpl_vector_get_data(calImgCol);
2014 for (int rx=0; rx<origNy; rx++) {
2015 lambdaIn[rx] = calImgColData[origNy-rx-1];
2016 aduIn[rx] = arcImgColData[origNy-rx-1];
2017 }
2018
2019 int nDegree = -5;
2020/*
2021 BRK_IF_ERROR(
2022 eris_ifu_1d_interpolation(lambdaIn, aduIn, (int) origNy,
2023 lambdaOut, aduOut, (int) nRows, nDegree));
2024*/
2025 errorState = cpl_errorstate_get();
2026 if (eris_ifu_1d_interpolation(lambdaIn, aduIn, (int) origNy,
2027 lambdaOut, aduOut, (int) nRows, nDegree)
2028 != CPL_ERROR_NONE) {
2029 errorHappend = true;
2030 cpl_errorstate_set(errorState);
2031 }
2032 for (int rx = 0; rx < nRows; rx++) {
2033 cpl_image_set(resampledImage, cx + 1, rx + 1, aduOut[rx]);
2034 }
2035 eris_ifu_free_vector(&arcImgCol);
2036 eris_ifu_free_vector(&calImgCol);
2037 }
2038 if (errorHappend) {
2039 cpl_msg_error(__func__,
2040 "One or more columns of the arc images could not be resampled");
2041 }
2042
2043 propName = cpl_sprintf("CTYPE%d", axisNumber);
2044 cpl_propertylist_update_string(plist, propName, "WAVE");
2045 eris_ifu_free_string(&propName);
2046 propName = cpl_sprintf("CUNIT%d", axisNumber);
2047 cpl_propertylist_update_string(plist, propName, "um");
2048 eris_ifu_free_string(&propName);
2049 propName = cpl_sprintf("CRPIX%d", axisNumber);
2050 cpl_propertylist_update_double(plist, propName, 1.);
2051 eris_ifu_free_string(&propName);
2052 propName = cpl_sprintf("CRVAL%d", axisNumber);
2053 cpl_propertylist_update_double(plist, propName, lambdaOut[0]);
2054 eris_ifu_free_string(&propName);
2055 propName = cpl_sprintf("CDELT%d", axisNumber);
2056 cpl_propertylist_update_double(plist, propName, dispersion);
2057 eris_ifu_free_string(&propName);
2058 for (int ix=1; ix<=axisNumber; ix++) {
2059 propName = cpl_sprintf("CD%d_%d", axisNumber, ix);
2060 if (ix == axisNumber) {
2061 cpl_propertylist_update_double(plist, propName, dispersion);
2062 } else {
2063 cpl_propertylist_update_double(plist, propName, 0.);
2064 }
2065 eris_ifu_free_string(&propName);
2066 }
2068
2069 }
2070 CATCH
2071 {
2072 eris_ifu_free_vector(&arcImgCol);
2073 eris_ifu_free_vector(&calImgCol);
2074 resampledImage = NULL;
2075 }
2076 eris_ifu_free_double_array(&lambdaIn);
2078 eris_ifu_free_double_array(&lambdaOut);
2080 return resampledImage;
2081}
2082
2106 int arcImgCnt,
2107 const cpl_image **dataImg,
2108 const cpl_image *waveCalImg,
2109 ifsBand band,
2110 int *lampStates,
2111 cpl_frameset* frameset,
2112 const cpl_parameterlist* parlist) {
2113
2114 cpl_error_code retVal = CPL_ERROR_NONE;
2115 cpl_propertylist *plist = NULL;
2116 cpl_image *resampledImg = NULL;
2117 cpl_image *tmpImg = NULL;
2118 double minLambda = 0.;
2119 double maxLambda = 0.;
2120
2121 TRY
2122 {
2124 plist = cpl_propertylist_new());
2126 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG,
2127 ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED));
2128
2129 /* AMO: not necessary as header is set later by cpl_dfs_save_image , else one duplicate products
2130 eris_setup_product_header(ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED_FN,
2131 ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED,
2132 CPL_FRAME_TYPE_IMAGE, "eris_ifu_wavecal",
2133 frameset, parlist, plist);
2134 */
2136 tmpImg = cpl_image_new(1, 1, CPL_TYPE_INT));
2137 /* Save ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED_FN as final product (PIPE-10189) */
2138 char* pipe_id = cpl_sprintf("%s%s%s", PACKAGE, "/", PACKAGE_VERSION);
2139 cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, tmpImg,
2140 CPL_TYPE_UNSPECIFIED, REC_NAME_WAVECAL, plist, "RADECSYS",
2141 pipe_id, ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED_FN);
2142 cpl_free(pipe_id);
2143 maxLambda = cpl_image_get_max(waveCalImg);
2144 minLambda = cpl_image_get_min(waveCalImg);
2145
2146 for (int ix = 0; ix < arcImgCnt; ix++) {
2147
2148 // create resampled arc image
2150 resampledImg =
2152 waveCalImg, band, minLambda, maxLambda, plist, 2));
2153
2154 cpl_propertylist_update_string(plist, "CTYPE1", "PIXEL");
2155 cpl_propertylist_update_string(plist, "CUNIT1", "PIXEL");
2156 cpl_propertylist_update_double(plist, "CRPIX1", 1.);
2157 cpl_propertylist_update_double(plist, "CRVAL1", 1.);
2158 cpl_propertylist_update_double(plist, "CDELT1", 1.);
2159 char* lamp_string = eris_ifu_get_lampString(lampStates[ix]);
2160 cpl_propertylist_update_string(plist, "LAMPS",lamp_string);
2161 cpl_free(lamp_string);
2162 eris_ifu_save_image_dbg(resampledImg,
2163 ERIS_IFU_PRO_WAVE_LAMP_RESAMPLED_FN, CPL_IO_EXTEND,plist);
2164 eris_ifu_free_image(&resampledImg);
2165 }
2166
2167 }
2168 CATCH
2169 {
2170 retVal = cpl_error_get_code();
2171 CATCH_MSG();
2172 CATCH_MSGS();
2173 RECOVER();
2174 }
2175
2176 eris_ifu_free_image(&tmpImg);
2177 //eris_ifu_free_image(&resampledImg);
2179
2180 return retVal;
2181}
2182
2201 const char* filename,
2202 ifsBand band,
2203 struct waveSetupStruct *waveSetup)
2204{
2205 cpl_error_code retVal = CPL_ERROR_NONE;
2206 cpl_table *table = NULL;
2207 cpl_size row;
2208 const char* bandName;
2209 const char* rowBandName;
2210 bool found = FALSE;
2211 bool invalidColumnFound = FALSE;
2212 int n;
2213
2214 TRY
2215 {
2216 /* Rough init in case table load fails */
2217 (void)memset(waveSetup, 0, sizeof(*waveSetup));
2218 bandName = eris_ifu_get_bandString(band);
2220 table = cpl_table_load(filename, 1, 0));
2221 for (row = 0; row<cpl_table_get_nrow(table); row++) {
2222 rowBandName = cpl_table_get_string(table, "band", row);
2224 if (strcmp(bandName, rowBandName) == 0){
2225 if (found) {
2226 BRK_WITH_ERROR_MSG(CPL_ERROR_BAD_FILE_FORMAT,
2227 "There are more than row in the WAVE_SETUP with "
2228 "the same band name %s", bandName);
2229 }
2230 found = TRUE;
2231 waveSetup->fwhm =
2232 cpl_table_get_double(table, "fwhm", row, &n);
2233 if (n == 1) {
2234 invalidColumnFound = TRUE;
2235 }
2236 waveSetup->s_range =
2237 cpl_table_get_int(table, "s_range", row, &n);
2238 if (n == 1) {
2239 invalidColumnFound = TRUE;
2240 }
2241 waveSetup->c_range =
2242 cpl_table_get_int(table, "c_range", row, &n);
2243 if (n == 1) {
2244 invalidColumnFound = TRUE;
2245 }
2246 waveSetup->ri_dispersion =
2247 cpl_table_get_double(table, "ri_dispersion", row, &n);
2248 if (n == 1) {
2249 invalidColumnFound = TRUE;
2250 }
2251 waveSetup->ri_centralLambda =
2252 cpl_table_get_double(table, "ri_centrallambda", row,&n);
2254 double convFactor = 2. * sqrt(2. * log(2.));
2255 waveSetup->sigma = waveSetup->fwhm / convFactor;
2256 }
2257 }
2258 if (! found) {
2259 BRK_WITH_ERROR_MSG(CPL_ERROR_BAD_FILE_FORMAT,
2260 "There is no row in the WAVE_SETUP with the band name %s",
2261 bandName);
2262 }
2263 if (invalidColumnFound) {
2264 BRK_WITH_ERROR_MSG(CPL_ERROR_BAD_FILE_FORMAT,
2265 "There is an invalid column in the WAVE_SETUP "
2266 "with the band name %s",
2267 bandName);
2268 }
2269 }
2270 CATCH
2271 {
2272 }
2273 eris_ifu_free_table(&table);
2274 return retVal;
2275}
2276
2296 struct waveTablesStruct *tables)
2297{
2298 cpl_ensure_code(tables, CPL_ERROR_NULL_INPUT);
2299 cpl_error_code retVal = CPL_ERROR_NONE;
2300
2301 TRY
2302 {
2303 tables->slitletFitting = NULL;
2304 tables->columnFitting = NULL;
2305 tables->slitletCoeff = NULL;
2306 tables->columnCoeffRaw = NULL;
2307 tables->columnCoeffSmoothed = NULL;
2308 tables->smoothingCoeff = NULL;
2309
2310 tables->slitletFitting = eris_ifu_wave_create_fitting_table();
2311 tables->columnFitting = eris_ifu_wave_create_fitting_table();
2312 tables->slitletCoeff = eris_ifu_wave_create_coeff_table(
2313 SLITLET_CNT, FIRST_FIT_DEGREE);
2314 tables->columnCoeffRaw = eris_ifu_wave_create_coeff_table(
2315 ERIS_IFU_DETECTOR_SIZE_X, COLUMN_FIT_DEGREE);
2316 tables->columnCoeffSmoothed = eris_ifu_wave_create_coeff_table(
2317 ERIS_IFU_DETECTOR_SIZE_X, COLUMN_FIT_DEGREE);
2318 tables->smoothingCoeff = eris_ifu_wave_create_coeff_table(
2319 SLITLET_CNT * (COLUMN_FIT_DEGREE + 1), SMOOTH_FIT_DEGREE);
2321
2322 }
2323 CATCH
2324 {
2325 }
2326 return retVal;
2327}
2328
2346{
2347
2348 cpl_table *table = NULL;
2349
2350 TRY
2351 {
2353 table = cpl_table_new(0));
2354 cpl_table_new_column(table, ERIS_IFU_FITTABLE_SLITLET, CPL_TYPE_INT);
2355 cpl_table_new_column(table, ERIS_IFU_FITTABLE_INDEX, CPL_TYPE_INT);
2356 cpl_table_new_column(table, "imgIdx", CPL_TYPE_INT);
2357 cpl_table_new_column(table, ERIS_IFU_FITTABLE_POSITION, CPL_TYPE_INT);
2358 cpl_table_new_column(table, ERIS_IFU_FITTABLE_WAVELENGTH, CPL_TYPE_DOUBLE);
2359 cpl_table_new_column(table, ERIS_IFU_FITTABLE_ERRORCODE, CPL_TYPE_INT);
2360 cpl_table_new_column(table, "x0", CPL_TYPE_DOUBLE);
2361 cpl_table_new_column(table, "sigma", CPL_TYPE_DOUBLE);
2362 cpl_table_new_column(table, "area", CPL_TYPE_DOUBLE);
2363 cpl_table_new_column(table, "offset", CPL_TYPE_DOUBLE);
2364 cpl_table_new_column(table, "mse", CPL_TYPE_DOUBLE);
2365 cpl_table_new_column(table, "wavelengthFit", CPL_TYPE_DOUBLE);
2366 cpl_table_new_column(table, "wavelengthError", CPL_TYPE_DOUBLE);
2367 cpl_table_new_column(table, "range", CPL_TYPE_INT);
2368 cpl_table_new_column_array(table, "xdata", CPL_TYPE_DOUBLE,
2369 GAUSS_PAR_RANGE_MAX);
2370 cpl_table_new_column_array(table, "ydata", CPL_TYPE_DOUBLE,
2371 GAUSS_PAR_RANGE_MAX);
2373 }
2374 CATCH
2375 {
2376
2377 }
2378 return table;
2379
2380}
2381
2402 cpl_table *table,
2403 int row,
2404 int slitlet,
2405 int index,
2406 int arcImgIdx,
2407 int position,
2408 double wavelength,
2409 struct gaussParStruct *gaussPar)
2410{
2411 cpl_error_code retVal = CPL_ERROR_NONE;
2412 cpl_array *xArray;
2413 cpl_array *yArray;
2414
2415 TRY
2416 {
2417 cpl_table_set_int(table, ERIS_IFU_FITTABLE_SLITLET, row, slitlet);
2418 cpl_table_set_int(table, ERIS_IFU_FITTABLE_INDEX, row, index);
2419 cpl_table_set_int(table, "imgIdx", row, arcImgIdx);
2420 cpl_table_set_int(table, ERIS_IFU_FITTABLE_POSITION, row, position);
2421 cpl_table_set_double(table, ERIS_IFU_FITTABLE_WAVELENGTH, row, wavelength);
2422 cpl_table_set_int(table, ERIS_IFU_FITTABLE_ERRORCODE, row, gaussPar->errorCode);
2423 cpl_table_set_double(table, "x0", row, gaussPar->x0);
2424 cpl_table_set_double(table, "sigma", row, gaussPar->sigma);
2425 cpl_table_set_double(table, "area", row, gaussPar->area);
2426 cpl_table_set_double(table, "offset", row, gaussPar->offset);
2427 cpl_table_set_double(table, "mse", row, gaussPar->mse);
2428 cpl_table_set_int(table, "range", row, gaussPar->range);
2430 // clear data beyond range to allow reference testing;
2431 for (int ix=gaussPar->range; ix<GAUSS_PAR_RANGE_MAX; ix++) {
2432 gaussPar->xdata[ix] = 0.0;
2433 gaussPar->ydata[ix] = 0.0;
2434 }
2436 xArray = cpl_array_wrap_double(gaussPar->xdata,
2437 GAUSS_PAR_RANGE_MAX));
2439 yArray = cpl_array_wrap_double(gaussPar->ydata,
2440 GAUSS_PAR_RANGE_MAX));
2441 cpl_table_set_array(table, "xdata", row, xArray);
2442 cpl_table_set_array(table, "ydata", row, yArray);
2443 cpl_array_unwrap(xArray);
2444 cpl_array_unwrap(yArray);
2445
2446 }
2447 CATCH
2448 {
2449
2450 }
2451 return retVal;
2452}
2453
2469 int size, int polynomialDegree)
2470{
2471
2472 cpl_table *table = NULL;
2473
2474 TRY
2475 {
2477 table = cpl_table_new(size));
2478 cpl_table_new_column(table, "slitlet", CPL_TYPE_INT);
2479 cpl_table_new_column(table, "nlines", CPL_TYPE_INT);
2480 cpl_table_new_column(table, "degree", CPL_TYPE_INT);
2481 cpl_table_new_column_array(table, "coeffs", CPL_TYPE_DOUBLE,
2482 polynomialDegree+1);
2484 }
2485 CATCH
2486 {
2487
2488 }
2489 return table;
2490
2491}
2492
2493
2509 cpl_table *table,
2510 int row,
2511 int idx,
2512 int nLines,
2513 cpl_polynomial *polynomial)
2514{
2515 cpl_error_code retVal = CPL_ERROR_NONE;
2516 cpl_array *array;
2517 cpl_size arrayDim;
2518 cpl_size degree;
2519
2520 TRY
2521 {
2522 degree = cpl_polynomial_get_degree(polynomial);
2523 arrayDim = cpl_table_get_column_dimension (table, "coeffs", 0);
2524 array = cpl_array_new(arrayDim, CPL_TYPE_DOUBLE);
2526
2527 cpl_table_set_int(table, "slitlet", row, idx);
2528 cpl_table_set_int(table, "nlines", row, nLines);
2529 cpl_table_set_int(table, "degree", row, (int) degree);
2530 for (cpl_size ix=0; ix<=degree; ix++) {
2531 cpl_array_set_double(array, ix,
2532 cpl_polynomial_get_coeff(polynomial, &ix));
2533 }
2534 cpl_table_set_array(table, "coeffs", row, array);
2535 cpl_array_delete(array);
2536
2537 }CATCH {
2538 CATCH_MSGS();
2539 }
2540 return retVal;
2541}
2542
2573 struct waveTablesStruct *tables,
2574 ifsInstrument instrument,
2575 ifsBand band,
2576 struct waveSetupStruct waveSetup,
2577 cpl_frameset* frameset,
2578 const cpl_parameterlist* parlist,
2579 const char* recipe_name)
2580{
2581 cpl_error_code retVal = CPL_ERROR_NONE;
2582 cpl_propertylist *phdr = NULL;
2583 cpl_propertylist *hdr = NULL;
2584 const char* filename = ERIS_IFU_PRO_WAVE_FIT_TABLES_FN;
2585 const char* extname = "EXTNAME";
2586 const char *instrString;
2587 const char *bandString;
2588 int ioMode = CPL_IO_CREATE;
2589
2590 TRY
2591 {
2592 switch (instrument) {
2593 case SPIFFIER:
2594 instrString = "ERIS";
2595 break;
2596 case SPIFFI:
2597 instrString = "SINFONI";
2598 break;
2599 default:
2600 instrString = "UNKNOWN";
2601 break;
2602 }
2603 bandString = eris_ifu_get_bandString(band);
2604
2606 hdr = cpl_propertylist_new());
2608 phdr = cpl_propertylist_new());
2610 cpl_propertylist_update_string(phdr, CPL_DFS_PRO_CATG,
2611 ERIS_IFU_PRO_WAVE_FIT_TABLES));
2613 cpl_propertylist_update_string(phdr, "INSTRUME", instrString));
2615 cpl_propertylist_update_string(phdr, "BAND", bandString));
2617 cpl_propertylist_update_int(phdr, "SRANGE", waveSetup.s_range));
2619 cpl_propertylist_update_int(phdr, "CRANGE", waveSetup.c_range));
2620 /* AMO added to have proper FITS header */
2621 eris_setup_product_header(filename, ERIS_IFU_PRO_WAVE_FIT_TABLES,
2622 CPL_FRAME_TYPE_IMAGE, recipe_name,
2623 frameset, parlist, phdr);
2624
2625 if (tables->slitletFitting != NULL) {
2627 cpl_propertylist_update_string(
2628 hdr, extname, "slitletFittingTable"));
2630 cpl_table_name_column(tables->slitletFitting, "index", "block"));
2632 cpl_table_save(tables->slitletFitting,
2633 phdr, hdr, filename, ioMode));
2634 ioMode = CPL_IO_EXTEND;
2635 }
2636
2637 if (tables->columnFitting != NULL) {
2639 cpl_propertylist_update_string(
2640 hdr, extname, "columnFittingTable"));
2642 cpl_table_name_column(tables->columnFitting, "index", "column"));
2644 cpl_table_save(tables->columnFitting,
2645 phdr, hdr, filename, ioMode));
2646 ioMode = CPL_IO_EXTEND;
2647 }
2648
2649 if (tables->columnCoeffRaw != NULL) {
2651 cpl_propertylist_update_string(
2652 hdr, extname, "slitletCoeff"));
2654 cpl_table_save(tables->slitletCoeff,
2655 phdr, hdr, filename, ioMode));
2656
2658 cpl_propertylist_update_string(
2659 hdr, extname, "columnCoeffRaw"));
2661 cpl_table_save(tables->columnCoeffRaw,
2662 phdr, hdr, filename, ioMode));
2663 ioMode = CPL_IO_EXTEND;
2664 }
2665
2666 if (tables->columnCoeffSmoothed != NULL) {
2668 cpl_propertylist_update_string(
2669 hdr, extname, "columnCoeffSmoothed"));
2671 cpl_table_name_column(tables->columnCoeffSmoothed, "nlines", "dummy"));
2673 cpl_table_save(tables->columnCoeffSmoothed,
2674 phdr, hdr, filename, ioMode));
2675 ioMode = CPL_IO_EXTEND;
2676 }
2677
2678 if (tables->smoothingCoeff != NULL) {
2680 cpl_propertylist_update_string(
2681 hdr, extname, "smoothingCoeff"));
2683 cpl_table_name_column(tables->smoothingCoeff, "nlines", "order"));
2685 cpl_table_save(tables->smoothingCoeff,
2686 phdr, hdr, filename, ioMode));
2687 ioMode = CPL_IO_EXTEND;
2688 }
2689
2690 // check whether no table was written
2691 if (ioMode == CPL_IO_CREATE) {
2692 // create an "empty" FITS file
2694 cpl_image_save(NULL, filename, CPL_TYPE_FLOAT, phdr, ioMode));
2695 }
2696
2697 }
2698 CATCH
2699 {
2700
2701 }
2704 return retVal;
2705}
2706
2716 struct waveTablesStruct *tables)
2717{
2718 eris_ifu_free_table(&tables->slitletFitting);
2719 eris_ifu_free_table(&tables->columnFitting);
2720 eris_ifu_free_table(&tables->slitletCoeff);
2721 eris_ifu_free_table(&tables->columnCoeffRaw);
2722 eris_ifu_free_table(&tables->columnCoeffSmoothed);
2723 eris_ifu_free_table(&tables->smoothingCoeff);
2724 return;
2725}
2726
2737 struct waveTablesStruct *tables)
2738{
2739 tables->slitletFitting = NULL;
2740 tables->columnFitting = NULL;
2741 tables->slitletCoeff = NULL;
2742 tables->columnCoeffRaw = NULL;
2743 tables->columnCoeffSmoothed = NULL;
2744 tables->smoothingCoeff = NULL;
2745 return;
2746}
2747
cpl_error_code eris_ifu_get_dispersion(ifsBand band, double *dispersion)
Get spectral dispersion for instrument band.
cpl_polynomial * eris_ifu_get_first_fit(cpl_image **spectra, int *lampStates, int spectrumCnt, int slitlet, int ffOffsetIn, int *ffOffsetOut, struct waveSetupStruct waveSetup, cpl_table *firstFitTable, cpl_table *fittingDumpTable, cpl_table *coeffDumpTable)
Generate initial wavelength fit for a slitlet.
cpl_error_code eris_ifu_wave_fill_fitting_table(cpl_table *table, int row, int slitlet, int index, int arcImgIdx, int position, double wavelength, struct gaussParStruct *gaussPar)
Fill fitting table row with Gaussian fit results.
cpl_table * eris_ifu_wave_create_coeff_table(int size, int polynomialDegree)
Create coefficient table for polynomial fits.
cpl_error_code eris_ifu_wave_get_arc_images(cpl_frameset *arcFrames, int exposureCorrectionMode, int *arcImgCnt, hdrl_imagelist **arcImages, int **lampStates, ifsBand *band, ifsPreopticsScale *scale, ifsInstrument *instrument, double saturation_threshold, cpl_table **qclog)
Load and preprocess arc lamp images for wavelength calibration.
void eris_ifu_wave_save_spectrum(cpl_image **collapsedSpectra, int aIdx, cpl_vector *collapsedSpectrum, int sIdx, cpl_size nRows, int lampStatus, ifsBand band, ifsInstrument instrument, cpl_bivector *refLines, int productDepth)
Save collapsed spectrum to product file.
cpl_bivector * eris_ifu_wave_get_refLines(const char *refLineTableFileName, ifsInstrument instrument, int lampState)
Load reference arc line wavelengths for specified lamp configuration.
cpl_image * eris_ifu_wave_get_calImg(int arcImagesCnt, hdrl_imagelist *arcImages, int *lampStates, ifsBand band, ifsInstrument instrument, struct waveSetupStruct waveSetup, const char *refLineTableFileName, const char *firstFitTableFileName, cpl_bivector *slitPos, struct waveTablesStruct *tables, int productDepth, cpl_frameset *fs, const cpl_parameterlist *parlist, cpl_table *qclog)
Generate wavelength calibration image from arc lamp data.
void eris_ifu_wave_free_tables(struct waveTablesStruct *tables)
Free all wavelength fitting tables.
hdrl_image * eris_ifu_wave_collapse_arc_images(cpl_table *darkTable, cpl_table *litTable, int lampState, float dit, int exposureCorrectionMode, double threshold, cpl_table **qclog)
Collapse multiple arc images with dark subtraction.
cpl_error_code eris_ifu_wave_smooth_coeffs(int sIdx, int start, int end, int fitDegree, cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y], cpl_table *columnCoeffSmoothedTable, cpl_table *smoothingCoeffTable)
Smooth polynomial coefficients across detector columns.
cpl_error_code eris_ifu_save_resampled_arc_images(int arcImgCnt, const cpl_image **dataImg, const cpl_image *waveCalImg, ifsBand band, int *lampStates, cpl_frameset *frameset, const cpl_parameterlist *parlist)
Save resampled arc images as FITS product.
cpl_table * eris_ifu_wave_create_fitting_table(void)
Create fitting table for line fit results.
cpl_error_code eris_ifu_wave_pos_err(cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y], cpl_table *fitTable, ifsBand band)
Compute wavelength errors and spectral resolution.
cpl_error_code eris_ifu_fit_all_lines(const char *recipe_name, int sIdx, const double *slitletStart, const double *slitletEnd, int arcImgCnt, const cpl_image **dataImg, cpl_bivector **refLines, struct waveSetupStruct waveSetup, cpl_polynomial *firstFit, cpl_polynomial *allFits[ERIS_IFU_DETECTOR_SIZE_Y], cpl_table *dumpTable, cpl_table *columnCoeffRawTable, cpl_table *columnCoeffSmoothedTable, cpl_table *smoothingCoeffTable)
Fit all reference lines in a slitlet across detector columns.
void eris_ifu_wave_clear_tables(struct waveTablesStruct *tables)
Clear wavelength table pointers without freeing.
cpl_image * eris_ifu_wave_resampled_arc_image(const cpl_image *arcImg, const cpl_image *waveCalImg, ifsBand band, double minLambda, double maxLambda, cpl_propertylist *plist, int axisNumber)
Resample arc image to uniform wavelength grid.
cpl_error_code eris_ifu_wave_init_tables(struct waveTablesStruct *tables)
Initialize wavelength fitting tables.
cpl_error_code eris_ifu_wave_save_fitting_tables(struct waveTablesStruct *tables, ifsInstrument instrument, ifsBand band, struct waveSetupStruct waveSetup, cpl_frameset *frameset, const cpl_parameterlist *parlist, const char *recipe_name)
Save all wavelength fitting tables to FITS file.
cpl_vector * eris_ifu_wave_collapse_slitlet(const cpl_image *dataImg, int center)
Collapse slitlet spatially to create 1D spectrum.
cpl_error_code eris_ifu_read_wave_setup(const char *filename, ifsBand band, struct waveSetupStruct *waveSetup)
Read wavelength setup parameters from configuration file.
cpl_table * eris_ifu_wave_get_firstFitTable(const char *firstFitTableFileName, ifsInstrument instrument, ifsBand band)
Load first fit table for instrument and band.
cpl_error_code eris_ifu_wave_fill_coeff_table(cpl_table *table, int row, int idx, int nLines, cpl_polynomial *polynomial)
Fill coefficient table row with polynomial data.
ifsPreopticsScale eris_ifu_get_preopticsScale(cpl_propertylist *header)
Return the the pre-optics scaling.
float eris_ifu_get_dit(cpl_propertylist *header)
Get the detector integration time (DIT) from FITS header.
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_polynomial * eris_ifu_1d_polynomial_fit(int nPoints, double *xdata, double *ydata, int degree)
Fit a 1D polynomial to arrays of data points.
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)
Load a raw detector exposure from file with corrections and noise.
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)
Convert lamp status bitmask to string.
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)
Save image for debugging (quick, no DFS overhead)
void eris_ifu_free_table(cpl_table **item)
Free memory and set pointer to null.
const char * eris_ifu_get_bandString(ifsBand band)
Convert band enum to string.
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
Definition: hdrl_image.c:391
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
Definition: hdrl_image.c:105
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:118
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
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.