CR2RE Pipeline Reference Manual 1.6.7
hdrl_efficiency-test.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 <math.h>
31#include <cpl.h>
32
33/*----------------------------------------------------------------------------*/
37/*----------------------------------------------------------------------------*/
38
39void test_efficiency(void){
40
41 cpl_size sz = 10;
42 cpl_image * flux = cpl_image_new(sz,1, CPL_TYPE_DOUBLE);
43 cpl_image * flux_e = cpl_image_new(sz,1, CPL_TYPE_DOUBLE);
44 cpl_array * waves = cpl_array_new(sz, CPL_TYPE_DOUBLE);
45
46 for(cpl_size i = 0; i < sz; ++i){
47 cpl_image_set(flux, i + 1, 1, (i + 1) * 2.5);
48 cpl_image_set(flux_e, i + 1, 1, (i + 1) * .02);
49 cpl_array_set(waves, i, (i + 1) * 3.0);
50 }
51
52 hdrl_spectrum1D * sp_obs =
53 hdrl_spectrum1D_create(flux, flux_e, waves, hdrl_spectrum1D_wave_scale_linear);
54
55 for(cpl_size i = 0; i < sz; ++i){
56 cpl_image_set(flux, i + 1, 1, (i + 1) * 0.5);
57 cpl_image_set(flux_e, i + 1, 1, 0.0);
58 cpl_array_set(waves, i, (i + 1) * 3.0);
59 }
60
61 hdrl_spectrum1D * sp_std =
62 hdrl_spectrum1D_create(flux, flux_e, waves, hdrl_spectrum1D_wave_scale_linear);
63
64 for(cpl_size i = 0; i < sz; ++i){
65 cpl_image_set(flux, i + 1, 1, (i + 1) * 1.5);
66 cpl_image_set(flux_e, i + 1, 1, 0.0);
67 cpl_array_set(waves, i, (i + 1) * 3.0);
68 }
69
70 hdrl_spectrum1D * sp_ext =
71 hdrl_spectrum1D_create(flux, flux_e, waves, hdrl_spectrum1D_wave_scale_linear);
72
73
74 hdrl_parameter * pars = hdrl_efficiency_parameter_create(
75 (hdrl_value){1.2, 0.0},
76 (hdrl_value){0.4, 0.0},
77 (hdrl_value){11.*12., 0.0},
78 (hdrl_value){1.1, 0.0},
79 (hdrl_value){2.2, 0.0});
80
81 hdrl_spectrum1D * sp_eff =
82 hdrl_efficiency_compute(sp_obs, sp_std, sp_ext, pars);
83
84 hdrl_parameter_delete(pars); pars = NULL;
85
86 hdrl_value v = hdrl_spectrum1D_get_flux_value(sp_eff, 3, NULL);
87 cpl_test_abs(v.data, 3.75528e-06, 1e-5);
88 cpl_test_abs(v.error, 3.00422e-08, 1e-5);
89
90 cpl_array_delete(waves);
91 cpl_image_delete(flux);
92 cpl_image_delete(flux_e);
97}
98
99/* Given the simplified formula: I_std * 10 ^(-0.4 * E_x)* E_ph we calculated the
100 * analytical error propagation function using the Wolfram Alpha website and we
101 * check this analytical model against the error propagation in the hdrl library.*/
102hdrl_value get_error(const hdrl_value s, const hdrl_value x, const hdrl_data_t l){
103 hdrl_error_t err = (hdrl_error_t)(exp(-1.84207 * x.data));
104 err *= (hdrl_error_t)(0.848304 * pow(x.error, 2.0) * pow(s.data, 2.0) +
105 pow(s.error, 2.0));
106
107 hdrl_data_t ephot = (hdrl_data_t)fabs(E_ph(l).data);
108 hdrl_data_t data = (hdrl_data_t)(s.data * pow(10.0, -0.4 * x.data));
109
110 const hdrl_value to_ret = {data * ephot, sqrt(err) * (hdrl_error_t)ephot};
111 return to_ret;
112}
113
114/* test error propagation using analytical model. We simplify the problem,
115 * everything, except extinction and observed spectrum are considered error-free.
116 * The values are set so that the formula becomes = I_std * 10 ^(0.4 * E_x)* E_ph.
117 * We want to exercise the exponential which has been implemented for this feature.*/
118void test_efficiency_error_propagation(void){
119
120 const cpl_size len = 20;
121
122 cpl_image * std_obs_flux = cpl_image_new(len, 1, CPL_TYPE_DOUBLE);
123 cpl_image * std_obs_flux_e = cpl_image_new(len, 1, CPL_TYPE_DOUBLE);
124
125 cpl_image * std_model_flux = cpl_image_new(len, 1, CPL_TYPE_DOUBLE);
126 cpl_image * std_model_flux_e = cpl_image_new(len, 1, CPL_TYPE_DOUBLE);
127
128 cpl_image * ext_flux = cpl_image_new(len, 1, CPL_TYPE_DOUBLE);
129 cpl_image * ext_flux_e = cpl_image_new(len, 1, CPL_TYPE_DOUBLE);
130
131 cpl_array * wave = cpl_array_new(len, CPL_TYPE_DOUBLE);
132
133 hdrl_value Ap = {3.0, 0.0};
134 hdrl_value Am = {2.0, 0.0};
135 hdrl_value G = {1.0, 0.0};
136 hdrl_value Tex = {1.0, 0.0};
137 hdrl_value Atel = {1.0, 0.0};
138
139
140 for(cpl_size i = 0; i < len; ++i){
141
142 const double l = (i * .3 + 1.0) * 1e-4;
143 cpl_array_set(wave, i, l);
144
145 cpl_image_set(std_obs_flux, i + 1, 1, sin(l * CPL_MATH_PI));
146 cpl_image_set(std_obs_flux_e, i + 1, 1, 0.2 * sin(l * CPL_MATH_PI));
147
148 cpl_image_set(ext_flux, i + 1, 1, 1.7 * sin(l * CPL_MATH_PI));
149 cpl_image_set(ext_flux_e, i + 1, 1, 0.02 * sin(l * CPL_MATH_PI));
150
151 /* denominator must be always 1*/
152 cpl_image_set(std_model_flux, i + 1, 1, 1.0);
153 cpl_image_set(std_model_flux_e, i + 1, 1, 0.0);
154 }
155
156 hdrl_spectrum1D * I_std = hdrl_spectrum1D_create(std_obs_flux, std_obs_flux_e,
157 wave, hdrl_spectrum1D_wave_scale_linear);
158
159 hdrl_spectrum1D * I_ref_std = hdrl_spectrum1D_create(std_model_flux,
160 std_model_flux_e, wave, hdrl_spectrum1D_wave_scale_linear);
161
162 hdrl_spectrum1D * ext = hdrl_spectrum1D_create(ext_flux, ext_flux_e,
163 wave, hdrl_spectrum1D_wave_scale_linear);
164
165 cpl_image_delete(std_obs_flux);
166 cpl_image_delete(std_obs_flux_e);
167
168 cpl_image_delete(std_model_flux);
169 cpl_image_delete(std_model_flux_e);
170
171 cpl_image_delete(ext_flux);
172 cpl_image_delete(ext_flux_e);
173
174
175 hdrl_parameter * pars =
176 hdrl_efficiency_parameter_create(Ap, Am, G, Tex, Atel);
177
178 hdrl_spectrum1D * eff = hdrl_efficiency_compute(I_std,
179 I_ref_std, ext, pars);
180
181 for(cpl_size i = 0; i < len; ++i){
182 int rej;
183 const hdrl_value eff_i1 = hdrl_spectrum1D_get_flux_value(eff, i, &rej);
184
185 const hdrl_value I_std_i = hdrl_spectrum1D_get_flux_value(I_std, i, &rej);
186 const hdrl_value ext_i = hdrl_spectrum1D_get_flux_value(ext, i, &rej);
187
188 const hdrl_data_t w = cpl_array_get(wave, i, &rej);
189
190 const hdrl_value eff_i2 = get_error(I_std_i, ext_i, w);
191
192 cpl_test_rel(eff_i1.data, eff_i2.data, 1e-5);
193 cpl_test_rel(eff_i1.error, eff_i2.error, 1e-5);
194 }
195
196 cpl_array_delete(wave);
197
199
201 hdrl_spectrum1D_delete(&I_ref_std);
203
205}
206
207void test_efficiency_spectrum_external_to_models(void){
208
209 cpl_size sz = 10;
210 cpl_image * flux = cpl_image_new(sz,1, CPL_TYPE_DOUBLE);
211 cpl_image * flux_e = cpl_image_new(sz,1, CPL_TYPE_DOUBLE);
212 cpl_array * waves = cpl_array_new(sz, CPL_TYPE_DOUBLE);
213
214 for(cpl_size i = 0; i < sz; ++i){
215 cpl_image_set(flux, i + 1, 1, (i + 1) * 2.5);
216 cpl_image_set(flux_e, i + 1, 1, (i + 1) * .02);
217
218 if(i == sz - 1)
219 cpl_array_set(waves, i, 3.0 * (sz + 5));
220 else
221 cpl_array_set(waves, i, (i - 1) * 3.0);
222 }
223
224 cpl_array * waves_obs = cpl_array_duplicate(waves);
225
226 hdrl_spectrum1D * sp_obs =
227 hdrl_spectrum1D_create(flux, flux_e, waves, hdrl_spectrum1D_wave_scale_linear);
228
229 for(cpl_size i = 0; i < sz; ++i){
230 cpl_image_set(flux, i + 1, 1, (i + 1) * 0.5);
231 cpl_image_set(flux_e, i + 1, 1, 0.0);
232 cpl_array_set(waves, i, (i + 1) * 3.0);
233 }
234
235 hdrl_spectrum1D * sp_std =
236 hdrl_spectrum1D_create(flux, flux_e, waves, hdrl_spectrum1D_wave_scale_linear);
237
238 for(cpl_size i = 0; i < sz; ++i){
239 cpl_image_set(flux, i + 1, 1, (i + 1) * 1.5);
240 cpl_image_set(flux_e, i + 1, 1, 0.0);
241 cpl_array_set(waves, i, (i + 2) * 3.0);
242 }
243
244 hdrl_spectrum1D * sp_ext =
245 hdrl_spectrum1D_create(flux, flux_e, waves, hdrl_spectrum1D_wave_scale_linear);
246
247
248 hdrl_parameter * pars = hdrl_efficiency_parameter_create(
249 (hdrl_value){1.2, 0.0},
250 (hdrl_value){0.4, 0.0},
251 (hdrl_value){11. * 12., 0.0},
252 (hdrl_value){1.1, 0.0},
253 (hdrl_value){2.2, 0.0});
254
255 hdrl_spectrum1D * sp_eff =
256 hdrl_efficiency_compute(sp_obs, sp_std, sp_ext, pars);
257
258 hdrl_parameter_delete(pars); pars = NULL;
259
260 cpl_test_eq(hdrl_spectrum1D_get_size(sp_eff), sz - 4);
261
262 const cpl_array * wavs_eff =
263 hdrl_spectrum1D_get_wavelength(sp_eff).wavelength;
264
265 for(cpl_size i = 3; i < sz - 1; ++i){
266
267 double w_f = cpl_array_get(wavs_eff, i - 3, NULL);
268 double w_obs = cpl_array_get(waves_obs, i, NULL);
269
270 cpl_test_rel(w_f, w_obs, 1e-16);
271 }
272
273 cpl_array_delete(waves);
274 cpl_array_delete(waves_obs);
275 cpl_image_delete(flux);
276 cpl_image_delete(flux_e);
277 hdrl_spectrum1D_delete(&sp_obs);
278 hdrl_spectrum1D_delete(&sp_std);
279 hdrl_spectrum1D_delete(&sp_eff);
280 hdrl_spectrum1D_delete(&sp_ext);
281}
282
283
284/*----------------------------------------------------------------------------*/
288/*----------------------------------------------------------------------------*/
289int main(void)
290{
291 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
292
293 test_efficiency();
294 test_efficiency_error_propagation();
295 test_efficiency_spectrum_external_to_models();
296
297 cpl_test_error(CPL_ERROR_NONE);
298
299 return cpl_test_end(0);
300}
301
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_size hdrl_spectrum1D_get_size(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter for size
void hdrl_spectrum1D_delete(hdrl_spectrum1D **p_self)
hdrl_spectrum1D destructor
hdrl_spectrum1D * hdrl_spectrum1D_create(const cpl_image *arg_flux, const cpl_image *arg_flux_e, const cpl_array *wavelength, hdrl_spectrum1D_wave_scale wave_scale)
hdrl_spectrum1D default constructor
hdrl_spectrum1D_wavelength hdrl_spectrum1D_get_wavelength(const hdrl_spectrum1D *self)
hdrl_spectrum1D getter for wavelengths
hdrl_value hdrl_spectrum1D_get_flux_value(const hdrl_spectrum1D *self, int idx, int *rej)
hdrl_spectrum1D getter for a flux value