UVES Pipeline Reference Manual  5.3.2
irplib_strehl-test.c
1 /* $Id: irplib_strehl-test.c,v 1.10 2013-01-29 08:43:33 jtaylor Exp $
2  *
3  * This file is part of the ESO Common Pipeline Library
4  * Copyright (C) 2001-2008 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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jtaylor $
23  * $Date: 2013-01-29 08:43:33 $
24  * $Revision: 1.10 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 /*-----------------------------------------------------------------------------
29  Includes
30  -----------------------------------------------------------------------------*/
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 
35 #include "irplib_strehl.h"
36 
37 /*-----------------------------------------------------------------------------
38  Defines
39  -----------------------------------------------------------------------------*/
40 
41 #ifndef IMAGESZ
42 #define IMAGESZ 1024
43 #endif
44 
45 #ifndef CWLEN
46 #define CWLEN 1.6
47 #endif
48 
49 #ifndef DWLEN
50 #define DWLEN 0.05
51 #endif
52 
53 #ifndef PIXSCALE
54 #define PIXSCALE 12.25e-3
55 #endif
56 
57 /*-----------------------------------------------------------------------------
58  Static functions
59  -----------------------------------------------------------------------------*/
60 static void irplib_strehl_test_one(void);
61 static void irplib_psf_test_one(int);
62 static void irplib_psf_test(void);
63 static cpl_image * irplib_strehl_create(cpl_size, cpl_size, cpl_type,
64  double, double, double);
65 static void irplib_strehl_test(const cpl_image *, double, double,
66  double, double, double);
67 
68 static void irplib_strehl_test_fits(const char *, double, double, double);
69 
70 
71 /*-----------------------------------------------------------------------------
72  Main
73  -----------------------------------------------------------------------------*/
74 int main (int argc, char * argv[])
75 {
76 
77  int iarg;
78 
79  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
80 
81  irplib_strehl_test_one();
82 
83  for (iarg = 1; iarg < argc; iarg++) {
84  irplib_strehl_test_fits(argv[iarg], PIXSCALE, CWLEN, DWLEN);
85  }
86 
87  irplib_psf_test();
88 
89  return cpl_test_end(0);
90 }
91 
92 
93 /*----------------------------------------------------------------------------*/
103 /*----------------------------------------------------------------------------*/
104 static void irplib_strehl_test_fits(const char * file, double pixscale,
105  double lam, double dlam)
106 {
107 
108  cpl_type type = CPL_TYPE_DOUBLE;
109  int i;
110 
111  for (i = 0; i < 2; i++, type = CPL_TYPE_FLOAT) {
112 
113  cpl_image * img = cpl_image_load(file, type, 0, 0);
114 
115  cpl_test_error(CPL_ERROR_NONE);
116  cpl_test_nonnull(img);
117 
118  cpl_msg_info(cpl_func, "Testing %s with pixel scale=%g, lam=%g, dlam=%g",
119  file, pixscale, lam, dlam);
120 
121  irplib_strehl_test(img, 0.0, 10.0, pixscale, lam, dlam);
122 
123  cpl_image_delete(img);
124  }
125 }
126 
127 
128 /*----------------------------------------------------------------------------*/
134 /*----------------------------------------------------------------------------*/
135 static void irplib_psf_test(void)
136 {
137 
138  const int is_bench = cpl_msg_get_level() <= CPL_MSG_INFO
139  ? CPL_TRUE : CPL_FALSE;
140 
141  double tstop;
142  const double tstart = cpl_test_get_cputime();
143 
144  int szstart = 4;
145  int szstop = is_bench ? IMAGESZ : IRPLIB_STREHL_BOX_SIZE * 2;
146 
147  int isz, irep;
148 
149  for (irep = 0; irep < (is_bench ? 3 : 1); irep++) {
150 
151  for (isz = szstart; isz <= szstop; isz *= 2) {
152  irplib_psf_test_one(isz);
153  }
154  }
155 
156  tstop = cpl_test_get_cputime() - tstart;
157 
158  cpl_msg_info(cpl_func, "Time to generate %d set(s) of PSFs up to size "
159  "%d X %d [s]: %g", irep, szstop, szstop, tstop);
160 }
161 
162 /*----------------------------------------------------------------------------*/
168 /*----------------------------------------------------------------------------*/
169 static void irplib_psf_test_one(int size)
170 {
171  cpl_image * imgpsf = irplib_strehl_generate_psf(IRPLIB_STREHL_M1,
173  CWLEN, DWLEN, PIXSCALE,
174  size);
175  cpl_test_error(CPL_ERROR_NONE);
176  cpl_test_nonnull(imgpsf);
177  cpl_test_eq(cpl_image_get_size_x(imgpsf),
178  cpl_image_get_size_y(imgpsf));
179 
180  cpl_test_eq(cpl_image_get_size_x(imgpsf), size);
181 
182  cpl_image_delete(imgpsf);
183 }
184 
185 /*----------------------------------------------------------------------------*/
191 /*----------------------------------------------------------------------------*/
192 static void irplib_strehl_test_one(void)
193 {
194  cpl_type type = CPL_TYPE_DOUBLE;
195  int i;
196 
197  for (i = 0; i < 2; i++, type = CPL_TYPE_FLOAT) {
198 
199  cpl_image * img = irplib_strehl_create(IMAGESZ, IMAGESZ, type,
200  1000.0, 1.0, 1.0);
201 
202  irplib_strehl_test(img, 1000.0, 1.0, 0.03,
203  2.18, 0.35); /* NACO values */
204 
205  cpl_image_delete(img);
206  }
207 }
208 
209 /*----------------------------------------------------------------------------*/
222 /*----------------------------------------------------------------------------*/
223 static cpl_image * irplib_strehl_create(cpl_size nx, cpl_size ny,
224  cpl_type type,
225  double norm,
226  double sig_x,
227  double sig_y)
228 {
229 
230  const double noise = FLT_EPSILON;
231  cpl_size mx, my;
232  cpl_image * im1 = cpl_image_new(nx, ny, type);
233  cpl_error_code code;
234 
235  code = cpl_image_fill_gaussian(im1, nx/2, ny/2, norm, sig_x, sig_y);
236  cpl_test_eq_error(code, CPL_ERROR_NONE);
237 
238  if (noise != 0.0) {
239  cpl_image * im0 = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
240  code = cpl_image_fill_noise_uniform(im0, -noise, noise);
241  cpl_test_eq_error(code, CPL_ERROR_NONE);
242  code = cpl_image_subtract(im1, im0);
243  cpl_test_eq_error(code, CPL_ERROR_NONE);
244  cpl_image_delete(im0);
245  }
246 
247  code = cpl_image_get_maxpos(im1, &mx, &my);
248  cpl_test_eq_error(code, CPL_ERROR_NONE);
249  cpl_test_eq(mx, nx/2);
250  cpl_test_eq(my, ny/2);
251 
252  return im1;
253 }
254 
255 /*----------------------------------------------------------------------------*/
267 /*----------------------------------------------------------------------------*/
268 static void irplib_strehl_test(const cpl_image * im1, double norm,
269  double sigma,
270  double pixscale, double lam, double dlam)
271 {
272 
273  const cpl_size nx = cpl_image_get_size_x(im1);
274  const cpl_size ny = cpl_image_get_size_y(im1);
275  cpl_error_code code;
276 
277  /* Sigma-levels for detection of a bright star, copied from NACO */
278  const double psigmas[] = {sigma, sigma/2.0, sigma/4.0};
279  const size_t nsigmas = sizeof(psigmas)/sizeof(*psigmas);
280  cpl_size isigma;
281  cpl_vector * sigmas = cpl_vector_wrap(nsigmas, (double*)psigmas);
282  cpl_apertures * apert = NULL;
283  double fwhm_x, fwhm_y;
284  cpl_size mx, my;
285  cpl_image * imgpsf;
286 
287  double strehl = 0.0, strehl_err = 0.0;
288  double star_bg = 0.0, star_peak = 0.0, star_flux = 0.0;
289  double psf_peak = 0.0, psf_flux = 0.0, bg_noise = 0.0;
290 
291  const double star_radius = IRPLIB_STREHL_STAR_RADIUS;
292  const double background_1 = IRPLIB_STREHL_BACKGROUND_R1;
293  const double background_2 = IRPLIB_STREHL_BACKGROUND_R2;
294 
295  code = cpl_image_get_maxpos(im1, &mx, &my);
296  cpl_test_eq_error(code, CPL_ERROR_NONE);
297  cpl_test_leq(mx - nx/4, mx);
298  cpl_test_leq(my - ny/4, my);
299  cpl_test_leq(mx, mx + nx/4);
300  cpl_test_leq(my, my + ny/4);
301 
302  apert = cpl_apertures_extract_window(im1, sigmas,
303  mx - nx/4, my - ny/4,
304  mx + nx/4, my + ny/4,
305  &isigma);
306  cpl_test_error(CPL_ERROR_NONE);
307  cpl_test_nonnull(apert);
308  cpl_test_zero(isigma);
309 
310  cpl_apertures_delete(apert);
311  cpl_test_eq_ptr(cpl_vector_unwrap(sigmas), psigmas);
312 
313  cpl_test_lt(0.0, pixscale);
314 
315  code = cpl_image_get_fwhm(im1, mx, my, &fwhm_x, &fwhm_y);
316  cpl_test_eq_error(code, CPL_ERROR_NONE);
317 
318  cpl_msg_info(cpl_func, "Expected star-radius vs. actual FWHM [pixel]: "
319  "%g <=> (%g, %g)", star_radius / pixscale,
320  fwhm_x, fwhm_y);
321 
322  cpl_msg_debug(cpl_func, "Inner and outer radius of ring-zone for noise "
323  "estimate [pixel]: %g < %g", background_1 / pixscale,
324  background_2 / pixscale);
325 
326 
327  imgpsf = irplib_strehl_generate_psf(IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
328  lam, dlam, pixscale,
330  cpl_test_error(CPL_ERROR_NONE);
331  cpl_test_nonnull(imgpsf);
332  cpl_test_eq(cpl_image_get_size_x(imgpsf),
333  cpl_image_get_size_y(imgpsf));
334 
335  cpl_test_eq(cpl_image_get_size_x(imgpsf),
337 
338  cpl_image_delete(imgpsf);
339 
340  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
341  lam, dlam, pixscale,
343  mx, my,
344  star_radius,
345  background_1,
346  background_2,
347  -1, -1,
348  &strehl,
349  &strehl_err,
350  &star_bg,
351  &star_peak,
352  &star_flux,
353  &psf_peak,
354  &psf_flux,
355  &bg_noise);
356  cpl_test_eq_error(code, CPL_ERROR_NONE);
357  cpl_test_leq(0.0, strehl);
358  cpl_test_leq(strehl, 1.0);
359  cpl_test_leq(0.0, strehl_err);
360  if (norm > 0.0) {
361  cpl_test_rel(norm, star_flux, 0.01);
362  }
363 
364  cpl_msg_info(cpl_func, "Strehl: ratio=%g, error=%g; Background: flux=%g, "
365  "noise=%g; Star: peak=%g, flux=%g; PSF: peak=%g, flux=%g",
366  strehl, strehl_err, star_bg, bg_noise, star_peak, star_flux,
367  psf_peak, psf_flux);
368 
369  /* Test for various errors */
370 
371  /* M2 < 0*/
372  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, 0.0,
373  lam, dlam, pixscale,
375  nx/2, ny/2,
376  star_radius,
377  background_1,
378  background_2,
379  -1, -1,
380  &strehl,
381  &strehl_err,
382  &star_bg,
383  &star_peak,
384  &star_flux,
385  &psf_peak,
386  &psf_flux,
387  &bg_noise);
388  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
389 
390 
391  /* M1 < M2 */
392  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M2, IRPLIB_STREHL_M1,
393  lam, dlam, pixscale,
395  nx/2, ny/2,
396  star_radius,
397  background_1,
398  background_2,
399  -1, -1,
400  &strehl,
401  &strehl_err,
402  &star_bg,
403  &star_peak,
404  &star_flux,
405  &psf_peak,
406  &psf_flux,
407  &bg_noise);
408  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
409 
410 
411  /* lam = 0 */
412  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
413  0.0, dlam, pixscale,
415  nx/2, ny/2,
416  star_radius,
417  background_1,
418  background_2,
419  -1, -1,
420  &strehl,
421  &strehl_err,
422  &star_bg,
423  &star_peak,
424  &star_flux,
425  &psf_peak,
426  &psf_flux,
427  &bg_noise);
428  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
429 
430  /* dlam = 0 */
431  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
432  lam, 0.0, pixscale,
434  nx/2, ny/2,
435  star_radius,
436  background_1,
437  background_2,
438  -1, -1,
439  &strehl,
440  &strehl_err,
441  &star_bg,
442  &star_peak,
443  &star_flux,
444  &psf_peak,
445  &psf_flux,
446  &bg_noise);
447  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
448 
449  /* pixscale = 0 */
450  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
451  lam, dlam, 0.0,
453  nx/2, ny/2,
454  star_radius,
455  background_1,
456  background_2,
457  -1, -1,
458  &strehl,
459  &strehl_err,
460  &star_bg,
461  &star_peak,
462  &star_flux,
463  &psf_peak,
464  &psf_flux,
465  &bg_noise);
466  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
467 
468  /* IRPLIB_STREHL_BOX_SIZE = 0 */
469  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
470  lam, dlam, pixscale,
471  0,
472  nx/2, ny/2,
473  star_radius,
474  background_1,
475  background_2,
476  -1, -1,
477  &strehl,
478  &strehl_err,
479  &star_bg,
480  &star_peak,
481  &star_flux,
482  &psf_peak,
483  &psf_flux,
484  &bg_noise);
485  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
486 
487  /* star_radius = 0 */
488  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
489  lam, dlam, pixscale,
491  nx/2, ny/2,
492  0.0,
493  background_1,
494  background_2,
495  -1, -1,
496  &strehl,
497  &strehl_err,
498  &star_bg,
499  &star_peak,
500  &star_flux,
501  &psf_peak,
502  &psf_flux,
503  &bg_noise);
504  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
505 
506  /* background_1 = 0 */
507  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
508  lam, dlam, pixscale,
510  nx/2, ny/2,
511  star_radius,
512  0.0,
513  background_2,
514  -1, -1,
515  &strehl,
516  &strehl_err,
517  &star_bg,
518  &star_peak,
519  &star_flux,
520  &psf_peak,
521  &psf_flux,
522  &bg_noise);
523  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
524 
525  /* background_2 too small */
526  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
527  lam, dlam, pixscale,
529  nx/2, ny/2,
530  star_radius,
531  background_1,
532  background_1,
533  -1, -1,
534  &strehl,
535  &strehl_err,
536  &star_bg,
537  &star_peak,
538  &star_flux,
539  &psf_peak,
540  &psf_flux,
541  &bg_noise);
542  cpl_test_eq_error(code, CPL_ERROR_ILLEGAL_INPUT);
543 
544  /* strehl pointer is NULL */
545  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
546  lam, dlam, pixscale,
548  nx/2, ny/2,
549  star_radius,
550  background_1,
551  background_2,
552  -1, -1,
553  NULL,
554  &strehl_err,
555  &star_bg,
556  &star_peak,
557  &star_flux,
558  &psf_peak,
559  &psf_flux,
560  &bg_noise);
561  cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
562 
563  /* strehl_err pointer is NULL */
564  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
565  lam, dlam, pixscale,
567  nx/2, ny/2,
568  star_radius,
569  background_1,
570  background_2,
571  -1, -1,
572  &strehl,
573  NULL,
574  &star_bg,
575  &star_peak,
576  &star_flux,
577  &psf_peak,
578  &psf_flux,
579  &bg_noise);
580  cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
581 
582  /* star_bg pointer is NULL */
583  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
584  lam, dlam, pixscale,
586  nx/2, ny/2,
587  star_radius,
588  background_1,
589  background_2,
590  -1, -1,
591  &strehl,
592  &strehl_err,
593  NULL,
594  &star_peak,
595  &star_flux,
596  &psf_peak,
597  &psf_flux,
598  &bg_noise);
599  cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
600 
601  /* star_peak pointer is NULL */
602  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
603  lam, dlam, pixscale,
605  nx/2, ny/2,
606  star_radius,
607  background_1,
608  background_2,
609  -1, -1,
610  &strehl,
611  &strehl_err,
612  &star_bg,
613  NULL,
614  &star_flux,
615  &psf_peak,
616  &psf_flux,
617  &bg_noise);
618  cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
619 
620  /* psf_peak pointer is NULL */
621  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
622  lam, dlam, pixscale,
624  nx/2, ny/2,
625  star_radius,
626  background_1,
627  background_2,
628  -1, -1,
629  &strehl,
630  &strehl_err,
631  &star_bg,
632  &star_peak,
633  &star_flux,
634  NULL,
635  &psf_flux,
636  &bg_noise);
637  cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
638 
639  /* psf_flux pointer is NULL */
640  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
641  lam, dlam, pixscale,
643  nx/2, ny/2,
644  star_radius,
645  background_1,
646  background_2,
647  -1, -1,
648  &strehl,
649  &strehl_err,
650  &star_bg,
651  &star_peak,
652  &star_flux,
653  &psf_peak,
654  NULL,
655  &bg_noise);
656  cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
657 
658 
659  /* bg_noise pointer is NULL */
660  code = irplib_strehl_compute(im1, IRPLIB_STREHL_M1, IRPLIB_STREHL_M2,
661  lam, dlam, pixscale,
663  nx/2, ny/2,
664  star_radius,
665  background_1,
666  background_2,
667  -1, -1,
668  &strehl,
669  &strehl_err,
670  &star_bg,
671  &star_peak,
672  &star_flux,
673  &psf_peak,
674  &psf_flux,
675  NULL);
676  cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
677 }