IIINSTRUMENT Pipeline Reference Manual  6.2.2
isaac_img_zpoint.c
1 /* $Id: isaac_img_zpoint.c,v 1.61 2013-03-12 08:06:48 llundin Exp $
2  *
3  * This file is part of the ISAAC 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: 2013-03-12 08:06:48 $
24  * $Revision: 1.61 $
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 <cpl.h>
37 
38 #include "irplib_plugin.h"
39 #include "irplib_utils.h"
40 #include "irplib_calib.h"
41 #include "irplib_strehl.h"
42 #include "irplib_stdstar.h"
43 
44 #include "isaac_utils.h"
45 #include "isaac_pfits.h"
46 #include "isaac_dfs.h"
47 
48 #include <string.h>
49 #include <math.h>
50 #include <assert.h>
51 
52 /*-----------------------------------------------------------------------------
53  Define
54  -----------------------------------------------------------------------------*/
55 
56 #define RECIPE_STRING "isaac_img_zpoint"
57 
58 #define PHOT_STAR_RADIUS 30.0
59 #define PHOT_BACKGROUND_R1 40.0
60 #define PHOT_BACKGROUND_R2 60.0
61 
62 #define DEF_LOCATE_SX 10
63 #define DEF_LOCATE_SY 10
64 
65 /*-----------------------------------------------------------------------------
66  Functions prototypes
67  -----------------------------------------------------------------------------*/
68 
69 static cpl_table * isaac_img_zpoint_reduce(cpl_frameset *, const char *,
70  const char *, const char *, const char *, const char *, cpl_image **);
71 static cpl_imagelist * isaac_img_zpoint_load(cpl_frameset *, const char *,
72  const char *, const char *, const char *);
73 static int isaac_img_zpoint_save(cpl_table *, cpl_image *, cpl_frameset *,
74  const cpl_parameterlist *, cpl_frameset *);
75 static cpl_table * isaac_img_zpoint_photom(cpl_imagelist *, cpl_bivector *);
76 static cpl_error_code isaac_img_zpoint_get_mag(const char *, double, double,
77  isaac_band);
78 static int isaac_img_zpoint_gradients(cpl_vector *, cpl_bivector *, double *,
79  double *, double *, double *);
80 static cpl_bivector * isaac_img_zpoint_get_offsets(cpl_frameset *);
81 static cpl_error_code isaac_img_zpoint_compute_keywords(const cpl_frameset *,
82  double *,double *);
83 static cpl_image * isaac_img_zpoint_check_im(cpl_imagelist *,
84  cpl_bivector *, double, double, double);
85 
86 cpl_recipe_define(isaac_img_zpoint, ISAAC_BINARY_VERSION,
87  "Lars Lundin", PACKAGE_BUGREPORT, "2008",
88  "ISAAC Zero point computation recipe",
89  RECIPE_STRING " -- ISAAC Zero point recipe\n"
90  "The files listed in the Set Of Frames (sof-file) must "
91  "be tagged:\n"
92  "raw-file.fits "ISAAC_IMG_ZPOINT_RAW" or\n"
93  "raw-file.fits "ISAAC_IMG_ZPOINT_CHOPPING_RAW" or\n"
94  "stdstars.fits "ISAAC_CALIB_STDSTARS" or\n"
95  "flat-file.fits "ISAAC_CALIB_FLAT" or\n"
96  "detlin-a-file.fits "ISAAC_CALIB_DETLIN_A" or\n"
97  "detlin-b-file.fits "ISAAC_CALIB_DETLIN_B" or\n"
98  "detlin-c-file.fits "ISAAC_CALIB_DETLIN_C"\n");
99 
100 /*-----------------------------------------------------------------------------
101  Static variables
102  -----------------------------------------------------------------------------*/
103 
104 static struct {
105  /* Inputs */
106  double ra;
107  double dec;
108  double magnitude;
109  int sx;
110  int sy;
111  double phot_star_radius;
112  double phot_bg_r1;
113  double phot_bg_r2;
114  int chopping;
115  int check_im;
116  /* Outputs */
117  double dit;
118  char filter[512];
119  isaac_band band;
120  char * starname;
121  char * sptype;
122  char * catalog;
123  double zpoint;
124  double zpointrms;
125  double flux_med;
126  double gradx;
127  double grady;
128  double graddx;
129  double graddy;
130  double fwhm_mean;
131 } isaac_img_zpoint_config;
132 
133 /*-----------------------------------------------------------------------------
134  Functions code
135  -----------------------------------------------------------------------------*/
136 
137 
138 /*----------------------------------------------------------------------------*/
146 /*----------------------------------------------------------------------------*/
147 static
148 cpl_error_code isaac_img_zpoint_fill_parameterlist(cpl_parameterlist * self)
149 {
150 
151  const char * context = PACKAGE "." RECIPE_STRING;
152  cpl_error_code err;
153 
154  cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
155 
156  /* Fill the parameters list */
157 
158 
159  /* --star_r */
160  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
161  "star_r", PHOT_STAR_RADIUS, NULL,
162  context, "The star radius");
163  cpl_ensure_code(!err, err);
164 
165  /* --bg_r1 */
166  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
167  "bg_r1", PHOT_BACKGROUND_R1, NULL,
168  context, "The internal background "
169  "radius");
170  cpl_ensure_code(!err, err);
171 
172  /* --bg_r2 */
173  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
174  "bg_r2", PHOT_BACKGROUND_R2, NULL,
175  context, "The external background "
176  "radius");
177  cpl_ensure_code(!err, err);
178 
179  /* --ra */
180  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
181  "ra", 999.0, NULL, context,
182  "Right Ascension [degrees]");
183  cpl_ensure_code(!err, err);
184 
185  /* --dec */
186  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
187  "dec", 999.0, NULL, context,
188  "Declination [degrees]");
189  cpl_ensure_code(!err, err);
190 
191  /* --mag */
192  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
193  "mag", 99.0, NULL, context,
194  "Standard Star Magnitude to use "
195  "instead of catalogue value");
196  cpl_ensure_code(!err, err);
197 
198  /* --sx */
199  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
200  "sx", DEF_LOCATE_SX, NULL, context,
201  "X-size of the search window");
202  cpl_ensure_code(!err, err);
203 
204  /* --sy */
205  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
206  "sy", DEF_LOCATE_SY, NULL, context,
207  "Y-size of the search window");
208  cpl_ensure_code(!err, err);
209 
210  /* --check_im */
211  err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
212  "check_im", CPL_FALSE, NULL, context,
213  "Flag to create the check image");
214  cpl_ensure_code(!err, err);
215 
216  return CPL_ERROR_NONE;
217 }
218 
219 
220 /*----------------------------------------------------------------------------*/
227 /*----------------------------------------------------------------------------*/
228 static int isaac_img_zpoint(cpl_frameset * framelist,
229  const cpl_parameterlist * parlist)
230 {
231 
232  const char * stdstars;
233  const char * flat;
234  const char * detlin_a;
235  const char * detlin_b;
236  const char * detlin_c;
237  cpl_frameset * rawframes = NULL;
238  cpl_table * tab = NULL;
239  cpl_image * check_im = NULL;
240 
241  /* Initialise */
242  isaac_img_zpoint_config.starname = NULL;
243  isaac_img_zpoint_config.sptype = NULL;
244  isaac_img_zpoint_config.filter[0] = (char)0;
245  isaac_img_zpoint_config.catalog = NULL;
246  isaac_img_zpoint_config.gradx = -1.0;
247  isaac_img_zpoint_config.grady = -1.0;
248  isaac_img_zpoint_config.graddx = -1.0;
249  isaac_img_zpoint_config.graddy = -1.0;
250  isaac_img_zpoint_config.fwhm_mean = -1.0;
251 
252  /* Retrieve input parameters */
253  /* --ra */
254  isaac_img_zpoint_config.ra =
255  irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING, "ra");
256 
257  /* --dec */
258  isaac_img_zpoint_config.dec =
259  irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING, "dec");
260 
261  /* --mag */
262  isaac_img_zpoint_config.magnitude =
263  irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING, "mag");
264 
265  /* --sx */
266  isaac_img_zpoint_config.sx =
267  irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING, "sx");
268 
269  /* --sy */
270  isaac_img_zpoint_config.sy =
271  irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING, "sy");
272 
273  /* --star_r */
274  isaac_img_zpoint_config.phot_star_radius =
275  irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
276  "star_r");
277  /* --bg_r1 */
278  isaac_img_zpoint_config.phot_bg_r1 =
279  irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
280  "bg_r1");
281 
282  /* --bg_r2 */
283  isaac_img_zpoint_config.phot_bg_r2 =
284  irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
285  "bg_r2");
286 
287  /* --check_im */
288  isaac_img_zpoint_config.check_im =
289  irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
290  "check_im");
291 
292  /* Identify the RAW and CALIB frames in the input frameset */
293  skip_if (isaac_dfs_set_groups(framelist));
294 
295  /* Retrieve calibration data */
296  detlin_a = isaac_extract_filename(framelist, ISAAC_CALIB_DETLIN_A);
297  detlin_b = isaac_extract_filename(framelist, ISAAC_CALIB_DETLIN_B);
298  detlin_c = isaac_extract_filename(framelist, ISAAC_CALIB_DETLIN_C);
299  flat = isaac_extract_filename(framelist, ISAAC_CALIB_FLAT);
300  stdstars = isaac_extract_filename(framelist, ISAAC_CALIB_STDSTARS);
301 
302  /* Retrieve raw frames */
303  if ((rawframes = isaac_extract_frameset(framelist,
304  ISAAC_IMG_ZPOINT_RAW)) != NULL) {
305  isaac_img_zpoint_config.chopping = 0;
306  } else if ((rawframes = isaac_extract_frameset(framelist,
307  ISAAC_IMG_ZPOINT_CHOPPING_RAW)) != NULL) {
308  isaac_img_zpoint_config.chopping = 1;
309  } else {
310  error_if(1, CPL_ERROR_DATA_NOT_FOUND, "Cannot find raw frames in the "
311  "input list");
312  }
313 
314  /* Compute the zpoint values */
315  cpl_msg_info(cpl_func, "Reduce the data");
316  cpl_msg_indent_more();
317  tab = isaac_img_zpoint_reduce(rawframes, stdstars, flat, detlin_a,
318  detlin_b, detlin_c, &check_im);
319  cpl_msg_indent_less();
320  skip_if(tab == NULL);
321 
322  /* Save the products */
323  cpl_msg_info(cpl_func, "Save the paf file");
324  cpl_msg_indent_more();
325  isaac_img_zpoint_save(tab, check_im, rawframes, parlist, framelist);
326  cpl_msg_indent_less();
327  skip_if (0);
328 
329  end_skip;
330 
331  cpl_image_delete(check_im);
332  cpl_frameset_delete(rawframes);
333  cpl_table_delete(tab);
334  cpl_free(isaac_img_zpoint_config.starname);
335  cpl_free(isaac_img_zpoint_config.sptype);
336  cpl_free(isaac_img_zpoint_config.catalog);
337 
338  return cpl_error_get_code();
339 }
340 
341 /*----------------------------------------------------------------------------*/
353 /*----------------------------------------------------------------------------*/
354 static cpl_table * isaac_img_zpoint_reduce(
355  cpl_frameset * set,
356  const char * stdstars,
357  const char * flat,
358  const char * detlin_a,
359  const char * detlin_b,
360  const char * detlin_c,
361  cpl_image ** check_im)
362 {
363  cpl_frame * cur_frame;
364  cpl_propertylist * plist;
365  const char * sval;
366  cpl_imagelist * imlist;
367  cpl_image * ima;
368  cpl_mask * kernel;
369  int niter;
370  int size_x, size_y;
371  double pos_x, pos_y, pos_x_cen, pos_y_cen, dist, min_dist;
372  cpl_apertures * aperts;
373  cpl_bivector * offsets,
374  * positions;
375  double off_x, off_y;
376  int llx, lly, urx, ury;
377  double val, sqsum, zprms, avg_zp;
378  cpl_table * tab_res;
379  cpl_vector * tmp_vec;
380  int nb_ok;
381  int i;
382 
383  /* Initialise */
384  *check_im = NULL;
385  pos_x_cen = pos_y_cen = -1.0;
386 
387  /* Get the filter name, DIT, RA and DEC */
388  cur_frame = cpl_frameset_get_position(set, 0);
389  plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
390  if ((sval = isaac_pfits_get_filter(plist)) == NULL) {
391  cpl_propertylist_delete(plist);
392  cpl_ensure(0, cpl_error_get_code(), NULL);
393  }
394  (void)strncpy(isaac_img_zpoint_config.filter, sval, 512);
395  isaac_img_zpoint_config.filter[511] = (char)0;
396  if (isaac_img_zpoint_config.ra > 998.0)
397  isaac_img_zpoint_config.ra = isaac_pfits_get_ra(plist);
398  if (isaac_img_zpoint_config.dec > 998.0)
399  isaac_img_zpoint_config.dec = isaac_pfits_get_dec(plist);
400  isaac_img_zpoint_config.dit = isaac_pfits_get_dit(plist);
401  cpl_propertylist_delete(plist);
402  if (cpl_error_get_code()) {
403  cpl_msg_error(cpl_func, "Cannot get some header informations");
404  return NULL;
405  }
406  cpl_msg_info(cpl_func, "Using star at position: RA = %g; DEC = %g",
407  isaac_img_zpoint_config.ra, isaac_img_zpoint_config.dec);
408 
409  /* Get the band */
410  if ((isaac_img_zpoint_config.band =
411  isaac_get_bbfilter(isaac_img_zpoint_config.filter)) ==
412  ISAAC_BAND_UNKNOWN) {
413  cpl_msg_error(cpl_func, "Cannot associate the filter to a BB one");
414  return NULL;
415  }
416 
417  /* Get the standard star information from database */
418  if (isaac_img_zpoint_config.magnitude > 98.0) {
419  cpl_msg_info(cpl_func, "Get the star magnitude");
420  if (isaac_img_zpoint_get_mag(stdstars, isaac_img_zpoint_config.ra,
421  isaac_img_zpoint_config.dec,
422  isaac_img_zpoint_config.band)) {
423  cpl_msg_error(cpl_func,"Cannot get the magnitude from the catalog");
424  return NULL;
425  }
426  }
427  cpl_msg_info(cpl_func, "Star magnitude with filter %s : %g",
428  isaac_img_zpoint_config.filter,
429  isaac_img_zpoint_config.magnitude);
430 
431  /* Load the images */
432  cpl_msg_info(cpl_func, "Load images");
433  if ((imlist = isaac_img_zpoint_load(set, flat, detlin_a, detlin_b,
434  detlin_c)) == NULL) {
435  cpl_msg_error(cpl_func, "Cannot load the images");
436  return NULL;
437  }
438 
439  /* Detect the central object in the first frame */
440  cpl_msg_info(cpl_func, "Detect a bright object in the first frame");
441  size_x = cpl_image_get_size_x(cpl_imagelist_get(imlist, 0));
442  size_y = cpl_image_get_size_y(cpl_imagelist_get(imlist, 0));
443  kernel = cpl_mask_new(3, 3);
444  cpl_mask_not(kernel);
445  ima = cpl_image_new(size_x, size_y,
446  cpl_image_get_type(cpl_imagelist_get(imlist, 0)));
447  cpl_image_filter_mask(ima, cpl_imagelist_get(imlist, 0), kernel,
448  CPL_FILTER_MEDIAN, CPL_BORDER_FILTER);
449  cpl_mask_delete(kernel);
450  aperts = cpl_apertures_extract_sigma(ima, 5.0);
451  cpl_image_delete(ima);
452  min_dist = size_x * size_x + size_y * size_y;
453  for (i=0; i<cpl_apertures_get_size(aperts); i++) {
454  pos_x = cpl_apertures_get_centroid_x(aperts, i+1);
455  pos_y = cpl_apertures_get_centroid_y(aperts, i+1);
456  dist = (pos_x-size_x/2)*(pos_x-size_x/2) +
457  (pos_y-size_y/2)*(pos_y-size_y/2);
458  if (dist<min_dist) {
459  min_dist = dist;
460  pos_x_cen = pos_x;
461  pos_y_cen = pos_y;
462  }
463  }
464  cpl_apertures_delete(aperts);
465  if (cpl_error_get_code()) {
466  cpl_msg_error(cpl_func, "Cannot find the central object");
467  cpl_imagelist_delete(imlist);
468  return NULL;
469  }
470  cpl_msg_info(cpl_func, "Bright object position: %g %g",
471  pos_x_cen, pos_y_cen);
472 
473  /* Get the offsets */
474  cpl_msg_info(cpl_func, "Read the offsets in the header");
475  offsets = isaac_img_zpoint_get_offsets(set);
476 
477  /* Deduce the objects positions */
478  niter = cpl_imagelist_get_size(imlist);
479  positions = cpl_bivector_new(niter);
480  for (i=0; i<niter; i++) {
481  off_x = cpl_vector_get(cpl_bivector_get_x(offsets), i) -
482  cpl_vector_get(cpl_bivector_get_x(offsets), 0);
483  off_y = cpl_vector_get(cpl_bivector_get_y(offsets), i) -
484  cpl_vector_get(cpl_bivector_get_y(offsets), 0);
485  pos_x = pos_x_cen + off_x;
486  pos_y = pos_y_cen + off_y;
487  cpl_vector_set(cpl_bivector_get_x(positions), i, pos_x);
488  cpl_vector_set(cpl_bivector_get_y(positions), i, pos_y);
489  }
490  cpl_bivector_delete(offsets);
491 
492  /* Refine the positions */
493  cpl_msg_info(cpl_func, "Refine the star positions");
494  for (i=1; i<niter; i++) {
495  pos_x = cpl_vector_get(cpl_bivector_get_x(positions), i);
496  pos_y = cpl_vector_get(cpl_bivector_get_y(positions), i);
497  llx = pos_x - isaac_img_zpoint_config.sx;
498  urx = pos_x + isaac_img_zpoint_config.sx;
499  lly = pos_y - isaac_img_zpoint_config.sy;
500  ury = pos_y + isaac_img_zpoint_config.sy;
501  ima = cpl_imagelist_get(imlist, i);
502  pos_x = cpl_image_get_centroid_x_window(ima, llx, lly, urx, ury);
503  pos_y = cpl_image_get_centroid_y_window(ima, llx, lly, urx, ury);
504  cpl_vector_set(cpl_bivector_get_x(positions), i, pos_x);
505  cpl_vector_set(cpl_bivector_get_y(positions), i, pos_y);
506  }
507  if (cpl_error_get_code()) {
508  cpl_msg_error(cpl_func, "Cannot refine the positions");
509  cpl_imagelist_delete(imlist);
510  cpl_bivector_delete(positions);
511  return NULL;
512  }
513 
514  /* Create the check image if requested */
515  if (isaac_img_zpoint_config.check_im) {
516  *check_im = isaac_img_zpoint_check_im(imlist, positions,
517  isaac_img_zpoint_config.phot_star_radius,
518  isaac_img_zpoint_config.phot_bg_r1,
519  isaac_img_zpoint_config.phot_bg_r2);
520  }
521 
522  /* Reduce the images */
523  cpl_msg_info(cpl_func, "Compute the photometry");
524  cpl_msg_indent_more();
525  if ((tab_res = isaac_img_zpoint_photom(imlist, positions)) == NULL) {
526  cpl_msg_error(cpl_func, "Cannot reduce");
527  cpl_bivector_delete(positions);
528  cpl_imagelist_delete(imlist);
529  cpl_image_delete(*check_im);
530  *check_im = NULL;
531  cpl_msg_indent_less();
532  return NULL;
533  }
534  cpl_msg_indent_less();
535  cpl_imagelist_delete(imlist);
536 
537  /* Compute the median of the flux */
538  isaac_img_zpoint_config.flux_med =
539  cpl_table_get_column_median(tab_res, "FLUX");
540 
541  /* Get the mean FWHM */
542  isaac_img_zpoint_config.fwhm_mean =
543  cpl_table_get_column_mean(tab_res, "FWHMX");
544  isaac_img_zpoint_config.fwhm_mean +=
545  cpl_table_get_column_mean(tab_res, "FWHMY");
546  isaac_img_zpoint_config.fwhm_mean /= 2.0;
547 
548  /* Compute the flux gradient */
549  tmp_vec = cpl_vector_new(niter);
550  for (i=0; i<niter; i++) {
551  cpl_vector_set(tmp_vec, i,
552  cpl_table_get_double(tab_res, "FLUX", i, NULL));
553  }
554  isaac_img_zpoint_gradients(tmp_vec, positions,
555  &(isaac_img_zpoint_config.gradx),
556  &(isaac_img_zpoint_config.grady),
557  &(isaac_img_zpoint_config.graddx),
558  &(isaac_img_zpoint_config.graddy));
559  cpl_vector_delete(tmp_vec);
560  cpl_bivector_delete(positions);
561 
562  /* Compute the averages of the results for the zero point */
563  tmp_vec = cpl_vector_new(niter);
564  for (i=0; i<niter; i++) {
565  cpl_vector_set(tmp_vec, i,
566  cpl_table_get_double(tab_res, "ZPOINT", i, NULL));
567  }
568  nb_ok = 0;
569  avg_zp = sqsum = 0.0;
570  if (isaac_img_zpoint_config.chopping == 0) {
571  cpl_vector_sort(tmp_vec, 1);
572  /* Reject highest and lowest value */
573  for (i=1; i<niter-1; i++) {
574  val = cpl_vector_get(tmp_vec, i);
575  if (val > 0.0) {
576  avg_zp += val;
577  sqsum += val * val;
578  nb_ok ++;
579  }
580  }
581  } else if (isaac_img_zpoint_config.chopping == 1) {
582  for (i=0; i<niter; i++) {
583  val = cpl_vector_get(tmp_vec, i);
584  if (val > 0.0) {
585  avg_zp += val;
586  sqsum += val * val;
587  nb_ok ++;
588  }
589  }
590  } else {
591  cpl_msg_error(cpl_func, "unsupported mode");
592  cpl_table_delete(tab_res);
593  cpl_vector_delete(tmp_vec);
594  cpl_image_delete(*check_im);
595  *check_im = NULL;
596  cpl_msg_indent_less();
597  return NULL;
598  }
599  cpl_vector_delete(tmp_vec);
600  if (nb_ok < 1) {
601  cpl_msg_error(cpl_func, "no valid zpoint measurement: cannot compute");
602  isaac_img_zpoint_config.zpoint = -1.0;
603  isaac_img_zpoint_config.zpointrms = -1.0;
604  } else {
605  avg_zp /= (double)nb_ok;
606  sqsum /= (double)nb_ok;
607  zprms = sqsum - avg_zp * avg_zp;
608  zprms = zprms > 0 ? sqrt(zprms) : 0;
609  isaac_img_zpoint_config.zpoint = avg_zp;
610  isaac_img_zpoint_config.zpointrms = zprms;
611  }
612 
613  /* Print final results */
614  cpl_msg_info(cpl_func, "***** FINAL RESULTS *****");
615  cpl_msg_info(cpl_func, "Zero point : %g", isaac_img_zpoint_config.zpoint);
616  cpl_msg_info(cpl_func, "Zero p. RMS: %g", isaac_img_zpoint_config.zpointrms);
617 
618  return tab_res;
619 }
620 
621 /*----------------------------------------------------------------------------*/
636 /*----------------------------------------------------------------------------*/
637 static cpl_image * isaac_img_zpoint_check_im(
638  cpl_imagelist * imlist,
639  cpl_bivector * positions,
640  double r1,
641  double r2,
642  double r3)
643 {
644  int nima, in_nx, in_ny, nx, ny, box_sz, llx, lly;
645  cpl_image * in_ima;
646  float * pin_ima;
647  cpl_image * out_ima;
648  float * pout_ima;
649  int out_pos, in_pos;
650  double * pos_x;
651  double * pos_y;
652  double dist;
653  int i, j, k;
654 
655  /* Check entries */
656  if (imlist == NULL) return NULL;
657  if (positions == NULL) return NULL;
658  nima = cpl_imagelist_get_size(imlist);
659  if (cpl_bivector_get_size(positions) != nima) return NULL;
660 
661  /* Initialise */
662  in_ima = cpl_imagelist_get(imlist, 0);
663  in_nx = cpl_image_get_size_x(in_ima);
664  in_ny = cpl_image_get_size_y(in_ima);
665  pos_x = cpl_bivector_get_x_data(positions);
666  pos_y = cpl_bivector_get_y_data(positions);
667 
668  /* Create the output image */
669  box_sz = 2 * (int)r3 + 1;
670  nx = nima * box_sz;
671  ny = box_sz;
672  out_ima = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
673  pout_ima = cpl_image_get_data_float(out_ima);
674 
675  /* Loop on the input images */
676  for (k=0; k<nima; k++) {
677  /* Get the current input image */
678  in_ima = cpl_imagelist_get(imlist, k);
679  pin_ima = cpl_image_get_data_float(in_ima);
680 
681  /* Get the sub image position */
682  llx = (int)(pos_x[k] - r3);
683  lly = (int)(pos_y[k] - r3);
684 
685  for (i=0; i<box_sz; i++) {
686  for (j=0; j<box_sz; j++) {
687  out_pos = (box_sz * k) + i + j * nx;
688  in_pos = llx + i + (lly+j) * in_nx;
689  if (in_pos >= 0 && in_pos < in_nx*in_ny)
690  pout_ima[out_pos] = pin_ima[in_pos];
691  }
692  }
693  }
694 
695  /* Draw circles */
696  for (i=0; i<box_sz; i++) {
697  for (j=0; j<box_sz; j++) {
698  dist = sqrt((i - (box_sz/2)) * (i - (box_sz/2)) +
699  (j - (box_sz/2)) * (j - (box_sz/2)));
700  if ((fabs(dist-sqrt(r1*r1))) < 0.5) pout_ima[i + j * nx] = 10000;
701  if ((fabs(dist-sqrt(r2*r2))) < 0.5) pout_ima[i + j * nx] = 10000;
702  if ((fabs(dist-sqrt(r3*r3))) < 0.5) pout_ima[i + j * nx] = 10000;
703  }
704  }
705 
706  /* Return */
707  return out_ima;
708 }
709 
710 /*----------------------------------------------------------------------------*/
716 /*----------------------------------------------------------------------------*/
717 static cpl_imagelist * isaac_img_zpoint_load(
718  cpl_frameset * set,
719  const char * flat,
720  const char * detlin_a,
721  const char * detlin_b,
722  const char * detlin_c)
723 {
724  cpl_imagelist * imlist;
725  cpl_imagelist * imlist2;
726  cpl_imagelist * diffs;
727  cpl_image * ima;
728  int i;
729 
730  /* Load the images */
731  if (isaac_img_zpoint_config.chopping == 0) {
732  if ((imlist = cpl_imagelist_load_frameset(set, CPL_TYPE_FLOAT, 1,
733  0)) == NULL) {
734  cpl_msg_error(cpl_func, "Cannot load the images");
735  return NULL;
736  }
737  } else if (isaac_img_zpoint_config.chopping == 1) {
738  if ((imlist = cpl_imagelist_load_frameset(set, CPL_TYPE_FLOAT, 1,
739  0)) == NULL) {
740  cpl_msg_error(cpl_func, "Cannot load the images");
741  return NULL;
742  }
743  if ((imlist2 = cpl_imagelist_load_frameset(set, CPL_TYPE_FLOAT, 2,
744  0)) == NULL) {
745  cpl_msg_error(cpl_func, "Cannot load the images");
746  cpl_imagelist_delete(imlist);
747  return NULL;
748  }
749  cpl_imagelist_subtract(imlist, imlist2);
750  cpl_imagelist_delete(imlist2);
751  } else {
752  cpl_msg_error(cpl_func, "Unsupported mode");
753  return NULL;
754  }
755 
756  /* Correct the detector linearity */
757  if (detlin_a && detlin_b && detlin_c) {
758  cpl_msg_info(cpl_func, "Correct for non-linearity");
759  if (irplib_detlin_correct(imlist, detlin_a, detlin_b, detlin_c) == -1) {
760  cpl_msg_error(cpl_func, "Cannot correct for non-linearity");
761  }
762  }
763 
764  /* Divide by the flatfield if one is provided */
765  if (flat) {
766  cpl_image * flat_im = cpl_image_load(flat, CPL_TYPE_UNSPECIFIED, 0, 0);
767  cpl_error_code error = flat_im ? CPL_ERROR_NONE : cpl_error_get_code();
768 
769  cpl_msg_info(cpl_func, "Divide by the flat field");
770 
771  /* Threshold all pixels below the "mid-point" of FLT_MIN and 1, and
772  all pixels above the "mid-point" of 1 and FLT_MAX. */
773  error |= cpl_image_threshold(flat_im, sqrt(FLT_MIN), sqrt(FLT_MAX),
774  1.0, 1.0);
775  error |= cpl_imagelist_divide_image(imlist, flat_im);
776  cpl_image_delete(flat_im);
777 
778  if (error) {
779  cpl_imagelist_delete(imlist);
780  (void)cpl_error_set_message(cpl_func, cpl_error_get_code(),
781  "Flat field correction failed");
782  return NULL;
783  }
784  }
785 
786  /* Different in chopping and non-chopping modes */
787  if (isaac_img_zpoint_config.chopping == 1) {
788  diffs = imlist;
789  imlist = NULL;
790  } else if (isaac_img_zpoint_config.chopping == 0) {
791  /* Build the difference image list */
792  diffs = cpl_imagelist_new();
793  for (i=0; i<cpl_imagelist_get_size(imlist)-1; i++) {
794  ima = cpl_image_subtract_create(
795  cpl_imagelist_get(imlist, i),
796  cpl_imagelist_get(imlist, i+1));
797  cpl_imagelist_set(diffs, ima, 2*i);
798  ima = cpl_image_subtract_create(
799  cpl_imagelist_get(imlist, i+1),
800  cpl_imagelist_get(imlist, i));
801  cpl_imagelist_set(diffs, ima, 2*i+1);
802  }
803  cpl_imagelist_delete(imlist);
804  if (cpl_error_get_code()) {
805  cpl_msg_error(cpl_func, "Cannot build the difference images");
806  cpl_imagelist_delete(diffs);
807  return NULL;
808  }
809  } else {
810  cpl_msg_error(cpl_func, "Unsupported mode - abort");
811  cpl_imagelist_delete(imlist);
812  return NULL;
813  }
814  return diffs;
815 }
816 
817 /*----------------------------------------------------------------------------*/
826 /*----------------------------------------------------------------------------*/
827 static cpl_table * isaac_img_zpoint_photom(
828  cpl_imagelist * ilist,
829  cpl_bivector * pos)
830 {
831  cpl_table * tab;
832  int nbima;
833  double r, r1, r2, mag, dit;
834  cpl_image * ima;
835  double * pos_x;
836  double * pos_y;
837  double bgd, fl, zp, peak, fwhm_x, fwhm_y;
838  int i;
839 
840  /* Test entries */
841  if (ilist == NULL) return NULL;
842  if (pos == NULL) return NULL;
843 
844  /* Initialise */
845  nbima = cpl_imagelist_get_size(ilist);
846  mag = isaac_img_zpoint_config.magnitude;
847  dit = isaac_img_zpoint_config.dit;
848  r = isaac_img_zpoint_config.phot_star_radius;
849  r1 = isaac_img_zpoint_config.phot_bg_r1;
850  r2 = isaac_img_zpoint_config.phot_bg_r2;
851 
852  /* Create the output table */
853  tab = cpl_table_new(nbima);
854  cpl_table_new_column(tab, "POSX", CPL_TYPE_DOUBLE);
855  cpl_table_new_column(tab, "POSY", CPL_TYPE_DOUBLE);
856  cpl_table_new_column(tab, "ZPOINT", CPL_TYPE_DOUBLE);
857  cpl_table_new_column(tab, "FLUX", CPL_TYPE_DOUBLE);
858  cpl_table_new_column(tab, "PEAK", CPL_TYPE_DOUBLE);
859  cpl_table_new_column(tab, "BGD", CPL_TYPE_DOUBLE);
860  cpl_table_new_column(tab, "FWHMX", CPL_TYPE_DOUBLE);
861  cpl_table_new_column(tab, "FWHMY", CPL_TYPE_DOUBLE);
862 
863  /* Loop on the images */
864  pos_x = cpl_bivector_get_x_data(pos);
865  pos_y = cpl_bivector_get_y_data(pos);
866  for (i=0; i<nbima; i++) {
867  /* Get the current image */
868  ima = cpl_imagelist_get(ilist, i);
869  /* Compute the photometry */
870  /* Background */
871  bgd = irplib_strehl_ring_background(ima, (int)(pos_x[i]),
872  (int)(pos_y[i]), (int)r1, (int)r2, IRPLIB_BG_METHOD_MEDIAN);
873  /* Flux */
874  fl = irplib_strehl_disk_flux(ima,
875  (int)(pos_x[i]), (int)(pos_y[i]), (int)r, bgd);
876  /* Zero Point */
877  zp = mag + 2.5 * log10(fl) - 2.5 * log10(dit);
878  cpl_msg_info(cpl_func, "Zero point nb %d: %g", i+1, zp);
879  /* Peak */
880  peak = cpl_image_get_max_window(ima,
881  (int)(pos_x[i]-5), (int)(pos_y[i]-5),
882  (int)(pos_x[i]+5), (int)(pos_y[i]+5));
883 
884  /* FWHM_X / FWHM_Y */
885  if (cpl_image_get_fwhm(ima, (int)(pos_x[i]), (int)(pos_y[i]),
886  &fwhm_x, &fwhm_y) != CPL_ERROR_NONE) {
887  cpl_msg_debug(cpl_func, "Cannot compute FWHM for image %d", i+1);
888  cpl_error_reset();
889  }
890 
891  /* Put the results in the table */
892  cpl_table_set_double(tab, "POSX", i, pos_x[i]);
893  cpl_table_set_double(tab, "POSY", i, pos_y[i]);
894  cpl_table_set_double(tab, "ZPOINT", i, zp);
895  cpl_table_set_double(tab, "FLUX", i, fl);
896  cpl_table_set_double(tab, "PEAK", i, peak);
897  cpl_table_set_double(tab, "BGD", i, bgd);
898  cpl_table_set_double(tab, "FWHMX", i, fwhm_x);
899  cpl_table_set_double(tab, "FWHMY", i, fwhm_y);
900  }
901  return tab;
902 }
903 
904 /*----------------------------------------------------------------------------*/
905 /*
906  @brief Compute the flux gradients
907  @param flux a vector with 8 fluxes
908  @param positions a bivector with the 8 positions
909  @param gradx the x gradient
910  @param grady the y gradient
911  @param graddx the x gradient error
912  @param graddy the y gradient error
913  @return 0 if ok, -1 otherwise
914  3 2
915  1
916  4 5
917  */
918 /*----------------------------------------------------------------------------*/
919 static int isaac_img_zpoint_gradients(
920  cpl_vector * flux,
921  cpl_bivector * positions,
922  double * gradx,
923  double * grady,
924  double * graddx,
925  double * graddy)
926 {
927  int nflux;
928  double two, three, four, five, mean;
929  double two_pos_x, three_pos_x, four_pos_x, five_pos_x,
930  two_pos_y, three_pos_y, four_pos_y, five_pos_y;
931  double * pflux;
932  double * ppos_x;
933  double * ppos_y;
934 
935  /* Test entries */
936  if (flux == NULL) return CPL_ERROR_UNSPECIFIED;
937 
938  /* Initialise */
939  nflux = cpl_vector_get_size(flux);
940  if (nflux != 8) {
941  *gradx = -1.0;
942  *grady = -1.0;
943  *graddx = -1.0;
944  *graddy = -1.0;
945  return 0;
946  }
947  mean = cpl_vector_get_mean(flux);
948 
949  /* Get the 4 positions fluxes */
950  pflux = cpl_vector_get_data(flux);
951  ppos_x = cpl_bivector_get_x_data(positions);
952  ppos_y = cpl_bivector_get_y_data(positions);
953  /* Flux */
954  two = (pflux[1] + pflux[2]) / 2.0;
955  three = (pflux[3] + pflux[4]) / 2.0;
956  four = (pflux[5] + pflux[6]) / 2.0;
957  five = pflux[7];
958  /* Positions */
959  two_pos_x = (ppos_x[1] + ppos_x[2]) / 2.0;
960  two_pos_y = (ppos_y[1] + ppos_y[2]) / 2.0;
961  three_pos_x = (ppos_x[3] + ppos_x[4]) / 2.0;
962  three_pos_y = (ppos_y[3] + ppos_y[4]) / 2.0;
963  four_pos_x = (ppos_x[5] + ppos_x[6]) / 2.0;
964  four_pos_y = (ppos_y[5] + ppos_y[6]) / 2.0;
965  five_pos_x = ppos_x[7];
966  five_pos_y = ppos_y[7];
967 
968  /* Compute grad */
969  *gradx = (two + five - three - four) / 2;
970  *grady = (three + two - four - five) / 2;
971 
972  /* Normalise to the nominal distance */
973  *gradx *= (512 / ((two_pos_x + five_pos_x - three_pos_x - four_pos_x)/2));
974  *grady *= (512 / ((three_pos_y + two_pos_y - four_pos_y - five_pos_y)/2));
975 
976  /* Compute error */
977  *graddx = sqrt((two-five)*(two-five) + (three-four)*(three-four))/2.0;
978  *graddy = sqrt((three-two)*(three-two) + (four-five)*(four-five))/2.0;
979 
980  /* Normalise */
981  *gradx /= mean;
982  *grady /= mean;
983  *graddx /= mean;
984  *graddy /= mean;
985 
986  return 0;
987 }
988 
989 /*----------------------------------------------------------------------------*/
995 /*----------------------------------------------------------------------------*/
996 static cpl_bivector * isaac_img_zpoint_get_offsets(cpl_frameset * set)
997 {
998  int nframes;
999  int noffsets;
1000  cpl_bivector * offs;
1001  cpl_frame * cur_frame;
1002  cpl_propertylist * plist;
1003  double off_x, off_y;
1004  int i;
1005 
1006  /* Test entries */
1007  if (set == NULL) return NULL;
1008 
1009  /* Initialize */
1010  nframes = cpl_frameset_get_size(set);
1011 
1012  /* Different in chopping and non-chopping modes */
1013  if (isaac_img_zpoint_config.chopping == 1) {
1014  offs = isaac_get_offsets(set);
1015  } else if (isaac_img_zpoint_config.chopping == 0) {
1016  noffsets = 2 * (nframes-1);
1017 
1018  /* Check error code */
1019  if (cpl_error_get_code()) return NULL;
1020 
1021  /* Create the bivector */
1022  offs = cpl_bivector_new(noffsets);
1023 
1024  /* Fill it */
1025  for (i=0; i<nframes; i++) {
1026  cur_frame = cpl_frameset_get_position(set, i);
1027  plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame),0);
1028  off_x = isaac_pfits_get_cumoffsetx(plist);
1029  off_y = isaac_pfits_get_cumoffsety(plist);
1030  cpl_propertylist_delete(plist);
1031  if (i==0) {
1032  cpl_vector_set(cpl_bivector_get_x(offs), 2*i, off_x);
1033  cpl_vector_set(cpl_bivector_get_y(offs), 2*i, off_y);
1034  } else if (i==nframes-1) {
1035  cpl_vector_set(cpl_bivector_get_x(offs), 2*i-1, off_x);
1036  cpl_vector_set(cpl_bivector_get_y(offs), 2*i-1, off_y);
1037  } else {
1038  cpl_vector_set(cpl_bivector_get_x(offs), 2*i, off_x);
1039  cpl_vector_set(cpl_bivector_get_y(offs), 2*i, off_y);
1040  cpl_vector_set(cpl_bivector_get_x(offs), 2*i-1, off_x);
1041  cpl_vector_set(cpl_bivector_get_y(offs), 2*i-1, off_y);
1042  }
1043  }
1044  } else {
1045  cpl_msg_error(cpl_func, "Unsupported mode - abort");
1046  return NULL;
1047  }
1048 
1049  /* Check if it went ok */
1050  if (cpl_error_get_code()) {
1051  cpl_bivector_delete(offs);
1052  cpl_msg_error(cpl_func, "Cannot find offsets in headers");
1053  return NULL;
1054  }
1055  return offs;
1056 }
1057 
1058 /*----------------------------------------------------------------------------*/
1066 /*----------------------------------------------------------------------------*/
1067 static cpl_error_code isaac_img_zpoint_get_mag(const char * stdstars,
1068  double ra,
1069  double dec,
1070  isaac_band band)
1071 {
1072  cpl_errorstate prestate = cpl_errorstate_get();
1073 
1074  bug_if(0);
1075  bug_if(stdstars == NULL);
1076 
1077  switch (band) {
1078  /* SW mode */
1079  case ISAAC_BAND_J:
1080  case ISAAC_BAND_H:
1081  case ISAAC_BAND_K:
1082  case ISAAC_BAND_KS:
1083  if (!irplib_stdstar_find_star(stdstars, ra, dec,
1084  isaac_std_band_name(band),
1085  "LCO-Palomar.txt",
1086  &isaac_img_zpoint_config.magnitude,
1087  &isaac_img_zpoint_config.starname,
1088  &isaac_img_zpoint_config.sptype,
1089  &isaac_img_zpoint_config.catalog,
1090  NULL, NULL, 2.0) ||
1091  !irplib_stdstar_find_star(stdstars, ra, dec,
1092  isaac_std_band_name(band),
1093  "LCO-Palomar-NICMOS-Red-Stars.txt",
1094  &isaac_img_zpoint_config.magnitude,
1095  &isaac_img_zpoint_config.starname,
1096  &isaac_img_zpoint_config.sptype,
1097  &isaac_img_zpoint_config.catalog,
1098  NULL, NULL, 2.0) ||
1099  !irplib_stdstar_find_star(stdstars, ra, dec,
1100  isaac_std_band_name(band),
1101  "all",
1102  &isaac_img_zpoint_config.magnitude,
1103  &isaac_img_zpoint_config.starname,
1104  &isaac_img_zpoint_config.sptype,
1105  &isaac_img_zpoint_config.catalog,
1106  NULL, NULL, 2.0) ||
1107  /* Special case: swap K and Ks if needed */
1108  (band == ISAAC_BAND_K &&
1109  !irplib_stdstar_find_star(stdstars, ra, dec,
1110  isaac_std_band_name(ISAAC_BAND_KS),
1111  "all",
1112  &isaac_img_zpoint_config.magnitude,
1113  &isaac_img_zpoint_config.starname,
1114  &isaac_img_zpoint_config.sptype,
1115  &isaac_img_zpoint_config.catalog,
1116  NULL, NULL, 2.0)) ||
1117  (band == ISAAC_BAND_KS &&
1118  !irplib_stdstar_find_star(stdstars, ra, dec,
1119  isaac_std_band_name(ISAAC_BAND_K),
1120  "all",
1121  &isaac_img_zpoint_config.magnitude,
1122  &isaac_img_zpoint_config.starname,
1123  &isaac_img_zpoint_config.sptype,
1124  &isaac_img_zpoint_config.catalog,
1125  NULL, NULL, 2.0))) {
1126  cpl_errorstate_set(prestate);
1127  } else {
1128  skip_if(1);
1129  }
1130  break;
1131  /* LW mode */
1132  case ISAAC_BAND_L:
1133  case ISAAC_BAND_M:
1134  if (!irplib_stdstar_find_star(stdstars, ra, dec,
1135  isaac_std_band_name(band),
1136  "ESO-VanDerBliek.txt",
1137  &isaac_img_zpoint_config.magnitude,
1138  &isaac_img_zpoint_config.starname,
1139  &isaac_img_zpoint_config.sptype,
1140  &isaac_img_zpoint_config.catalog,
1141  NULL, NULL, 2.0) ||
1142  !irplib_stdstar_find_star(stdstars, ra, dec,
1143  isaac_std_band_name(band),
1144  "MSSSO-Photometric.txt",
1145  &isaac_img_zpoint_config.magnitude,
1146  &isaac_img_zpoint_config.starname,
1147  &isaac_img_zpoint_config.sptype,
1148  &isaac_img_zpoint_config.catalog,
1149  NULL, NULL, 2.0) ||
1150  !irplib_stdstar_find_star(stdstars, ra, dec,
1151  isaac_std_band_name(band),
1152  "MSSSO-Spectroscopic.txt",
1153  &isaac_img_zpoint_config.magnitude,
1154  &isaac_img_zpoint_config.starname,
1155  &isaac_img_zpoint_config.sptype,
1156  &isaac_img_zpoint_config.catalog,
1157  NULL, NULL, 2.0) ||
1158  !irplib_stdstar_find_star(stdstars, ra, dec,
1159  isaac_std_band_name(band), "all",
1160  &isaac_img_zpoint_config.magnitude,
1161  &isaac_img_zpoint_config.starname,
1162  &isaac_img_zpoint_config.sptype,
1163  &isaac_img_zpoint_config.catalog,
1164  NULL, NULL, 2.0)) {
1165  cpl_errorstate_set(prestate);
1166  } else {
1167  skip_if(1);
1168  }
1169  break;
1170  default:
1171  cpl_msg_error(cpl_func, "cannot determine associated filter");
1172  skip_if(1);
1173  }
1174 
1175  end_skip;
1176 
1177  return cpl_error_get_code();
1178 }
1179 
1180 /*----------------------------------------------------------------------------*/
1190 /*----------------------------------------------------------------------------*/
1191 static int isaac_img_zpoint_save(
1192  cpl_table * tab,
1193  cpl_image * check_im,
1194  cpl_frameset * raw,
1195  const cpl_parameterlist * parlist,
1196  cpl_frameset * set)
1197 {
1198  cpl_propertylist * plist;
1199  cpl_propertylist * paflist;
1200  cpl_propertylist * qclist;
1201  const cpl_frame * ref_frame;
1202  const char * sval;
1203  double hum, airm, extinction;
1204 
1205  /* Initialise */
1206  airm = 0;
1207 
1208  /* Get the QC params in qclist */
1209  qclist = cpl_propertylist_new();
1210 
1211  /* Get the reference frame */
1212  ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
1213  if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
1214  0)) == NULL) {
1215  cpl_msg_error(cpl_func, "getting header from reference frame");
1216  cpl_propertylist_delete(qclist);
1217  return CPL_ERROR_UNSPECIFIED;
1218  }
1219  /* Test the status */
1220  if (cpl_error_get_code()) {
1221  cpl_propertylist_delete(qclist);
1222  cpl_propertylist_delete(plist);
1223  return CPL_ERROR_UNSPECIFIED;
1224  }
1225  sval = isaac_pfits_get_filter(plist);
1226  if (cpl_error_get_code()) cpl_error_reset();
1227  else cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
1228  cpl_propertylist_append_string(qclist, "ESO QC FILTER REF",
1229  isaac_std_band_name(isaac_img_zpoint_config.band));
1230  if (isaac_img_zpoint_compute_keywords(raw, &hum, &airm)) {
1231  cpl_propertylist_append_double(qclist, "ESO QC AMBI RHUM AVG", hum);
1232  cpl_propertylist_append_double(qclist, "ESO QC AIRMASS", airm);
1233  }
1234  cpl_propertylist_delete(plist);
1235  /* Get extinction */
1236  switch (isaac_img_zpoint_config.band) {
1237  case ISAAC_BAND_J: extinction = 0.09; break;
1238  case ISAAC_BAND_JS: extinction = 0.05; break;
1239  case ISAAC_BAND_H: extinction = 0.04; break;
1240  case ISAAC_BAND_KS: extinction = 0.06; break;
1241  default: extinction = 0.00; break;
1242  }
1243  cpl_propertylist_append_double(qclist, "ESO QC ZPOINT",
1244  isaac_img_zpoint_config.zpoint);
1245  cpl_propertylist_append_double(qclist, "ESO QC ZPOINT ATX0",
1246  isaac_img_zpoint_config.zpoint + airm * extinction);
1247  cpl_propertylist_append_double(qclist, "ESO QC ZPOINTRMS",
1248  isaac_img_zpoint_config.zpointrms);
1249  cpl_propertylist_append_double(qclist, "ESO QC FLUX MED",
1250  isaac_img_zpoint_config.flux_med);
1251  cpl_propertylist_append_string(qclist, "ESO QC STDNAME",
1252  isaac_img_zpoint_config.starname ?
1253  isaac_img_zpoint_config.starname : "");
1254  cpl_propertylist_append_string(qclist, "ESO QC SPECTYPE",
1255  isaac_img_zpoint_config.sptype ?
1256  isaac_img_zpoint_config.sptype : "");
1257  cpl_propertylist_append_double(qclist, "ESO QC STARMAG",
1258  isaac_img_zpoint_config.magnitude);
1259  cpl_propertylist_append_string(qclist, "ESO QC CATNAME",
1260  isaac_img_zpoint_config.catalog ?
1261  isaac_img_zpoint_config.catalog : "");
1262  cpl_propertylist_append_double(qclist, "ESO QC GRADX",
1263  isaac_img_zpoint_config.gradx);
1264  cpl_propertylist_append_double(qclist, "ESO QC GRADY",
1265  isaac_img_zpoint_config.grady);
1266  cpl_propertylist_append_double(qclist, "ESO QC GRADDX",
1267  isaac_img_zpoint_config.graddx);
1268  cpl_propertylist_append_double(qclist, "ESO QC GRADDY",
1269  isaac_img_zpoint_config.graddy);
1270  cpl_propertylist_append_double(qclist, "ESO QC FWHM MEAN",
1271  isaac_img_zpoint_config.fwhm_mean);
1272 
1273  /* Write the zpoint table */
1274  irplib_dfs_save_table(set,
1275  parlist,
1276  set,
1277  tab,
1278  NULL,
1279  "isaac_img_zpoint",
1280  ISAAC_IMG_ZPOINT_TAB,
1281  qclist,
1282  NULL,
1283  PACKAGE "/" PACKAGE_VERSION,
1284  "isaac_img_zpoint.fits");
1285  /* Write the check image */
1286  if (check_im) {
1287  irplib_dfs_save_image(set,
1288  parlist,
1289  set,
1290  check_im,
1291  CPL_BPP_IEEE_FLOAT,
1292  "isaac_img_zpoint",
1293  ISAAC_IMG_ZPOINT_CHECK,
1294  qclist,
1295  NULL,
1296  PACKAGE "/" PACKAGE_VERSION,
1297  "isaac_img_zpoint_check.fits");
1298  }
1299 
1300  /* Get the reference frame */
1301  ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
1302 
1303  /* Get FITS header from reference file */
1304  if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
1305  0)) == NULL) {
1306  cpl_msg_error(cpl_func, "getting header from reference frame");
1307  cpl_propertylist_delete(qclist);
1308  return CPL_ERROR_UNSPECIFIED;
1309  }
1310 
1311  /* Get the keywords for the paf file */
1312  paflist = cpl_propertylist_new();
1313  cpl_propertylist_copy_property_regexp(paflist, plist,
1314  "^(ARCFILE|ESO TPL ID|DATE-OBS|MJD-OBS|ESO INS MODE|"
1315  "ESO OBS ID|ESO DET DIT|ESO INS PIXSCALE|RA|DEC)$", 0);
1316  cpl_propertylist_delete(plist);
1317 
1318  /* Get the QC params in qclist and keys for paf in paflist */
1319  cpl_propertylist_copy_property_regexp(paflist, qclist, "ESO QC", 0);
1320  cpl_propertylist_delete(qclist);
1321 
1322  /* PRO.CATG */
1323  cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG,
1324  ISAAC_IMG_ZPOINT_TAB);
1325 
1326  /* Save the PAF file */
1327  cpl_dfs_save_paf("ISAAC",
1328  "isaac_img_zpoint",
1329  paflist,
1330  "isaac_img_zpoint.paf");
1331  cpl_propertylist_delete(paflist);
1332  return 0;
1333 }
1334 
1335 /*----------------------------------------------------------------------------*/
1343 /*----------------------------------------------------------------------------*/
1344 static
1345 cpl_error_code isaac_img_zpoint_compute_keywords(const cpl_frameset * set,
1346  double * hum,
1347  double * airm)
1348 {
1349  const cpl_size nframes = cpl_frameset_get_size(set);
1350  double meanhum = 0.0;
1351  cpl_size i;
1352 
1353  if (airm != NULL) *airm = 0.0;
1354  if (hum != NULL) *hum = 0.0;
1355 
1356  cpl_ensure_code(set != NULL, CPL_ERROR_NULL_INPUT);
1357  cpl_ensure_code(hum != NULL, CPL_ERROR_NULL_INPUT);
1358  cpl_ensure_code(airm != NULL, CPL_ERROR_NULL_INPUT);
1359  cpl_ensure_code(nframes > 0, CPL_ERROR_DATA_NOT_FOUND);
1360 
1361  for (i = 0; i < nframes; i++) {
1362  const cpl_frame * cur_frame = cpl_frameset_get_position_const(set, i);
1363  const char * filename = cpl_frame_get_filename(cur_frame);
1364  cpl_propertylist * plist = cpl_propertylist_load(filename, 0);
1365  const double humi = isaac_pfits_get_humidity_level(plist);
1366 
1367  if (i==0) *airm += isaac_pfits_get_airmass_start(plist);
1368  if (i==nframes-1) *airm += isaac_pfits_get_airmass_end(plist);
1369 
1370  cpl_propertylist_delete(plist);
1371 
1372  meanhum += (humi - meanhum) / (double)(i + 1);
1373 
1374  if (cpl_error_get_code()) break;
1375 
1376  }
1377 
1378  if (cpl_error_get_code()) return cpl_error_set_where(cpl_func);
1379 
1380  assert(i == nframes);
1381 
1382  *hum = meanhum;
1383  *airm *= 0.5;
1384 
1385  return CPL_ERROR_NONE;
1386 }
1387 
1388 
int isaac_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: isaac_dfs.c:60
double isaac_pfits_get_ra(const cpl_propertylist *plist)
find out the RA
Definition: isaac_pfits.c:760
double isaac_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: isaac_pfits.c:305
double isaac_pfits_get_cumoffsety(const cpl_propertylist *plist)
find out the cumulative offset in Y
Definition: isaac_pfits.c:211
double isaac_pfits_get_airmass_end(const cpl_propertylist *plist)
find out airmass end
Definition: isaac_pfits.c:76
double isaac_pfits_get_dec(const cpl_propertylist *plist)
find out the DEC
Definition: isaac_pfits.c:271
const char * isaac_pfits_get_filter(const cpl_propertylist *plist)
find out the filter
Definition: isaac_pfits.c:880
double isaac_pfits_get_humidity_level(const cpl_propertylist *plist)
find out the humidity level
Definition: isaac_pfits.c:417
double isaac_pfits_get_cumoffsetx(const cpl_propertylist *plist)
find out the cumulative offset in X
Definition: isaac_pfits.c:196
double isaac_pfits_get_airmass_start(const cpl_propertylist *plist)
find out airmass start
Definition: isaac_pfits.c:61
const char * isaac_extract_filename(const cpl_frameset *self, const char *tag)
Extract the filename of the first frame of the given tag.
Definition: isaac_utils.c:397
const char * isaac_std_band_name(isaac_band band)
Return a band name.
Definition: isaac_utils.c:243
isaac_band isaac_get_bbfilter(const char *f)
Get the broad band filter.
Definition: isaac_utils.c:144
cpl_bivector * isaac_get_offsets(const cpl_frameset *fset)
Get the offsets from a set of frames.
Definition: isaac_utils.c:92
cpl_frameset * isaac_extract_frameset(const cpl_frameset *self, const char *tag)
Extract the frames with the given tag from a frameset.
Definition: isaac_utils.c:356