CR2RE Pipeline Reference Manual 1.6.8
hdrl_strehl-test.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2014 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_strehl.c"
29#include "hdrl_strehl.h"
30#include "hdrl_test.h"
31
32#include <cpl.h>
33
34#include <math.h>
35#include <string.h>
36
37#ifndef ARRAY_LEN
38#define ARRAY_LEN(a) sizeof((a))/sizeof((a)[0])
39#endif
40
41
42/*----------------------------------------------------------------------------*/
46/*----------------------------------------------------------------------------*/
47
48void hdrl_strehl_test_parlist(void)
49{
50 /* Test null parameters */
51 hdrl_parameter *pFake1 = hdrl_strehl_parameter_create(
52 0., 0., 0., 0., 0., 0., 0., 0.);
53 hdrl_strehl_parameter_verify(NULL);
54 cpl_test_error(CPL_ERROR_NULL_INPUT);
56
57
58 /* parameter parsing smoketest */
59 double wavelength = 1.635e-6;
60 double m1 = 5.08/2;
61 double m2 = 5.08/2*0.36;
62 double psx = 0.0331932/2.;
63 double psy = 0.0331932/2.;
64 double r1 = 1.5;
65 double r2 = 1.5;
66 double r3 = 2.0;
67
68
69 /* Create parameter */
70 hdrl_parameter * hpar;
71 hdrl_parameter * strehl_def =
72 hdrl_strehl_parameter_create(wavelength, m1, m2, psx, psy, r1, r2, r3);
73
74
75 /* Check parameter */
76 cpl_test(!hdrl_strehl_parameter_check(pFake1));
77 cpl_test( hdrl_strehl_parameter_check(strehl_def));
78 cpl_test_error(CPL_ERROR_NONE);
79
80
81 /* Gets */
82
83 cpl_test_eq(hdrl_strehl_parameter_get_wavelength(NULL), -1.);
84 cpl_test_error(CPL_ERROR_NULL_INPUT);
85 cpl_test_eq(hdrl_strehl_parameter_get_wavelength(strehl_def), wavelength);
86 cpl_test_error(CPL_ERROR_NONE);
87
88 cpl_test_eq(hdrl_strehl_parameter_get_m1(NULL), -1.);
89 cpl_test_error(CPL_ERROR_NULL_INPUT);
90 cpl_test_eq(hdrl_strehl_parameter_get_m1(strehl_def), m1);
91 cpl_test_error(CPL_ERROR_NONE);
92
93 cpl_test_eq(hdrl_strehl_parameter_get_m2(NULL), -1);
94 cpl_test_error(CPL_ERROR_NULL_INPUT);
95 cpl_test_eq(hdrl_strehl_parameter_get_m2(strehl_def), m2);
96 cpl_test_error(CPL_ERROR_NONE);
97
98 cpl_test_eq(hdrl_strehl_parameter_get_pixel_scale_x(NULL), -1);
99 cpl_test_error(CPL_ERROR_NULL_INPUT);
100 cpl_test_eq(hdrl_strehl_parameter_get_pixel_scale_x(strehl_def), psx);
101 cpl_test_error(CPL_ERROR_NONE);
102
103 cpl_test_eq(hdrl_strehl_parameter_get_pixel_scale_y(NULL), -1);
104 cpl_test_error(CPL_ERROR_NULL_INPUT);
105 cpl_test_eq(hdrl_strehl_parameter_get_pixel_scale_y(strehl_def), psy);
106 cpl_test_error(CPL_ERROR_NONE);
107
108 cpl_test_eq(hdrl_strehl_parameter_get_flux_radius(NULL), -1);
109 cpl_test_error(CPL_ERROR_NULL_INPUT);
110 cpl_test_eq(hdrl_strehl_parameter_get_flux_radius(strehl_def), r1);
111 cpl_test_error(CPL_ERROR_NONE);
112
113 cpl_test_eq(hdrl_strehl_parameter_get_bkg_radius_low(NULL), -1);
114 cpl_test_error(CPL_ERROR_NULL_INPUT);
115 cpl_test_eq(hdrl_strehl_parameter_get_bkg_radius_low(strehl_def), r2);
116 cpl_test_error(CPL_ERROR_NONE);
117
118 cpl_test_eq(hdrl_strehl_parameter_get_bkg_radius_high(NULL), -1);
119 cpl_test_error(CPL_ERROR_NULL_INPUT);
120 cpl_test_eq(hdrl_strehl_parameter_get_bkg_radius_high(strehl_def), r3);
121 cpl_test_error(CPL_ERROR_NONE);
122
123
124 cpl_parameterlist * strehl = hdrl_strehl_parameter_create_parlist(
125 "RECIPE", "strehl", strehl_def);
126
127 hdrl_parameter_delete(strehl_def);
128 cpl_test_error(CPL_ERROR_NONE);
129
130 cpl_test_eq(cpl_parameterlist_get_size(strehl), 8);
131
132 hpar = hdrl_strehl_parameter_parse_parlist(strehl, "RECIPE.invalid");
133 cpl_test_null(hpar);
134 cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
135
136 hpar = hdrl_strehl_parameter_parse_parlist(strehl, "RECIPE.strehl");
137 cpl_parameterlist_delete(strehl);
138 cpl_test_error(CPL_ERROR_NONE);
139 {
140 cpl_test_eq(hdrl_strehl_parameter_get_wavelength(hpar), wavelength);
141 cpl_test_eq(hdrl_strehl_parameter_get_m1(hpar), m1);
142 cpl_test_eq(hdrl_strehl_parameter_get_m2(hpar), m2);
143 cpl_test_eq(hdrl_strehl_parameter_get_pixel_scale_x(hpar), psx);
144 cpl_test_eq(hdrl_strehl_parameter_get_pixel_scale_y(hpar), psy);
145 cpl_test_eq(hdrl_strehl_parameter_get_flux_radius(hpar), r1);
146 cpl_test_eq(hdrl_strehl_parameter_get_bkg_radius_low(hpar), r2);
147 cpl_test_eq(hdrl_strehl_parameter_get_bkg_radius_high(hpar), r3);
148 }
149
151}
152
153/*----------------------------------------------------------------------------*/
158/*----------------------------------------------------------------------------*/
159static hdrl_image* hdrl_strehl_test_gauss_create(void)
160{
161
162 double sig_x = 3.;
163 double sig_y = 3.;
164 cpl_size n = 5;
165 double dmad;
166 hdrl_image* hgauss;
167 cpl_image * gauss_data;
168 cpl_image * gauss_error;
169
170 gauss_data = cpl_image_new(2 * n + 1, 2 * n + 1, CPL_TYPE_DOUBLE);
171 cpl_image_fill_gaussian(gauss_data, n + 1, n + 1, (double)121.0, sig_x, sig_y);
172 gauss_error = cpl_image_duplicate(gauss_data);
173 cpl_image_multiply_scalar(gauss_error, 0);
174 cpl_image_get_mad(gauss_data, &dmad);
175 cpl_image_add_scalar(gauss_error, (dmad * CPL_MATH_STD_MAD));
176
177 hgauss = hdrl_image_create(gauss_data, gauss_error);
178 cpl_image_delete(gauss_data);
179 cpl_image_delete(gauss_error);
180
181 return hgauss;
182}
183
184
185/*----------------------------------------------------------------------------*/
190/*----------------------------------------------------------------------------*/
191static cpl_error_code hdrl_strehl_test_null_input(void)
192{
193 double w;
194
195 double m1 = 5.08/2;
196 double m2 = 5.08/2*0.36;
197 double psx = 0.0331932/2.;
198 double psy = 0.0331932/2.;
199 double r1 = 1.5;
200 double r2 = 1.5;
201 double r3 = 2.0;
202
203 hdrl_parameter *strehl_param;
204 hdrl_strehl_result strehl_result;
205
206 /* test functionality - Image null*/
207 hdrl_image *hima = NULL;
208 w = 1.635e-6;
209 strehl_param = hdrl_strehl_parameter_create(w, m1, m2, psx, psy, r1, r2, r3);
210 cpl_test(hdrl_strehl_parameter_check(strehl_param));
211 strehl_result = hdrl_strehl_compute(hima, strehl_param) ;
212 cpl_test_error(CPL_ERROR_NULL_INPUT);
213 hdrl_parameter_delete(strehl_param) ;
214 cpl_test(isnan(strehl_result.strehl_value.data));
215
216 /* Strehl Parameter wrong */
217 hima = hdrl_image_new(10, 10);
218 w = -1.;
219 strehl_param = hdrl_strehl_parameter_create(w, m1, m2, psx, psy, r1, r2, r3);
220 cpl_test(!hdrl_strehl_parameter_check(strehl_param));
221 strehl_result = hdrl_strehl_compute(hima, strehl_param);
222 cpl_test_error(CPL_ERROR_NULL_INPUT);
223 hdrl_parameter_delete(strehl_param);
224 hdrl_image_delete(hima);
225 cpl_test(isnan(strehl_result.strehl_value.data));
226
227 return cpl_error_get_code();
228}
229
230/*----------------------------------------------------------------------------*/
235/*----------------------------------------------------------------------------*/
236static cpl_error_code hdrl_strehl_test_illegal_input(void)
237{
238 double w = 1.635e-6;
239 double m1 = 5.08/2;
240 double m2 = 5.08/2*0.36;
241 double psx = 0.0331932/2.;
242 double psy = 0.0331932/2.;
243 double r1 = 1.5;
244 double r2 = 1.5;
245 double r3 = 2.0;
246
247 hdrl_image * hima = hdrl_strehl_test_gauss_create();
248 hdrl_parameter * strehl_param;
249
250 strehl_param = hdrl_strehl_parameter_create(-1, m1, m2, psx, psy, r1, r2, r3);
251 cpl_test_null(strehl_param);
252 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
253
254 strehl_param = hdrl_strehl_parameter_create(w, -1, m2, psx, psy, r1, r2, r3);
255 cpl_test_null(strehl_param);
256 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
257
258 strehl_param = hdrl_strehl_parameter_create(w, m1, -1, psx, psy, r1, r2, r3);
259 cpl_test_null(strehl_param);
260 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
261 strehl_param = hdrl_strehl_parameter_create(w, m1, m2, -1, psy, r1, r2, r3);
262 cpl_test_null(strehl_param);
263 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
264 strehl_param = hdrl_strehl_parameter_create(w, m1, m2, psx, -1, r1, r2, r3);
265 cpl_test_null(strehl_param);
266 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
267 strehl_param = hdrl_strehl_parameter_create(w, m1, m2, psx, psy, -1, r2, r3);
268 cpl_test_null(strehl_param);
269 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
270 strehl_param = hdrl_strehl_parameter_create(w, m1, m2, psx, psy, r1, -1, r3);
271 cpl_test_null(strehl_param);
272 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
273 strehl_param = hdrl_strehl_parameter_create(w, m1, m2, psx, psy, r1, r2, -1);
274 cpl_test_null(strehl_param);
275 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
276 strehl_param = hdrl_strehl_parameter_create(w, m1, m1 + 1, psx, psy, r1, r2, r3);
277 cpl_test_null(strehl_param);
278 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
279
280 hdrl_image_delete(hima);
281
282 return cpl_error_get_code();
283}
284
285
286
287/*----------------------------------------------------------------------------*/
292/*----------------------------------------------------------------------------*/
293
294void test_psf(void)
295{
296 double m1 = 8.3 / 2; /* telescope mirror radii [m] */
297 double m2 = 1.1 / 2; /* telescope obstruction radii [m] */
298 size_t nx = 256; /* PSF image X size */
299 size_t ny = 256; /* PSF image Y size */
300 size_t hx = nx / 2; /* pixel position of peak (FITS) */
301 size_t hy = ny / 2; /* pixel position of peak (FITS) */
302 double peak; /* expected PSF peak value */
303 int rej;
304
305
306 double wavelength = 7.7e-6; /* observing wavelength in [m] */
307 double pscale_x = 0.075; /* pixel scale in x [as] */
308 double pscale_y = 0.075; /* pixel scale in y [as] */
309
310 /* exactly centered psf (symmetric) */
311 cpl_image * psf = compute_psf(wavelength, m1, m2, pscale_x, pscale_y,
312 hx, hy,
313 nx, ny);
314 peak = 0.670695;
315 cpl_test_abs(cpl_image_get(psf, hx, hy, &rej), 1., 1e-4);
316 cpl_test_abs(cpl_image_get(psf, hx - 1, hy, &rej), peak, 1e-4);
317 cpl_test_abs(cpl_image_get(psf, hx, hy - 1, &rej), peak, 1e-4);
318 cpl_test_abs(cpl_image_get(psf, hx + 1, hy, &rej), peak, 1e-4);
319 cpl_test_abs(cpl_image_get(psf, hx, hy + 1, &rej), peak, 1e-4);
320 cpl_image_delete(psf);
321
322 /* exactly centered psf (symmetric) one pixel lower in x */
323 psf = compute_psf(wavelength, m1, m2, pscale_x, pscale_y,
324 hx - 1, hy,
325 nx, ny);
326 cpl_test_abs(cpl_image_get(psf, hx - 1, hy, &rej), 1., 1e-4);
327 cpl_test_abs(cpl_image_get(psf, hx - 2, hy, &rej), peak, 1e-4);
328 cpl_test_abs(cpl_image_get(psf, hx - 1, hy - 1, &rej), peak, 1e-4);
329 cpl_test_abs(cpl_image_get(psf, hx, hy, &rej), peak, 1e-4);
330 cpl_test_abs(cpl_image_get(psf, hx - 1, hy + 1, &rej), peak, 1e-4);
331 cpl_image_delete(psf);
332
333 /* centered at origin of pixel -> square block */
334 psf = compute_psf(wavelength, m1, m2, pscale_x, pscale_y,
335 hx - 0.5, hy - 0.5,
336 nx, ny);
337 peak = 0.821877;
338 cpl_test_abs(cpl_image_get(psf, hx, hy, &rej), peak, 1e-4);
339 cpl_test_abs(cpl_image_get(psf, hx - 1, hy - 1, &rej), peak, 1e-4);
340 cpl_test_abs(cpl_image_get(psf, hx, hy - 1, &rej), peak, 1e-4);
341 cpl_test_abs(cpl_image_get(psf, hx - 1, hy, &rej), peak, 1e-4);
342 cpl_image_delete(psf);
343
344 /* + .75 / 0.25 */
345 psf = compute_psf(wavelength, m1, m2, pscale_x, pscale_y,
346 hx + .75, hy + .25,
347 nx, ny);
348 cpl_test_abs(cpl_image_get(psf, hx, hy, &rej), 0.781698, 1e-4);
349 cpl_test_abs(cpl_image_get(psf, hx - 1, hy, &rej), 0.255305, 1e-4);
350 cpl_test_abs(cpl_image_get(psf, hx, hy - 1, &rej), 0.411749, 1e-4);
351 cpl_test_abs(cpl_image_get(psf, hx + 1, hy, &rej), 0.952739, 1e-4);
352 cpl_test_abs(cpl_image_get(psf, hx, hy + 1, &rej), 0.636695, 1e-4);
353 cpl_image_delete(psf);
354
355 /* centered at origin of pixel -> square block
356 * asymmetric pixel scale */
357 psf = compute_psf(wavelength, m1, m2, pscale_x, 0.025,
358 hx - 0.5, hy - 0.5,
359 nx, ny);
360 peak = 0.897496;
361 cpl_test_abs(cpl_image_get(psf, hx, hy, &rej), peak, 1e-4);
362 cpl_test_abs(cpl_image_get(psf, hx - 1, hy - 1, &rej), peak, 1e-4);
363 cpl_test_abs(cpl_image_get(psf, hx, hy - 1, &rej), peak, 1e-4);
364 cpl_test_abs(cpl_image_get(psf, hx - 1, hy, &rej), peak, 1e-4);
365 /* x direction tails */
366 peak = 0.383906;
367 cpl_test_abs(cpl_image_get(psf, hx + 1, hy, &rej), peak, 1e-4);
368 cpl_test_abs(cpl_image_get(psf, hx + 1, hy - 1, &rej), peak, 1e-4);
369 cpl_test_abs(cpl_image_get(psf, hx - 2, hy, &rej), peak, 1e-4);
370 cpl_test_abs(cpl_image_get(psf, hx - 2, hy - 1, &rej), peak, 1e-4);
371 /* y direction tails */
372 peak = 0.821877;
373 cpl_test_abs(cpl_image_get(psf, hx, hy + 1, &rej), peak, 1e-4);
374 cpl_test_abs(cpl_image_get(psf, hx - 1, hy + 1, &rej), peak, 1e-4);
375 cpl_test_abs(cpl_image_get(psf, hx, hy - 2, &rej), peak, 1e-4);
376 cpl_test_abs(cpl_image_get(psf, hx - 1, hy - 2, &rej), peak, 1e-4);
377 cpl_image_delete(psf);
378
379 /* exactly centered psf (symmetric) double sampled*/
380 hx = nx; /* fits */
381 hy = ny; /* fits */
382 psf = compute_psf(wavelength, m1, m2, pscale_x / 2., pscale_y / 2.,
383 hx, hx,
384 nx * 2, ny * 2);
385 peak = 0.907339;
386 cpl_test_abs(cpl_image_get(psf, hx, hy, &rej), 1., 1e-4);
387 cpl_test_abs(cpl_image_get(psf, hx - 1, hy, &rej), peak, 1e-4);
388 cpl_test_abs(cpl_image_get(psf, hx, hy - 1, &rej), peak, 1e-4);
389 cpl_test_abs(cpl_image_get(psf, hx + 1, hy, &rej), peak, 1e-4);
390 cpl_test_abs(cpl_image_get(psf, hx, hy + 1, &rej), peak, 1e-4);
391 cpl_image_delete(psf);
392
393 /* centered at origin of pixel -> square block
394 * asymmetric pixel scale and image size*/
395 ny = 2 * nx;
396 hx = nx / 2; /* fits */
397 hy = ny / 2; /* fits */
398 psf = compute_psf(wavelength, m1, m2, pscale_x, 0.025,
399 hx - 0.5, hy - 0.5,
400 nx, ny);
401 peak = 0.897496;
402 cpl_test_abs(cpl_image_get(psf, hx, hy, &rej), peak, 1e-4);
403 cpl_test_abs(cpl_image_get(psf, hx - 1, hy - 1, &rej), peak, 1e-4);
404 cpl_test_abs(cpl_image_get(psf, hx, hy - 1, &rej), peak, 1e-4);
405 cpl_test_abs(cpl_image_get(psf, hx - 1, hy, &rej), peak, 1e-4);
406 /* x direction tails */
407 peak = 0.383906;
408 cpl_test_abs(cpl_image_get(psf, hx + 1, hy, &rej), peak, 1e-4);
409 cpl_test_abs(cpl_image_get(psf, hx + 1, hy - 1, &rej), peak, 1e-4);
410 cpl_test_abs(cpl_image_get(psf, hx - 2, hy, &rej), peak, 1e-4);
411 cpl_test_abs(cpl_image_get(psf, hx - 2, hy - 1, &rej), peak, 1e-4);
412 /* y direction tails */
413 peak = 0.821877;
414 cpl_test_abs(cpl_image_get(psf, hx, hy + 1, &rej), peak, 1e-4);
415 cpl_test_abs(cpl_image_get(psf, hx - 1, hy + 1, &rej), peak, 1e-4);
416 cpl_test_abs(cpl_image_get(psf, hx, hy - 2, &rej), peak, 1e-4);
417 cpl_test_abs(cpl_image_get(psf, hx - 1, hy - 2, &rej), peak, 1e-4);
418 cpl_image_delete(psf);
419}
420
421
422void test_strehl_with_bkg(void)
423{
424 hdrl_image * himg;
425 cpl_image * img;
426 hdrl_strehl_result r;
427 /* TODO add more unit tests */
428 double m1 = 8.3 / 2;
429 double m2 = 1.1 / 2;
430 size_t nx = 256;
431 size_t ny = 256;
432 double lam = 7.7e-6;
433 /* oversampled image, 0.075 would be about 2*nyquist */
434 double pscale = 0.03;
435
436 /* realistic bkg slope */
437 double slope_x = 1. / nx * 100;
438
439 img = compute_psf(lam, m1, m2, pscale, pscale, nx / 2., ny / 2., nx, ny);
440
441 /* we multiply for a large factor to make sure that the psf has high S/N */
442 cpl_image_multiply_scalar(img, 2000.);
443
444 /* create a background image with a simple slope along X direction */
445 cpl_image *bkg = cpl_image_duplicate(img);
446 cpl_image_multiply_scalar(bkg, 0);
447 double *pbkg=cpl_image_get_data_double(bkg);
448
449
450 for(size_t j = 0; j < ny; j++) {
451 for(size_t i = 0; i < nx; i++) {
452 pbkg[i+nx*j] = i * slope_x;
453 }
454 }
455 cpl_image_add(img, bkg);
456 /*
457 cpl_image_save(img, "data.fits", CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
458 cpl_image_save(bkg, "bkg.fits", CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
459 */
460
461 himg = hdrl_image_create(img, NULL);
462
463 /* upsampling/downsampling introduces an error */
464 double rel = 0.015;
465
466 /* real test starts here: we need to subtract bkg from proper region */
467 r = compute_strehl(himg, lam, m1, m2, pscale, pscale, .5, 2.5, 3.0);
468 cpl_test_abs(r.strehl_value.data, 1.0, rel);
469
470 hdrl_image_delete(himg);
471 cpl_image_delete(img);
472 cpl_image_delete(bkg);
473
474}
475
476void test_strehl(void)
477{
478 hdrl_image * himg;
479 cpl_image * img;
480 hdrl_strehl_result r;
481 /* TODO add more unit tests */
482 double m1 = 8.3 / 2;
483 double m2 = 1.1 / 2;
484 size_t nx = 256;
485 size_t ny = 256;
486 double lam = 7.7e-6;
487 /* oversampled image, 0.075 would be about 2*nyquist */
488 double pscale = 0.03;
489 img = compute_psf(lam, m1, m2, pscale, pscale,
490 nx / 2, ny / 2, nx, ny);
491 himg = hdrl_image_create(img, NULL);
492
493 /* add unmasked larger maximum */
494 hdrl_image_set_pixel(himg, 28, 231, (hdrl_value){1.5, 1.5});
495
496 /* bad background */
497 compute_strehl(himg, lam, m1, m2, pscale, pscale, 1.5, -1, 4.);
498 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
499
500 compute_strehl(himg, lam, m1, m2, pscale, pscale, 1.5, 4., -1);
501 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
502
503 compute_strehl(himg, lam, m1, m2, pscale, pscale, 1.5, 5, 5);
504 cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
505 cpl_mask_not(hdrl_image_get_mask(himg));
506
507 compute_strehl(himg, lam, m1, m2, pscale, pscale, 1.5, 5, 6);
508 cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
509 cpl_mask_not(hdrl_image_get_mask(himg));
510
511 /* upsampling/downsampling introduces an error */
512 double rel = 0.015;
513
514 r = compute_strehl(himg, lam, m1, m2, pscale, pscale, .5, -1, -1);
515 cpl_test_abs(r.strehl_value.data, 1.0, rel);
516 cpl_test_abs(r.star_x, nx / 2., rel);
517 cpl_test_abs(r.star_y, nx / 2., rel);
518
519 /* test with background */
520 hdrl_image_add_scalar(himg, (hdrl_value){5., 0.});
521 r = compute_strehl(himg, lam, m1, m2, pscale, pscale, .5, 2, 3);
522 cpl_test_abs(r.strehl_value.data, 1.0, rel);
523 cpl_test_abs(r.star_background.data, 5.0, rel);
524 cpl_test_abs(r.star_background.error, 0., rel);
525
526 /* test with bad pixel in background */
527 hdrl_image_set_pixel(himg, 128, 161, (hdrl_value){1e20, 1e20});
528 hdrl_image_reject(himg, 128, 161);
529 r = compute_strehl(himg, lam, m1, m2, pscale, pscale, .5, 2, 3);
530 cpl_test_abs(r.strehl_value.data, 1.0, rel);
531 cpl_test_abs(r.star_background.data, 5.0, rel);
532 cpl_test_abs(r.star_background.error, 0., rel);
533
534 /* test zero background */
535 compute_strehl(himg, lam, m1, m2, pscale, pscale, .5, 50, 55);
536 cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
537
538 hdrl_image_delete(himg);
539 cpl_image_delete(img);
540
541
542 /* test other psf offsets */
543 for (size_t i = 0; i < 10; i++) {
544 img = compute_psf(lam, m1, m2, pscale, pscale,
545 nx / 2 + i / 10., ny / 2 + i / 10., nx, ny);
546 himg = hdrl_image_create(img, NULL);
547 r = compute_strehl(himg, lam, m1, m2, pscale, pscale, .5, -1, -1);
548 cpl_test_abs(r.strehl_value.data, 1.0, rel);
549 hdrl_image_delete(himg);
550 cpl_image_delete(img);
551 }
552
553 /* failing fit */
554 himg = hdrl_image_new(nx, ny);
555 compute_strehl(himg, lam, m1, m2, pscale, pscale, .5, -1, -1);
556 cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
557
558 hdrl_image_delete(himg);
559}
560
561/*
562void test_strehl_data(int argc, char * argv[])
563{
564 for (size_t i = 2; i < (size_t)argc; i++) {
565 hdrl_image * himg;
566 cpl_image * img;
567 hdrl_strehl_result r;
568 cpl_frame * frm = cpl_frame_new();
569 cpl_frame_set_filename(frm, argv[i]);
570 cpl_size next = cpl_frame_get_nextensions(frm);
571 cpl_frame_delete(frm);
572 img = cpl_image_load(argv[i], CPL_TYPE_DOUBLE, 0, 0);
573 double radius = atof(argv[1]); // arcsec
574 if (next == 0) {
575
576 double dmad;
577 cpl_image_get_mad(img, &dmad);
578 // signal/noise
579 cpl_image * err = cpl_image_duplicate(img);
580 cpl_image_multiply_scalar(err, 0);
581 cpl_image_add_scalar(err, (dmad * CPL_MATH_STD_MAD));
582 himg = hdrl_image_create(img, err);
583 cpl_msg_info(cpl_func, "image error %g", (dmad * CPL_MATH_STD_MAD));
584 }
585 else {
586 cpl_image * err = cpl_image_load(argv[i], CPL_TYPE_DOUBLE, 0, 1);
587 himg = hdrl_image_create(img, err);
588 cpl_msg_info(cpl_func, "using ext 1 as error");
589 }
590 if (strstr(argv[i], "_2.fits")) {
591 r = compute_strehl(himg, 1.635e-6, 5.08/2, 5.08/2*0.36, 0.0331932,
592 0.0331932, radius, -1, -1);
593 }
594 else if (strstr(argv[i], "_4.fits")) {
595 r = compute_strehl(himg, 1.635e-6, 5.08/2, 5.08/2*0.36,
596 0.0331932/2., 0.0331932/2., radius, -1, -1);
597 }
598 else if (strstr(argv[i], ".fits")) {
599 cpl_msg_warning(cpl_func,"case .fits");
600 cpl_image_save(hdrl_image_get_image(himg), "data.fits",
601 CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
602 cpl_image_save(hdrl_image_get_error(himg), "errs.fits",
603 CPL_TYPE_FLOAT, NULL, CPL_IO_DEFAULT);
604 cpl_msg_info(cpl_func,"r1=%g r2=%g r3=%g",radius,-1.,-1.);
605 cpl_msg_info(cpl_func,"m1=%g m2=%g pscale_x=%g pscale_y=%g",
606 8.0,1.12,0.01225,0.01225);
607 r = compute_strehl(himg, 1.6e-6, 8.0/2, 1.12/2,
608 0.01225, 0.01225, radius, 1.5, 2.0);
609 }
610 else {
611 cpl_msg_error(cpl_func, "Unknown pixelscale for %s", argv[i]);
612 continue;
613 }
614 cpl_msg_info(cpl_func, "Strehl for %s: %g", argv[i], r.strehl_value.data);
615 cpl_test_abs(r.strehl_value.data, 1.0, 0);
616 cpl_image_delete(img);
617 }
618
619
620}
621*/
622
623/*----------------------------------------------------------------------------*/
627/*----------------------------------------------------------------------------*/
628int main(int argc, char * argv[])
629{
630 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
631
632 hdrl_strehl_test_parlist();
633 hdrl_strehl_test_null_input();
634 hdrl_strehl_test_illegal_input();
635
636 test_psf();
637 test_strehl();
638 test_strehl_with_bkg();
639
640 cpl_msg_debug(cpl_func, "test_strehl_data only for command line "
641 "(argc=%d, argv=%s). If you need to test images images "
642 "via command line uncomment the function.", argc, argv[0]);
643/*
644 test_strehl_data(argc, argv);
645*/
646 return cpl_test_end(0);
647}
cpl_error_code hdrl_image_set_pixel(hdrl_image *self, cpl_size xpos, cpl_size ypos, hdrl_value value)
set pixel values of hdrl_image
Definition: hdrl_image.c:594
cpl_mask * hdrl_image_get_mask(hdrl_image *himg)
get cpl bad pixel mask from image
Definition: hdrl_image.c:157
cpl_error_code hdrl_image_add_scalar(hdrl_image *self, hdrl_value value)
Elementwise addition of a scalar to an image.
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
Definition: hdrl_image.c:295
cpl_error_code hdrl_image_reject(hdrl_image *self, cpl_size xpos, cpl_size ypos)
mark pixel as bad
Definition: hdrl_image.c:427
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
Definition: hdrl_image.c:311
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
void hdrl_parameter_destroy(hdrl_parameter *obj)
deep delete of a parameter
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
double hdrl_strehl_parameter_get_m1(const hdrl_parameter *p)
Access the primary mirror radius in the Strehl parameter.
Definition: hdrl_strehl.c:247
cpl_parameterlist * hdrl_strehl_parameter_create_parlist(const char *base_context, const char *prefix, hdrl_parameter *par)
Create parameter list for the Strehl computation.
Definition: hdrl_strehl.c:360
hdrl_strehl_result hdrl_strehl_compute(const hdrl_image *himg, hdrl_parameter *params)
This function computes the Strehl ratio.
Definition: hdrl_strehl.c:1326
double hdrl_strehl_parameter_get_flux_radius(const hdrl_parameter *p)
Access the total flux radius in the Strehl parameter.
Definition: hdrl_strehl.c:303
double hdrl_strehl_parameter_get_wavelength(const hdrl_parameter *p)
Access the wavelength in the Strehl parameter.
Definition: hdrl_strehl.c:233
double hdrl_strehl_parameter_get_m2(const hdrl_parameter *p)
Access the obstruction radius in the Strehl parameter.
Definition: hdrl_strehl.c:261
double hdrl_strehl_parameter_get_bkg_radius_high(const hdrl_parameter *p)
Access the background region external radius in the Strehl parameter.
Definition: hdrl_strehl.c:331
hdrl_parameter * hdrl_strehl_parameter_create(double wavelength, double m1_radius, double m2_radius, double pixel_scale_x, double pixel_scale_y, double flux_radius, double bkg_radius_low, double bkg_radius_high)
Creates Strehl Parameters object.
Definition: hdrl_strehl.c:188
double hdrl_strehl_parameter_get_pixel_scale_x(const hdrl_parameter *p)
Access the image X pixel scale in the Strehl parameter.
Definition: hdrl_strehl.c:275
double hdrl_strehl_parameter_get_bkg_radius_low(const hdrl_parameter *p)
Access the background region internal radius in the Strehl parameter.
Definition: hdrl_strehl.c:317
hdrl_parameter * hdrl_strehl_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameter list to create input parameters for the Strehl.
Definition: hdrl_strehl.c:448
cpl_boolean hdrl_strehl_parameter_check(const hdrl_parameter *self)
Check that the parameter is a Strehl parameter.
Definition: hdrl_strehl.c:221
double hdrl_strehl_parameter_get_pixel_scale_y(const hdrl_parameter *p)
Access the image Y pixel scale in the Strehl parameter.
Definition: hdrl_strehl.c:289