ERIS Pipeline Reference Manual 1.8.15
eris_ifu_wavecal.c
1/* $Id: eris_ifu_recipe.c,v 1.33 2013-03-26 17:00:45 jtaylor Exp $
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
21/*
22 * $Author: jtaylor $
23 * $Date: 2013-03-26 17:00:45 $
24 * $Revision: 1.33 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35#include <cpl.h>
36
37#include "eris_utils.h"
38#include "eris_pfits.h"
39#include "eris_dfs.h"
40#include "eris_ifu_dfs.h"
41#include "eris_ifu_utils.h"
42#include "eris_ifu_error.h"
43#include "eris_ifu_wavecal_static.h"
44#include "eris_ifu_distortion_static.h"
45
46/*-----------------------------------------------------------------------------
47 Static variables
48 -----------------------------------------------------------------------------*/
49static const char eris_ifu_wavecal_description[] = "\
50This recipe performs ERIS/SPIFFIER wavelength calibration data reduction.\n\
51\n\
52-----------------------------------------------------------------------------\n\
53Input files:\n\
54 DO CATG Explanation Required #Frames\n\
55 ------- ----------- -------- -------\n\
56 WAVE_LAMP Arclamp on/off exposures Y 2 \n\
57 DISTORTION Table with distortion correction parameters Y 1 \n\
58 REF_LINE_ARC Band-specific reference arc line list Y 1 \n\
59 WAVE_SETUP Table to configure wave calibration Y 1 \n\
60 FIRST_WAVE_FIT Table for the first attempt to fit ARClines Y 1 \n\
61 SLITLET_POS Table with slitlet edge positions N [0,1]\n\
62 MASTER_FLAT Optional master flat image N [0,1]\n\
63\n\
64Output files:\n\
65 DO CATG Explanation\n\
66 ------- -----------\n\
67 WAVE_MAP Wavelength calibrarion map\n\
68----------------------------------------------------------------------------\n\
69\n\
70Information on relevant parameters may be found with\n\
71 esorex --params "REC_NAME_WAVECAL"\n\
72 esorex --help "REC_NAME_WAVECAL"\n";
73
74/*-----------------------------------------------------------------------------
75 Private function prototypes
76 -----------------------------------------------------------------------------*/
77
78cpl_recipe_define(eris_ifu_wavecal, ERIS_BINARY_VERSION, "Erich Wiezorrek",
79 PACKAGE_BUGREPORT, "2018",
80 "This recipe performs the wavelength calibration",
81 eris_ifu_wavecal_description);
82
83cpl_error_code eris_ifu_wavecal_fetch_params(
84 const cpl_parameterlist * parlist,
85 struct stdParamStruct *stdParams );
86
87cpl_error_code eris_ifu_wavecal_processSof(
88 cpl_frameset* frames,
89 int exposureCorrectionMode,
90 double saturation_threhold,
91 int *arcImgCnt,
92 hdrl_imagelist **arcImages,
93 int **lampStates,
94 ifsBand *band,
95 ifsPreopticsScale *scale,
96 ifsInstrument *instrument,
97 cpl_bivector **slitPos,
98 cpl_table** qclog
99 );
100
101static cpl_propertylist * eris_ifu_wave_get_qc_params(const ifsBand band,
102 cpl_table* qclog, struct waveTablesStruct *tables);
103
104cpl_error_code eris_ifu_wave_save_products(
105 cpl_image *waveCalImg,
106 cpl_propertylist *applist,
107 cpl_frameset *frameset,
108 const cpl_parameterlist *parlist);
109
110/*-----------------------------------------------------------------------------
111 Function code
112 -----------------------------------------------------------------------------*/
113
114/*----------------------------------------------------------------------------*/
122/*----------------------------------------------------------------------------*/
123static cpl_error_code eris_ifu_wavecal_fill_parameterlist(cpl_parameterlist *pl)
124{
125 cpl_error_code err = CPL_ERROR_NONE;
126
127 TRY
128 {
130 eris_ifu_add_std_params(pl, REC_NAME_WAVECAL));
131 } CATCH {
132 CATCH_MSGS();
133 err = cpl_error_get_code();
134 }
135
136 return err;
137}
138
139/*----------------------------------------------------------------------------*/
146/*----------------------------------------------------------------------------*/
147static int eris_ifu_wavecal(cpl_frameset * frameset,
148 const cpl_parameterlist * parlist)
149{
150 int arcImgCnt = 0;
151 int *lampStates = NULL;
152 ifsBand band = UNDEFINED_BAND;
153 ifsPreopticsScale scale = UNDEFINED_SCALE;
154 ifsInstrument instrument = UNSET_INSTRUMENT;
155 struct stdParamStruct stdParams = stdParamStructInit;
156
157 hdrl_imagelist *arcImages = NULL;
158 const char *refLineTableFileName = NULL;
159 const char *firstFitTableFileName = NULL;
160 const char *waveSetupFileName = NULL;
161 cpl_bivector *slitPos = NULL;
162 cpl_image *waveCalImg = NULL;
163 cpl_propertylist *applist = NULL;
164 struct waveTablesStruct tables;
165 struct waveSetupStruct waveSetup;
166 cpl_table* qclog = NULL;
167 double saturation_threshold = 0;
168
169
170 /* check required input tags are present */
171 /* temporarily suppressed check on required input tags
172 const int ntags = 6;
173 const char* required_tags[6] = {
174 ERIS_IFU_PRO_DIST_DISTORTION,
175 ERIS_IFU_CALIB_FIRST_FIT,
176 ERIS_IFU_CALIB_REF_LINES,
177 ERIS_IFU_CALIB_WAVE_SETUP,
178 ERIS_IFU_CALIB_REF_LINES,
179 ERIS_IFU_RAW_ARC_LAMP
180 };
181
182
183 cpl_ensure_code(CPL_ERROR_NONE ==
184 eris_dfs_check_input_tags(frameset, required_tags, ntags, 1),
185 CPL_ERROR_ILLEGAL_INPUT);
186 */
187
188 const int nopt_tags = 1;
189 const char* optional_tags[1] = {ERIS_IFU_CALIB_FLATFIELD
190 };
191 eris_dfs_check_input_tags(frameset, optional_tags, nopt_tags, 0);
192
193
194 TRY
195 {
196 // make sure there is no nonsense in the table structure
197 // in case it is written before filled properly
199
200 cpl_msg_info(cpl_func, "Reading recipe parameters");
202 eris_ifu_wavecal_fetch_params(parlist, &stdParams));
203 cpl_msg_info(cpl_func,
204 "Instrument is %d, requested product level is %d",
205 stdParams.instrument, stdParams.productDepth);
206
207 eris_print_rec_status(0);
208 saturation_threshold = cpl_parameter_get_double(
209 cpl_parameterlist_find_const(parlist, "eris.eris_ifu_wavecal.pixel_saturation"));
210 eris_print_rec_status(1);
212 eris_ifu_wavecal_processSof(
213 frameset,
214 stdParams.rawImageCorrectionMask,
215 saturation_threshold,
216 &arcImgCnt,
217 &arcImages,
218 &lampStates,
219 &band,
220 &scale,
221 &instrument,
222 &slitPos,
223 &qclog
224 ));
225
226 refLineTableFileName = cpl_frame_get_filename(
227 cpl_frameset_find(frameset, ERIS_IFU_CALIB_REF_LINES));
228 firstFitTableFileName = cpl_frame_get_filename(
229 cpl_frameset_find(frameset, ERIS_IFU_CALIB_FIRST_FIT));
230 waveSetupFileName = cpl_frame_get_filename(
231 cpl_frameset_find(frameset, ERIS_IFU_CALIB_WAVE_SETUP));
233
235 eris_ifu_read_wave_setup(waveSetupFileName, band, &waveSetup));
238
240 waveCalImg = eris_ifu_wave_get_calImg(
241 arcImgCnt,
242 arcImages,
243 lampStates,
244 band,
245 instrument,
246 waveSetup,
247 refLineTableFileName,
248 firstFitTableFileName,
249 slitPos,
250 &tables,
251 stdParams.productDepth,
252 frameset,
253 parlist,
254 qclog)
255 );
256
257 if ((stdParams.productDepth & 1) != 0) {
259 eris_ifu_wave_save_fitting_tables(&tables, instrument, band,
260 waveSetup, frameset, parlist,
261 "eris_ifu_wavecal"));
262 }
263
264
265 applist = eris_ifu_wave_get_qc_params(band, qclog, &tables);
266
267 eris_ifu_wave_save_products(waveCalImg, applist, frameset, parlist);
268
270 } CATCH
271 {
272 if ((stdParams.productDepth & 1) != 0) {
273 eris_ifu_wave_save_fitting_tables(&tables, instrument, band,
274 waveSetup, frameset, parlist,
275 "eris_ifu_wavecal");
276 }
277// CATCH_MSGS();
278 }
279 cpl_table_delete(qclog);
280 eris_ifu_free_bivector(&slitPos);
281 eris_ifu_free_int_array(&lampStates);
283 eris_ifu_free_image(&waveCalImg);
286 eris_ifu_free_std_param(&stdParams);
287
288 return (int)cpl_error_get_code();
289}
290
291/*----------------------------------------------------------------------------*/
301/*----------------------------------------------------------------------------*/
302cpl_error_code eris_ifu_wavecal_fetch_params(
303 const cpl_parameterlist * parlist,
304 struct stdParamStruct *stdParams )
305{
306 TRY
307 {
309 eris_ifu_fetch_std_param(parlist, REC_NAME_WAVECAL, stdParams));
310 } CATCH
311 {
312 CATCH_MSGS();
313 }
314
315 return cpl_error_get_code();
316}
317/*----------------------------------------------------------------------------*/
335/*----------------------------------------------------------------------------*/
336cpl_error_code eris_ifu_wavecal_processSof(
337 cpl_frameset* frames,
338 int exposureCorrectionMode,
339 double saturation_threhold,
340 int *arcImgCnt,
341 hdrl_imagelist **arcImages,
342 int **lampStates,
343 ifsBand *band,
344 ifsPreopticsScale *scale,
345 ifsInstrument *instrument,
346 cpl_bivector **slitPos,
347 cpl_table** qclog
348 )
349{
350 cpl_frame *frame = NULL;
351 hdrl_image *flatfieldImage = NULL;
352 cpl_image *flatfieldMask;
353 cpl_polynomial *poly_u = NULL;
354 cpl_polynomial *poly_v = NULL;
355
356 TRY
357 {
358 if (frames == NULL) {
359 BRK_WITH_ERROR_MSG(CPL_ERROR_NULL_INPUT,
360 "missing frameset");
361 }
362 if (cpl_frameset_is_empty(frames)) {
363 BRK_WITH_ERROR_MSG(CPL_ERROR_NULL_INPUT,
364 "SOF file is empty or missing");
365 }
367
370
371 // get arc lamp image
372 cpl_frameset *arcFrames = NULL;
373
374 if (cpl_frameset_count_tags(frames, ERIS_IFU_RAW_ARC_LAMP) > 0) {
375 arcFrames = eris_ifu_get_frameset_by_tag(frames,
376 ERIS_IFU_RAW_ARC_LAMP);
377 } else if ( (cpl_frameset_count_tags(frames, ERIS_IFU_RAW_ARC_LAMP_ON) > 0) &&
378 (cpl_frameset_count_tags(frames, ERIS_IFU_RAW_ARC_LAMP_OFF) > 0) ) {
379
380 cpl_frameset* arcFrames_off = NULL;
381 arcFrames = eris_ifu_get_frameset_by_tag(frames, ERIS_IFU_RAW_ARC_LAMP_ON);
382
383 arcFrames_off = eris_ifu_get_frameset_by_tag(frames, ERIS_IFU_RAW_ARC_LAMP_OFF);
384
385 cpl_frameset_join(arcFrames, arcFrames_off);
386 cpl_frameset_delete(arcFrames_off);
387 }
388
391 exposureCorrectionMode,
392 arcImgCnt,
393 arcImages,
394 lampStates,
395 band,
396 scale,
397 instrument,
398 saturation_threhold,
399 qclog));
400 cpl_frameset_delete(arcFrames);
401 //PIPPO
402 // get reference lines
403 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_REF_LINES);
405 if (frame == NULL) {
406 BRK_WITH_ERROR_MSG(CPL_ERROR_NULL_INPUT,
407 "missing \"%s\" tag in the SOF, arc lamp reference lines",
408 ERIS_IFU_CALIB_REF_LINES);
409 }
410
411 // get flat field calibration file (which is not required)
412 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_FLATFIELD);
413 if (frame != NULL) {
414 deqQualityType qualityType;
416 flatfieldImage = eris_ifu_load_cal_image_frame(frame,
417 *band, *scale, &flatfieldMask, &qualityType));
418 cpl_msg_info(cpl_func,"Apply master flat to each input arc frame");
420 hdrl_imagelist_div_image(*arcImages, flatfieldImage));
421 eris_ifu_free_hdrl_image(&flatfieldImage);
422 eris_ifu_free_image(&flatfieldMask);
423 }
424
425 frame = cpl_frameset_find(frames, ERIS_IFU_CALIB_DISTORTION);
427 if (frame == NULL) {
428 BRK_WITH_ERROR_MSG(CPL_ERROR_NULL_INPUT,
429 "missing \"%s\" tag in the SOF, distortion polynomials",
430 ERIS_IFU_CALIB_DISTORTION);
431 }
432 if (cpl_fits_count_extensions(cpl_frame_get_filename(frame)) > 2) {
433 cpl_polynomial **distortion;
434 cpl_table *borders;
437 cpl_frame_get_filename(frame),
438 &distortion, &borders));
439 cpl_msg_info(cpl_func,"Correct distortions on each input arc frame");
440 for (cpl_size pos=0; pos<*arcImgCnt; pos++) {
441 hdrl_image *inImage = hdrl_imagelist_get(*arcImages, pos);
442 hdrl_image *tmpImage = eris_ifu_dist_warp_image(
443 inImage, distortion, borders);
444 hdrl_imagelist_set(*arcImages, tmpImage, pos);
446 }
447 for (cpl_size sc=0; sc < SLITLET_CNT; sc++) {
448 cpl_polynomial_delete(distortion[sc]);
449 }
450 cpl_free(distortion);
451 cpl_table_delete(borders);
452
453 } else {
456 cpl_frame_get_filename(frame), &poly_u, &poly_v));
457 // cpl_polynomial_dump(poly_u,stdout);
458 // cpl_polynomial_dump(poly_v,stdout);
459 for (cpl_size pos=0; pos<*arcImgCnt; pos++) {
460 hdrl_image *inImage = hdrl_imagelist_get(*arcImages, pos);
461 // cpl_image_save(hdrl_image_get_image(inImage),"warp.fits",
462 // CPL_TYPE_UNSPECIFIED, NULL, CPL_IO_CREATE);
463 hdrl_image *tmpImage = eris_ifu_warp_polynomial_image(
464 inImage, poly_u, poly_v);
465 // cpl_image_save(hdrl_image_get_image(tmpImage),"warp.fits",
466 // CPL_TYPE_UNSPECIFIED, NULL, CPL_IO_EXTEND);
467 hdrl_imagelist_set(*arcImages, tmpImage, pos);
469 }
470
471 frame = cpl_frameset_find(frames, ERIS_IFU_PRO_DIST_SLIT_POS);
475 cpl_frame_get_filename(frame)));
476 }
477
478 } CATCH
479 {
480// CATCH_MSGS();
481 }
484 return cpl_error_get_code();
485
486}
487/*----------------------------------------------------------------------------*/
496/*----------------------------------------------------------------------------*/
497static cpl_propertylist * eris_ifu_wave_get_qc_params(const ifsBand band,
498 cpl_table* qclog, struct waveTablesStruct *tables)
499{
500 cpl_propertylist *appList = NULL;
501 const cpl_array *tmpArray = NULL;
502 cpl_vector *coeffVec = NULL;
503 cpl_size coeffDim = 0;
504 cpl_size nRow = 0;
505 char * qcName = NULL;
506
507 TRY
508 {
509
510 appList = cpl_propertylist_new();
511 eris_pfits_put_qc(appList, qclog);
512 // calculate average and median of wavecal coeffs
513
514 coeffDim = cpl_table_get_int(tables->columnCoeffSmoothed, "degree", 0,
515 NULL);
516
517 nRow = cpl_table_get_nrow(tables->columnCoeffSmoothed);
519 coeffVec = cpl_vector_new(nRow));
520 for (cpl_size ix=0; ix<=coeffDim; ix++) {
521 for (cpl_size row=0; row<nRow; row++) {
522 tmpArray = cpl_table_get_array(
523 tables->columnCoeffSmoothed, "coeffs", row);
524
525
526 cpl_vector_set(coeffVec, row,
527 cpl_array_get_double(tmpArray, ix, NULL));
528 }
529
530 qcName = cpl_sprintf("COEF%lld AVG", ix);
531
532 eris_ifu_append_qc_double(appList, qcName,
533 cpl_vector_get_mean(coeffVec),
534 "Average wavecal Coef");
535 eris_ifu_free_string(&qcName);
536
537 qcName = cpl_sprintf("COEF%lld MED", ix);
538
539 eris_ifu_append_qc_double(appList, qcName,
540 cpl_vector_get_median(coeffVec),
541 "Median wavecal Coef");
542 eris_ifu_free_string(&qcName);
543 }
544
545 // calculate average and median of FWHM of arc lines
546
547 cpl_table_unselect_all(tables->columnFitting);
548
549 nRow = cpl_table_or_selected_int(tables->columnFitting, ERIS_IFU_FITTABLE_ERRORCODE,
550 CPL_EQUAL_TO, 0);
551
552 if (nRow > 0) {
553 cpl_table *tmpTable;
554
555 tmpTable= cpl_table_extract_selected(tables->columnFitting);
556
557 double sigmaMed = cpl_table_get_column_median(tmpTable, "sigma");
558 double sigmaAvg = cpl_table_get_column_mean(tmpTable, "sigma");
559 double sigmaRms = cpl_table_get_column_stdev(tmpTable, "sigma");
560 double resolMed = cpl_table_get_column_median(tmpTable, "resol");
561 double resolAvg = cpl_table_get_column_mean(tmpTable, "resol");
562 double resolRms = cpl_table_get_column_stdev(tmpTable, "resol");
563 cpl_size nRows = cpl_table_get_nrow(tmpTable);
564
565
566 double convFactor = 2. * sqrt(2. * log(2.));
567
568 eris_ifu_append_qc_double(appList, "FWHM AVG",
569 sigmaAvg * convFactor,
570 "[pix] Average FWHM of found lines");
571
572 eris_ifu_append_qc_double(appList, "FWHM MED",
573 sigmaMed * convFactor,
574 "[pix] Median FWHM of found lines");
575
576 eris_ifu_append_qc_double(appList, "FWHM STD",
577 sigmaRms * convFactor,
578 "[pix] Stdev FWHM of found lines");
579 eris_ifu_append_qc_int(appList, "NFITLINES",
580 nRows,
581 "Number of lines used tor the fit");
582 double centralLambda = 0;
583 eris_ifu_get_central_lambda(band, &centralLambda);
584 double dispersion = 0;
585 eris_ifu_get_dispersion(band, &dispersion);
586 /*
587 eris_ifu_append_qc_double(appList, "NOMRESOL AVG",
588 centralLambda / (sigmaAvg * convFactor) / dispersion,
589 "Nominal average resolution power");
590 eris_ifu_append_qc_double(appList, "NOMRESOL MED",
591 centralLambda / (sigmaMed * convFactor) / dispersion,
592 "Nominal median resolution power");
593 eris_ifu_append_qc_double(appList, "NOMRESOL STD",
594 centralLambda / (sigmaRms * convFactor) / dispersion,
595 "Nominal stdev resolution power");
596 */
597 eris_ifu_append_qc_double(appList, "RESOL AVG", resolAvg,
598 "average resolution power");
599 eris_ifu_append_qc_double(appList, "RESOL MED", resolMed,
600 "median resolution power");
601 eris_ifu_append_qc_double(appList, "RESOL STD", resolRms,
602 "stdev resolution power");
603
604 //cpl_table_dump_structure(tmpTable, stdout);
605 for(cpl_size i = 0; i < 32; i++) {
606 char* keyname;
607 char* keycomm;
608 cpl_table *extTable;
609 cpl_table_and_selected_int(tmpTable,"slitlet", CPL_EQUAL_TO, i);
610
611 extTable = cpl_table_extract_selected(tmpTable);
612 resolMed = cpl_table_get_column_median(extTable, "resol");
613 resolAvg = cpl_table_get_column_mean(extTable, "resol");
614 sigmaMed = cpl_table_get_column_median(extTable, "sigma");
615 sigmaAvg = cpl_table_get_column_mean(extTable, "sigma");
616 nRows = cpl_table_get_nrow(extTable);
617 //cpl_msg_warning(cpl_func, "Slitlet: %lld, nRows: %lld", i, nRows);
618 if(nRows > 0) {
619 resolRms = cpl_table_get_column_stdev(extTable, "resol");
620 sigmaRms = cpl_table_get_column_stdev(extTable, "sigma");
621 } else {
622 resolRms = 0;
623 sigmaRms = 0;
624 }
625
626 keyname = cpl_sprintf("SLITLET%lld FWHM AVG", i);
627 keycomm = cpl_sprintf("[pix] Average FWHM of found lines on slitlet %lld" ,i);
628 eris_ifu_append_qc_double(appList, keyname, sigmaAvg * convFactor,
629 keycomm);
630 cpl_free(keyname); cpl_free(keycomm);
631 keyname = cpl_sprintf("SLITLET%lld FWHM MED", i);
632 keycomm = cpl_sprintf("[pix] Median FWHM of found lines on slitlet %lld" ,i);
633 eris_ifu_append_qc_double(appList, keyname, sigmaMed * convFactor,
634 keycomm);
635 cpl_free(keyname); cpl_free(keycomm);
636 keyname = cpl_sprintf("SLITLET%lld FWHM STD", i);
637 keycomm = cpl_sprintf("[pix] Stdev FWHM of found lines on slitlet %lld" ,i);
638 eris_ifu_append_qc_double(appList, keyname, sigmaRms * convFactor,
639 keycomm);
640 cpl_free(keyname); cpl_free(keycomm);
641 keyname = cpl_sprintf("SLITLET%lld NFITLINES", i);
642 keycomm = cpl_sprintf("Number of lines used for the fit on slitlet %lld" ,i);
643 eris_ifu_append_qc_int(appList, keyname, nRows, keycomm);
644 cpl_free(keyname); cpl_free(keycomm);
645
646 /*
647 keyname = cpl_sprintf("SLITLET%lld NOMRESOL AVG", i);
648 keycomm = cpl_sprintf("Nominal average resolution power");
649 eris_ifu_append_qc_double(appList, keyname,
650 centralLambda / (sigmaAvg * convFactor) / dispersion,
651 keycomm);
652 cpl_free(keyname); cpl_free(keycomm);
653
654 keyname = cpl_sprintf("SLITLET%lld NOMRESOL MED", i);
655 keycomm = cpl_sprintf("Nominal median resolution power");
656 eris_ifu_append_qc_double(appList, keyname,
657 centralLambda / (sigmaMed * convFactor) / dispersion,
658 keycomm);
659 cpl_free(keyname); cpl_free(keycomm);
660 keyname = cpl_sprintf("SLITLET%lld NOMRESOL STD", i);
661 keycomm = cpl_sprintf("Nominal stdev resolution power");
662 eris_ifu_append_qc_double(appList, keyname,
663 centralLambda / (sigmaRms * convFactor) / dispersion,
664 keycomm);
665 cpl_free(keyname); cpl_free(keycomm);
666 */
667
668 keyname = cpl_sprintf("SLITLET%lld RESOL AVG", i);
669 keycomm = cpl_sprintf("average resolution power");
670 eris_ifu_append_qc_double(appList, keyname, resolAvg, keycomm);
671 cpl_free(keyname); cpl_free(keycomm);
672 keyname = cpl_sprintf("SLITLET%lld RESOL MED", i);
673 keycomm = cpl_sprintf("median resolution power");
674 eris_ifu_append_qc_double(appList, keyname, resolMed, keycomm);
675 cpl_free(keyname); cpl_free(keycomm);
676 keyname = cpl_sprintf("SLITLET%lld RESOL STD", i);
677 keycomm = cpl_sprintf("stdev resolution power");
678 eris_ifu_append_qc_double(appList, keyname, resolRms, keycomm);
679 cpl_free(keyname); cpl_free(keycomm);
680
681 cpl_table_delete(extTable);
682 cpl_table_select_all(tmpTable);
683 }
684 cpl_table_delete(tmpTable);
685 }
686
687 //calculate average and median of wavepos error
688 if (nRow > 0) {
689 cpl_table *tmpTable;
691 tmpTable= cpl_table_extract_selected(tables->columnFitting));
692 cpl_vector *tWavePosErr =cpl_vector_wrap(nRow,
693 cpl_table_get_data_double(tmpTable, "wavelengthError"));
694 cpl_vector *vWavePosErr =cpl_vector_duplicate(tWavePosErr);
695 cpl_vector_unwrap(tWavePosErr);
696 eris_ifu_free_table(&tmpTable);
698
699 cpl_vector_sort(vWavePosErr, CPL_SORT_ASCENDING);
700 double *data = cpl_vector_get_data(vWavePosErr);
701 cpl_vector *cvWavePosErr = cpl_vector_wrap(
702 (cpl_size) ((double)nRow * .8),
703 &data[(int) ((double)nRow * .1)]);
704 double wavePosErrAvg = cpl_vector_get_mean(vWavePosErr);
705 double wavePosErrMed = cpl_vector_get_median(vWavePosErr);
706 double cwavePosErrAvg = cpl_vector_get_mean(cvWavePosErr);
707 double cwavePosErrMed = cpl_vector_get_median(cvWavePosErr);
708 //convert all vector elements to their absolute values
709 double *vdata = cpl_vector_get_data(vWavePosErr);
710 for (cpl_size ix=0; ix<cpl_vector_get_size(vWavePosErr); ix++) {
711 vdata[ix] =fabs(vdata[ix]);
712 }
713 vdata = cpl_vector_get_data(cvWavePosErr);
714 for (cpl_size ix=0; ix<cpl_vector_get_size(cvWavePosErr); ix++) {
715 vdata[ix] =fabs(vdata[ix]);
716 }
717 double wavePosErrAvgAbs = cpl_vector_get_mean(vWavePosErr);
718 double wavePosErrMedAbs = cpl_vector_get_median(vWavePosErr);
719 double cwavePosErrAvgAbs = cpl_vector_get_mean(cvWavePosErr);
720 double cwavePosErrMedAbs = cpl_vector_get_median(cvWavePosErr);
721
723 cpl_vector_unwrap(cvWavePosErr);
724 cpl_vector_delete(vWavePosErr);
725
726 eris_ifu_append_qc_double(appList, "POSERR AVG",
727 wavePosErrAvg,
728 "[um] Average of reference line position errors");
729
730 eris_ifu_append_qc_double(appList, "POSERR MED",
731 wavePosErrMed,
732 "[um] Median of reference line position errors");
733
734 eris_ifu_append_qc_double(appList, "POSERR CLEAN AVG",
735 cwavePosErrAvg,
736 "[um] Clean average of reference line position errors");
737
738 eris_ifu_append_qc_double(appList, "POSERR CLEAN MED",
739 cwavePosErrMed,
740 "[um] Clean median of reference line position errors");
741
742 eris_ifu_append_qc_double(appList, "POSERR AVG ABS",
743 wavePosErrAvgAbs ,
744 "[um] Average of reference line position absolute errors");
745
746 eris_ifu_append_qc_double(appList, "POSERR MED ABS",
747 wavePosErrMedAbs ,
748 "[um] Median of reference line position absolute errors");
749
750 eris_ifu_append_qc_double(appList, "POSERR CLEAN AVG ABS",
751 cwavePosErrAvgAbs ,
752 "[um] Clean average of reference line position absolute errors");
753
754 eris_ifu_append_qc_double(appList, "POSERR CLEAN MED ABS",
755 cwavePosErrMedAbs ,
756 "[um] Clean median of reference line position absolute errors");
757
758 }
759
760 } CATCH
761 {
762 CATCH_MSGS();
764 }
765 eris_ifu_free_vector(&coeffVec);
766 return appList;
767}
768/*----------------------------------------------------------------------------*/
780/*----------------------------------------------------------------------------*/
781cpl_error_code eris_ifu_wave_save_products(
782 cpl_image *waveCalImg,
783 cpl_propertylist *applist,
784 cpl_frameset *frameset,
785 const cpl_parameterlist *parlist)
786{
787 TRY
788 {
790 eris_ifu_save_image(frameset, applist, parlist, REC_NAME_WAVECAL,
791 ERIS_IFU_PRO_WAVE_MAP, ERIS_IFU_PRO_WAVE_MAP_FN,
792 CPL_TYPE_UNSPECIFIED, waveCalImg));
793 } CATCH
794 {
795 CATCH_MSGS();
796 }
797
798 return cpl_error_get_code();
799}
800
cpl_error_code eris_ifu_get_dispersion(ifsBand band, double *dispersion)
Get spectral dispersion for instrument band.
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.
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.
void eris_ifu_wave_clear_tables(struct waveTablesStruct *tables)
Clear wavelength table pointers without freeing.
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_error_code eris_ifu_read_wave_setup(const char *filename, ifsBand band, struct waveSetupStruct *waveSetup)
Read wavelength setup parameters from configuration file.
cpl_error_code eris_ifu_append_qc_double(cpl_propertylist *pl, const char *name, double val, const char *comment)
Append a QC parameter of type DOUBLE to a property list.
cpl_bivector * eris_ifu_load_slit_positions(const char *filename)
Load slitlet position bivector from a table.
cpl_error_code eris_ifu_load_distortion_polynomials(const char *filename, cpl_polynomial ***polynomials, cpl_table **borders)
Load distortion polynomials and slitlet borders from a table.
hdrl_image * eris_ifu_load_cal_image_frame(const cpl_frame *frame, ifsBand band, ifsPreopticsScale scale, cpl_image **qualImage, deqQualityType *qualType)
Load a calibration image from a frame.
cpl_error_code eris_ifu_dfs_set_groups(cpl_frameset *self)
Set the frame group (RAW, CALIB, or PRODUCT) for all frames in a frameset.
Definition: eris_ifu_dfs.c:89
cpl_error_code eris_ifu_append_qc_int(cpl_propertylist *pl, const char *name, int val, const char *comment)
Append a QC parameter of type INT to a property list.
cpl_error_code eris_ifu_load_distortion_polynomials_old(const char *filename, cpl_polynomial **poly_u, cpl_polynomial **poly_v)
Load old-format distortion polynomials from a table.
hdrl_image * eris_ifu_dist_warp_image(const hdrl_image *imgIn, cpl_polynomial **poly_u, const cpl_table *borders)
Warp full detector image by warping each slitlet.
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define 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_fetch_std_param(const cpl_parameterlist *parlist, const char *recipename, struct stdParamStruct *stdParams)
Fetch standard parameters from parameter list into structure.
void eris_ifu_free_std_param(struct stdParamStruct *stdParams)
Free memory allocated for stdParamStruct.
cpl_error_code eris_ifu_add_std_params(cpl_parameterlist *pl, const char *recipename)
Add standard recipe parameters to a parameter list.
hdrl_image * eris_ifu_warp_polynomial_image(const hdrl_image *hdrlInImg, const cpl_polynomial *poly_u, const cpl_polynomial *poly_v)
Warp an HDRL image using 2D polynomial transformations.
void eris_ifu_free_propertylist(cpl_propertylist **item)
Free memory and set pointer to null.
void eris_ifu_free_string(char **item)
Free memory and set pointer to null.
void eris_ifu_free_vector(cpl_vector **item)
Free memory and set pointer to null.
void eris_ifu_free_table(cpl_table **item)
Free memory and set pointer to null.
cpl_error_code eris_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.
void eris_ifu_free_int_array(int **item)
Free memory and set pointer to null.
void eris_ifu_free_hdrl_imagelist(hdrl_imagelist **item)
Free memory and set pointer to null.
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.
cpl_frameset * eris_ifu_get_frameset_by_tag(const cpl_frameset *frameset, const char *tag)
Get frames with given tag from frameset.
cpl_error_code eris_ifu_save_image(cpl_frameset *fs, const cpl_propertylist *plist, const cpl_parameterlist *parlist, const char *recipe, const char *procatg, const char *filename, cpl_type type, const cpl_image *image)
Save image with DFS compliance.
void eris_ifu_free_bivector(cpl_bivector **item)
Free memory and set pointer to null.
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
cpl_error_code hdrl_imagelist_div_image(hdrl_imagelist *himlist, const hdrl_image *himg)
Divide an image from an image list.