IIINSTRUMENT Pipeline Reference Manual  4.4.10
naco_img_zpoint.c
1 /* $Id: naco_img_zpoint.c,v 1.99 2011-12-22 11:09:36 llundin Exp $
2  *
3  * This file is part of the NACO Pipeline
4  * Copyright (C) 2002,2003 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: llundin $
23  * $Date: 2011-12-22 11:09:36 $
24  * $Revision: 1.99 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include "naco_recipe.h"
37 #include "naco_strehl.h"
38 
39 #include "irplib_strehl.h"
40 #include "irplib_wcs.h"
41 #include "irplib_stdstar.h"
42 
43 #include <string.h>
44 
45 /*-----------------------------------------------------------------------------
46  Defines
47  -----------------------------------------------------------------------------*/
48 
49 #define RECIPE_STRING "naco_img_zpoint"
50 
51 /* @cond */
52 typedef enum _NACO_BAND_ {
53  BAND_J,
54  BAND_JS,
55  BAND_JBLOCK,
56  BAND_H,
57  BAND_K,
58  BAND_KS,
59  BAND_L,
60  BAND_M,
61  BAND_LP,
62  BAND_MP,
63  BAND_Z,
64  BAND_SZ,
65  BAND_SH,
66  BAND_SK,
67  BAND_SL,
68  BAND_UNKNOWN
69 } naco_band;
70 /* @endcond */
71 
72 /*-----------------------------------------------------------------------------
73  Private Functions prototypes
74  -----------------------------------------------------------------------------*/
75 
76 static cpl_table * naco_img_zpoint_reduce(cpl_propertylist *,
77  const irplib_framelist *,
78  const cpl_parameterlist *,
79  const char *, const char *,
80  cpl_image **);
81 
82 static cpl_error_code naco_img_zpoint_qc(cpl_propertylist *,
83  cpl_propertylist *,
84  const irplib_framelist *);
85 
86 static cpl_error_code naco_img_zpoint_save(cpl_frameset *,
87  const cpl_parameterlist *,
88  const cpl_propertylist *,
89  const cpl_propertylist *,
90  const cpl_table *,
91  const cpl_image *);
92 
93 static cpl_error_code naco_img_zpoint_reduce_one(cpl_table *, cpl_vector *, int,
94  const cpl_image *,
95  const cpl_parameterlist *,
96  const char *, double, double,
97  double, double *, double *,
98  double *, double *, double *);
99 
100 static double naco_img_zpoint_find_mag(cpl_propertylist *, double, double,
101  const char *, const char *);
102 
103 static cpl_table * naco_img_zpoint_load_std_star(const char *, double, double, double);
104 
105 static cpl_error_code naco_img_zpoint_find_std_star(cpl_table *,
106  const char *[],
107  double, double,
108  const char *,
109  cpl_boolean,
110  int *);
111 
112 static cpl_error_code naco_img_zpoint_qc_all(cpl_propertylist *,
113  cpl_propertylist *,
114  const irplib_framelist *);
115 
116 static cpl_error_code naco_img_zpoint_check_im(cpl_image **, const cpl_image *,
117  int, int, double, double,
118  double, double, double);
119 
120 static naco_band naco_get_bbfilter(const char *);
121 
122 static const char * naco_std_band_name(naco_band);
123 
124 
125 NACO_RECIPE_DEFINE(naco_img_zpoint,
126  NACO_PARAM_STAR_R |
127  NACO_PARAM_BG_RINT |
128  NACO_PARAM_BG_REXT |
129  NACO_PARAM_RA |
130  NACO_PARAM_DEC |
131  NACO_PARAM_PIXSCALE|
132  NACO_PARAM_MAGNITD |
133  NACO_PARAM_SX |
134  NACO_PARAM_SY |
135  NACO_PARAM_CHK_IMG,
136  "Zero point computation recipe",
137  RECIPE_STRING " -- Zero point recipe\n"
138  "The files listed in the Set Of Frames (sof-file) "
139  "must be tagged:\n"
140  "NACO-raw-file.fits " NACO_IMG_ZPOINT_CHOP " or\n"
141  "NACO-raw-file.fits " NACO_IMG_ZPOINT_JITTER ".\n"
142  "NACO-Imaging-Standard-Star-Catalog.fits "
143  NACO_IMG_STD_CAT "\n"
144  "Optionally, a flat field frame may be inluded:\n"
145  "NACO-flat-file.fits " NACO_CALIB_FLAT "\n");
146 
147 /*-----------------------------------------------------------------------------
148  Static variables
149  -----------------------------------------------------------------------------*/
150 
151 static struct {
152  /* Inputs */
153  double ra;
154  double dec;
155  double magnitude;
156  int sx;
157  int sy;
158  double phot_star_radius;
159  double phot_bg_r1;
160  double phot_bg_r2;
161  double pscale;
162  int check_im;
163 
164 } naco_img_zpoint_config;
165 
166 
167 /*----------------------------------------------------------------------------*/
171 /*----------------------------------------------------------------------------*/
172 
173 /*-----------------------------------------------------------------------------
174  Functions code
175  -----------------------------------------------------------------------------*/
176 
177 /*----------------------------------------------------------------------------*/
185 /*----------------------------------------------------------------------------*/
186 static int naco_img_zpoint(cpl_frameset * framelist,
187  const cpl_parameterlist * parlist)
188 {
189  irplib_framelist* allframes = NULL;
190  irplib_framelist* rawframes = NULL;
191  cpl_propertylist* qclist = cpl_propertylist_new();
192  cpl_propertylist* paflist = cpl_propertylist_new();
193  const char * flat;
194  const char * star_cat;
195  cpl_table * tab = NULL;
196  cpl_image * check_im = NULL;
197 
198  /* Retrieve input parameters */
199  /* --ra */
200  naco_img_zpoint_config.ra
201  = naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_RA);
202  /* --dec */
203  naco_img_zpoint_config.dec
204  = naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_DEC);
205  /* --pscale */
206  naco_img_zpoint_config.pscale
207  = naco_parameterlist_get_double(parlist,RECIPE_STRING,NACO_PARAM_PIXSCALE);
208  /* --mag */
209  naco_img_zpoint_config.magnitude
210  = naco_parameterlist_get_double(parlist, RECIPE_STRING,NACO_PARAM_MAGNITD);
211  /* --sx */
212  naco_img_zpoint_config.sx
213  = naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_SX);
214 
215  skip_if_lt(naco_img_zpoint_config.sx, 1,
216  "for the size of the search window in X-direction [pixel]");
217 
218  /* --sy */
219  naco_img_zpoint_config.sy
220  = naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_SY);
221 
222  skip_if_lt(naco_img_zpoint_config.sy, 1,
223  "for the size of the search window in Y-direction [pixel]");
224 
225  /* --star_r */
226  naco_img_zpoint_config.phot_star_radius
227  = naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_STAR_R);
228 
229  /* --bg_r1 */
230  naco_img_zpoint_config.phot_bg_r1
231  = naco_parameterlist_get_double(parlist, RECIPE_STRING,NACO_PARAM_BG_RINT);
232 
233  /* --bg_r2 */
234  naco_img_zpoint_config.phot_bg_r2
235  = naco_parameterlist_get_double(parlist, RECIPE_STRING,NACO_PARAM_BG_REXT);
236 
237  /* --check_im */
238  naco_img_zpoint_config.check_im
239  = naco_parameterlist_get_bool(parlist, RECIPE_STRING, NACO_PARAM_CHK_IMG);
240 
241  /* Identify the RAW and CALIB frames in the input frameset */
242  skip_if (naco_dfs_set_groups(framelist));
243 
244  allframes = irplib_framelist_cast(framelist);
245  skip_if(allframes == NULL);
246 
247  rawframes = irplib_framelist_extract_regexp(allframes,
248  "^(" NACO_IMG_ZPOINT_JITTER
249  "|" NACO_IMG_ZPOINT_CHOP ")$",
250  CPL_FALSE);
251  skip_if(rawframes == NULL);
252  irplib_framelist_empty(allframes);
253 
254  /* Standard star catalog */
255  star_cat = irplib_frameset_find_file(framelist, NACO_IMG_STD_CAT);
256  error_if (star_cat == NULL, CPL_ERROR_DATA_NOT_FOUND, "The input "
257  "file(s) have no star catalog tagged %s", NACO_IMG_STD_CAT);
258 
259  /* Retrieve calibration data */
260  flat = irplib_frameset_find_file(framelist, NACO_CALIB_FLAT);
261  bug_if(0);
262 
263  skip_if( irplib_framelist_load_propertylist(rawframes, 0, 0, "^("
264  IRPLIB_PFITS_REGEXP_RECAL "|"
265  NACO_PFITS_REGEXP_ZPOINT "|"
266  NACO_PFITS_REGEXP_ZPOINT_PAF "|"
267  NACO_PFITS_REGEXP_ZPOINT_REF
268  ")$", CPL_FALSE));
269 
270  skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^("
271  NACO_PFITS_REGEXP_ZPOINT
272  ")$", CPL_FALSE));
273 
274  /* Compute the strehl/zpoint values */
275  tab = naco_img_zpoint_reduce(qclist, rawframes, parlist, star_cat, flat,
276  &check_im);
277  skip_if (tab == NULL);
278 
279  skip_if(naco_img_zpoint_qc(qclist, paflist, rawframes));
280 
281  /* Reduce maximum number of pointers used */
282  irplib_framelist_empty(rawframes);
283 
284  /* PRO.CATG */
285  bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
286  NACO_IMG_ZPOINT_RES));
287 
288  /* Save the products */
289  skip_if (naco_img_zpoint_save(framelist, parlist, qclist, paflist, tab,
290  check_im));
291 
292  end_skip;
293 
294  cpl_table_delete(tab);
295  cpl_image_delete(check_im);
296  irplib_framelist_delete(allframes);
297  irplib_framelist_delete(rawframes);
298  cpl_propertylist_delete(qclist);
299  cpl_propertylist_delete(paflist);
300 
301  return cpl_error_get_code();
302 }
303 
304 /*----------------------------------------------------------------------------*/
316 /*----------------------------------------------------------------------------*/
317 static cpl_table * naco_img_zpoint_reduce(cpl_propertylist * qclist,
318  const irplib_framelist * rawframes,
319  const cpl_parameterlist * parlist,
320  const char * star_cat,
321  const char * flat,
322  cpl_image ** pcheck_im)
323 {
324  cpl_errorstate prestate = cpl_errorstate_get();
325  const cpl_propertylist * plist
326  = irplib_framelist_get_propertylist_const(rawframes, 0);
327  cpl_image * flat_im = NULL;
328  cpl_image * rawimage = NULL;
329  cpl_image * imdiff = NULL;
330  const char * filter;
331  const int ndiff = 2 * irplib_framelist_get_size(rawframes)-2;
332  double pos_x_cen = DBL_MAX; /* Avoid uninit warning */
333  double pos_y_cen = DBL_MAX; /* Avoid uninit warning */
334  cpl_apertures * aperts = NULL;
335  double psigmas[] = {20.0, 10.0, 8.0, 6.0, 5.0};
336  const int nsigmas = (int)(sizeof(psigmas)/sizeof(double));
337  cpl_size isigma;
338  cpl_vector * sigmas = NULL;
339  cpl_table * out_tab = NULL;
340  cpl_vector * zpoints = NULL;
341  cpl_stats * fstats = NULL;
342  double dit;
343  double off_x0 = DBL_MAX; /* Avoid uninit warning */
344  double off_y0 = DBL_MAX; /* Avoid uninit warning */
345  double off_x = DBL_MAX; /* Avoid uninit warning */
346  double off_y = DBL_MAX; /* Avoid uninit warning */
347  double str_sum = 0.0;
348  double str_err_sum = 0.0;
349  double pe_sum = 0.0;
350  double fl_sum = 0.0;
351  double bg_no_sum = 0.0;
352  double sqsum = 0.0;
353  double avg_zp = 0.0;
354  int nok_zp = 0;
355  int nok_strehl = 0;
356  cpl_error_code code;
357  int i;
358 
359  /* QC Parameters */
360  double zpointrms;
361  double strehl;
362  double strehl_err;
363  double strehl_rms;
364  double star_peak;
365  double star_flux;
366 
367 
368 
369  bug_if (0);
370  bug_if (pcheck_im == NULL);
371  bug_if (*pcheck_im != NULL);
372 
373  skip_if_lt(ndiff/2+1, 3, "raw frames");
374 
375  /* Get the filter name, DIT, RA, DEC and pixelscale */
376 
377  dit = naco_pfits_get_dit(plist);
378  skip_if (dit <= 0.0);
379  if (naco_img_zpoint_config.ra > 998.0)
380  naco_img_zpoint_config.ra = naco_pfits_get_ra(plist);
381  if (naco_img_zpoint_config.dec > 998.0)
382  naco_img_zpoint_config.dec = naco_pfits_get_dec(plist);
383  skip_if(0);
384 
385  if (naco_img_zpoint_config.pscale <= 0.0) {
386  naco_img_zpoint_config.pscale = naco_pfits_get_pixscale(plist);
387  skip_if(naco_img_zpoint_config.pscale <= 0.0);
388  }
389 
390  cpl_msg_info(cpl_func, "Using star at position: RA = %g ; DEC = %g",
391  naco_img_zpoint_config.ra, naco_img_zpoint_config.dec);
392 
393  filter = naco_pfits_get_filter(plist);
394  skip_if(0);
395 
396  /* Get the standard star information from database */
397  if (naco_img_zpoint_config.magnitude > IRPLIB_STDSTAR_LIMIT) {
398  naco_img_zpoint_config.magnitude
399  = naco_img_zpoint_find_mag(qclist,
400  naco_img_zpoint_config.ra,
401  naco_img_zpoint_config.dec,
402  star_cat, filter);
403  if (cpl_error_get_code()) {
404  const cpl_propertylist * reflist
405  = irplib_framelist_get_propertylist_const(rawframes, 0);
406  const char * starname = naco_pfits_get_object(reflist);
407 
408  if (starname != NULL) {
409  error_if (0, cpl_error_get_code(), "Star '%s' has "
410  "no magnitude for filter '%s' in catalogue '%s'",
411  starname, filter, star_cat);
412  }
413  }
414  }
415  cpl_msg_info(cpl_func, "Star magnitude with filter %s : %g", filter,
416  naco_img_zpoint_config.magnitude);
417  bug_if(cpl_propertylist_append_double(qclist, "ESO QC STARMAG",
418  naco_img_zpoint_config.magnitude));
419 
420  zpoints = cpl_vector_new(ndiff);
421  out_tab = cpl_table_new(ndiff);
422  cpl_table_new_column(out_tab, "POSX", CPL_TYPE_DOUBLE);
423  cpl_table_new_column(out_tab, "POSY", CPL_TYPE_DOUBLE);
424  cpl_table_new_column(out_tab, "ZPOINT", CPL_TYPE_DOUBLE);
425  cpl_table_new_column(out_tab, "PEAK", CPL_TYPE_DOUBLE);
426  cpl_table_new_column(out_tab, "FLUX", CPL_TYPE_DOUBLE);
427  cpl_table_new_column(out_tab, "BGD_NOISE", CPL_TYPE_DOUBLE);
428  cpl_table_new_column(out_tab, "STREHL", CPL_TYPE_DOUBLE);
429  cpl_table_new_column(out_tab, "STREHL_ERR", CPL_TYPE_DOUBLE);
430  cpl_table_new_column(out_tab, "BGD", CPL_TYPE_DOUBLE);
431  cpl_table_new_column(out_tab, "FWHMX", CPL_TYPE_DOUBLE);
432  cpl_table_new_column(out_tab, "FWHMY", CPL_TYPE_DOUBLE);
433  bug_if(0);
434 
435  /* Load the the flatfield if one is provided */
436  if (flat != NULL) {
437  flat_im = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0);
438 
439  if (flat_im == NULL) {
440  cpl_msg_error(cpl_func, "Could not load flat field %s", flat);
441  skip_if(1);
442  } else {
443  fstats = cpl_stats_new_from_image(flat_im, CPL_STATS_ALL);
444  if (cpl_stats_get_min(fstats) <= 0.0) {
445  cpl_msg_warning(cpl_func, "Setting non-positive (down to %g) "
446  "flat field pixels to 1",
447  cpl_stats_get_min(fstats));
448  bug_if(cpl_image_threshold(flat_im, 0.0, DBL_MAX, 1.0,
449  DBL_MAX));
450  }
451  }
452  }
453 
454  cpl_msg_info(cpl_func, "Loading the image from raw frame %d",1);
455  rawimage = cpl_image_load(cpl_frame_get_filename(
456  irplib_framelist_get_const(rawframes, 0)),
457  CPL_TYPE_FLOAT, 0, 0);
458  if (rawimage == NULL) {
459  cpl_msg_error(cpl_func, "Could not load image from first raw frame");
460  skip_if(1);
461  }
462 
463  for (i=0; i < ndiff; i++) {
464 
465  double pos_x, pos_y;
466  double str, str_err, pe, fl, bg_no;
467 
468 
469  bug_if(0);
470 
471  if (i == 0 || i % 2 == 1) {
472  /* Get the offsets */
473 
474  off_x = naco_pfits_get_cumoffsetx(plist);
475  off_y = naco_pfits_get_cumoffsety(plist);
476 
477  skip_if(0);
478 
479  if (i == 0) {
480  off_x0 = off_x;
481  off_y0 = off_y;
482  }
483 
484  off_x -= off_x0;
485  off_y -= off_y0;
486 
487  cpl_msg_info(cpl_func, "Offsets for difference image %d: (%g,%g)",
488  i, off_x, off_y);
489 
490  /* Update the plist to that of the next frame */
491  if (i + 1 < ndiff)
492  plist = irplib_framelist_get_propertylist_const(rawframes,
493  1 + (i+1)/2);
494  }
495 
496  if (i % 2 == 0) {
497  const char * filename = cpl_frame_get_filename(
498  irplib_framelist_get_const(rawframes, 1+i/2));
499 
500  bug_if(0);
501 
502  cpl_image_delete(imdiff);
503  imdiff = rawimage;
504 
505  cpl_msg_info(cpl_func, "Loading the image from raw frame %d",2+i/2);
506  rawimage = cpl_image_load(filename, CPL_TYPE_FLOAT, 0, 0);
507  if (rawimage == NULL) {
508  cpl_msg_error(cpl_func, "Could not load image %d", 2+i/2);
509  skip_if(1);
510  }
511  bug_if(cpl_image_subtract(imdiff, rawimage));
512  if (flat_im != NULL) skip_if(cpl_image_divide(imdiff, flat_im));
513  } else {
514  bug_if(cpl_image_multiply_scalar(imdiff, -1.0));
515  }
516 
517  if (i == 0) {
518  double min_dist = DBL_MAX; /* Avoid (false) uninit warning */
519  const int size_x = cpl_image_get_size_x(imdiff);
520  const int size_y = cpl_image_get_size_y(imdiff);
521  int iap;
522 
523  /* Detect the central object in the first frame */
524  cpl_msg_info(cpl_func, "Detecting a bright object in the first "
525  "difference image using %d sigma-levels ranging from "
526  "%g down to %g", nsigmas, psigmas[0],
527  psigmas[nsigmas-1]);
528  sigmas = cpl_vector_wrap(nsigmas, psigmas);
529 
530  aperts = cpl_apertures_extract(imdiff, sigmas, &isigma);
531  if (aperts == NULL || cpl_apertures_get_size(aperts) < 1) {
532  cpl_msg_error(cpl_func, "Could not detect any bright object");
533  skip_if(1);
534  }
535  for (iap=0; iap < cpl_apertures_get_size(aperts); iap++) {
536  const double d_x
537  = cpl_apertures_get_centroid_x(aperts, iap+1) - size_x/2.0;
538  const double d_y
539  = cpl_apertures_get_centroid_y(aperts, iap+1) - size_y/2.0;
540  const double dist = d_x * d_x + d_y * d_y;
541  if (iap == 0 || dist < min_dist) {
542  min_dist = dist;
543  pos_x_cen = d_x;
544  pos_y_cen = d_y;
545  }
546  }
547  cpl_apertures_delete(aperts);
548  aperts = NULL;
549  bug_if(0);
550  pos_x_cen += size_x/2.0;
551  pos_y_cen += size_y/2.0;
552  cpl_msg_info(cpl_func, "Detected a bright object at sigma=%g, at "
553  "position: %g %g", psigmas[isigma], pos_x_cen,
554  pos_y_cen);
555 
556  }
557 
558  pos_x = pos_x_cen + off_x;
559  pos_y = pos_y_cen + off_y;
560 
561  if (i > 0) {
562  /* Refine the positions */
563  const double opos_x = pos_x;
564  const double opos_y = pos_y;
565  const int llx = (int)pos_x - naco_img_zpoint_config.sx;
566  const int urx = (int)pos_x + naco_img_zpoint_config.sx;
567  const int lly = (int)pos_y - naco_img_zpoint_config.sy;
568  const int ury = (int)pos_y + naco_img_zpoint_config.sy;
569  pos_x = cpl_image_get_centroid_x_window(imdiff, llx, lly, urx, ury);
570  pos_y = cpl_image_get_centroid_y_window(imdiff, llx, lly, urx, ury);
571  error_if (0, cpl_error_get_code(), "Could not refine the positions "
572  "of difference image %d", i+1);
573  cpl_msg_info(cpl_func, "For difference image %d refined object "
574  "position (x,y): (%g,%g) -> (%g,%g)", i,
575  opos_x, opos_y, pos_x, pos_y);
576  }
577 
578  bug_if(0);
579 
580  /* Create the check image if requested */
581  if (naco_img_zpoint_config.check_im) {
582  const double r1 = naco_img_zpoint_config.phot_star_radius
583  /naco_img_zpoint_config.pscale;
584  const double r2 = naco_img_zpoint_config.phot_bg_r1
585  /naco_img_zpoint_config.pscale;
586  const double r3 = naco_img_zpoint_config.phot_bg_r2
587  /naco_img_zpoint_config.pscale;
588 
589  skip_if(naco_img_zpoint_check_im(pcheck_im, imdiff, i, ndiff,
590  pos_x, pos_y, r1, r2, r3));
591  }
592 
593  /* Compute the flux/strehl in the current image */
594  code = naco_img_zpoint_reduce_one(out_tab, zpoints, i, imdiff,
595  parlist, filter,
596  pos_x, pos_y, dit,
597  &str, &str_err, &pe, &fl, &bg_no);
598  if (code) {
599  cpl_msg_warning(cpl_func, "Strehl computation for difference image "
600  "%d at (x,y)=(%g,%g) failed:", i+1, pos_x, pos_y);
601  cpl_errorstate_dump(prestate, CPL_FALSE,
602  cpl_errorstate_dump_one_warning);
603  cpl_errorstate_set(prestate);
604  continue;
605  } else if (str <= 0.0 || str >= 1.0) {
606  cpl_msg_info(cpl_func, "Excluding from statistics non-physical "
607  "Strehl ratio for difference image %d at (x,y)=(%g,%g)"
608  ": %g", i+1, pos_x, pos_y, str);
609  continue;
610  }
611 
612  /* Compute the averages of the results for the strehl */
613  nok_strehl++;
614 
615  str_sum += str;
616  str_err_sum += str_err;
617  bg_no_sum += bg_no;
618  pe_sum += pe;
619  fl_sum += fl;
620  }
621 
622  skip_if_lt(nok_strehl, 1, "valid strehl measurements");
623 
624  strehl = str_sum / (double)nok_strehl;
625  strehl_err = str_err_sum / (double)nok_strehl;
626  strehl_rms = bg_no_sum / (double)nok_strehl;
627  star_peak = pe_sum / (double)nok_strehl;
628  star_flux = fl_sum / (double)nok_strehl;
629 
630  /* Compute the averages of the results for the zero point */
631  cpl_vector_sort(zpoints, 1);
632  /* Reject highest and lowest value */
633  for (i=1; i < ndiff-1; i++) {
634  const double zp = cpl_vector_get(zpoints, i);
635  if (zp > 0.0) {
636  avg_zp += zp;
637  sqsum += zp * zp;
638  nok_zp ++;
639  }
640  }
641  cpl_vector_delete(zpoints);
642  zpoints = NULL;
643 
644  skip_if_lt(nok_zp, 1, "valid zpoint measurements");
645 
646  avg_zp /= (double)nok_zp;
647  sqsum /= (double)nok_zp;
648  zpointrms = sqsum - avg_zp * avg_zp;
649  zpointrms = zpointrms > 0.0 ? sqrt(zpointrms) : 0.0;
650 
651  /* Print final results */
652  cpl_msg_info(cpl_func, "***** FINAL RESULTS *****");
653  cpl_msg_info(cpl_func, "Strehl : %g", strehl);
654  cpl_msg_info(cpl_func, "Strehl error : %g", strehl_err);
655  cpl_msg_info(cpl_func, "Peak : %g", star_peak);
656  cpl_msg_info(cpl_func, "Flux : %g", star_flux);
657  cpl_msg_info(cpl_func, "Strehl RMS %g", strehl_rms);
658  cpl_msg_info(cpl_func, "Zero point : %g", avg_zp);
659  cpl_msg_info(cpl_func, "Zero p. RMS: %g", zpointrms);
660 
661  cpl_propertylist_append_double(qclist, "ESO QC ZPOINT", avg_zp);
662  cpl_propertylist_append_double(qclist, "ESO QC ZPOINTRMS", zpointrms);
663  cpl_propertylist_append_double(qclist, "ESO QC STREHL", strehl);
664  cpl_propertylist_append_double(qclist, "ESO QC STREHL ERROR", strehl_err);
665  cpl_propertylist_append_double(qclist, "ESO QC STREHL RMS", strehl_rms);
666  cpl_propertylist_append_double(qclist, "ESO QC STREHL PEAK", star_peak);
667  cpl_propertylist_append_double(qclist, "ESO QC STREHL FLUX", star_flux);
668  cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", filter);
669 
670  bug_if(0);
671 
672  end_skip;
673 
674  cpl_stats_delete(fstats);
675  cpl_image_delete(rawimage);
676  cpl_image_delete(imdiff);
677  cpl_image_delete(flat_im);
678  cpl_apertures_delete(aperts);
679  cpl_vector_unwrap(sigmas);
680  cpl_vector_delete(zpoints);
681 
682  if (cpl_error_get_code()) {
683  cpl_image_delete(*pcheck_im);
684  *pcheck_im = NULL;
685  cpl_table_delete(out_tab);
686  out_tab = NULL;
687  }
688 
689  return out_tab;
690 }
691 
692 /*----------------------------------------------------------------------------*/
712 /*----------------------------------------------------------------------------*/
713 static cpl_error_code naco_img_zpoint_check_im(cpl_image ** self,
714  const cpl_image * imdiff,
715  int idiff,
716  int nima,
717  double pos_x,
718  double pos_y,
719  double r1,
720  double r2,
721  double r3)
722 {
723  const float * pin_ima = cpl_image_get_data_float_const(imdiff);
724  float * pout_ima;
725  const int in_nx = cpl_image_get_size_x(imdiff);
726  const int in_ny = cpl_image_get_size_y(imdiff);
727  const int box_sz = 2 * (int)r3 + 1;
728  const int nx = box_sz * nima;
729  const int ny = box_sz;
730  /* Get the sub image position */
731  const int llx = (int)(pos_x - r3);
732  const int lly = (int)(pos_y - r3);
733  int i, j;
734 
735 
736  bug_if(0);
737 
738  bug_if(self == NULL);
739 
740  skip_if (r1 > r2);
741  skip_if (r2 >= r3);
742 
743  if (idiff == 0) {
744  bug_if(*self != NULL);
745 
746  cpl_msg_info(cpl_func, "Creating %d X %d X %d check-image",
747  nima, box_sz, box_sz);
748 
749  /* Create the output image */
750  *self = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
751  }
752 
753  pout_ima = cpl_image_get_data_float(*self);
754 
755  bug_if(0);
756 
757  for (j=0; j < box_sz; j++) {
758  if (j + lly < 0 || j + lly >= in_ny) continue;
759  for (i=0; i < box_sz; i++) {
760  if (i + llx >= 0 && i + llx < in_nx) {
761  const int in_pos = llx + i + (lly+j) * in_nx;
762  const int out_pos = (box_sz * idiff) + i + j * nx;
763 
764  bug_if ( in_pos < 0 || in_pos >= in_nx*in_ny);
765  bug_if (out_pos < 0 || out_pos >= nx* ny);
766 
767  pout_ima[out_pos] = pin_ima[in_pos];
768  }
769  }
770  }
771 
772  if (idiff == 0) {
773  /* Draw the two circles */
774  const double sqr1 = sqrt(r1*r1);
775  const double sqr2 = sqrt(r2*r2);
776  const double sqr3 = sqrt(r3*r3);
777  for (j=0; j < box_sz; j++) {
778  const int jdist = j - box_sz/2;
779  for (i=0; i < box_sz; i++) {
780  const int idist = i - box_sz/2;
781  const double dist
782  = sqrt((double)(idist * idist + jdist * jdist));
783  if (fabs(dist-sqr1) < 0.5 ||
784  fabs(dist-sqr2) < 0.5 ||
785  fabs(dist-sqr3) < 0.5) pout_ima[i + j * nx] = 10000;
786  }
787  }
788  }
789 
790  end_skip;
791 
792  return cpl_error_get_code();
793 }
794 
795 /*----------------------------------------------------------------------------*/
816 /*----------------------------------------------------------------------------*/
817 static
818 cpl_error_code naco_img_zpoint_reduce_one(cpl_table * zptab,
819  cpl_vector * zpoints,
820  int idiff,
821  const cpl_image * self,
822  const cpl_parameterlist * parlist,
823  const char * filter,
824  double pos_x,
825  double pos_y,
826  double dit,
827  double * pstrehl,
828  double * pstrehl_err,
829  double * pstar_peak,
830  double * pstar_flux,
831  double * pbg_noise)
832 {
833  cpl_errorstate cleanstate = cpl_errorstate_get();
834  double zeropoint, background;
835  double r, r1, r2;
836  double lam, dlam;
837  double star_bg, psf_peak, psf_flux;
838  double fwhm_x, fwhm_y;
839 
840 
841  bug_if(pstar_flux == NULL);
842  bug_if(filter == NULL);
843 
844  /* Compute the photometry */
845  r = naco_img_zpoint_config.phot_star_radius/naco_img_zpoint_config.pscale;
846  r1 = naco_img_zpoint_config.phot_bg_r1/naco_img_zpoint_config.pscale;
847  r2 = naco_img_zpoint_config.phot_bg_r2/naco_img_zpoint_config.pscale;
848  background = irplib_strehl_ring_background(self, pos_x, pos_y, r1, r2,
849  IRPLIB_BG_METHOD_AVER_REJ);
850  skip_if(0);
851  *pstar_flux = irplib_strehl_disk_flux(self, pos_x, pos_y, r, background);
852  skip_if(0);
853 
854  /* Get lam and dlam from the filter name for the Strehl computation */
855  irplib_check(naco_get_filter_infos(filter, &lam, &dlam),
856  "Cannot get filter infos [%s]", filter);
857 
858  /* Compute the strehl */
859  irplib_check(naco_strehl_compute(self, parlist, RECIPE_STRING, lam, dlam,
860  pos_x, pos_y,
861  naco_img_zpoint_config.pscale,
862  pstrehl, pstrehl_err, &star_bg,
863  pstar_peak, pstar_flux,
864  &psf_peak, &psf_flux, pbg_noise),
865  "Could not compute the Strehl ratio. r=%g <= r1=%g < r2=%g",
866  r, r1, r2);
867 
868  /* FWHM_X / FWHM_Y */
869  if (cpl_image_get_fwhm(self, (int)pos_x, (int)pos_y, &fwhm_x, &fwhm_y)) {
870  irplib_error_recover(cleanstate, "Could not compute FWHM for image %d:",
871  idiff+1);
872  fwhm_x = fwhm_y = 0.0;
873  } else {
874  if (fwhm_x <= 0.0) {
875  cpl_msg_warning(cpl_func, "Could not compute FWHM in x for image "
876  "%d:", idiff+1);
877  fwhm_x = 0.0;
878  }
879  if (fwhm_y <= 0.0) {
880  cpl_msg_warning(cpl_func, "Could not compute FWHM in y for image "
881  "%d:", idiff+1);
882  fwhm_y = 0.0;
883  }
884  }
885 
886  zeropoint = naco_img_zpoint_config.magnitude + 2.5 * log10(*pstar_flux/dit);
887 
888  cpl_msg_info(cpl_func, "Strehl : %g", *pstrehl);
889  cpl_msg_info(cpl_func, "Strehl error : %g", *pstrehl_err);
890  cpl_msg_info(cpl_func, "Peak : %g", *pstar_peak);
891  cpl_msg_info(cpl_func, "Flux : %g", *pstar_flux);
892  cpl_msg_info(cpl_func, "Background : %g", background);
893  cpl_msg_info(cpl_func, "Bg noise : %g", *pbg_noise);
894  cpl_msg_info(cpl_func, "Zero point : %g", zeropoint);
895  cpl_msg_info(cpl_func, "FWHM in x : %g", fwhm_x);
896  cpl_msg_info(cpl_func, "FWHM in y : %g", fwhm_y);
897 
898  /* Save the results in the vectors */
899  cpl_vector_set(zpoints, idiff, zeropoint);
900  cpl_table_set_double(zptab, "POSX", idiff, pos_x);
901  cpl_table_set_double(zptab, "POSY", idiff, pos_y);
902  cpl_table_set_double(zptab, "ZPOINT", idiff, zeropoint);
903  cpl_table_set_double(zptab, "PEAK", idiff, *pstar_peak);
904  cpl_table_set_double(zptab, "FLUX", idiff, *pstar_flux);
905  cpl_table_set_double(zptab, "BGD_NOISE", idiff, *pbg_noise);
906  cpl_table_set_double(zptab, "STREHL", idiff, *pstrehl);
907  cpl_table_set_double(zptab, "STREHL_ERR", idiff, *pstrehl_err);
908  cpl_table_set_double(zptab, "BGD", idiff, background);
909  cpl_table_set_double(zptab, "FWHMX", idiff, fwhm_x);
910  cpl_table_set_double(zptab, "FWHMY", idiff, fwhm_y);
911 
912  bug_if(0);
913 
914  end_skip;
915 
916  if (cpl_error_get_code())
917  cpl_msg_error(cpl_func, "Cannot reduce the image %d", idiff+1);
918 
919  return cpl_error_get_code();
920 }
921 
922 /*----------------------------------------------------------------------------*/
933 /*----------------------------------------------------------------------------*/
934 static double naco_img_zpoint_find_mag(cpl_propertylist * qclist,
935  double ra,
936  double dec,
937  const char * star_cat,
938  const char * filter)
939 {
940  cpl_error_code error;
941  const char * star_name;
942  const char * star_type;
943  const char * cat_name;
944  int istar;
945  double star_mag = 0.0;
946  naco_band band;
947  const char * bandname = NULL;
948  cpl_table * stdstars = NULL;
949  const char * sw_cat[] = {"LCO-Palomar", "LCO-Palomar-NICMOS-Red-Stars",
950  "ESO-VanDerBliek", "UKIRT-Extended",
951  "UKIRT-Fundamental", "SAAO-Carter", NULL};
952  const char * lw_cat[] = {"ESO-VanDerBliek", "UKIRT-Standards",
953  "UKIRT-LM", NULL};
954 
955  bug_if (filter == NULL);
956 
957  cpl_msg_info(cpl_func, "Get the star magnitude with filter: %s", filter);
958 
959  band = naco_get_bbfilter(filter); /* Get the band */
960 
961  skip_if(0);
962 
963  /* Get the nearby standard stars */
964  stdstars = naco_img_zpoint_load_std_star(star_cat, ra, dec, /* degrees */
965  (IRPLIB_STDSTAR_MAXDIST)/60.0);
966 
967  skip_if(stdstars == NULL);
968  skip_if(cpl_table_get_nrow(stdstars) == 0);
969 
970  istar = -1;
971 
972  switch (band) {
973  /* SW mode */
974  case BAND_J:
975  case BAND_H:
976  case BAND_K:
977  case BAND_KS:
978 
979  bandname = naco_std_band_name(band);
980 
981  error = naco_img_zpoint_find_std_star(stdstars, sw_cat, ra, dec,
982  bandname, CPL_FALSE, &istar);
983 
984  if (error) break;
985  if (istar >= 0) break;
986 
987 
988  /* Special case: swap K and Ks if needed */
989  if (band == BAND_K) {
990  bandname = naco_std_band_name(BAND_KS);
991 
992  cpl_msg_info(cpl_func, "Retrying with alternative band: %s",
993  bandname);
994 
995  error = naco_img_zpoint_find_std_star(stdstars, sw_cat, ra, dec,
996  bandname, CPL_TRUE, &istar);
997 
998  } else if (band == BAND_KS) {
999  bandname = naco_std_band_name(BAND_K);
1000 
1001  cpl_msg_info(cpl_func, "Retrying with alternative band: %s",
1002  bandname);
1003 
1004  error = naco_img_zpoint_find_std_star(stdstars, sw_cat, ra, dec,
1005  bandname, CPL_TRUE, &istar);
1006  }
1007  break;
1008 
1009  /* LW mode */
1010  case BAND_L:
1011  case BAND_M:
1012  case BAND_LP:
1013  case BAND_MP:
1014 
1015  bandname = naco_std_band_name(band);
1016 
1017  error = naco_img_zpoint_find_std_star(stdstars, lw_cat, ra, dec,
1018  bandname, CPL_FALSE, &istar);
1019 
1020  if (error) break;
1021  if (istar < 0) {
1022  naco_band other = BAND_UNKNOWN;
1023 
1024  switch(band) {
1025  case BAND_L:
1026  other = BAND_LP;
1027  break;
1028  case BAND_M:
1029  other = BAND_MP;
1030  break;
1031  case BAND_LP:
1032  other = BAND_L;
1033  break;
1034  case BAND_MP:
1035  other = BAND_M;
1036  break;
1037  default:
1038  bug_if (1);
1039  }
1040 
1041  bandname = naco_std_band_name(other);
1042 
1043  cpl_msg_info(cpl_func, "Retrying with alternative band: %s",
1044  bandname);
1045 
1046  error = naco_img_zpoint_find_std_star(stdstars, lw_cat, ra, dec,
1047  bandname, CPL_TRUE, &istar);
1048  }
1049  break;
1050  default:
1051  skip_if(1);
1052  }
1053 
1054  error_if (error || istar < 0, CPL_ERROR_DATA_NOT_FOUND, "Star magnitude "
1055  "for filter '%s' not found in catalog(s) at (RA,DEC)=(%g,%g)"
1056  " with tolerance=%g (degrees)", filter, ra, dec,
1057  IRPLIB_STDSTAR_MAXDIST/60.0);
1058 
1059  star_mag = cpl_table_get_double(stdstars, bandname, istar, NULL);
1060  star_name = cpl_table_get_string(stdstars, IRPLIB_STDSTAR_STAR_COL, istar);
1061  star_type = cpl_table_get_string(stdstars, IRPLIB_STDSTAR_TYPE_COL, istar);
1062  cat_name = cpl_table_get_string(stdstars, "CAT_NAME", istar);
1063 
1064 
1065  /* Store results */
1066  bug_if(cpl_propertylist_append_string(qclist, "ESO QC STDNAME",
1067  star_name));
1068  bug_if(cpl_propertylist_append_string(qclist, "ESO QC CATNAME",
1069  cat_name));
1070  bug_if(cpl_propertylist_append_string(qclist, "ESO QC SPECTYPE",
1071  star_type));
1072 
1073  cpl_msg_info(cpl_func, "Found standard star '%s' of type '%s' with "
1074  "magnitude %g for filter %s from catalog '%s'",
1075  star_name, star_type, star_mag, bandname, cat_name);
1076 
1077  end_skip;
1078 
1079  cpl_table_delete(stdstars);
1080 
1081  return star_mag;
1082 }
1083 
1084 
1085 /*----------------------------------------------------------------------------*/
1107 /*----------------------------------------------------------------------------*/
1108 static cpl_error_code naco_img_zpoint_find_std_star(cpl_table * self,
1109  const char * cat[],
1110  double ra, double dec,
1111  const char * bandname,
1112  cpl_boolean retry,
1113  int * pistar)
1114 {
1115 
1116  double min_dist = IRPLIB_STDSTAR_MAXDIST / 60.0; /* Maximum */
1117  int nsel;
1118 
1119  bug_if (pistar == NULL);
1120  *pistar = -1;
1121 
1122  bug_if (self == NULL);
1123  bug_if (bandname == NULL);
1124 
1125  nsel = (retry
1126  ? cpl_table_or_selected_double
1127  : cpl_table_and_selected_double)(self, bandname,
1128  CPL_LESS_THAN,
1129  IRPLIB_STDSTAR_LIMIT);
1130 
1131  if (nsel == 0) {
1132  cpl_msg_info(cpl_func, "None of the standard star catalog(s) have "
1133  "a star with a known magnitude for band %s within a "
1134  "distance of tol=%g [degrees] from (RA,DEC)=(%g,%g)",
1135  bandname, min_dist, ra, dec);
1136  } else {
1137 
1138  /* At this point we are sure to find a star, if not in the specified
1139  list of catalogs, then when searching them all */
1140 
1141  const int nrows = cpl_table_get_nrow(self);
1142  int ibest = -1;
1143  int i;
1144 
1145  int icat;
1146 
1147  bug_if (cat == NULL);
1148 
1149  for (icat = 0; cat[icat] != NULL; icat++) {
1150 
1151  char * regexp = cpl_sprintf("^%s$", cat[icat]);
1152 
1153  cpl_msg_info(cpl_func, "Trying %s", cat[icat]);
1154 
1155  nsel = cpl_table_and_selected_string(self, "CAT_NAME",
1156  CPL_EQUAL_TO, regexp);
1157  cpl_free(regexp);
1158 
1159  if (nsel > 0) break;
1160 
1161  /* No stars found in this catalog, reset to try next */
1162  nsel = cpl_table_or_selected_double(self, bandname,
1163  CPL_LESS_THAN,
1164  IRPLIB_STDSTAR_LIMIT);
1165  bug_if(nsel == 0);
1166  }
1167 
1168  bug_if (nsel == 0);
1169 
1170  /* Compute distances to the selected rows */
1171 
1172  for (i=0; i < nrows; i++) {
1173  if (cpl_table_is_selected(self, i)) {
1174  /* The row is selected - compute the distance */
1175  const double distance
1176  = irplib_wcs_great_circle_dist(ra, dec,
1177  cpl_table_get_double(self, IRPLIB_STDSTAR_RA_COL, i, NULL),
1178  cpl_table_get_double(self, IRPLIB_STDSTAR_DEC_COL, i,NULL));
1179 
1180  if (distance < min_dist) {
1181  min_dist = distance;
1182  ibest = i;
1183  }
1184  }
1185  }
1186 
1187  bug_if (ibest < 0);
1188 
1189  cpl_msg_info(cpl_func, "Found %d star(s) with known magnitude in band "
1190  "%s - selected one with distance %g", nsel, bandname,
1191  min_dist);
1192 
1193  *pistar = ibest;
1194  }
1195 
1196  end_skip;
1197 
1198  return cpl_error_get_code();
1199 }
1200 
1201 
1202 /*----------------------------------------------------------------------------*/
1211 /*----------------------------------------------------------------------------*/
1212 static cpl_error_code naco_img_zpoint_qc(cpl_propertylist * qclist,
1213  cpl_propertylist * paflist,
1214  const irplib_framelist * rawframes)
1215 {
1216 
1217  cpl_errorstate cleanstate = cpl_errorstate_get();
1218  const cpl_propertylist * reflist
1219  = irplib_framelist_get_propertylist_const(rawframes, 0);
1220 
1221  const char * sval;
1222 
1223 
1224  bug_if(0);
1225 
1226  /* Copy the keywords for the paf file */
1227  bug_if(cpl_propertylist_copy_property_regexp(paflist, reflist, "^("
1228  NACO_PFITS_REGEXP_ZPOINT_PAF
1229  ")$", 0));
1230 
1231  /* Add QC parameters */
1232 
1233  sval = naco_pfits_get_opti3_name(reflist);
1234  if (sval == NULL)
1235  naco_error_reset("Could not get FITS key:");
1236  else
1237  bug_if(cpl_propertylist_append_string(qclist, "ESO QC FILTER NDENS",
1238  sval));
1239  sval = naco_pfits_get_opti4_name(reflist);
1240  if (sval == NULL)
1241  naco_error_reset("Could not get FITS key:");
1242  else
1243  bug_if(cpl_propertylist_append_string(qclist, "ESO QC FILTER POL",
1244  sval));
1245 
1246  skip_if (naco_img_zpoint_qc_all(qclist, paflist, rawframes));
1247 
1248  bug_if(cpl_propertylist_append(paflist, qclist));
1249 
1250  bug_if(cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
1251  IRPLIB_PFITS_REGEXP_RECAL
1252  ")$", 0));
1253 
1254  bug_if (irplib_pfits_set_airmass(qclist, rawframes));
1255  bug_if(cpl_propertylist_append_double(qclist, "ESO QC AIRMASS",
1256  irplib_pfits_get_double(qclist,
1257  "AIRMASS")));
1258 
1259  end_skip;
1260 
1261  return cpl_error_get_code();
1262 }
1263 
1264 /*----------------------------------------------------------------------------*/
1276 /*----------------------------------------------------------------------------*/
1277 static cpl_error_code naco_img_zpoint_save(cpl_frameset * set,
1278  const cpl_parameterlist * parlist,
1279  const cpl_propertylist * qclist,
1280  const cpl_propertylist * paflist,
1281  const cpl_table * tab,
1282  const cpl_image * check_im)
1283 {
1284 
1285  bug_if(0);
1286 
1287  /* Write the zpoint table */
1288  skip_if (irplib_dfs_save_table(set, parlist, set, tab, NULL, RECIPE_STRING,
1289  NACO_IMG_ZPOINT_RES, qclist, NULL, naco_pipe_id,
1290  RECIPE_STRING CPL_DFS_FITS));
1291 
1292 
1293  /* Write the check image */
1294  if (check_im)
1295  skip_if (irplib_dfs_save_image(set, parlist, set, check_im,
1296  CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
1297  NACO_IMG_ZPOINT_CHECK, qclist, NULL,
1298  naco_pipe_id,
1299  RECIPE_STRING "_check" CPL_DFS_FITS));
1300 
1301  skip_if (cpl_dfs_save_paf("NACO", RECIPE_STRING, paflist,
1302  RECIPE_STRING CPL_DFS_PAF));
1303 
1304  end_skip;
1305 
1306  return cpl_error_get_code();
1307 }
1308 
1309 /*----------------------------------------------------------------------------*/
1318 /*----------------------------------------------------------------------------*/
1319 static cpl_error_code naco_img_zpoint_qc_all(cpl_propertylist * qclist,
1320  cpl_propertylist * paflist,
1321  const irplib_framelist * rawframes)
1322 {
1323  const int nframes = irplib_framelist_get_size(rawframes);
1324  cpl_vector * ec_vec = cpl_vector_new(nframes);
1325  cpl_vector * flux_vec = cpl_vector_new(nframes);
1326  cpl_vector * l0_vec = cpl_vector_new(nframes);
1327  cpl_vector * t0_vec = cpl_vector_new(nframes);
1328  cpl_vector * r0_vec = cpl_vector_new(nframes);
1329  cpl_vector * hum_vec = cpl_vector_new(nframes);
1330  double ec, flux, l0, t0, r0, hum;
1331  int i;
1332 
1333 
1334  bug_if(0);
1335 
1336  bug_if(nframes <= 0);
1337 
1338  for (i = 0; i < nframes; i++) {
1339  const cpl_propertylist * plist
1340  = irplib_framelist_get_propertylist_const(rawframes, i);
1341 
1342  bug_if(0);
1343 
1344  skip_if(cpl_vector_set(ec_vec, i, naco_pfits_get_ecmean(plist)));
1345  skip_if(cpl_vector_set(flux_vec, i, naco_pfits_get_fluxmean(plist)));
1346  skip_if(cpl_vector_set(t0_vec, i, naco_pfits_get_t0mean(plist)));
1347  skip_if(cpl_vector_set(l0_vec, i, naco_pfits_get_l0mean(plist)));
1348  skip_if(cpl_vector_set(r0_vec, i, naco_pfits_get_r0mean(plist)));
1349  skip_if(cpl_vector_set(hum_vec, i,
1351 
1352  }
1353 
1354  bug_if(0);
1355 
1356  ec = cpl_vector_get_median(ec_vec); /* vector-permute */
1357  flux = cpl_vector_get_median(flux_vec); /* vector-permute */
1358  l0 = cpl_vector_get_median(l0_vec); /* vector-permute */
1359  t0 = cpl_vector_get_median(t0_vec); /* vector-permute */
1360  r0 = cpl_vector_get_median(r0_vec); /* vector-permute */
1361  hum = cpl_vector_get_mean(hum_vec);
1362  bug_if(0);
1363 
1364  cpl_propertylist_append_double(qclist, "ESO QC AMBI RHUM AVG", hum);
1365  cpl_propertylist_append_double(paflist,
1366  "ESO AOS RTC DET DST L0MEAN", l0);
1367  cpl_propertylist_append_double(paflist,
1368  "ESO AOS RTC DET DST T0MEAN", t0);
1369  cpl_propertylist_append_double(paflist,
1370  "ESO AOS RTC DET DST R0MEAN", r0);
1371  cpl_propertylist_append_double(paflist,
1372  "ESO AOS RTC DET DST ECMEAN", ec);
1373  cpl_propertylist_append_double(paflist,
1374  "ESO AOS RTC DET DST FLUXMEAN", flux);
1375  bug_if(0);
1376 
1377 
1378  end_skip;
1379 
1380  cpl_vector_delete(ec_vec);
1381  cpl_vector_delete(flux_vec);
1382  cpl_vector_delete(r0_vec);
1383  cpl_vector_delete(t0_vec);
1384  cpl_vector_delete(l0_vec);
1385  cpl_vector_delete(hum_vec);
1386 
1387  return cpl_error_get_code();
1388 }
1389 
1390 
1391 /*----------------------------------------------------------------------------*/
1398 /*----------------------------------------------------------------------------*/
1399 static naco_band naco_get_bbfilter(const char * filter)
1400 {
1401  naco_band self = BAND_UNKNOWN;
1402 
1403 
1404  bug_if (filter == NULL);
1405 
1406  if (!strcmp(filter, "J")) self = BAND_J;
1407  else if (!strcmp(filter, "Jc")) self = BAND_J;
1408  else if (!strcmp(filter, "H")) self = BAND_H;
1409  else if (!strcmp(filter, "K")) self = BAND_K;
1410  else if (!strcmp(filter, "Ks")) self = BAND_KS;
1411  else if (!strcmp(filter, "L")) self = BAND_L;
1412  else if (!strcmp(filter, "L_prime")) self = BAND_LP;
1413  else if (!strcmp(filter, "M_prime")) self = BAND_MP;
1414  else if (!strcmp(filter, "NB_1.04")) self = BAND_J;
1415  else if (!strcmp(filter, "NB_1.08")) self = BAND_J;
1416  else if (!strcmp(filter, "NB_1.09")) self = BAND_J;
1417  else if (!strcmp(filter, "NB_1.24")) self = BAND_J;
1418  else if (!strcmp(filter, "NB_1.26")) self = BAND_J;
1419  else if (!strcmp(filter, "NB_1.28")) self = BAND_J;
1420  else if (!strcmp(filter, "NB_1.64")) self = BAND_H;
1421  else if (!strcmp(filter, "NB_1.75")) self = BAND_H;
1422  else if (!strcmp(filter, "NB_3.74")) self = BAND_L;
1423  else if (!strcmp(filter, "IB_2.00")) self = BAND_K;
1424  else if (!strcmp(filter, "IB_2.03")) self = BAND_K;
1425  else if (!strcmp(filter, "IB_2.06")) self = BAND_K;
1426  else if (!strcmp(filter, "IB_2.09")) self = BAND_K;
1427  else if (!strcmp(filter, "IB_2.12")) self = BAND_K;
1428  else if (!strcmp(filter, "NB_2.12")) self = BAND_K;
1429  else if (!strcmp(filter, "IB_2.15")) self = BAND_K;
1430  else if (!strcmp(filter, "NB_2.17")) self = BAND_K;
1431  else if (!strcmp(filter, "IB_2.18")) self = BAND_K;
1432  else if (!strcmp(filter, "IB_2.21")) self = BAND_K;
1433  else if (!strcmp(filter, "IB_2.24")) self = BAND_K;
1434  else if (!strcmp(filter, "IB_2.27")) self = BAND_K;
1435  else if (!strcmp(filter, "IB_2.30")) self = BAND_K;
1436  else if (!strcmp(filter, "IB_2.33")) self = BAND_K;
1437  else if (!strcmp(filter, "IB_2.36")) self = BAND_K;
1438  else if (!strcmp(filter, "IB_2.39")) self = BAND_K;
1439  else if (!strcmp(filter, "IB_2.42")) self = BAND_K;
1440  else if (!strcmp(filter, "IB_2.45")) self = BAND_K;
1441  else if (!strcmp(filter, "IB_2.48")) self = BAND_K;
1442  else if (!strcmp(filter, "NB_4.05")) self = BAND_M;
1443  /* As per email 2009-10-13 from epompei@eso.org */
1444  else if (!strcmp(filter, "IB_4.05")) self = BAND_M;
1445  else if (!strcmp(filter, "SJ")) self = BAND_UNKNOWN;
1446  else if (!strcmp(filter, "SH")) self = BAND_UNKNOWN;
1447  else if (!strcmp(filter, "SK")) self = BAND_UNKNOWN;
1448 
1449  error_if (self == BAND_UNKNOWN, CPL_ERROR_UNSUPPORTED_MODE, "No broad-"
1450  "band could be associated with the filter: %s", filter);
1451 
1452  end_skip;
1453 
1454  return self;
1455 }
1456 
1457 
1458 /*----------------------------------------------------------------------------*/
1469 /*----------------------------------------------------------------------------*/
1470 static cpl_table * naco_img_zpoint_load_std_star(const char * star_cat,
1471  double ra, double dec,
1472  double tol)
1473 {
1474 
1475  cpl_table * self = cpl_table_load(star_cat, 1, 0);
1476  const double * pra
1477  = cpl_table_get_data_double_const(self, IRPLIB_STDSTAR_RA_COL);
1478  const double * pdec
1479  = cpl_table_get_data_double_const(self, IRPLIB_STDSTAR_DEC_COL);
1480  const int nrow = cpl_table_get_nrow(self);
1481  int i;
1482 
1483  skip_if(self == NULL);
1484  bug_if(star_cat == NULL);
1485  skip_if(pra == NULL);
1486  skip_if(pdec == NULL);
1487  skip_if(tol < 0.0);
1488 
1489  bug_if(cpl_table_unselect_all(self));
1490 
1491  for (i = 0; i < nrow; i++) {
1492  const double deci = pdec[i];
1493 
1494  if (deci > dec + tol ||
1495  deci < dec - tol ||
1496  irplib_wcs_great_circle_dist(ra, dec, pra[i], deci) > tol) {
1497 
1498  bug_if(cpl_table_select_row(self, i));
1499 
1500  }
1501  }
1502 
1503  if (cpl_table_count_selected(self) == nrow) {
1504  double mindist = DBL_MAX; /* Avoid uninit warning */
1505  int idist = 0; /* Avoid uninit warning */
1506 
1507  for (i = 0; i < nrow; i++) {
1508  const double dist
1509  = irplib_wcs_great_circle_dist(ra, dec, pra[i], pdec[i]);
1510 
1511  if (i == 0 || dist < mindist) {
1512  idist = i;
1513  mindist = dist;
1514  }
1515  }
1516 
1517  (void)cpl_error_set_message_macro(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1518  __FILE__, __LINE__, "Catalog '%s' "
1519  "star %d of %d at (RA,DEC)=(%g,%g) "
1520  "is closest to target at "
1521  "(RA,DEC)=(%g,%g) with a too large "
1522  "distance of %g [degrees] > %g",
1523  star_cat, 1+idist, nrow, pra[idist],
1524  pdec[idist], ra, dec, mindist, tol);
1525  }
1526 
1527  bug_if(cpl_table_erase_selected(self));
1528 
1529  cpl_msg_info(cpl_func, "Loaded %d of %d stars from '%s' which are within "
1530  "%g degrees from (RA,DEC)=(%g,%g)",
1531  (int)cpl_table_get_nrow(self), nrow, star_cat, tol, ra, dec);
1532  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
1533  cpl_table_dump(self, 0, cpl_table_get_nrow(self), stdout);
1534  }
1535 
1536  end_skip;
1537 
1538  return self;
1539 
1540 }
1541 
1542 /*-------------------------------------------------------------------------*/
1549 /*--------------------------------------------------------------------------*/
1550 static const char * naco_std_band_name(naco_band band)
1551 {
1552  switch (band) {
1553  case BAND_J: return "J";
1554  case BAND_JS: return "Js";
1555  case BAND_JBLOCK: return "J+Block";
1556  case BAND_H: return "H";
1557  case BAND_K: return "K";
1558  case BAND_KS: return "Ks";
1559  case BAND_L: return "L";
1560  case BAND_M: return "M";
1561  case BAND_LP: return "Lp";
1562  case BAND_MP: return "Mp";
1563  case BAND_Z: return "Z";
1564  case BAND_SZ: return "SZ";
1565  case BAND_SH: return "SH";
1566  case BAND_SK: return "SK";
1567  case BAND_SL: return "SL";
1568  default: return "Unknown";
1569  }
1570 }
1571 
naco_pfits_get_l0mean
double naco_pfits_get_l0mean(const cpl_propertylist *self)
find out the L0MEAN
Definition: naco_pfits.c:244
naco_pfits_get_cumoffsety
double naco_pfits_get_cumoffsety(const cpl_propertylist *self)
find out the cumulative offset in Y
Definition: naco_pfits.c:107
naco_pfits_get_cumoffsetx
double naco_pfits_get_cumoffsetx(const cpl_propertylist *self)
find out the cumulative offset in X
Definition: naco_pfits.c:95
naco_pfits_get_dec
double naco_pfits_get_dec(const cpl_propertylist *self)
find out the DEC
Definition: naco_pfits.c:119
naco_pfits_get_object
const char * naco_pfits_get_object(const cpl_propertylist *self)
Get the Object name.
Definition: naco_pfits.c:280
naco_strehl_compute
cpl_error_code naco_strehl_compute(const cpl_image *self, const cpl_parameterlist *parlist, const char *recipename, double lam, double dlam, double pos_x, double pos_y, double pixscale, double *pstrehl, double *pstrehl_err, double *pstar_bg, double *pstar_peak, double *pstar_flux, double *ppsf_peak, double *ppsf_flux, double *pbg_noise)
Compute the strehl ratio in an image.
Definition: naco_strehl.c:80
irplib_pfits_set_airmass
cpl_error_code irplib_pfits_set_airmass(cpl_propertylist *self, const irplib_framelist *rawframes)
Update/Set the AIRMASS property.
Definition: irplib_pfits.c:373
naco_pfits_get_humidity_level
double naco_pfits_get_humidity_level(const cpl_propertylist *self)
find out the humidity level
Definition: naco_pfits.c:232
naco_pfits_get_r0mean
double naco_pfits_get_r0mean(const cpl_propertylist *self)
find out the R0MEAN key
Definition: naco_pfits.c:353
naco_pfits_get_dit
double naco_pfits_get_dit(const cpl_propertylist *self)
find out the DIT
Definition: naco_pfits.c:131
naco_parameterlist_get_double
double naco_parameterlist_get_double(const cpl_parameterlist *self, const char *recipe, naco_parameter bitmask)
Retrieve the value of a NACO parameter of type double.
Definition: naco_parameter.c:538
naco_pfits_get_ecmean
double naco_pfits_get_ecmean(const cpl_propertylist *self)
find out the ECMEAN key
Definition: naco_pfits.c:143
naco_pfits_get_filter
const char * naco_pfits_get_filter(const cpl_propertylist *self)
find out the filter
Definition: naco_pfits.c:167
naco_pfits_get_pixscale
double naco_pfits_get_pixscale(const cpl_propertylist *self)
find out the pixel scale
Definition: naco_pfits.c:341
naco_pfits_get_opti4_name
const char * naco_pfits_get_opti4_name(const cpl_propertylist *self)
find out the OPTI4.NAME key
Definition: naco_pfits.c:316
naco_pfits_get_ra
double naco_pfits_get_ra(const cpl_propertylist *self)
find out the RA
Definition: naco_pfits.c:365
naco_pfits_get_opti3_name
const char * naco_pfits_get_opti3_name(const cpl_propertylist *self)
find out the OPTI3.NAME key
Definition: naco_pfits.c:304
naco_parameterlist_get_int
int naco_parameterlist_get_int(const cpl_parameterlist *self, const char *recipe, naco_parameter bitmask)
Retrieve the value of a NACO integer parameter.
Definition: naco_parameter.c:474
naco_get_filter_infos
cpl_error_code naco_get_filter_infos(const char *f, double *lam, double *dlam)
Get the infos of one of the filters.
Definition: naco_utils.c:61
naco_pfits_get_t0mean
double naco_pfits_get_t0mean(const cpl_propertylist *self)
find out the T0MEAN key
Definition: naco_pfits.c:401
naco_dfs_set_groups
int naco_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: naco_dfs.c:62
naco_pfits_get_fluxmean
double naco_pfits_get_fluxmean(const cpl_propertylist *self)
find out the FLUXMEAN key
Definition: naco_pfits.c:208
naco_parameterlist_get_bool
cpl_boolean naco_parameterlist_get_bool(const cpl_parameterlist *self, const char *recipe, naco_parameter bitmask)
Retrieve the value of a NACO boolean parameter.
Definition: naco_parameter.c:419