CR2RE Pipeline Reference Manual 1.6.7
hdrl_efficiency.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2017 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include <hdrl_efficiency.h>
29
30#include "hdrl_spectrum.h"
31#include "hdrl_spectrum_resample.h"
32#include "hdrl_parameter.h"
33#include <math.h>
34
35/*-----------------------------------------------------------------------------
36 Private Functions and Data Structures
37 -----------------------------------------------------------------------------*/
38
39/*Parameter used for the efficiency calculation*/
40typedef struct {
41 HDRL_PARAMETER_HEAD;
42 hdrl_value Ap;
43 hdrl_value Am;
44 hdrl_value G;
45 hdrl_value Tex;
46 hdrl_value Atel;
47} hdrl_efficiency_parameters;
48
49static hdrl_parameter_typeobj
50hdrl_efficiency_parameters_type = {
51 HDRL_PARAMETER_EFFICIENCY, /* type */
52 (hdrl_alloc *)&cpl_malloc, /* fp_alloc */
53 (hdrl_free *)&cpl_free, /* fp_free */
54 NULL, /* fp_destroy */
55 sizeof(hdrl_efficiency_parameters), /* obj_size */
56};
57
58static inline cpl_error_code
59hdrl_efficiency_parameter_check(const hdrl_parameter * pars);
60
61static inline hdrl_value
62hdrl_efficiency_parameter_get_Am(const hdrl_parameter * pars);
63static inline hdrl_value
64hdrl_efficiency_parameter_get_Ap(const hdrl_parameter * pars);
65static inline hdrl_value
66hdrl_efficiency_parameter_get_G(const hdrl_parameter * pars);
67static inline hdrl_value
68hdrl_efficiency_parameter_get_Tex(const hdrl_parameter * pars);
69static inline hdrl_value
70hdrl_efficiency_parameter_get_Atel(const hdrl_parameter * pars);
71
72static inline hdrl_spectrum1D *
73select_obs_spectrum(const hdrl_spectrum1D * I_std,
74 const hdrl_spectrum1D * I_std_ref,
75 const hdrl_spectrum1D * E_x);
76
77static inline hdrl_data_t
78lowest_w_max(const cpl_array * a1, const cpl_array * a2);
79
80static inline hdrl_data_t
81highest_w_min(const cpl_array * a1, const cpl_array * a2);
82
87/*-----------------------------------------------------------------------------
88 Functions
89 -----------------------------------------------------------------------------*/
90
91/* ---------------------------------------------------------------------------*/
102/* ---------------------------------------------------------------------------*/
104 const hdrl_value Ap, const hdrl_value Am, const hdrl_value G,
105 const hdrl_value Tex){
106
107 hdrl_efficiency_parameters * p
108 = (hdrl_efficiency_parameters *)
109 hdrl_parameter_new(&hdrl_efficiency_parameters_type);
110
111 p->Am = Am;
112 p->Ap = Ap;
113 p->G = G;
114 p->Tex = Tex;
115 p->Atel = (hdrl_value){0.0, 0.0};
116 return (hdrl_parameter*) p;
117}
118
119
120/* ---------------------------------------------------------------------------*/
132/* ---------------------------------------------------------------------------*/
134 const hdrl_value Ap, const hdrl_value Am, const hdrl_value G,
135 const hdrl_value Tex, const hdrl_value Atel){
136
137 hdrl_efficiency_parameters * p
138 = (hdrl_efficiency_parameters *)
139 hdrl_parameter_new(&hdrl_efficiency_parameters_type);
140
141 p->Am = Am;
142 p->Ap = Ap;
143 p->G = G;
144 p->Tex = Tex;
145 p->Atel = Atel;
146 return (hdrl_parameter*) p;
147}
148
149/* ---------------------------------------------------------------------------*/
177/* ---------------------------------------------------------------------------*/
178
179
180hdrl_spectrum1D *
182const hdrl_spectrum1D * I_std_arg,
183const hdrl_spectrum1D * I_std_ref,
184const hdrl_spectrum1D * E_x,
185const hdrl_parameter * pars){
186
187 cpl_ensure(I_std_arg != NULL, CPL_ERROR_NULL_INPUT, NULL);
188 cpl_ensure(I_std_ref != NULL, CPL_ERROR_NULL_INPUT, NULL);
189 cpl_ensure(E_x != NULL, CPL_ERROR_NULL_INPUT, NULL);
190 cpl_ensure(pars != NULL, CPL_ERROR_NULL_INPUT, NULL);
191
192 const hdrl_value Ap = hdrl_efficiency_parameter_get_Ap(pars);
193 const hdrl_value Am = hdrl_efficiency_parameter_get_Am(pars);
194 const hdrl_value G = hdrl_efficiency_parameter_get_G(pars);
195 const hdrl_value Tex = hdrl_efficiency_parameter_get_Tex(pars);
196
197 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE,
198 CPL_ERROR_ILLEGAL_OUTPUT, NULL);
199
200 hdrl_spectrum1D * I_std = select_obs_spectrum(I_std_arg, I_std_ref, E_x);
201
202 cpl_ensure(I_std != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
203
204 const hdrl_spectrum1D_wavelength spec_wav =
206
208 hdrl_spectrum1D_interp_akima);
209 hdrl_spectrum1D *exponential = hdrl_spectrum1D_resample(E_x, &spec_wav, params);
210 hdrl_parameter_delete(params);
211 cpl_ensure(exponential != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
212
214 hdrl_spectrum1D_interp_akima);
215 hdrl_spectrum1D * I_std_ref_resampled = hdrl_spectrum1D_resample(I_std_ref,
216 &spec_wav, params);
217 hdrl_parameter_delete(params);
218 cpl_ensure(I_std_ref_resampled != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
219
220
221 /* exponent of 10.0*/
222 {
223 hdrl_spectrum1D * exponential2 = hdrl_spectrum1D_duplicate(exponential);
224
225 /*0.4A_pE_x(f) */
226 hdrl_spectrum1D_mul_scalar(exponential, (hdrl_value){0.4, 0.0});
227 hdrl_spectrum1D_mul_scalar(exponential, Ap);
228
229 /*0.4A_mE_x(f) */
230 hdrl_spectrum1D_mul_scalar(exponential2, (hdrl_value){0.4, 0.0});
231 hdrl_spectrum1D_mul_scalar(exponential2, Am);
232
233 /*0.4A_pE_x(f) - 0.4A_mE_x(f) */
234 hdrl_spectrum1D_sub_spectrum(exponential, exponential2);
235
236 hdrl_spectrum1D_delete(&exponential2);
237 }
238
239 hdrl_spectrum1D_exp_scalar(exponential, (hdrl_value){10.0, 0.0});
240 hdrl_spectrum1D_mul_scalar(exponential, G);
241 hdrl_spectrum1D_mul_spectrum(exponential, I_std_ref_resampled);
242 hdrl_spectrum1D_mul_scalar(exponential, Tex);
243 hdrl_spectrum1D_div_spectrum(exponential, I_std);
244
245 hdrl_spectrum1D_delete(&I_std_ref_resampled);
247
248 return exponential;
249}
250
251
252/* ---------------------------------------------------------------------------*/
281/* ---------------------------------------------------------------------------*/
282
283hdrl_spectrum1D * hdrl_efficiency_compute(
284 const hdrl_spectrum1D * I_std_arg,
285 const hdrl_spectrum1D * I_std_ref,
286 const hdrl_spectrum1D * E_x,
287 const hdrl_parameter * pars)
288{
289
290 cpl_ensure(I_std_arg != NULL, CPL_ERROR_NULL_INPUT, NULL);
291 cpl_ensure(I_std_ref != NULL, CPL_ERROR_NULL_INPUT, NULL);
292 cpl_ensure(E_x != NULL, CPL_ERROR_NULL_INPUT, NULL);
293 cpl_ensure(pars != NULL, CPL_ERROR_NULL_INPUT, NULL);
294
295 const hdrl_value Ap = hdrl_efficiency_parameter_get_Ap(pars);
296 const hdrl_value Am = hdrl_efficiency_parameter_get_Am(pars);
297 const hdrl_value G = hdrl_efficiency_parameter_get_G(pars);
298 const hdrl_value Tex = hdrl_efficiency_parameter_get_Tex(pars);
299 const hdrl_value Atel = hdrl_efficiency_parameter_get_Atel(pars);
300
301 cpl_ensure(cpl_error_get_code() == CPL_ERROR_NONE, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
302
303 hdrl_spectrum1D * I_std = select_obs_spectrum(I_std_arg, I_std_ref, E_x);
304 cpl_ensure(I_std != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
305
306 const hdrl_spectrum1D_wavelength spec_wav = hdrl_spectrum1D_get_wavelength(I_std);
307
309 hdrl_spectrum1D_interp_akima);
310 hdrl_spectrum1D * exponential = hdrl_spectrum1D_resample(E_x,
311 &spec_wav, params);
312 hdrl_parameter_delete(params);
313 cpl_ensure(exponential != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
314
316 hdrl_spectrum1D_interp_akima);
317 hdrl_spectrum1D * I_std_ref_resampled = hdrl_spectrum1D_resample(I_std_ref,
318 &spec_wav, params);
319 hdrl_parameter_delete(params);
320 cpl_ensure(I_std_ref_resampled != NULL, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
321
322 /* exponent of 10.0*/
323 {
324 hdrl_spectrum1D * exponential2 = hdrl_spectrum1D_duplicate(exponential);
325
326 /*0.4A_mE_x(f) */
327 hdrl_spectrum1D_mul_scalar(exponential, (hdrl_value){0.4, 0.0});
328 hdrl_spectrum1D_mul_scalar(exponential, Am);
329 /*0.4A_pE_x(f) */
330 hdrl_spectrum1D_mul_scalar(exponential2, (hdrl_value){0.4, 0.0});
331 hdrl_spectrum1D_mul_scalar(exponential2, Ap);
332
333 /*0.4A_mE_x(f) - 0.4A_pE_x(f) */
334 hdrl_spectrum1D_sub_spectrum(exponential, exponential2);
335
336 hdrl_spectrum1D_delete(&exponential2);
337 }
338
339 hdrl_spectrum1D * eph_spec = hdrl_spectrum1D_create_analytic(
340 E_ph, spec_wav.wavelength, spec_wav.scale);
341
342 hdrl_spectrum1D_exp_scalar(exponential, (hdrl_value){10.0, 0.0});
343 hdrl_spectrum1D_mul_scalar(exponential, G);
344 hdrl_spectrum1D_mul_spectrum(exponential, I_std);
345 hdrl_spectrum1D_mul_spectrum(exponential, eph_spec);
346 hdrl_spectrum1D_div_scalar(exponential, Tex);
347 hdrl_spectrum1D_div_scalar(exponential, Atel);
348 hdrl_spectrum1D_div_spectrum(exponential, I_std_ref_resampled);
349
350 hdrl_spectrum1D_delete(&eph_spec);
351 hdrl_spectrum1D_delete(&I_std_ref_resampled);
353 return exponential;
354
355}
356
357/* ---------------------------------------------------------------------------*/
363/* ---------------------------------------------------------------------------*/
364hdrl_value E_ph(hdrl_data_t lambda){
365 const double nm2um = 0.001;
366 const double hc = 1.e7*1.986e-19 / nm2um;
367
368 return (hdrl_value){ hc / lambda, 0.0};
369}
370
371/*-----------------------------------------------------------------------------
372 Private Functions Implementation
373 -----------------------------------------------------------------------------*/
374/* check that hdrl_parameter is an compatible with the efficiency computation
375 * routine.*/
376static inline cpl_error_code
377hdrl_efficiency_parameter_check(const hdrl_parameter * pars){
378
379
380 cpl_ensure_code(pars != NULL, CPL_ERROR_NULL_INPUT);
381
382 cpl_boolean is_compatible = hdrl_parameter_get_parameter_enum(pars) ==
383 HDRL_PARAMETER_EFFICIENCY;
384 cpl_ensure_code(is_compatible , CPL_ERROR_INCOMPATIBLE_INPUT);
385
386 return CPL_ERROR_NONE;
387}
388
389static inline hdrl_value
390hdrl_efficiency_parameter_get_Am(const hdrl_parameter * pars){
391
392 if(hdrl_efficiency_parameter_check(pars))
393 return (hdrl_value){0.0,0.0};
394
395 const hdrl_efficiency_parameters * p
396 = (const hdrl_efficiency_parameters*)pars;
397
398 return p->Am;
399}
400
401static inline hdrl_value
402hdrl_efficiency_parameter_get_Ap(const hdrl_parameter * pars){
403
404 if(hdrl_efficiency_parameter_check(pars))
405 return (hdrl_value){0.0,0.0};
406
407 const hdrl_efficiency_parameters * p
408 = (const hdrl_efficiency_parameters*)pars;
409
410 return p->Ap;
411}
412
413static inline hdrl_value
414hdrl_efficiency_parameter_get_G(const hdrl_parameter * pars){
415
416 if(hdrl_efficiency_parameter_check(pars))
417 return (hdrl_value){0.0,0.0};
418
419 const hdrl_efficiency_parameters * p
420 = (const hdrl_efficiency_parameters*)pars;
421
422 return p->G;
423}
424
425static inline hdrl_value
426hdrl_efficiency_parameter_get_Tex(const hdrl_parameter * pars){
427
428 if(hdrl_efficiency_parameter_check(pars))
429 return (hdrl_value){0.0,0.0};
430
431 const hdrl_efficiency_parameters * p
432 = (const hdrl_efficiency_parameters*)pars;
433
434 return p->Tex;
435}
436
437static inline hdrl_value
438hdrl_efficiency_parameter_get_Atel(const hdrl_parameter * pars){
439
440 if(hdrl_efficiency_parameter_check(pars))
441 return (hdrl_value){0.0,0.0};
442
443 const hdrl_efficiency_parameters * p
444 = (const hdrl_efficiency_parameters*)pars;
445
446 return p->Atel;
447}
448/*get the maximum between the two minimum values of a1 and a2*/
449static inline hdrl_data_t
450highest_w_min(const cpl_array * a1, const cpl_array * a2){
451 const hdrl_data_t w1 = cpl_array_get_min(a1);
452 const hdrl_data_t w2 = cpl_array_get_min(a2);
453
454 return CPL_MAX(w2, w1);
455}
456
457/*get the minimum between the two maximum values of a1 and a2*/
458static inline hdrl_data_t
459lowest_w_max(const cpl_array * a1, const cpl_array * a2){
460 const hdrl_data_t w1 = cpl_array_get_max(a1);
461 const hdrl_data_t w2 = cpl_array_get_max(a2);
462
463 return CPL_MIN(w2, w1);
464}
465
466/*Removes lines inside I_std whose wavelengths are not contained inside I_std_ref
467 * or E_x*/
468static inline hdrl_spectrum1D *
469select_obs_spectrum(const hdrl_spectrum1D * I_std,
470 const hdrl_spectrum1D * I_std_ref,
471 const hdrl_spectrum1D * E_x){
472
473 const cpl_array * w_std_ref =
474 hdrl_spectrum1D_get_wavelength(I_std_ref).wavelength;
475
476 const cpl_array * E_x_ref =
477 hdrl_spectrum1D_get_wavelength(E_x).wavelength;
478
479 const hdrl_data_t w_min = highest_w_min(w_std_ref, E_x_ref);
480 const hdrl_data_t w_max = lowest_w_max(w_std_ref, E_x_ref);
481
482 cpl_ensure(w_min < w_max, CPL_ERROR_ILLEGAL_INPUT, NULL);
483
484 cpl_bivector * wavs = cpl_bivector_new(1);
485 cpl_vector_set(cpl_bivector_get_x(wavs), 0, w_min);
486 cpl_vector_set(cpl_bivector_get_y(wavs), 0, w_max);
487
488 hdrl_spectrum1D * to_ret = hdrl_spectrum1D_select_wavelengths(I_std,
489 wavs, CPL_TRUE);
490
491 cpl_bivector_delete(wavs);
492
493 return to_ret;
494}
495
hdrl_spectrum1D * hdrl_response_core_compute(const hdrl_spectrum1D *I_std_arg, const hdrl_spectrum1D *I_std_ref, const hdrl_spectrum1D *E_x, const hdrl_parameter *pars)
core response calculation
hdrl_parameter * hdrl_response_parameter_create(const hdrl_value Ap, const hdrl_value Am, const hdrl_value G, const hdrl_value Tex)
ctor for the hdrl_parameter for response
hdrl_parameter * hdrl_efficiency_parameter_create(const hdrl_value Ap, const hdrl_value Am, const hdrl_value G, const hdrl_value Tex, const hdrl_value Atel)
ctor for the hdrl_parameter for efficiency
hdrl_value E_ph(hdrl_data_t lambda)
energy of the photon calculation
hdrl_spectrum1D * hdrl_efficiency_compute(const hdrl_spectrum1D *I_std_arg, const hdrl_spectrum1D *I_std_ref, const hdrl_spectrum1D *E_x, const hdrl_parameter *pars)
efficiency calculation
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
cpl_error_code hdrl_spectrum1D_mul_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise multiplication of a spectrum by a scalar, the self parameter is modified
hdrl_spectrum1D * hdrl_spectrum1D_resample(const hdrl_spectrum1D *self, const hdrl_spectrum1D_wavelength *waves, const hdrl_parameter *par)
resample a hdrl_spectrum1D on the wavelengths contained in waves
cpl_error_code hdrl_spectrum1D_div_spectrum(hdrl_spectrum1D *self, const hdrl_spectrum1D *other)
divide one spectrum by another spectrum
hdrl_parameter * hdrl_spectrum1D_resample_interpolate_parameter_create(const hdrl_spectrum1D_interpolation_method method)
constructor for the hdrl_parameter in the case of interpolation
hdrl_spectrum1D * hdrl_spectrum1D_duplicate(const hdrl_spectrum1D *self)
hdrl_spectrum1D copy constructor
void hdrl_spectrum1D_delete(hdrl_spectrum1D **p_self)
hdrl_spectrum1D destructor
cpl_error_code hdrl_spectrum1D_mul_spectrum(hdrl_spectrum1D *self, const hdrl_spectrum1D *other)
multiply one spectrum by another spectrum
cpl_error_code hdrl_spectrum1D_exp_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise power of the scalar to the flux, the self parameter is modified
cpl_error_code hdrl_spectrum1D_sub_spectrum(hdrl_spectrum1D *self, const hdrl_spectrum1D *other)
subtract two spectra
hdrl_spectrum1D_wavelength hdrl_spectrum1D_get_wavelength(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter for wavelengths
hdrl_spectrum1D * hdrl_spectrum1D_create_analytic(calculate_analytic_spectrum_point func, const cpl_array *wavelength, hdrl_spectrum1D_wave_scale scale)
hdrl_spectrum1D constructor in the case of a spectrum defined by an analytical function
hdrl_spectrum1D * hdrl_spectrum1D_select_wavelengths(const hdrl_spectrum1D *self, const cpl_bivector *windows, const cpl_boolean is_internal)
the function selects or discards flux values according to whether the value of the corresponding wave...
cpl_error_code hdrl_spectrum1D_div_scalar(hdrl_spectrum1D *self, hdrl_value scalar_operator)
computes the elementwise division of a spectrum by a scalar, the self parameter is modified