ERIS Pipeline Reference Manual 1.9.2
eris_ifu_efficiency.c
1/* $Id: eris_ifu_efficiency.c,v 0.1 2018-07-22 06:06:06 agudo 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25/*-----------------------------------------------------------------------------
26 Includes
27 -----------------------------------------------------------------------------*/
28#include <cpl.h>
29#include "hdrl.h"
30#include <string.h>
31
32#include "eris_ifu_utils.h"
33#include "eris_ifu_efficiency_response.h"
34
35#define LICENCE_INFO "This file is part of the ERIS Instrument Pipeline \n\
36 Copyright (C) 2017 European Southern Observatory \n\
37 \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\
42 \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\
47 \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\
51 MA 02111-1307 USA"
52
53
54
55/*-----------------------------------------------------------------------------
56 Plugin registration
57 -----------------------------------------------------------------------------*/
58
59
60/*-----------------------------------------------------------------------------
61 Private function prototypes
62 -----------------------------------------------------------------------------*/
63
64/*-----------------------------------------------------------------------------
65 Static variables
66 -----------------------------------------------------------------------------*/
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"
77 "\n";
78cpl_recipe_define( eris_ifu_efficiency,
79 ERIS_BINARY_VERSION,
80 "Andrea Modigliani",
81 "usd-help@eso.org",
82 "2022",
83 "Compute efficiency.",
84 eris_ifu_efficiency_description);
85/*-----------------------------------------------------------------------------
86 Function code
87 -----------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96static cpl_error_code eris_ifu_efficiency_fill_parameterlist(
97 cpl_parameterlist * self) {
98
99 cpl_parameter * par ;
100 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, cpl_error_get_code());
101
102 /* hdrldemo_response window for noise calculation */
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.",
106 RECIPE_NAME, 10);
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);
110
111 /* hdrldemo_response sampling period, to calculate wavelengths */
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);
117
118 /* ------------------ Telluric Calculation parameters ------------------ */
119
120 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-step",
121 CPL_TYPE_DOUBLE, "Cross correlation step", RECIPE_NAME,
122 10.0);
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);
126
127 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-half-window",
128 CPL_TYPE_INT, "Search window for telluric-xcorr", RECIPE_NAME,
129 200);
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);
133
134
135 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-normalize",
136 CPL_TYPE_BOOL, "Normalize telluric-xcorr", RECIPE_NAME,
137 CPL_TRUE);
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);
141
142
143 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-l-min",
144 CPL_TYPE_DOUBLE, "Cross correlation lmin", RECIPE_NAME,
145 7.);
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);
149
150 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-l-max",
151 CPL_TYPE_DOUBLE, "Cross correlation lmax", RECIPE_NAME,
152 7.1);
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);
156
157 /* ------------------ Velocity Calculation parameters ------------------ */
158 par = cpl_parameter_new_value(RECIPE_NAME".velocity-wguess",
159 CPL_TYPE_DOUBLE,
160 "Velocity Calculation: reference line wavelength position",
161 RECIPE_NAME, 0.0);
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);
165
166 par = cpl_parameter_new_value(RECIPE_NAME".velocity-enable",
167 CPL_TYPE_BOOL,
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);
173
174 par = cpl_parameter_new_value(RECIPE_NAME".velocity-range-wmin",
175 CPL_TYPE_DOUBLE,
176 "Velocity Calculation: minimum of wavelength box for line fit ",
177 RECIPE_NAME, 0.0);
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);
181
182 par = cpl_parameter_new_value(RECIPE_NAME".velocity-range-wmax",
183 CPL_TYPE_DOUBLE,
184 "Velocity Calculation: maximum of wavelength box for line fit ",
185 RECIPE_NAME, 0.0);
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);
189
190 par = cpl_parameter_new_value(RECIPE_NAME".velocity-fit-wmin",
191 CPL_TYPE_DOUBLE,
192 "Velocity Calculation: minimum wavelength value used to fit line slope",
193 RECIPE_NAME, 0.0);
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);
197
198 par = cpl_parameter_new_value(RECIPE_NAME".velocity-fit-wmax",
199 CPL_TYPE_DOUBLE,
200 "Velocity Calculation: maximum wavelength value used to fit line slope",
201 RECIPE_NAME, 0.0);
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);
205
206 par = cpl_parameter_new_value(RECIPE_NAME".velocity-fit-half-win",
207 CPL_TYPE_DOUBLE,
208 "Velocity Calculation: half box where polynomial fit is performed",
209 RECIPE_NAME, 0.0);
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);
213
214 par = cpl_parameter_new_value(RECIPE_NAME".response-wrange-median-final-interpolation",
215 CPL_TYPE_DOUBLE,
216 "Response calculation: wavelength range to be taken around an interpolation point",
217 RECIPE_NAME, 0.0);
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);
221
222 /*-------------------------- Exposure Time -------------------------*/
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);
228
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);
234 /*-------------------------- Exposure Time -------------------------*/
235
236 /*----------------------------- Airmass ----------------------------*/
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);
242
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",
245 RECIPE_NAME, 0.0);
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);
249 /*----------------------------- Airmass ----------------------------*/
250
251 /*----------------------- Airmass correction -----------------------*/
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",
255 RECIPE_NAME, 0.0);
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);
259
260 par = cpl_parameter_new_value(RECIPE_NAME".response-airmass-correction-error",
261 CPL_TYPE_DOUBLE, "Error on the airmass-correction parameter",
262 RECIPE_NAME, 0.0);
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);
267 /*----------------------- Airmass correction -----------------------*/
268
269 /*------------------------------ Gain ------------------------------*/
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);
275
276 par = cpl_parameter_new_value(RECIPE_NAME".response-gain-error",
277 CPL_TYPE_DOUBLE, "Error on the detector gain in [e/ADU]",
278 RECIPE_NAME, 0.0);
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);
282 /*------------------------------ Gain ------------------------------*/
283
284
285 /*--------------------- Flux scaling factor ------------------------*/
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);
292 /*--------------------- Flux scaling factor ------------------------*/
293
294 return CPL_ERROR_NONE;
295}
296
297/*----------------------------------------------------------------------------*/
304/*----------------------------------------------------------------------------*/
305static int eris_ifu_efficiency(
306 cpl_frameset * frameset,
307 const cpl_parameterlist * parlist)
308{
309
310 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, -1);
311 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, -1);
312 /*
313 const cpl_parameter * param = NULL ;
314 const char * name_o = NULL ;
315 const char * name_i = NULL ;
316 const char * name_m = NULL ;
317 */
318 cpl_propertylist * plist = NULL ;
319
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;
327
328 eris_ifu_dfs_set_groups(frameset);
329 for(cpl_size i = 0; i < fsize; ++i){
330 cpl_frame * cur_frame = cpl_frameset_get_position(frameset, i);
331
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");
341 } else{
342 cpl_msg_info(cpl_func, "SOF contains unknown tags");
343 }
344 }
345
346
347
348 /* convert input frame from image to table to fit with what is expected */
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);
353 if (plist != NULL) {
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;
364 }
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");
371 } else {
372 frm_sci = cpl_frame_duplicate(spectrum_frame);
373 }
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);
381 }
382
383 return cpl_error_get_code() ? cpl_error_set_where(cpl_func) : 0;
384}
385
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