32#include "eris_ifu_utils.h"
33#include "eris_ifu_efficiency_response.h"
35#define LICENCE_INFO "This file is part of the ERIS Instrument Pipeline \n\
36 Copyright (C) 2017 European Southern Observatory \n\
38 This program is free software; you can redistribute it and/or modify \n\
39 it under the terms of the GNU General Public License as published by \n\
40 the Free Software Foundation; either version 2 of the License, or\n\
41 (at your option) any later version.\n\
43 This program is distributed in the hope that it will be useful,\n\
44 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
45 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
46 GNU General Public License for more details.\n\
48 You should have received a copy of the GNU General Public License\n\
49 along with this program; if not, write to the Free Software\n\
50 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, \n\
67#define RECIPE_NAME "eris_ifu_efficiency"
68static const char eris_ifu_efficiency_description[] =
69 "This recipe computes the efficiency.\n"
70 "The input files are 1D extracted spectrum and static files\n"
71 "their associated tags are: \n"
72 "SPECTRUM1D, 1D spectrum of a flux STD star (not flatfielded)\n"
73 "FLUX_STD_CATALOG, the catalog of flux std stars \n"
74 "EXTCOEFF_TABLE, The Atmospheric Extinction correction table\n"
75 "EFFICIENCY_WINDOWS, the regions used to compute QC on efficiency\n"
76 "The output is the efficiency spectrum, PRO.CATG: EFFICIENCY\n"
78cpl_recipe_define( eris_ifu_efficiency,
83 "Compute efficiency.",
84 eris_ifu_efficiency_description);
96static cpl_error_code eris_ifu_efficiency_fill_parameterlist(
97 cpl_parameterlist * self) {
100 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, cpl_error_get_code());
103 par = cpl_parameter_new_value(RECIPE_NAME
".der-snr-half-window", CPL_TYPE_INT,
104 "Half window used for noise calculation following the DER-SNR approach."
105 "\nA good value is 2.5 x the resolving power of a spectral line.",
107 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"der-snr-half-window");
108 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
109 cpl_parameterlist_append(self, par);
112 par = cpl_parameter_new_value(RECIPE_NAME
".sampling-period", CPL_TYPE_DOUBLE,
113 "Conversion factor to put the wavelength in [nm]", RECIPE_NAME, 1.0);
114 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"sampling-period");
115 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
116 cpl_parameterlist_append(self, par);
120 par = cpl_parameter_new_value(RECIPE_NAME
".telluric-xcorr-step",
121 CPL_TYPE_DOUBLE,
"Cross correlation step", RECIPE_NAME,
123 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"telluric-xcorr-step");
124 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
125 cpl_parameterlist_append(self, par);
127 par = cpl_parameter_new_value(RECIPE_NAME
".telluric-xcorr-half-window",
128 CPL_TYPE_INT,
"Search window for telluric-xcorr", RECIPE_NAME,
130 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"telluric-xcorr-half-window");
131 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
132 cpl_parameterlist_append(self, par);
135 par = cpl_parameter_new_value(RECIPE_NAME
".telluric-xcorr-normalize",
136 CPL_TYPE_BOOL,
"Normalize telluric-xcorr", RECIPE_NAME,
138 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"telluric-xcorr-normalize");
139 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
140 cpl_parameterlist_append(self, par);
143 par = cpl_parameter_new_value(RECIPE_NAME
".telluric-xcorr-l-min",
144 CPL_TYPE_DOUBLE,
"Cross correlation lmin", RECIPE_NAME,
146 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"telluric-xcorr-l-min");
147 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
148 cpl_parameterlist_append(self, par);
150 par = cpl_parameter_new_value(RECIPE_NAME
".telluric-xcorr-l-max",
151 CPL_TYPE_DOUBLE,
"Cross correlation lmax", RECIPE_NAME,
153 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"telluric-xcorr-l-max");
154 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
155 cpl_parameterlist_append(self, par);
158 par = cpl_parameter_new_value(RECIPE_NAME
".velocity-wguess",
160 "Velocity Calculation: reference line wavelength position",
162 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"velocity-wguess");
163 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
164 cpl_parameterlist_append(self, par);
166 par = cpl_parameter_new_value(RECIPE_NAME
".velocity-enable",
168 "Velocity Calculation: enable",
169 RECIPE_NAME, CPL_FALSE);
170 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"velocity-enable");
171 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
172 cpl_parameterlist_append(self, par);
174 par = cpl_parameter_new_value(RECIPE_NAME
".velocity-range-wmin",
176 "Velocity Calculation: minimum of wavelength box for line fit ",
178 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"velocity-range-wmin");
179 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
180 cpl_parameterlist_append(self, par);
182 par = cpl_parameter_new_value(RECIPE_NAME
".velocity-range-wmax",
184 "Velocity Calculation: maximum of wavelength box for line fit ",
186 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"velocity-range-wmax");
187 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
188 cpl_parameterlist_append(self, par);
190 par = cpl_parameter_new_value(RECIPE_NAME
".velocity-fit-wmin",
192 "Velocity Calculation: minimum wavelength value used to fit line slope",
194 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"velocity-fit-wmin");
195 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
196 cpl_parameterlist_append(self, par);
198 par = cpl_parameter_new_value(RECIPE_NAME
".velocity-fit-wmax",
200 "Velocity Calculation: maximum wavelength value used to fit line slope",
202 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"velocity-fit-wmax");
203 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
204 cpl_parameterlist_append(self, par);
206 par = cpl_parameter_new_value(RECIPE_NAME
".velocity-fit-half-win",
208 "Velocity Calculation: half box where polynomial fit is performed",
210 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"velocity-fit-half-win");
211 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
212 cpl_parameterlist_append(self, par);
214 par = cpl_parameter_new_value(RECIPE_NAME
".response-wrange-median-final-interpolation",
216 "Response calculation: wavelength range to be taken around an interpolation point",
218 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-wrange-median-final-interpolation");
219 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
220 cpl_parameterlist_append(self, par);
223 par = cpl_parameter_new_value(RECIPE_NAME
".response-exposure-time", CPL_TYPE_DOUBLE,
224 "Exposure time in [s]", RECIPE_NAME, 0.0);
225 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-exposure-time");
226 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
227 cpl_parameterlist_append(self, par);
229 par = cpl_parameter_new_value(RECIPE_NAME
".response-exposure-time-error",
230 CPL_TYPE_DOUBLE,
"Exposure time error in [s]", RECIPE_NAME, 0.0);
231 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-exposure-time-error");
232 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
233 cpl_parameterlist_append(self, par);
237 par = cpl_parameter_new_value(RECIPE_NAME
".response-airmass", CPL_TYPE_DOUBLE,
238 "Airmass at which the standard star was observed", RECIPE_NAME, 1.0);
239 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-airmass");
240 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
241 cpl_parameterlist_append(self, par);
243 par = cpl_parameter_new_value(RECIPE_NAME
".response-airmass-error", CPL_TYPE_DOUBLE,
244 "Error on the airmass at which the standard star was observed",
246 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-airmass-error");
247 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
248 cpl_parameterlist_append(self, par);
252 par = cpl_parameter_new_value(RECIPE_NAME
".response-airmass-correction",
253 CPL_TYPE_DOUBLE,
"Parameter to indicate if the response is "
254 "computed at arimass=0, or at a given non-zero value",
256 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-airmass-correction");
257 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
258 cpl_parameterlist_append(self, par);
260 par = cpl_parameter_new_value(RECIPE_NAME
".response-airmass-correction-error",
261 CPL_TYPE_DOUBLE,
"Error on the airmass-correction parameter",
263 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
264 "response-airmass-correction-error");
265 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
266 cpl_parameterlist_append(self, par);
270 par = cpl_parameter_new_value(RECIPE_NAME
".response-gain", CPL_TYPE_DOUBLE,
271 "Detector gain in [e/ADU]", RECIPE_NAME, 1.0);
272 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-gain");
273 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
274 cpl_parameterlist_append(self, par);
276 par = cpl_parameter_new_value(RECIPE_NAME
".response-gain-error",
277 CPL_TYPE_DOUBLE,
"Error on the detector gain in [e/ADU]",
279 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"response-gain-error");
280 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
281 cpl_parameterlist_append(self, par);
286 par = cpl_parameter_new_value(RECIPE_NAME
".flux-scaling-factor",
287 CPL_TYPE_DOUBLE,
"Factor to convert the observed flux from "
288 "actual bin size to Angstrom units", RECIPE_NAME, 1.0);
289 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
"flux-scaling-factor");
290 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
291 cpl_parameterlist_append(self, par);
294 return CPL_ERROR_NONE;
305static int eris_ifu_efficiency(
306 cpl_frameset * frameset,
307 const cpl_parameterlist * parlist)
310 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, -1);
311 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, -1);
318 cpl_propertylist * plist = NULL ;
320 cpl_size fsize = cpl_frameset_get_size(frameset);
321 cpl_frame* frm_sci = NULL;
322 cpl_frame* frm_cat = NULL;
323 cpl_frame* frm_atmext = NULL;
324 cpl_frame * spectrum_frame = NULL;
325 cpl_frame * extcoeff_frame = NULL;
326 cpl_frame * fluxstdcat_frame = NULL;
329 for(cpl_size i = 0; i < fsize; ++i){
330 cpl_frame * cur_frame = cpl_frameset_get_position(frameset, i);
332 if (!strcmp(cpl_frame_get_tag(cur_frame), ERIS_IFU_PRO_JITTER_SPECTRUM)) {
333 spectrum_frame = cpl_frame_duplicate(cur_frame);
334 cpl_msg_info(cpl_func,
"Observed spectrum found in the SOF");
335 }
else if (!strcmp(cpl_frame_get_tag(cur_frame), ERIS_IFU_CALIB_EXTCOEFF_TABLE)) {
336 extcoeff_frame = cpl_frame_duplicate(cur_frame);
337 cpl_msg_info(cpl_func,
"Atm Extinction found in SOF");
338 }
else if (!strcmp(cpl_frame_get_tag(cur_frame), ERIS_IFU_CALIB_FLUX_STD_CATALOG)) {
339 fluxstdcat_frame = cpl_frame_duplicate(cur_frame);
340 cpl_msg_info(cpl_func,
"Std star catalog found in SOF");
342 cpl_msg_info(cpl_func,
"SOF contains unknown tags");
349 const char* fname = cpl_frame_get_filename(spectrum_frame);
350 plist = cpl_propertylist_load(fname, 0);
351 const char* instrume = cpl_propertylist_get_string(plist,
"INSTRUME");
352 cpl_msg_warning(cpl_func,
"instrume: %s",instrume);
354 if(strcmp(instrume,
"ERIS") == 0) {
355 cpl_vector* v = cpl_vector_load(fname, 0);
356 cpl_size sz = cpl_vector_get_size(v);
357 cpl_table* t = cpl_table_new(sz);
358 double crpix1 = cpl_propertylist_get_double(plist,
"CRPIX1");
359 double crval1 = cpl_propertylist_get_double(plist,
"CRVAL1");
360 double cdelt1 = cpl_propertylist_get_double(plist,
"CDELT1");
361 double* wave = cpl_calloc(sz,
sizeof(
double));
362 for(cpl_size i = 0; i < sz; i++) {
363 wave[i] = crval1 + i * cdelt1;
365 cpl_table_wrap_double(t, wave,
"WAVE");
366 cpl_table_wrap_double(t, cpl_vector_get_data(v),
"FLUX");
367 cpl_table_save(t, plist, NULL,
"sci_tab.fits", CPL_IO_CREATE);
368 cpl_vector_delete(v);
369 frm_sci = cpl_frame_duplicate(spectrum_frame);
370 cpl_frame_set_filename(frm_sci,
"sci_tab.fits");
372 frm_sci = cpl_frame_duplicate(spectrum_frame);
374 cpl_frame_set_group(frm_sci, CPL_FRAME_GROUP_RAW);
375 cpl_table* tab_eff = eris_efficiency_compute(frm_sci, fluxstdcat_frame,
376 extcoeff_frame, frameset,
377 parlist, RECIPE_NAME);
378 cpl_propertylist_delete(plist);
379 cpl_table_delete(tab_eff);
380 cpl_frame_delete(frm_sci);
383 return cpl_error_get_code() ? cpl_error_set_where(cpl_func) : 0;
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.