ERIS Pipeline Reference Manual 1.8.15
eris_ifu_sdp.c
1/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim:set sw=2 sts=2 et cin: */
3/*
4 * This file is part of the MUSE Instrument Pipeline
5 * Copyright (C) 2015 European Southern Observatory
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26/*----------------------------------------------------------------------------*
27 * Includes *
28 *----------------------------------------------------------------------------*/
29#include <string.h>
30#include <eris_pfits.h>
31#include "eris_ifu_sdp.h"
32#include "eris_ifu_dfs.h"
33#include <math.h>
34#include <cpl.h>
35#include <eris_utils.h>
36#include <eris_ifu_utils.h>
37#include <eris_ifu_wavecal_static.h>
38/*
39#include "muse_dfs.h"
40#include "muse_pfits.h"
41#include "muse_rtcdata.h"
42#include "muse_pixtable.h"
43#include "muse_cplwrappers.h"
44#include "muse_wcs.h"
45#include "muse_flux.h"
46#include "muse_utils.h"
47 */
48
49/*----------------------------------------------------------------------------*
50 * Defines *
51 *----------------------------------------------------------------------------*/
52
53#define KEY_ASSON "ASSON"
54#define KEY_ASSON_COMMENT "Associated file name"
55#define KEY_ASSOC "ASSON"
56#define KEY_ASSOC_COMMENT "Associated file category"
57#define KEY_ASSOM "ASSOM"
58#define KEY_ASSOM_COMMENT "Associated file datamd5"
59
60#define KEY_DEC "DEC"
61#define KEY_DEC_COMMENT "[deg] Image center (J2000)"
62#define KEY_EXPTIME "EXPTIME"
63#define KEY_EXPTIME_COMMENT "[s] Total integration time per pixel"
64#define KEY_FLUXCAL "FLUXCAL"
65#define KEY_FLUXCAL_COMMENT "Type of flux calibration (ABSOLUTE or UNCALIBRATED)"
66#define KEY_FLUXCAL_VALUE_FALSE "UNCALIBRATED"
67#define KEY_FLUXCAL_VALUE_TRUE "ABSOLUTE"
68#define KEY_MJDOBS "MJD-OBS"
69#define KEY_MJDOBS_COMMENT "[d] Start of observations (days)"
70#define KEY_MJDEND "MJD-END"
71#define KEY_MJDEND_COMMENT "[d] End of observations (days)"
72#define KEY_OBID "OBID"
73#define KEY_OBID1 "OBID1"
74#define KEY_OBID_COMMENT "Observation block ID"
75#define KEY_OBSTECH "OBSTECH"
76#define KEY_OBSTECH_COMMENT "Technique for observation"
77#define KEY_PROCSOFT "PROCSOFT"
78#define KEY_PROCSOFT_COMMENT "ESO pipeline version"
79#define KEY_PRODCATG "PRODCATG"
80#define KEY_PRODCATG_COMMENT "Data product category"
81#define KEY_PRODCATG_VALUE_IFS_CUBE "SCIENCE.CUBE.IFS"
82#define KEY_PRODCATG_VALUE_FOV_IMAGE "ANCILLARY.IMAGE"
83#define KEY_PROG_ID "PROG_ID"
84#define KEY_PROG_ID_COMMENT "ESO programme identification"
85#define KEY_PROG_ID_VALUE_MULTIPLE "MULTI"
86#define KEY_PROGID "PROGID"
87#define KEY_PROGID_COMMENT KEY_PROG_ID_COMMENT
88#define KEY_PROV "PROV"
89#define KEY_PROV_COMMENT "Originating raw science file"
90#define KEY_RA "RA"
91#define KEY_RA_COMMENT "[deg] Image center (J2000)"
92#define KEY_REFERENC "REFERENC"
93#define KEY_REFERENC_COMMENT "Reference publication"
94#define KEY_TEXPTIME "TEXPTIME"
95#define KEY_TEXPTIME_COMMENT "[s] Total integration time of all exposures"
96#define KEY_WAVELMIN "WAVELMIN"
97#define KEY_WAVELMIN_COMMENT "[nm] Minimum wavelength"
98#define KEY_WAVELMAX "WAVELMAX"
99#define KEY_WAVELMAX_COMMENT "[nm] Maximum wavelength"
100#define KEY_SKY_RES "SKY_RES"
101#define KEY_SKY_RES_COMMENT "[arcsec] FWHM effective spatial resolution"
102#define KEY_SKY_RERR "SKY_RERR"
103#define KEY_SKY_RERR_COMMENT "[arcsec] Error of SKY_RES"
104#define KEY_SPEC_RES "SPEC_RES"
105#define KEY_SPEC_RES_COMMENT "Spectral resolving power at central wavelength"
106#define KEY_SPEC_ERR "CRDER3"
107#define KEY_SPEC_ERR_COMMENT "[angstrom] Random error in spectral coordinate"
108#define KEY_SPECSYS "SPECSYS"
109#define KEY_SPECSYS_COMMENT "Frame of reference for spectral coordinates."
110#define KEY_PIXNOISE "PIXNOISE"
111#define KEY_PIXNOISE_COMMENT "[erg.s**(-1).cm**(-2).angstrom**(-1)] pixel-to-pixel noise"
112#define KEY_ABMAGLIM "ABMAGLIM"
113#define KEY_ABMAGLIM_COMMENT "5-sigma magnitude limit for point sources"
114#define KEY_NCOMBINE "NCOMBINE"
115#define KEY_NCOMBINE_COMMENT "No. of combined raw science data files"
116
117/* A regular expression matching SDP IFS standard keywords to be cleared. */
118#define CLEAN_KEYS_REGEXP \
119 "^(" KEY_MJDEND "|" \
120 KEY_PROCSOFT "|" \
121 KEY_PRODCATG "|" \
122 KEY_PROG_ID "|" \
123 KEY_PROGID "[0-9]+|" \
124 KEY_OBID "[0-9]+|" \
125 KEY_OBSTECH "|" \
126 KEY_FLUXCAL "|" \
127 KEY_TEXPTIME "|" \
128 KEY_WAVELMIN "|" \
129 KEY_WAVELMAX "|" \
130 KEY_SKY_RES "|" \
131 KEY_SKY_RERR "|" \
132 KEY_SPEC_RES "|" \
133 KEY_PIXNOISE "|" \
134 KEY_ABMAGLIM "|" \
135 KEY_REFERENC "|" \
136 KEY_NCOMBINE "|" \
137 KEY_PROV "[0-9]+|" \
138 KEY_ASSON "[0-9]+" ")$"
139
140/*----------------------------------------------------------------------------*/
163/*----------------------------------------------------------------------------*/
164
165/* Lookup table for spectral resolution vs. wavelength */
166
167typedef struct {
168 /* Wavelength in Angstrom at which the spectral resolution was measured. */
169 double lambda;
170 /* Measured spectral resolution. */
171 double R;
172} eris_ifu_specres_lut_entry;
173
174/* The last entry in the data tables must have a zero wavelength entry! */
175
176//static const eris_ifu_specres_lut_entry
177//eris_ifu_specres_data_wfm[] =
178//{
179// {4650.0000, 1674.77},
180// {4810.3448, 1769.45},
181// {4970.6897, 1864.50},
182// {5131.0345, 1959.52},
183// {5291.3793, 2054.19},
184// {5451.7242, 2148.34},
185// {5612.0690, 2241.81},
186// {5772.4138, 2334.46},
187// {5932.7587, 2426.18},
188// {6093.1035, 2516.84},
189// {6253.4483, 2606.28},
190// {6413.7932, 2694.36},
191// {6574.1380, 2780.89},
192// {6734.4828, 2865.70},
193// {6894.8277, 2948.59},
194// {7055.1725, 3029.32},
195// {7215.5173, 3107.70},
196// {7375.8622, 3183.46},
197// {7536.2070, 3256.36},
198// {7696.5518, 3326.12},
199// {7856.8967, 3392.45},
200// {8017.2415, 3455.01},
201// {8177.5863, 3513.44},
202// {8337.9312, 3567.37},
203// {8498.2760, 3616.34},
204// {8658.6208, 3659.87},
205// {8818.9657, 3697.42},
206// {8979.3105, 3728.38},
207// {9139.6553, 3752.11},
208// {9300.0002, 3767.93},
209// { 0.0000 , 0.00}
210//};
211
212/* XXX: Dummy values from the User Manual for the NFM. Update for production. */
213//static const eris_ifu_specres_lut_entry
214//eris_ifu_specres_data_nfm[] =
215//{
216// {4800.0000, 1740.00},
217// {9300.0000, 3450.00},
218// { 0.0000 , 0.00}
219//};
220
221/* Instrument properties and reference values */
222
223/* Number of detector readout ports */
224//static const unsigned int kErisNumQuadrants = 4;
225
226/* Nominal field size [arcsec] */
227//static const double kErisFovSizeWFM = 60.00;
228//static const double kErisFovSizeNFM = 7.43;
229
230/* Nominal pixel scale wfm, nfm */
231//static const double kErisPixscaleWFM = 0.2;
232//static const double kErisPixscaleNFM = 0.025;
233
234/* Reference wavelength [Angstrom] */
235//static const double kErisLambdaRef = 7000.;
236
237/* Instrument response at reference wavelength */
238//static const double kErisResponseRef = 41.2;
239
240/* Typical error estimated from unresolved sources [arcsec] */
241//static const double kErisExtraErrorIQE = 0.3;
242
243/* Typical values [arcsec] for the effective spatial resolution *
244 * and its uncertainty, given by the median and the standard *
245 * deviation of previous measurements. */
246//static const double kErisSkyResWFM = 0.853823;
247//static const double kErisSkyResErrorWFM = 0.495547;
248//static const double kErisSkyResNFM = 0.15;
249//static const double kErisSkyResErrorNFM = 0.05;
250
251
252/* Unit conversion factors */
253
254static const double day2sec = 86400.0; /* Seconds per day */
255//static const double m2nm = 1.e9; /* meter to nanometer */
256//static const double nm2Angstrom = 10.; /* nanometer to Angstrom */
257//static const double deg2as = 3600.; /* degrees to arcseconds */
258
259
260/*----------------------------------------------------------------------------*
261 * Functions *
262 *----------------------------------------------------------------------------*/
263
264
267// @private
268// @brief Compute spectral resolution for the central wavelength.
269// @param aLambda Wavelength in Angstrom.
270// @param aSpecresLut Spectral resolution look-up table.
271// @return The interpolated spectral resolution
272
273// The function computes the spectral resolution at the wavelength @em aLambda,
274// by interpolating the data points given by the look-up table @em aSpecresLut.
275// For wavelengths outside of the wavelength range of the table, the lower, or
276// the upper boundary value is returned, respectively.
277// */
279//static double
280//eris_ifu_idp_compute_specres(double aLambda, const eris_ifu_specres_lut_entry *aSpecresLut)
281//{
282
283// /* Locate the appropriate wavelength bin in the lut and compute the *
284// * spectral by linear interpolation. */
285
286// cpl_size i = 0;
287// while ((aSpecresLut[i].lambda > 0.) && (aLambda > aSpecresLut[i].lambda)) {
288// ++i;
289// }
290
291// if (i == 0) {
292// return aSpecresLut[0].R;
293// }
294// else if (aSpecresLut[i].lambda == 0.) {
295// return aSpecresLut[i - 1].R;
296// }
297
298// double t = (aLambda - aSpecresLut[i - 1].lambda) /
299// (aSpecresLut[i].lambda - aSpecresLut[i - 1].lambda);
300
301// return (1 - t) * aSpecresLut[i - 1].R + t * aSpecresLut[i].R;
302//}
303
306// @private
307// @brief Estimate image quality at a given wavelength from the seeing
308// and the airmass.
309// @param aLambda Wavelength in Angstrom at which the image quality is
310// computed.
311// @param aSeeing The seeing as seen by the telescope and corrected for
312// airmass.
313// @param aAirmass Airmass at which the observation was carried out.
314// @return The estimate of the image quality at the given wavelength.
315
316// The returned image quality estimate is in units of arcsec.
317// */
319//static double
320//eris_ifu_idp_compute_iqe(double aLambda, double aSeeing, double aAirmass)
321//{
322
323// const double rad2as = 180. / CPL_MATH_PI * 3600.; /* radians to arcsec */
324
325
326// /* Wavefront outer scale at Paranal [meters] */
327// const double L0 = 23.;
328
329// /* UT M1 diameter [meters] from UT M1 vignetted area */
330// const double D = 8.1175365721399437;
331
332// /* Kolb factor (cf. ESO Technical Report 12) */
333// const double Fkolb = 1. / (1. + 300. * D / L0) - 1.;
334
335
336// /* Scaled wavelength: lambda over lambda_ref */
337// double lambda = aLambda / 5000.;
338
339// /* Fried parameter */
340// double r0 = 0.976 * 5.e-7 / aSeeing * rad2as *
341// pow(lambda, 1.2) * pow(aAirmass, -0.6);
342
343// double iqe = aSeeing * pow(lambda, -0.2) * pow(aAirmass, 0.6);
344// iqe *= sqrt(1. + Fkolb * 2.183 * pow(r0 / L0, 0.356));
345
346// return iqe;
347//}
348
351// @private
352// @brief Compute the effective spatial resolution from the Strehl ratio.
353// @param aSkyres Computed effective spatial resolution.
354// @param aSkyresError Error of the computed effective spatial resolution.
355// @param aStrehl Strehl ratio to convert.
356// @param aStrehlError Error of the Strehl ratio.
357// @return Nothing.
358
359// Converts the given input Strehl ratio into an effective spatial resolution
360// valid for a MUSE NFM observation. The conversion uses an empirical model
361// which is only valid for the MUSE NFM mode!
362
363// The computed spatial resolution and its uncertainty are stored at the
364// location referenced by @em aSkyres and @em aSkyresError.
365// */
367//static void
368//eris_ifu_idp_compute_skyres_from_strehl(double *aSkyres, double *aSkyresError,
369// double aStrehl, double aStrehlError)
370//{
371// /* Parameter values of the empirically determined model used to convert *
372// * a Strehl ratio into an effective spatial resolution for the NFM *
373// * instrument mode. */
374// const double rms = 0.01;
375// const double parameter[3] = {-0.71985411, 0.81622807, -0.01941496};
376
377// const double strehl_min = 1.;
378// const double strehl_max = 80.;
379
380// /* The uncertainty of the Strehl ratio is actually not used in the *
381// * following model implementation. Keep it to be prepared. */
382// CPL_UNUSED(aStrehlError);
383
384// /* Keep the input strehl ratio to the model within the limits */
385// double strehl = CPL_MIN(CPL_MAX(aStrehl, strehl_min), strehl_max);
386
387// double skyres = parameter[0] + parameter[1] * pow(strehl, parameter[2]);
388// double skyrerr = parameter[1] * parameter[2] *
389// pow(strehl, (parameter[2] - 1.));
390// skyrerr = sqrt(skyrerr * skyrerr + rms * rms);
391
392// *aSkyres = skyres;
393// *aSkyresError = skyrerr;
394// return;
395//}
396
397/*----------------------------------------------------------------------------*/
418/*----------------------------------------------------------------------------*/
419
420static double
421eris_ifu_sdp_compute_fwhm(cpl_frameset* set)
422{
423 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, 0);
424 // double abmaglimit = 0;
425 cpl_frame* frm = NULL;
426 // cpl_size nexposures = cpl_frameset_count_tags(set, ERIS_IFU_RAW_OBJ);
427 cpl_size kexposure = 0;
428 const char* fname;
429 cpl_propertylist* phead;
430 cpl_size next = 0;
431
432 frm = cpl_frameset_get_position(set, kexposure);
433 next = cpl_frame_get_nextensions(frm);
434 fname = cpl_frame_get_filename(frm);
435 phead = cpl_propertylist_load(fname, 0);
436 cpl_msg_info(cpl_func,"fname: %s next: %lld",fname, next);
437 cpl_table* asm_data;
438 double IA_fwhm_corr = 0;
439 double IA_fwhm_corr_pix = 0;
440 if (next > 0) {
441 double IA_fwhm = 0;
442 double dimm = 0;
443 ifsBand bandId = eris_ifu_get_band(phead);
444 asm_data = cpl_table_load(fname, 1, 0);
445 if(cpl_table_has_column(asm_data,"IA_FWHM")) {
446 IA_fwhm = cpl_table_get_column_mean(asm_data,"IA_FWHM");
447 } else if (cpl_propertylist_has(phead,"ESO TEL IA FWHM")) {
448 IA_fwhm = cpl_propertylist_get_double(phead,"ESO TEL IA FWHM");
449 }
450 if(cpl_table_has_column(asm_data,"DIMM_SEEING")) {
451 dimm = cpl_table_get_column_mean(asm_data,"DIMM_SEEING");
452 } else {
453 double airm_start = 0;
454 double airm_end = 0;
455
456 if (cpl_propertylist_has(phead,"ESO TEL AMBI FWHM START")) {
457 airm_start = eris_pfits_get_fwhm_start(phead);
458 }
459
460 if (cpl_propertylist_has(phead,"ESO TEL AMBI FWHM END")) {
461 airm_end = eris_pfits_get_fwhm_end(phead);
462 }
463
464 if(airm_start > 0 && airm_end > 0) {
465 dimm = 0.5 * (airm_start + airm_end);
466 } else if (airm_start > 0 && airm_end == 0) {
467 dimm = airm_start;
468 } else if (airm_start > 0 && airm_end == 0) {
469 dimm = airm_end;
470 }
471
472 }
473 cpl_table_delete(asm_data);
474 /* compute the wavelength corrected FWHM values from the ASM extension */
475 double lambda_c = 1;
476 eris_ifu_get_central_lambda(bandId, &lambda_c);
477 ifsPreopticsScale scale = eris_ifu_get_preopticsScale(phead);
478 double pix_scale = 1;
479 switch(scale){
480 case S25MAS: pix_scale = 0.025; break;
481 case S100MAS:pix_scale = 0.100; break;
482 case S250MAS:pix_scale = 0.250; break;
483 default:
484 cpl_msg_error(cpl_func,"scale not found");
485 break;
486 }
487
488
489 IA_fwhm_corr = IA_fwhm * pow((0.500/lambda_c), 0.2 );
490 IA_fwhm_corr_pix = IA_fwhm_corr / pix_scale;
491 cpl_msg_info(cpl_func,"IA_fwhm_corr: %g",IA_fwhm_corr);
492 cpl_msg_info(cpl_func,"IA_fwhm_corr_pix: %g",IA_fwhm_corr_pix);
493 double airmass = eris_pfits_get_airmass(phead);
494
495 double dimm_corr = dimm *
496 pow((0.500/lambda_c),0.2) *
497 pow(airmass,(3./5.)) *
498 (1. - 78.08 *
499 (pow( (lambda_c / 1.e6), 0.4) *
500 (pow(airmass, -0.2) / pow(dimm, (1./3.)))
501 ));
502 cpl_msg_info(cpl_func,"dimm_corr: %g",dimm_corr);
503 double dimm_corr_pix = dimm_corr/pix_scale;
504 cpl_msg_info(cpl_func,"dimm_corr_pix: %g",dimm_corr_pix);
505 }
506
507 cpl_propertylist_delete(phead);
508 eris_check_error_code("eris_ifu_sdp_compute_fwhm");
509 return IA_fwhm_corr;
510
511
512 //abmaglimit = -2.5 * log10(2. * sdev / kMuseFluxUnitFactor) + zeropoint;
513}
514
515/*----------------------------------------------------------------------------*/
537/*----------------------------------------------------------------------------*/
538
539static double
540eris_ifu_sdp_compute_pixnoise(cpl_frameset* set) {
541
542 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, 0);
543 cpl_frame* frm = NULL;
544 //cpl_frameset_dump(set,stdout);
545 cpl_error_code error_code = cpl_error_get_code();
546 cpl_error_set(cpl_func, error_code);
547
548 if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
549 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
550 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_MEAN_FLUXCAL)) {
551 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_MEAN_FLUXCAL);
552 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN)) {
553 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN);
554 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN)) {
555 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
556 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN)) {
557 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
558 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
559 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN);
560 }
561
562 const char* fname = cpl_frame_get_filename(frm);
563 cpl_msg_warning(cpl_func,"fname: %s",fname);
564 cpl_image* data = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 1);
565 cpl_image* errs = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 2);
566 cpl_image* qual = cpl_image_load(fname, CPL_TYPE_INT, 0, 3);
567
568 cpl_mask* bpm = cpl_mask_threshold_image_create(qual, DBL_MIN, 0.9);
569 cpl_image_reject_from_mask(data, bpm);
570 cpl_mask_delete(bpm);
571 //cpl_image_set_bpm(errs, bpm);
572
573 hdrl_image* hima = hdrl_image_create(data, errs);
574
575 cpl_image_delete(data);
576 cpl_image_delete(errs);
577 cpl_image_delete(qual);
578
580 /* TODO: which of the two option should we use to mask the object? */
581 //cpl_mask* obj_mask = eris_ifu_hima_get_obj_mask_percent(hima, 0.5);
582 cpl_mask* obj_mask = eris_ifu_hima_get_obj_mask(hima, 3, 3);
583
584 hdrl_image_reject_from_mask(hima, obj_mask);
585
586 double pixnoise = hdrl_image_get_stdev(hima);
587
588 hdrl_image_delete(hima);
589
590
591 cpl_mask_delete(obj_mask);
592 eris_check_error_code("eris_ifu_sdp_compute_pixnoise");
593 return pixnoise;
594}
595
596/*----------------------------------------------------------------------------*/
618/*----------------------------------------------------------------------------*/
619
620static hdrl_image*
621eris_ifu_sdp_get_obj_mean(cpl_frameset* set) {
622
623 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, NULL);
624 cpl_frame* frm = NULL;
625 //cpl_frameset_dump(set,stdout);
626 cpl_error_code error_code = cpl_error_get_code();
627 cpl_error_set(cpl_func, error_code);
628 cpl_msg_warning(cpl_func,"search input frame");
629
630 if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN)) {
631 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN);
632 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
633 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
634 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN)) {
635 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN);
636 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN)) {
637 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
638 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN)) {
639 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
640 } else if(NULL != cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN)) {
641 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN);
642 }
643
644 const char* fname = cpl_frame_get_filename(frm);
645
646 cpl_image* data = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 1);
647 cpl_image* errs = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 2);
648 cpl_image* qual = cpl_image_load(fname, CPL_TYPE_INT, 0, 3);
649 cpl_mask* bpm = cpl_mask_threshold_image_create(qual, DBL_MIN, 0.9);
650
651 cpl_image_set_bpm(data, bpm);
652 //cpl_image_set_bpm(errs, bpm);
653
654 hdrl_image* hima = hdrl_image_create(data, errs);
655
657
658 /* TODO: which of the two option should we use to mask the object? */
659 //cpl_mask* obj_mask = eris_ifu_hima_get_obj_mask_percent(hima, 0.5);
660 cpl_mask* obj_mask = eris_ifu_hima_get_obj_mask(hima, 1, 3);
661 //hdrl_image_reject_from_mask(hima, obj_mask);
662
663 cpl_image_delete(data);
664 cpl_image_delete(errs);
665 cpl_image_delete(qual);
666 cpl_mask_delete(obj_mask);
667
668 eris_check_error_code("eris_ifu_sdp_get_obj_mean");
669 return hima;
670}
671
672/*----------------------------------------------------------------------------*/
691/*----------------------------------------------------------------------------*/
692
693static double
694eris_ifu_sdp_compute_zp(ifsBand band)
695{
696 double ZP = 0;
697 switch(band) {
698 /* OLD
699 case J_LOW: ZP = -23.05987; break; // no result??
700 case J_SHORT: ZP = -22.720572007420277; break;
701 case J_MIDDLE: ZP = -23.059874978944993; break;
702 case J_LONG: ZP = -23.40258436053865; break;
703 case H_LOW: ZP = -23.36106526995602; break;
704 case H_SHORT: ZP = -23.539146965; break;
705 case H_MIDDLE: ZP = -23.911951487414118; break;
706 case H_LONG: ZP = -23.9152376244; break;
707 case K_LOW: ZP = -24.516976313167717; break;
708 case K_SHORT: ZP = -24.2690232517; break;
709 case K_MIDDLE: ZP = -24.413665245625793; break;
710 case K_LONG: ZP = -24.644367831; break;
711 default: ZP = 2; break;
712 */
713 /* Using Mark's formula:zp = ab_mag + 2.5 * math.log10(f3_max) - apcor3 */
714 case J_LOW: ZP = -23.564080671; break; //not available take mean of other band values
715 case J_SHORT: ZP = -23.370149709; break; //
716 case J_MIDDLE: ZP = -23.575634864; break; //
717 case J_LONG: ZP = -23.746457445; break; //
718 case H_LOW: ZP = -23.764826331; break; //
719 case H_SHORT: ZP = -23.961968187; break; //
720 case H_MIDDLE: ZP = -24.238252577; break; //
721 case H_LONG: ZP = -24.396966217; break; //
722 case K_LOW: ZP = -24.89135131; break;//
723 case K_SHORT: ZP = -24.730943402; break; //
724 case K_MIDDLE: ZP = -24.8542167693; break;//
725 case K_LONG: ZP = -25.24818993; break;//
726 default: ZP = 2; break;
727
728
729 }
730 return ZP;
731}
732
733/*----------------------------------------------------------------------------*/
758/*----------------------------------------------------------------------------*/
759
760static double
761eris_ifu_sdp_compute_abmaglimit(const double sky_rms, const double fwhm,
762 ifsBand band) {
763
764 double abmaglim = 0;
765 //ABmaglim = -2.5*log10(5. * FWHM * sky_rms * sqrt(pi)/(2. * sqrt(log(4)))) - 2.5 * log10(2.) + ZP
766 double ZP = eris_ifu_sdp_compute_zp(band);
767 abmaglim = -2.5*log10(5. * fwhm * sky_rms * sqrt(CPL_MATH_PI) /
768 (2. * sqrt(log(4)))) - 2.5 * log10(2.) + ZP;
769
770 eris_check_error_code("eris_ifu_sdp_compute_abmaglimit");
771 return abmaglim;
772}
773
774/*----------------------------------------------------------------------------*/
788/*----------------------------------------------------------------------------*/
789
790eris_ifu_sdp_properties *
792 eris_ifu_sdp_properties *properties = cpl_calloc(1, sizeof *properties);
793 return properties;
794}
795
796/*----------------------------------------------------------------------------*/
810/*----------------------------------------------------------------------------*/
811
812void
813eris_ifu_sdp_properties_delete(eris_ifu_sdp_properties *aProperties)
814{
815 if (aProperties) {
816 cpl_array_delete(aProperties->obid);
817 cpl_array_delete(aProperties->progid);
818 cpl_propertylist_delete(aProperties->prov);
819 cpl_array_delete(aProperties->asson);
820
821 /* TODO: Remove deallocator call for assoc once it has been *
822 * removed from the interface. */
823 cpl_array_delete(aProperties->assoc);
824 cpl_free((char *)aProperties->prodcatg);
825 //cpl_free((char *)aProperties->procsoft);
826 cpl_free((char *)aProperties->specsys);
827 cpl_free((char *)aProperties->obstech);
828 cpl_free((char *)aProperties->referenc);
829 }
830 cpl_free(aProperties);
831 return;
832}
833
834/*----------------------------------------------------------------------------*/
848/*----------------------------------------------------------------------------*/
849
850const char *
851eris_ifu_pfits_get_origfile(const cpl_propertylist *aHeaders)
852{
853 const char *value = cpl_propertylist_get_string(aHeaders, "ORIGFILE");
854 cpl_ensure(value, cpl_error_get_code(), NULL);
855 return value;
856}
857
860// @private
861// @brief Estimate image quality at a given wavelength from the seeing
862// and the airmass.
863// @param aLambda Wavelength in Angstrom at which the image quality is
864// computed.
865// @param aSeeing The seeing as seen by the telescope and corrected for
866// airmass.
867// @param aAirmass Airmass at which the observation was carried out.
868// @return The estimate of the image quality at the given wavelength.
869
870// The returned image quality estimate is in units of arcsec.
871// */
873//static double
874//eris_ifu_sdp_compute_iqe(double aLambda, double aSeeing, double aAirmass)
875//{
876
877// const double rad2as = 180. / CPL_MATH_PI * 3600.; /* radians to arcsec */
878
879
880// /* Wavefront outer scale at Paranal [meters] */
881// const double L0 = 23.;
882
883// /* UT M1 diameter [meters] from UT M1 vignetted area */
884// const double D = 8.1175365721399437;
885
886// /* Kolb factor (cf. ESO Technical Report 12) */
887// const double Fkolb = 1. / (1. + 300. * D / L0) - 1.;
888
889
890// /* Scaled wavelength: lambda over lambda_ref */
891// double lambda = aLambda / 5000.;
892
893// /* Fried parameter */
894// double r0 = 0.976 * 5.e-7 / aSeeing * rad2as *
895// pow(lambda, 1.2) * pow(aAirmass, -0.6);
896
897// double iqe = aSeeing * pow(lambda, -0.2) * pow(aAirmass, 0.6);
898// iqe *= sqrt(1. + Fkolb * 2.183 * pow(r0 / L0, 0.356));
899
900// return iqe;
901//}
902
903static cpl_error_code
904eris_ifu_get_sdp_frames(cpl_frameset* set, const cpl_parameterlist* parlist,
905 const char* recipe_name, eris_ifu_sdp_properties *properties,
906 cpl_frameset** raws_obj, cpl_frameset** raws_sky, cpl_frameset** pros_obj)
907{
908
909 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
910 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
911 cpl_ensure(recipe_name != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
912 cpl_ensure(properties != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
913
914 char* param_name = cpl_sprintf("eris.%s.dar-corr", recipe_name);
915 cpl_boolean is_dar_cor =
916 cpl_parameter_get_bool(cpl_parameterlist_find_const(parlist, param_name));
917 cpl_free(param_name);
918
919
920 param_name = cpl_sprintf("eris.%s.sky_tweak", recipe_name);
921 int is_sky_tweak =
922 cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, param_name));
923 cpl_free(param_name);
924
925 cpl_size nexposures = 0;
926 cpl_frame* frm = NULL;
927 //cpl_frameset_dump(set, stdout);
928 //exit(0);
929 if (strstr(recipe_name, "jitter") != NULL) {
930
931 *raws_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_RAW_OBJ);
932 if(is_dar_cor) {
933 *pros_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_PRO_JITTER_DAR_CUBE);
934 } else {
935 *pros_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_PRO_JITTER_OBJ_CUBE);
936 }
937
938 if(is_sky_tweak > 0) {
939 *pros_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_PRO_JITTER_TWK_CUBE);
940 } else {
941 *pros_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_PRO_JITTER_OBJ_CUBE);
942 }
943 if(*pros_obj != NULL) {
944 // same PRO.CATG independently from DAR correction
945 if(is_dar_cor) {
946 if(NULL == (frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN))) {
947 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
948 }
949 } else {
950 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
951 }
952 if(frm != NULL) {
953 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
954 }
955
956
957 if(is_sky_tweak > 0) {
958 if(NULL == (frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_DAR_CUBE_FLUXCAL_MEAN))) {
959 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
960 }
961 } else {
962 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_OBJ_CUBE_COADD_FLUXCAL_MEAN);
963 }
964 if(frm != NULL) {
965 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
966 }
967
968
969 }
970
971
972 if(*pros_obj != NULL) {
973 // same PRO.CATG independently from DAR correction
974 if(is_sky_tweak > 0) {
975 if(NULL == (frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN))) {
976 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_TWK_OBJ_CUBE_COADD_FLUXCAL_MEAN);
977 }
978
979 if(frm != NULL) {
980 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
981 }
982 }
983 }
984
985 if(*pros_obj == NULL) {
986 *pros_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_PRO_JITTER_TWK_CUBE);
987 }
988
989 nexposures = cpl_frameset_count_tags(*raws_obj, ERIS_IFU_RAW_OBJ);
990 } else if (strstr(recipe_name, "stdstar") != NULL) {
991 *raws_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_RAW_STD_FLUX);
992 /* for STD stars PRO.CATG is independent from dar correction */
993 if(is_dar_cor) {
994 *pros_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE);
995 } else {
996 *pros_obj = eris_dfs_extract_frames_with_tag (set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE);
997 }
998
999 if(*pros_obj != NULL) {
1000 if(is_dar_cor) {
1001 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
1002 } else {
1003 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_FLUX_CUBE_COADD_FLUXCAL_MEAN);
1004 }
1005 if(frm != NULL) {
1006 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1007 }
1008 }
1009
1010 if(pros_obj != NULL) {
1011 if(is_dar_cor) {
1012 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
1013 } else {
1014 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_FLUX_STD_CUBE_COADD_FLUXCAL_MEAN);
1015 }
1016 if(frm != NULL) {
1017 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1018 }
1019 }
1020
1021 if(*pros_obj != NULL) {
1022 if(is_dar_cor) {
1023 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN);
1024 } else {
1025 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_STD_CUBE_COADD_FLUXCAL_MEAN);
1026 }
1027 if(frm != NULL) {
1028 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1029 }
1030 }
1031 nexposures = cpl_frameset_count_tags(*raws_obj, ERIS_IFU_RAW_STD_FLUX);
1032 }
1033
1034 *raws_sky =
1035 eris_dfs_extract_frames_with_tag(set, ERIS_IFU_PRO_JITTER_SKY_CUBE);
1036
1037 properties->ncombine = nexposures;
1038
1039
1040 //cpl_frameset_dump(set,stdout);
1041 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_EXPOSURE_MAP);
1042 if(frm != NULL) {
1043 cpl_frameset_insert(*pros_obj, cpl_frame_duplicate(frm));
1044 }
1045
1046
1047 eris_check_error_code("eris_ifu_get_sdp_frames");
1048 return cpl_error_get_code();
1049
1050}
1051
1052/*----------------------------------------------------------------------------*/
1089/*----------------------------------------------------------------------------*/
1090
1091eris_ifu_sdp_properties *
1092eris_ifu_sdp_properties_collect(hdrl_resample_result *aCube, cpl_frameset* set,
1093 const cpl_parameterlist* parlist, const char* recipe_name)
1094{
1095
1096 cpl_ensure(aCube != NULL, CPL_ERROR_NULL_INPUT, NULL);
1097 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, NULL);
1098 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
1099 cpl_ensure(recipe_name != NULL, CPL_ERROR_NULL_INPUT, NULL);
1100
1101// cpl_errorstate _status = cpl_errorstate_get();
1102 cpl_frameset* raws_obj = NULL;
1103 cpl_frameset* raws_sky = NULL;
1104 cpl_frameset* pros_obj = NULL;
1105 cpl_propertylist* header = aCube->header;
1106 cpl_frame* frm;
1107 int naxis3 = hdrl_imagelist_get_size(aCube->himlist);
1108 eris_ifu_sdp_properties *properties = eris_ifu_sdp_properties_new();
1109
1110 properties->wlerror = 0.026; /* Fallback random error estimate of wavelength */
1111
1112 eris_ifu_get_sdp_frames(set, parlist, recipe_name, properties, &raws_obj,
1113 &raws_sky, &pros_obj);
1114// cpl_size nsky = cpl_frameset_get_size(raws_sky);
1115 if(raws_sky != NULL) {
1116 cpl_frameset_join(pros_obj, raws_sky);
1117 }
1118cpl_frameset_delete(raws_sky);
1119 cpl_size nexposures = properties->ncombine;
1120 /* Collect data from the raw data files */
1121 // cpl_errorstate status = cpl_errorstate_get();
1122 properties->obid = cpl_array_new(nexposures, CPL_TYPE_LONG);
1123 properties->progid = cpl_array_new(nexposures, CPL_TYPE_STRING);
1124
1125 cpl_msg_info(cpl_func,"obid array size: %lld",
1126 cpl_array_get_size(properties->obid));
1127
1128 cpl_msg_info(cpl_func,"progid array size: %lld",
1129 cpl_array_get_size(properties->progid));
1130
1131 properties->prov = cpl_propertylist_new();
1132
1133 const char* fname = NULL;
1134 cpl_propertylist* phead = NULL;
1135 cpl_propertylist* pchead = NULL;
1136 double exptime = 0;
1137 double dit = 0;
1138 int ndit = 0;
1139 // int npixel = 64 * 64;
1140 properties->texptime = 0;
1141 double ia_fwhm_corr = 0;
1142 for(cpl_size kexposure = 0; kexposure < properties->ncombine; kexposure++) {
1143
1144 frm = cpl_frameset_get_position(raws_obj, kexposure);
1145 fname = cpl_frame_get_filename(frm);
1146 phead = cpl_propertylist_load(fname, 0);
1147
1148 const char *progid = eris_pfits_get_progid(phead);
1149
1150 long obid = eris_pfits_get_obsid(phead);
1151 cpl_msg_info(cpl_func,"obid: %ld",obid);
1152 dit = eris_pfits_get_dit(phead);
1153 ndit = eris_pfits_get_ndit(phead);
1154 exptime = dit * ndit;
1155
1156 double mjd = eris_pfits_get_mjdobs(phead);
1157
1158 double endtime = mjd + exptime / day2sec;
1159
1160 properties->texptime += exptime;
1161 properties->mjd_end = CPL_MAX(endtime, properties->mjd_end);
1162
1163 /* Get image quality SKY_RES (at the reference wavelength)
1164 * and the associated error for this exposure */
1165
1166
1167 cpl_msg_info(cpl_func,"compute FWHM");
1168 if (strstr(recipe_name, "jitter") != NULL) {
1169 ia_fwhm_corr = eris_ifu_sdp_compute_fwhm(raws_obj);
1170 } else {
1171 /* in STD stars miss a FITS extension required to determine FWHM */
1172 ia_fwhm_corr=7.18;
1173 }
1174
1175 properties->skyres += ia_fwhm_corr;
1176 cpl_msg_info(cpl_func, "compute exposure time");
1177 frm = cpl_frameset_find(set, ERIS_IFU_PRO_JITTER_EXPOSURE_MAP);
1178 cpl_image* expt = cpl_image_load(cpl_frame_get_filename(frm),
1179 CPL_TYPE_DOUBLE, 0, 0);
1180 cpl_mask* bpm = cpl_image_get_bpm(expt);
1181 cpl_mask_threshold_image(bpm, expt, 0, DBL_MAX, CPL_BINARY_0);
1182 cpl_image_set_bpm(expt, bpm);
1183 properties->exptime = cpl_image_get_median(expt);
1184 cpl_image_delete(expt);
1185
1186 /* Observation ID, program ID, etc. */
1187 cpl_array_set_long(properties->obid, kexposure, obid);
1188 if (progid) {
1189 cpl_array_set_string(properties->progid, kexposure, progid);
1190 }
1191
1192 /* provenance */
1193 unsigned int nraw = cpl_propertylist_get_size(properties->prov);
1194 const char *prov = eris_pfits_get_ancestor(phead);
1195
1196 if (!prov) {
1197 prov = eris_pfits_get_arcfile(phead);
1198 if (!prov) {
1199 prov = eris_ifu_pfits_get_origfile(phead);
1200 }
1201 }
1202
1203 if (prov) {
1204 char *name = cpl_sprintf("PROV%-u", ++nraw);
1205 cpl_propertylist_append_string(properties->prov, name, prov);
1206 cpl_free(name);
1207 } else {
1208 unsigned int iraw = 1;
1209 prov =eris_pfits_get_raw_filename(phead, iraw);
1210 while (prov) {
1211 char *name = cpl_sprintf("PROV%-u", ++nraw);
1212 cpl_propertylist_append_string(properties->prov, name, prov);
1213 prov =eris_pfits_get_raw_filename(phead, ++iraw);
1214 cpl_free(name);
1215 }
1216 }
1217
1218 cpl_propertylist_delete(phead);
1219 }
1220 properties->skyres /= properties->ncombine;
1221
1222 //ASSON WAS HERE
1223
1224 /* ABMAGLIM */
1225 double abmaglim = 0.0;
1226
1227 cpl_msg_info(cpl_func,"compute abmaglim");
1228
1229 double pixnoise = 1;
1230 //cpl_frameset_dump(pros_obj,stdout);
1231 pixnoise = eris_ifu_sdp_compute_pixnoise(pros_obj);
1232
1233 properties->pixnoise = pixnoise;
1234 cpl_size nobj = cpl_frameset_get_size(raws_obj);
1235 cpl_frameset_delete(raws_obj);
1236 cpl_msg_info(cpl_func,"obid array size: %lld",
1237 cpl_array_get_size(properties->obid));
1238
1239 cpl_frame* wave_frm = cpl_frameset_find(set, ERIS_IFU_CALIB_WAVE_MAP);
1240 fname = cpl_frame_get_filename(wave_frm);
1241 phead = cpl_propertylist_load(fname, 0);
1242 //double resol_med = cpl_propertylist_get_double(phead, "ESO QC RESOL MED");
1243 ifsBand bandId = eris_ifu_get_band(phead);
1244 double resol_med = eris_ifu_get_band_resolution(bandId);
1245 cpl_propertylist_delete(phead);
1246
1247 hdrl_image* hima_obj_mean = eris_ifu_sdp_get_obj_mean(pros_obj);
1248
1249 cpl_image* ima_obj_mean = hdrl_image_get_image(hima_obj_mean);
1250
1251 double zp = eris_ifu_sdp_compute_zp(bandId);
1252 //double fwhm = 10;
1253 const cpl_size kernel_size_x = 3;
1254 const cpl_size kernel_size_y = 3;
1255
1256 /*Mode parameters*/
1257 double histo_min = 0.;
1258 double histo_max = 0.;
1259 double bin_size = 0.;
1260 cpl_size error_niter = 0;
1261 hdrl_mode_type mode_method = HDRL_MODE_MEDIAN;
1262 /*
1263 hdrl_mode_parameter_parse_parlist(parlist, "eris_ifu_jitter", &histo_min, &histo_max,
1264 &bin_size, &mode_method, &error_niter);
1265 */
1266
1267 hdrl_parameter * mode_parameter = hdrl_collapse_mode_parameter_create(histo_min,
1268 histo_max, bin_size, mode_method, error_niter);
1269
1270 hdrl_maglim_compute(ima_obj_mean, zp, ia_fwhm_corr, kernel_size_x, kernel_size_y,
1271 HDRL_IMAGE_EXTEND_NEAREST, mode_parameter,&abmaglim);
1272 hdrl_parameter_delete(mode_parameter);
1273 hdrl_image_delete(hima_obj_mean);
1274 cpl_msg_info(cpl_func,"HDRL computed abmaglim: %g", abmaglim);
1275 abmaglim = eris_ifu_sdp_compute_abmaglimit(pixnoise, ia_fwhm_corr, bandId);
1276 properties->abmaglimit = abmaglim;
1277 cpl_msg_info(cpl_func,"LODO computed abmaglim: %g", abmaglim);
1278
1279 /* The following IDP properties are simply hard coded here since *
1280 * not supposed to change. */
1281 properties->prodcatg = cpl_strdup(KEY_PRODCATG_VALUE_IFS_CUBE);
1282 properties->obstech = cpl_strdup("IFU");
1283
1284 char *key = cpl_sprintf("ESO PRO REC1 PIPE ID");
1285 if(cpl_propertylist_has(header, key)) {
1286 properties->procsoft = cpl_propertylist_get_string(header, key);
1287 }
1288 cpl_free(key);
1289 properties->referenc = NULL;
1290 if(cpl_propertylist_has(header, KEY_PROG_ID) ){
1291 cpl_propertylist_get_string(header, KEY_PROG_ID);
1292 }
1293 properties->fluxcal = CPL_TRUE;
1294
1295 /* TODO: ASSON */
1296 cpl_size npros = cpl_frameset_get_size(pros_obj);
1297 //cpl_frameset_dump(pros_obj, stdout);
1298 properties->asson = cpl_array_new(npros, CPL_TYPE_STRING);
1299 cpl_size kstart = 0;
1300 if (nobj == 1) {
1301 /* If nobj == 1 3D cube object (ADU) (1st of list) is not associated */
1302 properties->nobj = 1;
1303 kstart = 1;
1304 }
1305 for(cpl_size kexposure = kstart; kexposure < npros; kexposure++) {
1306 frm = cpl_frameset_get_position(pros_obj, kexposure);
1307 fname = cpl_frame_get_filename(frm);
1308 pchead = cpl_propertylist_load(fname, 0);
1309 cpl_array_set_string(properties->asson, kexposure,
1310 eris_pfits_get_pipefile(pchead));
1311 cpl_propertylist_delete(pchead);
1312 }
1313
1314
1315
1316
1317
1318 properties->specres = resol_med;
1319 properties->specsys = cpl_sprintf("TOPOCENT");
1320 //properties->obid = eris_pfits_get_obsid(header);
1321 // double wstart = 0;
1322 // double wend = 100;
1323 if(cpl_propertylist_has(header,"CRVAL3")) {
1324 properties->wlenrange[0] = cpl_propertylist_get_double(header,"CRVAL3");
1325 }
1326
1327 double cd3_3 = 0;
1328 if(cpl_propertylist_has(header,"CD3_3")) {
1329 cd3_3 = cpl_propertylist_get_double(header,"CD3_3");
1330 }
1331 properties->wlenrange[1] = properties->wlenrange[0] + cd3_3 * (double)(naxis3 -1.);
1332
1333 /* TODO
1334 mandatory keyword PIXNOISE is undefined.
1335 mandatory keyword SKY_RES is undefined.
1336 mandatory keyword ABMAGLIM is undefined.
1337 mandatory keyword ext:HDUCLASS is undefined in HDU0.
1338 mandatory keyword ext:HDUCLASS is undefined in HDU1.
1339 mandatory keyword ext:HDUCLASS is undefined in HDU2.
1340 mandatory keyword ext:HDUDOC is undefined in HDU0.
1341 mandatory keyword ext:HDUDOC is undefined in HDU1.
1342 mandatory keyword ext:HDUDOC is undefined in HDU2.
1343 mandatory keyword ext:HDUVERS is undefined in HDU0.
1344 mandatory keyword ext:HDUVERS is undefined in HDU1.
1345 mandatory keyword ext:HDUVERS is undefined in HDU2.
1346 mandatory keyword ext:HDUCLAS1 is undefined in HDU0.
1347 mandatory keyword ext:HDUCLAS1 is undefined in HDU1.
1348 mandatory keyword ext:HDUCLAS1 is undefined in HDU2.
1349
13503. The keywords CDELT are not supported by the SDP standard. They are in every extension.
1351
13524. ORIGFILE must be recorded in the primary header, and not duplicated in any extension.
1353 */
1354 if (pros_obj) cpl_frameset_delete(pros_obj);
1355
1356 //if (raws_obj) cpl_frameset_delete(raws_obj);
1357 eris_check_error_code("eris_ifu_sdp_properties_collect");
1358 return properties;
1359}
1360
1361/*----------------------------------------------------------------------------*/
1362/* Helper functions for quicksort */
1363/*----------------------------------------------------------------------------*/
1364
1366static int cmp_double_asc(const void *p1, const void *p2) {
1367 double d = (*(const double *)p1 - *(const double *)p2);
1368 return (d < 0)?-1:(d>0)?1:0;
1369}
1370
1372static int cmp_double_desc(const void *p1, const void *p2) {
1373 double d = (*(const double *)p1 - *(const double *)p2);
1374 return (d < 0)?1:(d>0)?-1:0;
1375}
1376
1378static int cmp_float_asc(const void *p1, const void *p2) {
1379 float d = (*(const float *)p1 - *(const float *)p2);
1380 return (d < 0)?-1:(d>0)?1:0;
1381}
1382
1384static int cmp_float_desc(const void *p1, const void *p2) {
1385 float d = (*(const float *)p1 - *(const float *)p2);
1386 return (d < 0)?1:(d>0)?-1:0;
1387}
1388
1390static int cmp_int_asc(const void *p1, const void *p2) {
1391 return (*(const int *)p1 - *(const int *)p2);
1392}
1393
1395static int cmp_int_desc(const void *p1, const void *p2) {
1396 return (*(const int *)p2 - *(const int *)p1);
1397}
1398
1400static int cmp_long_asc(const void *p1, const void *p2) {
1401 return (*(const long *)p1 - *(const long *)p2);
1402}
1403
1405static int cmp_long_desc(const void *p1, const void *p2) {
1406 return (*(const long *)p2 - *(const long *)p1);
1407}
1408
1410static int cmp_string_asc(const void *p1, const void *p2) {
1411 return strcmp(*(const char **)p1, *(const char **)p2);
1412}
1413
1415static int cmp_string_desc(const void *p1, const void *p2) {
1416 return strcmp(*(const char **)p2, *(const char **)p1);
1417}
1418
1419/*----------------------------------------------------------------------------*/
1437/*----------------------------------------------------------------------------*/
1438
1439cpl_error_code
1440eris_ifu_cplarray_sort(cpl_array *aArray, cpl_boolean aOrder)
1441{
1442 cpl_ensure_code(aArray != NULL, CPL_ERROR_NULL_INPUT);
1443 cpl_ensure_code(!cpl_array_has_invalid(aArray), CPL_ERROR_NULL_INPUT);
1444
1445 cpl_size n = cpl_array_get_size(aArray);
1446 if (cpl_array_get_type(aArray) == CPL_TYPE_DOUBLE) {
1447 double *d = cpl_array_get_data_double(aArray);
1448 qsort(d, n, sizeof(double), (aOrder)?cmp_double_asc:cmp_double_desc);
1449 return CPL_ERROR_NONE;
1450 } else if (cpl_array_get_type(aArray) == CPL_TYPE_FLOAT) {
1451 float *d = cpl_array_get_data_float(aArray);
1452 qsort(d, n, sizeof(float), (aOrder)?cmp_float_asc:cmp_float_desc);
1453 return CPL_ERROR_NONE;
1454 } else if (cpl_array_get_type(aArray) == CPL_TYPE_INT) {
1455 int *d = cpl_array_get_data_int(aArray);
1456 qsort(d, n, sizeof(int), (aOrder)?cmp_int_asc:cmp_int_desc);
1457 return CPL_ERROR_NONE;
1458 } else if (cpl_array_get_type(aArray) == CPL_TYPE_LONG) {
1459 long *d = cpl_array_get_data_long(aArray);
1460 qsort(d, n, sizeof(long), (aOrder)?cmp_long_asc:cmp_long_desc);
1461 return CPL_ERROR_NONE;
1462 } else if (cpl_array_get_type(aArray) == CPL_TYPE_STRING) {
1463 char **d = cpl_array_get_data_string(aArray);
1464 qsort(d, n, sizeof(char *), (aOrder)?cmp_string_asc:cmp_string_desc);
1465 return CPL_ERROR_NONE;
1466 } else {
1467 return CPL_ERROR_ILLEGAL_INPUT;
1468 }
1469}
1470
1471/*----------------------------------------------------------------------------*/
1506/*----------------------------------------------------------------------------*/
1507
1508cpl_error_code
1509eris_ifu_sdp_properties_update(cpl_propertylist *aHeader,
1510 const eris_ifu_sdp_properties *aProperties)
1511{
1512 cpl_ensure(aHeader && aProperties, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
1513
1514 /* TODO */
1515 cpl_ensure(cpl_array_get_size(aProperties->obid) == aProperties->ncombine,
1516 CPL_ERROR_ILLEGAL_INPUT, CPL_ERROR_ILLEGAL_INPUT);
1517
1518 cpl_ensure(cpl_array_get_size(aProperties->progid) == aProperties->ncombine,
1519 CPL_ERROR_ILLEGAL_INPUT, CPL_ERROR_ILLEGAL_INPUT);
1520 cpl_ensure(cpl_propertylist_get_size(aProperties->prov) >= aProperties->ncombine,
1521 CPL_ERROR_ILLEGAL_INPUT, CPL_ERROR_ILLEGAL_INPUT);
1522
1523
1524 cpl_propertylist_erase_regexp(aHeader, CLEAN_KEYS_REGEXP, 0);
1525
1526 cpl_propertylist_update_double(aHeader, KEY_RA, aProperties->fovcenter[0]);
1527 cpl_propertylist_set_comment(aHeader, KEY_RA, KEY_RA_COMMENT);
1528 cpl_propertylist_update_double(aHeader, KEY_DEC, aProperties->fovcenter[1]);
1529 cpl_propertylist_set_comment(aHeader, KEY_DEC, KEY_DEC_COMMENT);
1530 cpl_propertylist_update_double(aHeader, KEY_EXPTIME, aProperties->exptime);
1531 cpl_propertylist_set_comment(aHeader, KEY_EXPTIME, KEY_EXPTIME_COMMENT);
1532
1533 cpl_propertylist_insert_after_double(aHeader, KEY_EXPTIME,
1534 KEY_TEXPTIME, aProperties->texptime);
1535 cpl_propertylist_set_comment(aHeader, KEY_TEXPTIME, KEY_TEXPTIME_COMMENT);
1536
1537 cpl_propertylist_insert_after_int(aHeader, KEY_TEXPTIME,
1538 KEY_NCOMBINE, aProperties->ncombine);
1539 cpl_propertylist_set_comment(aHeader, KEY_NCOMBINE, KEY_NCOMBINE_COMMENT);
1540
1541 cpl_propertylist_set_comment(aHeader, KEY_MJDOBS, KEY_MJDOBS_COMMENT);
1542 cpl_propertylist_insert_after_double(aHeader, KEY_MJDOBS,
1543 KEY_MJDEND, aProperties->mjd_end);
1544 cpl_propertylist_set_comment(aHeader, KEY_MJDEND, KEY_MJDEND_COMMENT);
1545
1546 /* TODO */
1547 cpl_array *obids = cpl_array_duplicate(aProperties->obid);
1548
1549 eris_ifu_cplarray_sort(obids, CPL_TRUE);
1550
1551 // Add observation block IDs, skipping duplicates
1552 long obid = cpl_array_get_long(obids, 0, NULL);
1553 cpl_msg_warning(cpl_func,"obid: %ld",obid);
1554 cpl_propertylist_update_long(aHeader, KEY_OBID1, obid);
1555 cpl_propertylist_set_comment(aHeader, KEY_OBID1, KEY_OBID_COMMENT);
1556
1557 if (aProperties->ncombine > 1) {
1558 unsigned int ik = 1;
1559 cpl_size idx;
1560 for (idx = 1; idx < aProperties->ncombine; ++idx) {
1561 long _obid = cpl_array_get_long(obids, idx, NULL);
1562 if (_obid != obid) {
1563 char *key = cpl_sprintf(KEY_OBID "%-u", ++ik);
1564 cpl_propertylist_update_long(aHeader, key, _obid);
1565 cpl_propertylist_set_comment(aHeader, key, KEY_OBID_COMMENT);
1566 cpl_free(key);
1567 obid = _obid;
1568 }
1569 }
1570 }
1571 cpl_array_delete(obids);
1572
1573 /* Add the ESO program ID(s). If the product is made from a single program *
1574 * PROG_ID is the ID string, otherwise it set to the special value MULTI, *
1575 * followed by a list of all IDs, skipping duplicate ID values */
1576
1577 /* TODO */
1578 if(aProperties->progid != NULL) {
1579
1580 cpl_array *progids = cpl_array_duplicate(aProperties->progid);
1581
1582 /* TODO */
1583 eris_ifu_cplarray_sort(progids, CPL_TRUE);
1584
1585 const char *progid = cpl_array_get_string(progids, 0);
1586
1587 if (aProperties->ncombine > 1) {
1588 unsigned int nprogid = 1;
1589 cpl_size idx;
1590 for (idx = 1; idx < aProperties->ncombine; ++idx) {
1591 const char *_progid = cpl_array_get_string(progids, idx);
1592 if (strcmp(_progid, progid) != 0) {
1593 progid = _progid;
1594 ++nprogid;
1595 }
1596 }
1597
1598 progid = cpl_array_get_string(progids, 0);
1599 if (nprogid == 1) {
1600 cpl_propertylist_update_string(aHeader, KEY_PROG_ID, progid);
1601 } else {
1602 cpl_propertylist_update_string(aHeader, KEY_PROG_ID,
1603 KEY_PROG_ID_VALUE_MULTIPLE);
1604 cpl_propertylist_update_string(aHeader, KEY_PROGID "1", progid);
1605 cpl_propertylist_set_comment(aHeader, KEY_PROGID "1", KEY_PROGID_COMMENT);
1606
1607 unsigned int ik = 1;
1608 for (idx = 1; idx < aProperties->ncombine; ++idx) {
1609 const char *_progid = cpl_array_get_string(progids, idx);
1610 if (strcmp(_progid, progid) != 0) {
1611 char *key = cpl_sprintf(KEY_PROGID "%-u", ++ik);
1612 cpl_propertylist_update_string(aHeader, key, _progid);
1613 cpl_propertylist_set_comment(aHeader, key, KEY_PROGID_COMMENT);
1614 cpl_free(key);
1615 progid = _progid;
1616 }
1617 }
1618 }
1619 cpl_propertylist_set_comment(aHeader, KEY_PROG_ID, KEY_PROG_ID_COMMENT);
1620
1621 } else {
1622 cpl_propertylist_update_string(aHeader, KEY_PROG_ID, progid);
1623 cpl_propertylist_set_comment(aHeader, KEY_PROG_ID, KEY_PROG_ID_COMMENT);
1624 }
1625 cpl_array_delete(progids);
1626 }
1627
1628
1629 /* Add raw data information */
1630 cpl_propertylist_append(aHeader, aProperties->prov);
1631
1632 /* Add ancillary products file information */
1633 /* TODO */
1634 cpl_size idx_start = 0;
1635 if(aProperties->nobj == 1) {
1636 idx_start = 1;
1637 }
1638
1639 for (cpl_size idx = idx_start; idx < cpl_array_get_size(aProperties->asson); ++idx) {
1640 char *name = cpl_sprintf(KEY_ASSON "%-" CPL_SIZE_FORMAT, idx - idx_start + 1 );
1641 cpl_propertylist_update_string(aHeader, name,
1642 cpl_array_get_string(aProperties->asson, idx));
1643 cpl_free(name);
1644 }
1645
1646
1647 cpl_propertylist_update_string(aHeader, KEY_PRODCATG, aProperties->prodcatg);
1648 cpl_propertylist_set_comment(aHeader, KEY_PRODCATG, KEY_PRODCATG_COMMENT);
1649
1650 cpl_propertylist_update_string(aHeader, KEY_PROCSOFT, aProperties->procsoft);
1651 cpl_propertylist_set_comment(aHeader, KEY_PROCSOFT, KEY_PROCSOFT_COMMENT);
1652
1653 cpl_propertylist_update_string(aHeader, KEY_OBSTECH, aProperties->obstech);
1654 cpl_propertylist_set_comment(aHeader, KEY_OBSTECH, KEY_OBSTECH_COMMENT);
1655
1656 const char *fluxcal = KEY_FLUXCAL_VALUE_TRUE;
1657 if (aProperties->fluxcal == CPL_FALSE) {
1658 fluxcal = KEY_FLUXCAL_VALUE_FALSE;
1659 }
1660
1661 cpl_propertylist_update_string(aHeader, KEY_FLUXCAL, fluxcal);
1662 cpl_propertylist_set_comment(aHeader, KEY_FLUXCAL, KEY_FLUXCAL_COMMENT);
1663 double um2nm = 1000.;
1664 cpl_propertylist_insert_after_double(aHeader, KEY_FLUXCAL, KEY_WAVELMIN,
1665 aProperties->wlenrange[0] * um2nm);
1666 cpl_propertylist_set_comment(aHeader, KEY_WAVELMIN, KEY_WAVELMIN_COMMENT);
1667 cpl_propertylist_insert_after_double(aHeader, KEY_WAVELMIN, KEY_WAVELMAX,
1668 aProperties->wlenrange[1] * um2nm);
1669 cpl_propertylist_set_comment(aHeader, KEY_WAVELMAX, KEY_WAVELMAX_COMMENT);
1670 cpl_propertylist_insert_after_double(aHeader, KEY_WAVELMAX, KEY_SPEC_RES,
1671 aProperties->specres);
1672 cpl_propertylist_set_comment(aHeader, KEY_SPEC_RES, KEY_SPEC_RES_COMMENT);
1673 cpl_propertylist_insert_after_string(aHeader, KEY_SPEC_RES, KEY_SPECSYS,
1674 aProperties->specsys);
1675 cpl_propertylist_set_comment(aHeader, KEY_SPECSYS, KEY_SPECSYS_COMMENT);
1676
1677 /* If any of the properties 'skyres' and 'skyrerr' is negative, the value *
1678 * is a default rather than a measured quantity. Indicate this in the *
1679 * comment. The actual value to be written to the header is the absolute *
1680 * value of the quantity. */
1681
1682 cpl_propertylist_insert_after_double(aHeader, KEY_SPEC_RES, KEY_SKY_RES,
1683 fabs(aProperties->skyres));
1684
1685 const char *method_qualifier = (aProperties->skyres < 0.) ?
1686 "default" : "measured";
1687 char *comment = cpl_sprintf(KEY_SKY_RES_COMMENT " (%s)", method_qualifier);
1688 cpl_propertylist_set_comment(aHeader, KEY_SKY_RES, comment);
1689 cpl_free(comment);
1690 /* TODO
1691 cpl_propertylist_insert_after_double(aHeader, KEY_SKY_RES, KEY_SKY_RERR,
1692 fabs(aProperties->skyrerr));
1693
1694 method_qualifier = (aProperties->skyrerr < 0.) ? "default" : "measured";
1695 comment = cpl_sprintf(KEY_SKY_RERR_COMMENT " (%s)", method_qualifier);
1696 cpl_propertylist_set_comment(aHeader, KEY_SKY_RERR, comment);
1697 cpl_free(comment);
1698 */
1699 cpl_propertylist_insert_after_double(aHeader, KEY_SKY_RES, KEY_PIXNOISE,
1700 aProperties->pixnoise);
1701 cpl_propertylist_set_comment(aHeader, KEY_PIXNOISE, KEY_PIXNOISE_COMMENT);
1702
1703 /* TODO */
1704 cpl_propertylist_insert_after_double(aHeader, KEY_WAVELMAX, KEY_ABMAGLIM,
1705 aProperties->abmaglimit);
1706 cpl_propertylist_set_comment(aHeader, KEY_ABMAGLIM, KEY_ABMAGLIM_COMMENT);
1707
1708 const char *reference = "";
1709 if (aProperties->referenc) {
1710 reference = aProperties->referenc;
1711 }
1712 cpl_propertylist_update_string(aHeader, KEY_REFERENC, reference);
1713 cpl_propertylist_set_comment(aHeader, KEY_REFERENC, KEY_REFERENC_COMMENT);
1714
1715 /* TODO: NEEDED??
1716 cpl_propertylist_insert_after_double(aHeader, KEY_REFERENC, KEY_SPEC_ERR,
1717 aProperties->wlerror);
1718 cpl_propertylist_set_comment(aHeader, KEY_SPEC_ERR, KEY_SPEC_ERR_COMMENT);
1719 */
1720
1721 /* Update data unit values to IDP standards */
1722 /* TODO
1723 if (!strncmp(eris_ifu_pfits_get_cunit(aHeader, 3), "Angstrom", 9)) {
1724 cpl_propertylist_update_string(aHeader, "CUNIT3",
1725 kErisIdpWavelengthUnit);
1726 }
1727 */
1728 /*
1729 if (!strncmp(eris_ifu_pfits_get_bunit(aHeader),
1730 kErisFluxUnitString, strlen(kErisFluxUnitString) + 1)) {
1731 cpl_propertylist_update_string(aHeader, "BUNIT", kErisIdpFluxDataUnit);
1732 }
1733 */
1734
1735 /* Fallback required for IDPs */
1736 /* TODO: not required but would be nice to have them. In such a case we need
1737 * to add correct values
1738
1739 if (!cpl_propertylist_has(aHeader, "CSYER1")) {
1740 cpl_propertylist_update_double(aHeader, "CSYER1", -1.);
1741 cpl_propertylist_set_comment(aHeader, "CSYER1",
1742 "[deg] Systematic error in coordinate");
1743 }
1744 if (!cpl_propertylist_has(aHeader, "CSYER2")) {
1745 cpl_propertylist_update_double(aHeader, "CSYER2", -1.);
1746 cpl_propertylist_set_comment(aHeader, "CSYER2",
1747 "[deg] Systematic error in coordinate");
1748 }
1749 */
1750
1751 eris_check_error_code("eris_ifu_sdp_properties_update");
1752 return CPL_ERROR_NONE;
1753}
1754
1755
ifsPreopticsScale eris_ifu_get_preopticsScale(cpl_propertylist *header)
Return the the pre-optics scaling.
ifsBand eris_ifu_get_band(const cpl_propertylist *header)
Determine preoptic band.
eris_ifu_sdp_properties * eris_ifu_sdp_properties_new(void)
Allocate and initialize new SDP properties structure.
Definition: eris_ifu_sdp.c:791
const char * eris_ifu_pfits_get_origfile(const cpl_propertylist *aHeaders)
Get ORIGFILE keyword value from FITS header.
Definition: eris_ifu_sdp.c:851
cpl_error_code eris_ifu_cplarray_sort(cpl_array *aArray, cpl_boolean aOrder)
Sort CPL array in place using quicksort.
eris_ifu_sdp_properties * eris_ifu_sdp_properties_collect(hdrl_resample_result *aCube, cpl_frameset *set, const cpl_parameterlist *parlist, const char *recipe_name)
Collect all SDP metadata from cube, frameset, and parameters.
void eris_ifu_sdp_properties_delete(eris_ifu_sdp_properties *aProperties)
Free SDP properties structure and all contained data.
Definition: eris_ifu_sdp.c:813
cpl_error_code eris_ifu_sdp_properties_update(cpl_propertylist *aHeader, const eris_ifu_sdp_properties *aProperties)
Update FITS header with ESO Science Data Product keywords.
cpl_error_code eris_ifu_mask_nans_in_hdrlimage(hdrl_image **hima)
Flag NaNs in HDRL image.
double eris_ifu_get_band_resolution(ifsBand band)
Get nominal spectral resolution for a given band.
cpl_mask * eris_ifu_hima_get_obj_mask(hdrl_image *hima, const cpl_size niter, const double kappa)
find mask flagging pixels above a threshold set by ks-clip algorithm
double eris_pfits_get_mjdobs(const cpl_propertylist *aHeaders)
find out the Julian Date of the observation
Definition: eris_pfits.c:811
const char * eris_pfits_get_raw_filename(const cpl_propertylist *aHeaders, unsigned int idx)
find out the i-th raw file name.
Definition: eris_pfits.c:609
const char * eris_pfits_get_arcfile(const cpl_propertylist *plist)
find out the arcfile
Definition: eris_pfits.c:82
double eris_pfits_get_fwhm_start(const cpl_propertylist *aHeaders)
find out the ambient seeing at start of exposure (in arcsec)
Definition: eris_pfits.c:649
double eris_pfits_get_fwhm_end(const cpl_propertylist *aHeaders)
find out the ambient seeing at end of exposure (in arcsec)
Definition: eris_pfits.c:669
const char * eris_pfits_get_pipefile(const cpl_propertylist *aHeaders)
find out the PIPEFILE id
Definition: eris_pfits.c:867
int eris_pfits_get_ndit(const cpl_propertylist *plist)
find out the DIT value
Definition: eris_pfits.c:117
const char * eris_pfits_get_ancestor(const cpl_propertylist *aHeaders)
find out the ancestor of a file.
Definition: eris_pfits.c:65
const char * eris_pfits_get_progid(const cpl_propertylist *aHeaders)
find out the ESO program identification
Definition: eris_pfits.c:829
long eris_pfits_get_obsid(const cpl_propertylist *aHeaders)
find out the observation block id
Definition: eris_pfits.c:848
double eris_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: eris_pfits.c:98
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
Definition: eris_utils.c:56
cpl_frameset * eris_dfs_extract_frames_with_tag(cpl_frameset *input, const char *rtag)
Extract frames of user given tag.
Definition: eris_utils.c:227
hdrl_parameter * hdrl_collapse_mode_parameter_create(double histo_min, double histo_max, double bin_size, hdrl_mode_type mode_method, cpl_size error_niter)
create a parameter object for the mode
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
Definition: hdrl_image.c:407
double hdrl_image_get_stdev(const hdrl_image *self)
computes the standard deviation of the data of an image
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
Definition: hdrl_image.c:295
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
cpl_error_code hdrl_maglim_compute(const cpl_image *image, const double zeropoint, const double fwhm, const cpl_size kernel_size_x, const cpl_size kernel_size_y, const hdrl_image_extend_method image_extend_method, const hdrl_parameter *mode_parameter, double *limiting_magnitude)
Computes the limiting magnitude of an image.
Definition: hdrl_maglim.c:114
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter