ERIS Pipeline Reference Manual 1.9.2
eris_ifu_response.c
1/* $Id: eris_ifu_response.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_efficiency_response.h"
33#include "eris_ifu_dfs.h"
34#define LICENCE_INFO "This file is part of the ERIS Instrument Pipeline \n\
35 Copyright (C) 2017 European Southern Observatory \n\
36 \n\
37 This program is free software; you can redistribute it and/or modify \n\
38 it under the terms of the GNU General Public License as published by \n\
39 the Free Software Foundation; either version 2 of the License, or\n\
40 (at your option) any later version.\n\
41 \n\
42 This program is distributed in the hope that it will be useful,\n\
43 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
44 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
45 GNU General Public License for more details.\n\
46 \n\
47 You should have received a copy of the GNU General Public License\n\
48 along with this program; if not, write to the Free Software\n\
49 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, \n\
50 MA 02111-1307 USA"
51
52
53
54
55#define KEY_NAME_FILT_NAME "ESO INS3 SPGW ID"
56
57/*-----------------------------------------------------------------------------
58 Plugin registration
59 -----------------------------------------------------------------------------*/
60
61
62/*-----------------------------------------------------------------------------
63 Private function prototypes
64 -----------------------------------------------------------------------------*/
65
66
67/*-----------------------------------------------------------------------------
68 Static variables
69 -----------------------------------------------------------------------------*/
70#define RECIPE_NAME "eris_ifu_response"
71static const char eris_ifu_response_description[] =
72 "This recipe computes the response.\n"
73 "The input files are 1D extracted spectrum and static files\n"
74 "their associated tags are: \n"
75 "SPECTRUM1D, 1D spectrum of a flux STD star (not flatfielded)\n"
76 "FLUX_STD_CATALOG, the catalog of flux std stars \n"
77 "EXTCOEFF_TABLE, The Atmospheric Extinction correction table\n"
78 "EFFICIENCY_WINDOWS, the regions used to compute QC on response\n"
79 "The output is the response spectrum, PRO.CATG: EFFICIENCY\n"
80 "\n";
81cpl_recipe_define( eris_ifu_response,
82 ERIS_BINARY_VERSION,
83 "Andrea Modigliani",
84 "usd-help@eso.org",
85 "2018",
86 "Compute response.",
87 eris_ifu_response_description);
88/*-----------------------------------------------------------------------------
89 Function code
90 -----------------------------------------------------------------------------*/
91
92/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100static cpl_error_code eris_ifu_response_fill_parameterlist(
101 cpl_parameterlist * self) {
102
103 cpl_parameter * par ;
104
105 /* hdrldemo_response window for noise calculation */
106 par = cpl_parameter_new_value(RECIPE_NAME".der-snr-half-window", CPL_TYPE_INT,
107 "Half window used for noise calculation following the DER-SNR approach."
108 "\nA good value is 2.5 x the resolving power of a spectral line.",
109 RECIPE_NAME, 10);
110 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "der-snr-half-window");
111 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
112 cpl_parameterlist_append(self, par);
113
114 /* hdrldemo_response sampling period, to calculate wavelengths */
115 par = cpl_parameter_new_value(RECIPE_NAME".sampling-period", CPL_TYPE_DOUBLE,
116 "Conversion factor to put the wavelength in [nm]", RECIPE_NAME, 1.0);
117 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "sampling-period");
118 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
119 cpl_parameterlist_append(self, par);
120
121 /* ------------------ Telluric Calculation parameters ------------------ */
122
123 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-step",
124 CPL_TYPE_DOUBLE, "Cross correlation step", RECIPE_NAME,
125 10.0);
126 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "telluric-xcorr-step");
127 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
128 cpl_parameterlist_append(self, par);
129
130 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-half-window",
131 CPL_TYPE_INT, "Search window for telluric-xcorr", RECIPE_NAME,
132 200);
133 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "telluric-xcorr-half-window");
134 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
135 cpl_parameterlist_append(self, par);
136
137
138 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-normalize",
139 CPL_TYPE_BOOL, "Normalize telluric-xcorr", RECIPE_NAME,
140 CPL_TRUE);
141 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "telluric-xcorr-normalize");
142 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
143 cpl_parameterlist_append(self, par);
144
145
146 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-l-min",
147 CPL_TYPE_DOUBLE, "Cross correlation lmin", RECIPE_NAME,
148 7.);
149 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "telluric-xcorr-l-min");
150 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
151 cpl_parameterlist_append(self, par);
152
153 par = cpl_parameter_new_value(RECIPE_NAME".telluric-xcorr-l-max",
154 CPL_TYPE_DOUBLE, "Cross correlation lmax", RECIPE_NAME,
155 7.1);
156 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "telluric-xcorr-l-max");
157 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
158 cpl_parameterlist_append(self, par);
159
160 /* ------------------ Velocity Calculation parameters ------------------ */
161 par = cpl_parameter_new_value(RECIPE_NAME".velocity-wguess",
162 CPL_TYPE_DOUBLE,
163 "Velocity Calculation: reference line wavelength position",
164 RECIPE_NAME, 0.0);
165 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "velocity-wguess");
166 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
167 cpl_parameterlist_append(self, par);
168
169 par = cpl_parameter_new_value(RECIPE_NAME".velocity-enable",
170 CPL_TYPE_BOOL,
171 "Velocity Calculation: enable",
172 RECIPE_NAME, CPL_FALSE);
173 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "velocity-enable");
174 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
175 cpl_parameterlist_append(self, par);
176
177 par = cpl_parameter_new_value(RECIPE_NAME".velocity-range-wmin",
178 CPL_TYPE_DOUBLE,
179 "Velocity Calculation: minimum of wavelength box for line fit ",
180 RECIPE_NAME, 0.0);
181 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "velocity-range-wmin");
182 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
183 cpl_parameterlist_append(self, par);
184
185 par = cpl_parameter_new_value(RECIPE_NAME".velocity-range-wmax",
186 CPL_TYPE_DOUBLE,
187 "Velocity Calculation: maximum of wavelength box for line fit ",
188 RECIPE_NAME, 0.0);
189 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "velocity-range-wmax");
190 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
191 cpl_parameterlist_append(self, par);
192
193 par = cpl_parameter_new_value(RECIPE_NAME".velocity-fit-wmin",
194 CPL_TYPE_DOUBLE,
195 "Velocity Calculation: minimum wavelength value used to fit line slope",
196 RECIPE_NAME, 0.0);
197 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "velocity-fit-wmin");
198 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
199 cpl_parameterlist_append(self, par);
200
201 par = cpl_parameter_new_value(RECIPE_NAME".velocity-fit-wmax",
202 CPL_TYPE_DOUBLE,
203 "Velocity Calculation: maximum wavelength value used to fit line slope",
204 RECIPE_NAME, 0.0);
205 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "velocity-fit-wmax");
206 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
207 cpl_parameterlist_append(self, par);
208
209 par = cpl_parameter_new_value(RECIPE_NAME".velocity-fit-half-win",
210 CPL_TYPE_DOUBLE,
211 "Velocity Calculation: half box where polynomial fit is performed",
212 RECIPE_NAME, 0.0);
213 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "velocity-fit-half-win");
214 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
215 cpl_parameterlist_append(self, par);
216
217 par = cpl_parameter_new_value(RECIPE_NAME".response-wrange-median-final-interpolation",
218 CPL_TYPE_DOUBLE,
219 "Response calculation: wavelength range to be taken around an interpolation point",
220 RECIPE_NAME, 0.0);
221 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-wrange-median-final-interpolation");
222 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
223 cpl_parameterlist_append(self, par);
224
225 /*-------------------------- Exposure Time -------------------------*/
226 par = cpl_parameter_new_value(RECIPE_NAME".response-exposure-time", CPL_TYPE_DOUBLE,
227 "Exposure time in [s]", RECIPE_NAME, 0.0);
228 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-exposure-time");
229 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
230 cpl_parameterlist_append(self, par);
231
232 par = cpl_parameter_new_value(RECIPE_NAME".response-exposure-time-error",
233 CPL_TYPE_DOUBLE, "Exposure time error in [s]", RECIPE_NAME, 0.0);
234 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-exposure-time-error");
235 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
236 cpl_parameterlist_append(self, par);
237 /*-------------------------- Exposure Time -------------------------*/
238
239 /*----------------------------- Airmass ----------------------------*/
240 par = cpl_parameter_new_value(RECIPE_NAME".response-airmass", CPL_TYPE_DOUBLE,
241 "Airmass at which the standard star was observed", RECIPE_NAME, 1.0);
242 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-airmass");
243 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
244 cpl_parameterlist_append(self, par);
245
246 par = cpl_parameter_new_value(RECIPE_NAME".response-airmass-error", CPL_TYPE_DOUBLE,
247 "Error on the airmass at which the standard star was observed",
248 RECIPE_NAME, 0.0);
249 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-airmass-error");
250 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
251 cpl_parameterlist_append(self, par);
252 /*----------------------------- Airmass ----------------------------*/
253
254 /*----------------------- Airmass correction -----------------------*/
255 par = cpl_parameter_new_value(RECIPE_NAME".response-airmass-correction",
256 CPL_TYPE_DOUBLE, "Parameter to indicate if the response is "
257 "computed at arimass=0, or at a given non-zero value",
258 RECIPE_NAME, 0.0);
259 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-airmass-correction");
260 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
261 cpl_parameterlist_append(self, par);
262
263 par = cpl_parameter_new_value(RECIPE_NAME".response-airmass-correction-error",
264 CPL_TYPE_DOUBLE, "Error on the airmass-correction parameter",
265 RECIPE_NAME, 0.0);
266 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
267 "response-airmass-correction-error");
268 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
269 cpl_parameterlist_append(self, par);
270 /*----------------------- Airmass correction -----------------------*/
271
272 /*------------------------------ Gain ------------------------------*/
273 par = cpl_parameter_new_value(RECIPE_NAME".response-gain", CPL_TYPE_DOUBLE,
274 "Detector gain in [e/ADU]", RECIPE_NAME, 1.0);
275 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-gain");
276 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
277 cpl_parameterlist_append(self, par);
278
279 par = cpl_parameter_new_value(RECIPE_NAME".response-gain-error",
280 CPL_TYPE_DOUBLE, "Error on the detector gain in [e/ADU]",
281 RECIPE_NAME, 0.0);
282 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "response-gain-error");
283 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
284 cpl_parameterlist_append(self, par);
285 /*------------------------------ Gain ------------------------------*/
286
287
288 /*--------------------- Flux scaling factor ------------------------*/
289 par = cpl_parameter_new_value(RECIPE_NAME".flux-scaling-factor",
290 CPL_TYPE_DOUBLE, "Factor to convert the observed flux from "
291 "actual bin size to Angstrom units", RECIPE_NAME, 1.0);
292 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, "flux-scaling-factor");
293 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
294 cpl_parameterlist_append(self, par);
295 /*--------------------- Flux scaling factor ------------------------*/
296
297 return CPL_ERROR_NONE;
298}
299
300#define ERIS_STD_STAR_SPECTRUM "STD_STAR_SPECTRUM"
301#define ERIS_EXTCOEFF_TABLE "EXTCOEFF_TABLE"
302#define ERIS_FLUX_STD_CATALOG "FLUX_STD_CATALOG"
303/*----------------------------------------------------------------------------*/
310/*----------------------------------------------------------------------------*/
311static int eris_ifu_response(
312 cpl_frameset * frameset,
313 const cpl_parameterlist * parlist)
314{
315
316 cpl_ensure(frameset != NULL, CPL_ERROR_NULL_INPUT, -1);
317 cpl_ensure(parlist != NULL, CPL_ERROR_NULL_INPUT, -1);
318 eris_ifu_dfs_set_groups(frameset);
319 cpl_size fsize = cpl_frameset_get_size(frameset);
320 cpl_frame* frm_sci = NULL;
321 cpl_frame* extcoeff_frame = NULL;
322 cpl_frame * spectrum_frame = NULL;
323 cpl_frame * fluxstdcat_frame = NULL;
324 cpl_propertylist* plist = NULL;
325 for(cpl_size i = 0; i < fsize; ++i){
326 cpl_frame * cur_frame = cpl_frameset_get_position(frameset, i);
327
328 if (!strcmp(cpl_frame_get_tag(cur_frame), ERIS_STD_STAR_SPECTRUM)) {
329 spectrum_frame = cpl_frame_duplicate(cur_frame);
330 cpl_msg_info(cpl_func, "Observed spectrum found in the SOF");
331 } else if (!strcmp(cpl_frame_get_tag(cur_frame), ERIS_EXTCOEFF_TABLE)) {
332 extcoeff_frame = cpl_frame_duplicate(cur_frame);
333 cpl_msg_info(cpl_func, "Atm Extinction found in SOF");
334 } else if (!strcmp(cpl_frame_get_tag(cur_frame), ERIS_FLUX_STD_CATALOG)) {
335 fluxstdcat_frame = cpl_frame_duplicate(cur_frame);
336 cpl_msg_info(cpl_func, "Std star catalog found in SOF");
337 }
338 }
339
340 /* convert input frame from image to table to fit with what is expected */
341 const char* fname = cpl_frame_get_filename(spectrum_frame);
342 plist = cpl_propertylist_load(fname, 0);
343 cpl_vector* v = cpl_vector_load(fname, 0);
344 if (v != NULL) {
345 cpl_size sz = cpl_vector_get_size(v);
346 cpl_table* t = cpl_table_new(sz);
347 double crpix1 = cpl_propertylist_get_double(plist, "CRPIX1");
348 double crval1 = cpl_propertylist_get_double(plist, "CRVAL1");
349 double cdelt1 = cpl_propertylist_get_double(plist, "CDELT1");
350 double* wave = cpl_calloc(sz, sizeof(double));
351 for(cpl_size i = 0; i < sz; i++) {
352 wave[i] = crval1 + i * cdelt1;
353 }
354 cpl_table_wrap_double(t, wave, "WAVE");
355 cpl_table_wrap_double(t, cpl_vector_get_data(v), "FLUX");
356 cpl_table_save(t, plist, NULL, "sci_tab.fits", CPL_IO_CREATE);
357 cpl_vector_delete(v);
358 cpl_frameset_erase(frameset, ERIS_STD_STAR_SPECTRUM);
359
360 frm_sci = cpl_frame_duplicate(spectrum_frame);
361 cpl_frame_set_filename(frm_sci, "sci_tab.fits");
362 cpl_frameset_insert(frameset, frm_sci);
363
364
365 const char* plugin_id = RECIPE_NAME;
366
367 eris_response_compute(plugin_id, parlist, frameset, frameset);
368 }
369 cpl_propertylist_delete(plist);
370
371
372
373 return cpl_error_get_code() ? (int)cpl_error_set_where(cpl_func) : 0;
374}
375
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