35 #include "irplib_strehl.h"
36 #include "irplib_utils.h"
57 #define PIXSCALE 12.25e-3
63 static void irplib_strehl_test_one(
void);
64 static void irplib_psf_test_one(
int);
65 static void irplib_psf_test(
void);
66 static cpl_image * irplib_strehl_create(cpl_size, cpl_size, cpl_type,
67 double,
double,
double);
68 static void irplib_strehl_test(
const cpl_image *,
double,
double,
69 double,
double,
double,
double,
double,
72 static void irplib_strehl_test_fits(
const char *,
double,
double,
double,
73 double,
double, cpl_size);
75 static const char * irplib_get_base_name(
const char *);
99 int main (
int argc,
char * argv[])
116 {
"Torino_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
117 {
"Trieste_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
118 {
"Bologna_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
119 {
"Cagliari_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
120 {
"Catania_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
121 {
"Firenze_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
122 {
"Lapalma_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
123 {
"Milano_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
124 {
"Napoli_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
125 {
"Padova_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
126 {
"Palermo_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
127 {
"Roma_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
128 {
"Teramo_2.fits", 0.0331932, 1.635, 0.0001, 5.0800, 1.8288, 0},
130 {
"Bologna_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
131 {
"Cagliari_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
132 {
"Catania_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
133 {
"Firenze_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
134 {
"Lapalma.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
135 {
"Milano_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
136 {
"Naoli_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
137 {
"Padova_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
138 {
"Palermo_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
139 {
"Roma_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
140 {
"Teramo_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
141 {
"Torino_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
142 {
"Trieste_4.fits", 0.0165966, 1.635, 0.0001, 5.0800, 1.8288, 0},
175 const size_t suitesz =
sizeof(suite) /
sizeof(*suite);
178 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
180 cpl_msg_info(
"Strehl-testing with star with ",
188 irplib_strehl_test_one();
190 for (iarg = 1; iarg < argc; iarg++) {
191 const char * basename = irplib_get_base_name(argv[iarg]);
192 double pixscale = PIXSCALE;
193 double cwlen = CWLEN;
194 double dwlen = DWLEN;
200 cpl_test_assert(basename != NULL);
202 for (i = 0; i < suitesz; i++) {
203 if (!strcmp(basename, suite[i].bname)) {
204 pixscale = suite[i].pixscale;
205 cwlen = suite[i].cwlen;
206 dwlen = suite[i].dwlen;
209 iplane = suite[i].iplane;
214 irplib_strehl_test_fits(argv[iarg], pixscale, cwlen, dwlen, m1, m2,
220 return cpl_test_end(0);
238 static void irplib_strehl_test_fits(
const char * file,
double pixscale,
239 double lam,
double dlam,
double m1,
240 double m2, cpl_size iplane)
243 cpl_type type = CPL_TYPE_DOUBLE;
246 for (i = 0; i < 1; i++, type = CPL_TYPE_FLOAT) {
248 cpl_image * img = cpl_image_load(file, type, iplane, 0);
250 cpl_test_error(CPL_ERROR_NONE);
251 cpl_test_nonnull(img);
253 irplib_strehl_test(img, 0.0, 10.0, pixscale, lam, dlam, m1, m2, file);
255 cpl_image_delete(img);
267 static void irplib_psf_test(
void)
270 const int is_bench = cpl_msg_get_level() <= CPL_MSG_INFO
271 ? CPL_TRUE : CPL_FALSE;
274 const double tstart = cpl_test_get_cputime();
281 for (irep = 0; irep < (is_bench ? 3 : 1); irep++) {
283 for (isz = szstart; isz <= szstop; isz *= 2) {
284 irplib_psf_test_one(isz);
288 tstop = cpl_test_get_cputime() - tstart;
290 cpl_msg_info(cpl_func,
"Time to generate %d set(s) of PSFs up to size "
291 "%d X %d [s]: %g", irep, szstop, szstop, tstop);
301 static void irplib_psf_test_one(
int size)
305 CWLEN, DWLEN, PIXSCALE,
307 cpl_test_error(CPL_ERROR_NONE);
308 cpl_test_nonnull(imgpsf);
309 cpl_test_eq(cpl_image_get_size_x(imgpsf),
310 cpl_image_get_size_y(imgpsf));
312 cpl_test_eq(cpl_image_get_size_x(imgpsf), size);
314 cpl_image_delete(imgpsf);
324 static void irplib_strehl_test_one(
void)
326 cpl_type type = CPL_TYPE_DOUBLE;
329 for (i = 0; i < 2; i++, type = CPL_TYPE_FLOAT) {
331 cpl_image * img = irplib_strehl_create(IMAGESZ, IMAGESZ, type,
334 irplib_strehl_test(img, 1000.0, 1.0, 0.03,
338 cpl_image_delete(img);
356 static cpl_image * irplib_strehl_create(cpl_size nx, cpl_size ny,
363 const double noise = FLT_EPSILON;
365 cpl_image * im1 = cpl_image_new(nx, ny, type);
368 code = cpl_image_fill_gaussian(im1, nx/2, ny/2, norm, sig_x, sig_y);
369 cpl_test_eq_error(code, CPL_ERROR_NONE);
372 cpl_image * im0 = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
373 code = cpl_image_fill_noise_uniform(im0, -noise, noise);
374 cpl_test_eq_error(code, CPL_ERROR_NONE);
375 code = cpl_image_subtract(im1, im0);
376 cpl_test_eq_error(code, CPL_ERROR_NONE);
377 cpl_image_delete(im0);
380 code = cpl_image_get_maxpos(im1, &mx, &my);
381 cpl_test_eq_error(code, CPL_ERROR_NONE);
382 cpl_test_eq(mx, nx/2);
383 cpl_test_eq(my, ny/2);
404 static void irplib_strehl_test(
const cpl_image * im1,
double norm,
406 double pixscale,
double lam,
double dlam,
407 double m1,
double m2,
411 const cpl_size nx = cpl_image_get_size_x(im1);
412 const cpl_size ny = cpl_image_get_size_y(im1);
416 const double psigmas[] = {sigma, sigma/2.0, sigma/4.0};
417 const size_t nsigmas =
sizeof(psigmas)/
sizeof(*psigmas);
419 cpl_vector * sigmas = cpl_vector_wrap(nsigmas, (
double*)psigmas);
420 cpl_apertures * apert = NULL;
421 double fwhm_x, fwhm_y;
425 double strehl = 0.0, strehl_err = 0.0;
426 double star_bg = 0.0, star_peak = 0.0, star_flux = 0.0;
427 double psf_peak = 0.0, psf_flux = 0.0, bg_noise = 0.0;
433 code = cpl_image_get_maxpos(im1, &mx, &my);
434 cpl_test_eq_error(code, CPL_ERROR_NONE);
435 cpl_test_leq(mx - nx/4, mx);
436 cpl_test_leq(my - ny/4, my);
437 cpl_test_leq(mx, mx + nx/4);
438 cpl_test_leq(my, my + ny/4);
440 apert = cpl_apertures_extract_window(im1, sigmas,
441 mx - nx/4, my - ny/4,
442 mx + nx/4, my + ny/4,
444 cpl_test_error(CPL_ERROR_NONE);
445 cpl_test_nonnull(apert);
446 cpl_test_zero(isigma);
448 cpl_apertures_delete(apert);
449 cpl_test_eq_ptr(cpl_vector_unwrap(sigmas), psigmas);
451 cpl_test_lt(0.0, pixscale);
453 code = cpl_image_get_fwhm(im1, mx, my, &fwhm_x, &fwhm_y);
454 cpl_test_eq_error(code, CPL_ERROR_NONE);
456 cpl_msg_info(cpl_func,
"Expected star-radius vs. actual FWHM [pixel]: "
457 "%g <=> (%g, %g)", star_radius / pixscale,
460 cpl_msg_debug(cpl_func,
"Inner and outer radius of ring-zone for noise "
461 "estimate [pixel]: %g < %g", background_1 / pixscale,
462 background_2 / pixscale);
465 imgpsf = irplib_strehl_generate_psf(m1, m2,
468 cpl_test_error(CPL_ERROR_NONE);
469 cpl_test_nonnull(imgpsf);
470 cpl_test_eq(cpl_image_get_size_x(imgpsf),
471 cpl_image_get_size_y(imgpsf));
473 cpl_test_eq(cpl_image_get_size_x(imgpsf),
476 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
477 cpl_plot_image(
"",
"",
"", imgpsf);
479 cpl_image_delete(imgpsf);
481 code = irplib_strehl_compute(im1, m1, m2,
497 cpl_test_eq_error(code, CPL_ERROR_NONE);
498 cpl_test_leq(0.0, strehl);
499 cpl_test_leq(strehl, 1.0);
500 cpl_test_leq(0.0, strehl_err);
502 cpl_test_rel(norm, star_flux, 0.01);
505 cpl_msg_info(cpl_func,
"Strehl: ratio=%g, error=%g; Background: flux=%g, "
506 "noise=%g; Star: peak=%g, flux=%g; PSF: peak=%g, flux=%g",
507 strehl, strehl_err, star_bg, bg_noise, star_peak, star_flux,
510 cpl_msg_info(cpl_func,
"%-16s %-10.9g %-8.6g %-8.6g %-8.6g %-8.6g "
511 "%-8.4g %-8.4g", label, pixscale, lam, dlam, m1, m2,
517 code = irplib_strehl_compute(im1, m1, 0.0,
533 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
537 code = irplib_strehl_compute(im1, m2, m1,
553 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
557 code = irplib_strehl_compute(im1, m1, m2,
573 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
576 code = irplib_strehl_compute(im1, m1, m2,
592 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
595 code = irplib_strehl_compute(im1, m1, m2,
611 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
614 code = irplib_strehl_compute(im1, m1, m2,
630 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
633 code = irplib_strehl_compute(im1, m1, m2,
649 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
652 code = irplib_strehl_compute(im1, m1, m2,
668 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
671 code = irplib_strehl_compute(im1, m1, m2,
687 cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
690 code = irplib_strehl_compute(im1, m1, m2,
706 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
709 code = irplib_strehl_compute(im1, m1, m2,
725 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
728 code = irplib_strehl_compute(im1, m1, m2,
744 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
747 code = irplib_strehl_compute(im1, m1, m2,
763 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
766 code = irplib_strehl_compute(im1, m1, m2,
782 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
785 code = irplib_strehl_compute(im1, m1, m2,
801 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
805 code = irplib_strehl_compute(im1, m1, m2,
821 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
836 static const char * irplib_get_base_name(
const char *
self)
838 const char * p =
self ? strrchr(
self,
'/') : NULL;
840 return p ? p + 1 :
self;
#define IRPLIB_STREHL_STAR_RADIUS
The radius of the star, [Arcseconds].
int main(void)
Find a plugin and submit it to some tests.
#define IRPLIB_STREHL_M2
The diameter of the secondary mirror, [m].
#define IRPLIB_STREHL_M1
The diameter of the primary mirror, [m].
#define IRPLIB_STREHL_BACKGROUND_R2
The outer radius of the noise-estimation region, [Arcseconds].
#define IRPLIB_STREHL_BOX_SIZE
The size of the internally used PSF-image, [pixel].
#define IRPLIB_STREHL_BACKGROUND_R1
The inner radius of the noise-estimation region, [Arcseconds].