HAWKI Pipeline Reference Manual  1.8.12
hawki_step_photom_2mass.c
1 /* $Id: hawki_step_photom_2mass.c,v 1.18 2013/01/14 15:58:23 cgarcia Exp $
2  *
3  * This file is part of the HAWKI 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: cgarcia $
23  * $Date: 2013/01/14 15:58:23 $
24  * $Revision: 1.18 $
25  * $Name: hawki-1_8_12 $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <math.h>
37 #include <cpl.h>
38 #include <string.h>
39 
40 #include "irplib_utils.h"
41 
42 #include "hawki_alloc.h"
43 #include "hawki_utils.h"
44 #include "hawki_load.h"
45 #include "hawki_save.h"
46 #include "hawki_pfits.h"
47 #include "hawki_dfs.h"
48 #include "irplib_cat.h"
49 #include "irplib_stdstar.h"
50 
51 /*-----------------------------------------------------------------------------
52  Functions prototypes
53  -----------------------------------------------------------------------------*/
54 
55 #ifdef __cplusplus
56 extern "C"
57 #endif
58 int cpl_plugin_get_info(cpl_pluginlist * list);
59 
60 static int hawki_step_photom_2mass_create(cpl_plugin *) ;
61 static int hawki_step_photom_2mass_exec(cpl_plugin *) ;
62 static int hawki_step_photom_2mass_destroy(cpl_plugin *) ;
63 static int hawki_step_photom_2mass(cpl_parameterlist * parlist,
64  cpl_frameset * frameset);
65 
66 
67 cpl_table ** hawki_step_photom_2mass_get_zpoints
68 (cpl_frameset * cat_2mass,
69  cpl_frameset * obj_param,
70  cpl_frameset * obj_ima);
71 
72 static cpl_table * hawki_step_photom_2mass_retrieve_stars
73 (cpl_frameset * cat_2mass,
74  cpl_propertylist * wcs_keywords);
75 
76 static cpl_array * hawki_step_photom_2mass_ppm
77 (cpl_table * stars_2mass,
78  cpl_table * obj_det);
79 
80 static cpl_table * hawki_step_photom_2mass_fill_zpoint_table
81 (cpl_table * stars_2mass,
82  cpl_table * obj_det_param,
83  cpl_array * matches,
84  cpl_propertylist * plist,
85  int idet);
86 
87 static cpl_propertylist ** hawki_step_photom_2mass_qc
88 (cpl_table ** zpoint_table);
89 
90 static int hawki_step_photom_2mass_save
91 (cpl_table ** zpoints,
92  cpl_parameterlist * parlist,
93  cpl_propertylist ** qclists,
94  cpl_frameset * set);
95 
96 /*-----------------------------------------------------------------------------
97  Static variables
98  -----------------------------------------------------------------------------*/
99 
100 static char hawki_step_photom_2mass_description[] =
101 "hawki_step_photom_2mass -- HAWK-I photometric autocalibration using 2MASS.\n"
102 "The input files must be tagged:\n"
103 "obj_param.fits "HAWKI_CALPRO_OBJ_PARAM"\n"
104 "image.fits "HAWKI_CALPRO_COMBINED"\n"
105 "2mass_master_index.fits "HAWKI_UTIL_CAT_2MASS"\n"
106 "The recipe creates as an output:\n"
107 "hawki_cal_photom_2mass.fits ("HAWKI_CALPRO_ZPOINT_TAB"): \n"
108 "The recipe does the following steps:\n"
109 "-Search the 2MASS catalogue for stars in the FOV\n"
110 "-Matches the input detected object catalogue and the 2MASS stars\n"
111 "-Computes photometric characteristics for each matched star\n"
112 "Return code:\n"
113 "esorex exits with an error code of 0 if the recipe completes successfully\n"
114 "or 1 otherwise";
115 
116 /*-----------------------------------------------------------------------------
117  Functions code
118  -----------------------------------------------------------------------------*/
119 
120 /*----------------------------------------------------------------------------*/
128 /*----------------------------------------------------------------------------*/
129 int cpl_plugin_get_info(cpl_pluginlist * list)
130 {
131  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
132  cpl_plugin * plugin = &recipe->interface ;
133 
134  cpl_plugin_init(plugin,
135  CPL_PLUGIN_API,
136  HAWKI_BINARY_VERSION,
137  CPL_PLUGIN_TYPE_RECIPE,
138  "hawki_step_photom_2mass",
139  "2MASS photometric calibration",
140  hawki_step_photom_2mass_description,
141  "Cesar Enrique Garcia Dabo",
142  PACKAGE_BUGREPORT,
144  hawki_step_photom_2mass_create,
145  hawki_step_photom_2mass_exec,
146  hawki_step_photom_2mass_destroy);
147 
148  cpl_pluginlist_append(list, plugin) ;
149 
150  return 0;
151 }
152 
153 /*----------------------------------------------------------------------------*/
162 /*----------------------------------------------------------------------------*/
163 static int hawki_step_photom_2mass_create(cpl_plugin * plugin)
164 {
165  cpl_recipe * recipe ;
166 
167  /* Get the recipe out of the plugin */
168  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
169  recipe = (cpl_recipe *)plugin ;
170  else return -1 ;
171 
172  /* Create the parameters list in the cpl_recipe object */
173  recipe->parameters = cpl_parameterlist_new() ;
174  if (recipe->parameters == NULL)
175  return 1;
176 
177  /* Return */
178  return 0;
179 }
180 
181 /*----------------------------------------------------------------------------*/
187 /*----------------------------------------------------------------------------*/
188 static int hawki_step_photom_2mass_exec(cpl_plugin * plugin)
189 {
190  cpl_recipe * recipe ;
191 
192  /* Get the recipe out of the plugin */
193  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
194  recipe = (cpl_recipe *)plugin ;
195  else return -1 ;
196 
197  /* Issue a banner */
199 
200  return hawki_step_photom_2mass(recipe->parameters, recipe->frames) ;
201 }
202 
203 /*----------------------------------------------------------------------------*/
209 /*----------------------------------------------------------------------------*/
210 static int hawki_step_photom_2mass_destroy(cpl_plugin * plugin)
211 {
212  cpl_recipe * recipe ;
213 
214  /* Get the recipe out of the plugin */
215  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
216  recipe = (cpl_recipe *)plugin ;
217  else return -1 ;
218 
219  cpl_parameterlist_delete(recipe->parameters) ;
220  return 0 ;
221 }
222 
223 /*----------------------------------------------------------------------------*/
229 /*----------------------------------------------------------------------------*/
230 static int hawki_step_photom_2mass(cpl_parameterlist * parlist,
231  cpl_frameset * frameset)
232 {
233  cpl_frameset * cat_2mass;
234  cpl_frameset * obj_param;
235  cpl_frameset * obj_ima;
236  cpl_table ** zpoint_table;
237  cpl_propertylist ** qclists;
238  int idet;
239 
240  /* Identify the RAW and CALIB frames in the input frameset */
241  if (hawki_dfs_set_groups(frameset)) {
242  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
243  return -1 ;
244  }
245 
246  /* Retrieve 2MASS catalogue */
247  if ((cat_2mass = hawki_extract_frameset(frameset,
248  HAWKI_UTIL_CAT_2MASS)) == NULL)
249  {
250  cpl_msg_error(__func__, "Cannot find 2MASS catalogue (%s)",
251  HAWKI_UTIL_CAT_2MASS);
252  return -1 ;
253  }
254 
255  /* Retrieve obj param */
256  if ((obj_param = hawki_extract_frameset
257  (frameset, HAWKI_CALPRO_OBJ_PARAM)) == NULL)
258  {
259  cpl_msg_error(__func__, "Cannot find object parameters (%s)",
260  HAWKI_CALPRO_OBJ_PARAM);
261  return -1 ;
262  }
263 
264  /* Retrieve reference image */
265  if ((obj_ima = hawki_extract_frameset
266  (frameset, HAWKI_CALPRO_COMBINED)) == NULL)
267  {
268  cpl_msg_error(__func__, "Cannot find combined image (%s) ",
269  HAWKI_CALPRO_COMBINED);
270  return -1 ;
271  }
272 
273  /* Compute the zpoints */
274  zpoint_table = hawki_step_photom_2mass_get_zpoints
275  (cat_2mass, obj_param, obj_ima);
276  if(zpoint_table == NULL)
277  {
278  cpl_msg_error(__func__,"Could not get the zpoints");
279  cpl_frameset_delete(cat_2mass);
280  cpl_frameset_delete(obj_param);
281  cpl_frameset_delete(obj_ima);
282  return -1;
283  }
284 
285  /* Get some QC */
286  qclists = hawki_step_photom_2mass_qc(zpoint_table);
287  if(zpoint_table == NULL)
288  {
289  cpl_msg_error(__func__,"Could not compute quality controls");
290  cpl_frameset_delete(cat_2mass);
291  cpl_frameset_delete(obj_param);
292  cpl_frameset_delete(obj_ima);
293  hawki_table_delete(zpoint_table);
294  return -1;
295  }
296 
297  /* Save the products */
298  cpl_msg_info(__func__,"Saving products");
299  if(hawki_step_photom_2mass_save(zpoint_table, parlist, qclists, frameset) == -1)
300  {
301  cpl_msg_error(__func__,"Could not save products");
302  cpl_frameset_delete(cat_2mass);
303  cpl_frameset_delete(obj_param);
304  cpl_frameset_delete(obj_ima);
305  hawki_table_delete(zpoint_table);
306  return -1;
307  }
308 
309  /* Free and return */
310  cpl_frameset_delete(cat_2mass);
311  cpl_frameset_delete(obj_param);
312  cpl_frameset_delete(obj_ima);
313  hawki_table_delete(zpoint_table);
314  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
315  cpl_propertylist_delete(qclists[idet]);
316  cpl_free(qclists);
317 
318  /* Return */
319  if (cpl_error_get_code())
320  {
321  cpl_msg_error(__func__,
322  "HAWK-I pipeline could not recover from previous errors");
323  return -1 ;
324  }
325  else return 0 ;
326 }
327 
328 cpl_table ** hawki_step_photom_2mass_get_zpoints
329 (cpl_frameset * cat_2mass,
330  cpl_frameset * obj_param,
331  cpl_frameset * obj_ima)
332 {
333  cpl_table ** zpoint_table;
334  cpl_table ** obj_det_param;
335  cpl_propertylist * plist;
336  int idet;
337  cpl_errorstate error_prevstate = cpl_errorstate_get();
338 
339  /* Allocate zpoint_table */
340  zpoint_table = cpl_malloc(sizeof(cpl_table *) * HAWKI_NB_DETECTORS);
341 
342  /* Load detected obj */
343  obj_det_param = hawki_load_tables(cpl_frameset_get_first(obj_param));
344 
345  /* Read the main header */
346  plist = cpl_propertylist_load
347  (cpl_frame_get_filename(cpl_frameset_get_first(obj_ima)), 0);
348  /* Loop on detectors */
349  for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
350  {
351  cpl_propertylist * wcs_info;
352  cpl_table * stars_2mass;
353  cpl_array * matches;
354  int ext_nb;
355 
356  cpl_msg_info(__func__,"Working on chip %d", idet + 1);
357  cpl_msg_indent_more();
358 
359  /* Retrieve stars */
361  (cpl_frame_get_filename(cpl_frameset_get_first(obj_ima)),idet+1);
362  wcs_info = cpl_propertylist_load
363  (cpl_frame_get_filename(cpl_frameset_get_first(obj_ima)), ext_nb);
364  stars_2mass =
365  hawki_step_photom_2mass_retrieve_stars(cat_2mass, wcs_info);
366  if(stars_2mass == NULL)
367  {
368  int jdet;
369  cpl_msg_error(__func__, "Cannot retrieve stars");
370  cpl_propertylist_delete(plist);
371  cpl_propertylist_delete(wcs_info);
372  hawki_table_delete(obj_det_param);
373  for(jdet = 0; jdet <idet; ++jdet)
374  cpl_table_delete(zpoint_table[jdet]);
375  cpl_free(zpoint_table);
376  return NULL;
377  }
378 
379  /* Pattern matching btw stars in 2MASS and detected ones */
380  cpl_msg_info(__func__,"Matching %"CPL_SIZE_FORMAT
381  " 2MASS stars and %"CPL_SIZE_FORMAT" detections",
382  cpl_table_get_nrow(stars_2mass),
383  cpl_table_get_nrow(obj_det_param[idet]));
384  matches = hawki_step_photom_2mass_ppm(stars_2mass, obj_det_param[idet]);
385 
386  /* Fill the zpoint table */
387  cpl_msg_info(__func__,"Computing zero points");
388  zpoint_table[idet] = hawki_step_photom_2mass_fill_zpoint_table
389  (stars_2mass, obj_det_param[idet], matches, plist, idet);
390  if(zpoint_table[idet] == NULL)
391  {
392  int jdet;
393  cpl_msg_error(__func__, "Could not compute the zero points");
394  cpl_propertylist_delete(plist);
395  cpl_propertylist_delete(wcs_info);
396  hawki_table_delete(obj_det_param);
397  cpl_table_delete(stars_2mass);
398  for(jdet = 0; jdet <idet; ++jdet)
399  cpl_table_delete(zpoint_table[jdet]);
400  cpl_free(zpoint_table);
401  cpl_array_delete(matches);
402  return NULL;
403  }
404 
405  /* Cleaning resources */
406  cpl_msg_indent_less();
407  cpl_propertylist_delete(wcs_info);
408  cpl_table_delete(stars_2mass);
409  cpl_array_delete(matches);
410  }
411 
412  /* Free and return */
413  hawki_table_delete(obj_det_param);
414  cpl_propertylist_delete(plist);
415  if(!cpl_errorstate_is_equal(error_prevstate))
416  {
417  int jdet;
418  for(jdet = 0; jdet <HAWKI_NB_DETECTORS; ++jdet)
419  cpl_table_delete(zpoint_table[jdet]);
420  cpl_free(zpoint_table);
421  cpl_msg_error(__func__, "A problem happened computing the zero point");
422  cpl_errorstate_set(CPL_ERROR_NONE);
423  return NULL;
424  }
425  return zpoint_table;
426 }
427 
428 static cpl_table * hawki_step_photom_2mass_retrieve_stars
429 (cpl_frameset * cat_2mass,
430  cpl_propertylist * wcs_keywords)
431 {
432  char * catpath;
433  char * catname;
434  cpl_table * stars;
435  cpl_wcs * wcs;
436  int nstars;
437  int istar;
438  double ra1;
439  double ra2;
440  double dec1;
441  double dec2;
442  double extra_search = 0.;
443  cpl_matrix * from_coord;
444  cpl_matrix * to_coord;
445  cpl_array * status;
446 
447 
448  /* Extract the catalog path */
449  if (irplib_2mass_get_catpars(cpl_frameset_get_first(cat_2mass),
450  &catpath, &catname) != CPL_ERROR_NONE)
451  return NULL;
452 
453  /* Get the WCS info */
454  wcs = cpl_wcs_new_from_propertylist(wcs_keywords);
455  if(cpl_error_get_code() == CPL_ERROR_NO_WCS)
456  {
457  cpl_msg_error(__func__,"Not compiled with WCS support.");
458  return NULL;
459  }
460 
461  /* Get the limits to search */
462  if(irplib_cat_get_image_limits(wcs, extra_search,
463  &ra1, &ra2, &dec1, &dec2) ==
464  CPL_ERROR_DATA_NOT_FOUND)
465  {
466  cpl_msg_error(__func__,"No WCS information found");
467  cpl_free(catname);
468  cpl_free(catpath);
469  cpl_wcs_delete(wcs);
470  return NULL;
471  }
472  cpl_msg_info(__func__,"Searching stars in RA=[%f,%f] DEC=[%f,%f]",
473  ra1/15., ra2/15., dec1, dec2);
474 
475 
476  /* Search the stars */
477  stars = irplib_2mass_extract(catpath, ra1, ra2, dec1, dec2);
478  if(stars == NULL)
479  {
480  cpl_msg_error(__func__,"Error retrieving 2mass stars: %s ",
481  cpl_error_get_message());
482  cpl_free(catname);
483  cpl_free(catpath);
484  cpl_wcs_delete(wcs);
485  return NULL;
486  }
487  nstars = cpl_table_get_nrow(stars);
488  cpl_msg_indent_more();
489  cpl_msg_info(__func__, "%d 2MASS stars found", nstars);
490 
491  /* Convert Ra, Dec to X,Y using the WCS information from image */
492  from_coord = cpl_matrix_new(nstars, 2);
493  for (istar=0; istar<nstars; istar++)
494  {
495  cpl_matrix_set(from_coord, istar, 0, cpl_table_get_float
496  (stars, HAWKI_COL_2MASS_RA, istar, NULL));
497  cpl_matrix_set(from_coord, istar, 1, cpl_table_get_float
498  (stars, HAWKI_COL_2MASS_DEC, istar, NULL));
499  }
500 
501  to_coord = NULL;
502  status = NULL;
503  if(cpl_wcs_convert(wcs, from_coord, &to_coord,
504  &status, CPL_WCS_WORLD2PHYS) != CPL_ERROR_NONE)
505  {
506  cpl_array_delete(status);
507  cpl_matrix_delete(from_coord);
508  cpl_matrix_delete(to_coord);
509  cpl_free(catname);
510  cpl_free(catpath);
511  cpl_wcs_delete(wcs);
512  cpl_msg_error(cpl_func,"Error in cpl_wcs conversion. %s",
513  cpl_error_get_message());
514  return NULL;
515  }
516 
517  /* Add the predicted x,y coordinate columns to the 2MASS table */
518  cpl_table_new_column(stars, HAWKI_COL_2MASS_XPREDICT, CPL_TYPE_FLOAT);
519  cpl_table_set_column_unit(stars,HAWKI_COL_2MASS_XPREDICT, "pixels");
520  cpl_table_new_column(stars, HAWKI_COL_2MASS_YPREDICT, CPL_TYPE_FLOAT);
521  cpl_table_set_column_unit(stars, HAWKI_COL_2MASS_YPREDICT, "pixels");
522  for(istar=0; istar< nstars; istar++)
523  {
524  float xpredict = (float)cpl_matrix_get(to_coord, istar, 0);
525  float ypredict = (float)cpl_matrix_get(to_coord, istar, 1);
526  cpl_table_set_float(stars,"xpredict", istar, xpredict);
527  cpl_table_set_float(stars,"ypredict", istar, ypredict);
528  }
529 
530  /* Free and return */
531  cpl_array_delete(status);
532  cpl_matrix_delete(from_coord);
533  cpl_matrix_delete(to_coord);
534  cpl_wcs_delete(wcs);
535  cpl_free(catname);
536  cpl_free(catpath);
537  cpl_msg_indent_less();
538  return stars;
539 }
540 
541 /*----------------------------------------------------------------------------*/
547 /*----------------------------------------------------------------------------*/
548 static cpl_array * hawki_step_photom_2mass_ppm
549 (cpl_table * stars_2mass,
550  cpl_table * obj_det)
551 {
552  int istar;
553  int iobj;
554  int iter;
555  int nstars_2mass;
556  int nstars_2mass_used_match;
557  int nobj;
558  int nobj_used_match;
559  int nmatches;
560  int nmax_match_pattern = 30;
561  cpl_matrix * pattern;
562  cpl_array * matches;
563  double tol = 0.1;
564  double pradius = 30.0;
565  double mean_data_pos_err = 5.;
566  int ppm_max_iter = 5;
567  double scale = 1;
568  double angle;
569  cpl_matrix * obj_pos;
570  cpl_propertylist * sort_prop;
571 
572 
573  /* Sort the detected objects */
574  cpl_msg_indent_more();
575  sort_prop = cpl_propertylist_new();
576  cpl_propertylist_append_bool(sort_prop, HAWKI_COL_OBJ_FLUX, 1);
577  if (cpl_table_sort(obj_det, sort_prop) != CPL_ERROR_NONE)
578  {
579  cpl_msg_error(cpl_func,"Cannot sort detected sources table");
580  cpl_propertylist_delete(sort_prop);
581  return NULL;
582  }
583 
584  /* Create matrix of X,Y coordinates of detected objects*/
585  nobj = cpl_table_get_nrow(obj_det);
586  obj_pos = cpl_matrix_new(2, nobj);
587  for (iobj=0; iobj<nobj; iobj++)
588  {
589  float xim = cpl_table_get_double
590  (obj_det, HAWKI_COL_OBJ_POSX, iobj, NULL);
591  float yim = cpl_table_get_double
592  (obj_det, HAWKI_COL_OBJ_POSY, iobj, NULL);
593  cpl_matrix_set(obj_pos, 0, iobj, xim);
594  cpl_matrix_set(obj_pos, 1, iobj, yim);
595  }
596 
597  /* Sort the 2MASS stars by magnitude */
598  cpl_propertylist_empty(sort_prop);
599  cpl_propertylist_append_bool(sort_prop, HAWKI_COL_2MASS_K_MAG, 0);
600  if (cpl_table_sort(stars_2mass, sort_prop) != CPL_ERROR_NONE)
601  {
602  cpl_msg_error(cpl_func,"Cannot sort 2MASS stars table");
603  cpl_propertylist_delete(sort_prop);
604  return NULL;
605  }
606 
607  /* Prepare the 2MASS matrix for the pattern matching */
608  nstars_2mass = cpl_table_get_nrow(stars_2mass);
609  pattern = cpl_matrix_new(2, nstars_2mass);
610  for(istar=0; istar<nstars_2mass ; istar++)
611  {
612  float x = cpl_table_get_float
613  (stars_2mass, HAWKI_COL_2MASS_XPREDICT, istar, NULL);
614  float y = cpl_table_get_float
615  (stars_2mass, HAWKI_COL_2MASS_YPREDICT, istar, NULL);
616  cpl_matrix_set(pattern, 0, istar, x);
617  cpl_matrix_set(pattern, 1, istar, y);
618  }
619 
620  /* Do the ppm */
621  nstars_2mass_used_match = nmax_match_pattern;
622  if(nstars_2mass < nmax_match_pattern)
623  nstars_2mass_used_match = nstars_2mass;
624  nobj_used_match = (int)(1.7 * nstars_2mass_used_match);
625  if(nobj_used_match > nobj)
626  nobj_used_match = nobj;
627  if(nobj_used_match < nstars_2mass_used_match)
628  nobj_used_match = nstars_2mass_used_match;
629  cpl_msg_info(__func__,"The first step match will use %d stars "
630  "and %d objects", nstars_2mass_used_match,nobj_used_match);
631  for (iter = 0; iter < ppm_max_iter; iter++)
632  {
633  int nmatchsize;
634  nmatches = 0;
635  matches = cpl_ppm_match_points(obj_pos, nobj_used_match,
636  mean_data_pos_err,
637  pattern, nstars_2mass_used_match,
638  1, tol, pradius,
639  NULL, NULL, &scale, &angle);
640  if(matches != NULL)
641  {
642  nmatchsize = cpl_array_get_size(matches);
643  nmatches = nmatchsize -
644  cpl_array_count_invalid(matches);
645  }
646  else
647  {
648  nmatchsize = 0;
649  nmatches = 0;
650  }
651 
652  cpl_msg_info(cpl_func,"Total matches: %d. Valid matches: %d",
653  nmatchsize, nmatches);
654  cpl_msg_info(cpl_func,"Scale=%g angle=%g", scale, angle);
655  if((matches == NULL) || (nmatches < floor(nobj_used_match*0.1)))
656  {
657  nobj_used_match = nobj_used_match + 10;
658  cpl_msg_info(cpl_func,
659  "Increasing number of detections used in PPM to %d",
660  nobj_used_match);
661  continue;
662  }
663  else
664  break;
665  }
666 
667  /* Output debug messages */
668  cpl_msg_indent_more();
669  cpl_msg_debug(__func__,"Matched stars:");
670  cpl_msg_indent_more();
671  cpl_msg_debug(__func__,"X_OBJ Y_OBJ X_STAR Y_STAR X_DIFF Y_DIFF:");
672  for(istar=0; istar < nstars_2mass; ++istar)
673  {
674  int null;
675  double x_obj, y_obj, x_star, y_star, x_diff, y_diff;
676  iobj = cpl_array_get_int(matches, istar, &null);
677 
678  if(null != 0)
679  continue;
680  x_obj = cpl_matrix_get(obj_pos, 0, iobj);
681  y_obj = cpl_matrix_get(obj_pos, 1, iobj);
682  x_star = cpl_matrix_get(pattern, 0, istar);
683  y_star = cpl_matrix_get(pattern, 1, istar);
684  x_diff = x_obj - x_star;
685  y_diff = y_obj - y_star;
686  cpl_msg_debug(__func__,"%6.1f %6.1f %6.1f %6.1f %6.1f %6.1f\n",
687  x_obj, y_obj, x_star, y_star, x_diff, y_diff);
688  }
689  cpl_msg_indent_less();
690  cpl_msg_indent_less();
691 
692  cpl_matrix_delete(pattern);
693  cpl_msg_info(cpl_func, "%d points matched", nmatches);
694 
695  if(matches == NULL || nmatches == 0)
696  {
697  if(nmatches == 0)
698  cpl_array_delete(matches);
699  cpl_msg_error(cpl_func,"Error in PPM. %s",cpl_error_get_message());
700  cpl_matrix_delete(obj_pos);
701  cpl_propertylist_delete(sort_prop);
702  cpl_msg_indent_less();
703  return NULL;
704  }
705 
706  if(nmatches < floor(nobj_used_match*0.1))
707  {
708  cpl_msg_warning(cpl_func,"PPM detected matched only %d objects."
709  " Results could be unreliable",nmatches);
710  }
711 
712  /* Free and return */
713  cpl_matrix_delete(obj_pos);
714  cpl_propertylist_delete(sort_prop);
715  cpl_msg_indent_less();
716  return matches;
717 }
718 
719 /*----------------------------------------------------------------------------*/
724 /*----------------------------------------------------------------------------*/
725 static cpl_table * hawki_step_photom_2mass_fill_zpoint_table
726 (cpl_table * stars_2mass,
727  cpl_table * obj_det_param,
728  cpl_array * matches,
729  cpl_propertylist * plist,
730  int idet)
731 {
732  cpl_table * zpoints;
733  int nmatches;
734  int nstars;
735  int imatch;
736  int istar;
737  const char * filter;
738  char magcol_2mass[100];
739  char magerrcol_2mass[100];
740  double dit;
741  double airmass;
742  double pixscale;
743  double extinction;
744  cpl_errorstate error_prevstate = cpl_errorstate_get();
745 
746  /* Read parameters from the propertylist */
747  airmass = (hawki_pfits_get_airmass_start(plist) +
748  hawki_pfits_get_airmass_end(plist)) / 2.;
749  filter = hawki_pfits_get_filter(plist);
750  dit = hawki_pfits_get_dit(plist);
751  pixscale = hawki_pfits_get_pixscale(plist);
752  switch (hawki_get_band(filter))
753  {
754  case HAWKI_BAND_J:
755  extinction = 0.098;
756  strncpy(magcol_2mass, HAWKI_COL_2MASS_J_MAG, 98);
757  strncpy(magerrcol_2mass, HAWKI_COL_2MASS_J_MAGSIG, 98);
758  break ;
759  case HAWKI_BAND_H:
760  extinction = 0.039;
761  strncpy(magcol_2mass, HAWKI_COL_2MASS_H_MAG, 98);
762  strncpy(magerrcol_2mass, HAWKI_COL_2MASS_H_MAGSIG, 98);
763  break ;
764  case HAWKI_BAND_K:
765  extinction = 0.065;
766  strncpy(magcol_2mass, HAWKI_COL_2MASS_K_MAG, 98);
767  strncpy(magerrcol_2mass, HAWKI_COL_2MASS_K_MAGSIG, 98);
768  break ;
769  default:
770  extinction = 0.00;
771  cpl_msg_warning(__func__,"The filter %s does not exist in 2MASS. "
772  "The 2MASS K band will be used instead. "
773  "Columns %s, %s, %s and %s in product will not "
774  "be accurate", filter,
775  HAWKI_COL_ZPOINT_MAG, HAWKI_COL_ZPOINT_ERRMAG,
776  HAWKI_COL_ZPOINT_ZPOINT, HAWKI_COL_ZPOINT_ATX0);
777  strncpy(magcol_2mass, HAWKI_COL_2MASS_K_MAG, 98);
778  strncpy(magerrcol_2mass, HAWKI_COL_2MASS_K_MAGSIG, 98);
779  break ;
780  }
781 
782  /* Select only stars in 2MASS that have the given magnitude */
783  //irplib_stdstar_select_stars_mag(stars_2mass, magcol_2mass);
784  //cpl_msg_warning(__func__,"Paso irplib");
785 
786  /* Create the table */
787  nstars = cpl_table_get_nrow(stars_2mass);
788  nmatches = cpl_array_get_size(matches) - cpl_array_count_invalid(matches);
789  zpoints = cpl_table_new(nmatches) ;
790  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_CHIP, CPL_TYPE_INT) ;
791  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_POSX, CPL_TYPE_DOUBLE) ;
792  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_POSY, CPL_TYPE_DOUBLE) ;
793  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_ZPOINT, CPL_TYPE_DOUBLE) ;
794  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_ATX0, CPL_TYPE_DOUBLE) ;
795  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_MAG, CPL_TYPE_DOUBLE) ;
796  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_ERRMAG, CPL_TYPE_DOUBLE) ;
797  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_AIRMASS, CPL_TYPE_DOUBLE) ;
798  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FLUX, CPL_TYPE_DOUBLE) ;
799  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FILTER, CPL_TYPE_STRING) ;
800 // cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_PEAK, CPL_TYPE_DOUBLE) ;
801 // cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_BGD, CPL_TYPE_DOUBLE) ;
802  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMX, CPL_TYPE_DOUBLE) ;
803  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMY, CPL_TYPE_DOUBLE) ;
804  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHM, CPL_TYPE_DOUBLE) ;
805  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMX_AS, CPL_TYPE_DOUBLE) ;
806  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMY_AS, CPL_TYPE_DOUBLE) ;
807  cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHM_AS, CPL_TYPE_DOUBLE) ;
808  imatch = 0;
809 
810  for (istar=0; istar<nstars; istar++)
811  {
812  int iobj;
813  int null;
814  double zpoint;
815  double atx0;
816  double flux;
817  double mag;
818  double errmag;
819  double fwhm_x;
820  double fwhm_y;
821  double fwhm;
822 
823  iobj = cpl_array_get_int(matches, istar, &null);
824 
825  if(null != 0)
826  continue;
827  if(!cpl_table_is_selected(stars_2mass, istar))
828  continue;
829 
830  flux = cpl_table_get_double
831  (obj_det_param, HAWKI_COL_OBJ_FLUX, iobj, NULL);
832  mag = cpl_table_get_float
833  (stars_2mass, magcol_2mass, istar, NULL);
834  errmag = cpl_table_get_float
835  (stars_2mass, magerrcol_2mass, istar, NULL);
836  zpoint = mag + 2.5 * log10(flux) - 2.5 * log10(dit);
837  atx0 = zpoint + airmass * extinction;
838  fwhm_x = cpl_table_get_double
839  (obj_det_param, HAWKI_COL_OBJ_FWHM_MAJAX, iobj, NULL);
840  fwhm_y = cpl_table_get_double
841  (obj_det_param, HAWKI_COL_OBJ_FWHM_MINAX, iobj, NULL);
842  fwhm = sqrt(fwhm_x*fwhm_y);
843 
844  cpl_table_set_int(zpoints, HAWKI_COL_ZPOINT_CHIP, imatch, idet + 1) ;
845  cpl_table_set_double
846  (zpoints, HAWKI_COL_ZPOINT_MAG, imatch, mag);
847  cpl_table_set_double
848  (zpoints, HAWKI_COL_ZPOINT_ERRMAG, imatch, errmag);
849  cpl_table_set_string
850  (zpoints, HAWKI_COL_ZPOINT_FILTER, imatch, filter);
851  cpl_table_set_double
852  (zpoints, HAWKI_COL_ZPOINT_AIRMASS, imatch, airmass);
853  cpl_table_set_double
854  (zpoints, HAWKI_COL_ZPOINT_POSX, imatch, cpl_table_get_double
855  (obj_det_param, HAWKI_COL_OBJ_POSX, iobj, NULL));
856  cpl_table_set_double
857  (zpoints, HAWKI_COL_ZPOINT_POSY, imatch, cpl_table_get_double
858  (obj_det_param, HAWKI_COL_OBJ_POSY, iobj, NULL));
859  cpl_table_set_double(zpoints, HAWKI_COL_ZPOINT_ZPOINT, imatch, zpoint);
860  cpl_table_set_double(zpoints, HAWKI_COL_ZPOINT_ATX0, imatch, atx0);
861  cpl_table_set_double
862  (zpoints, HAWKI_COL_ZPOINT_FLUX, imatch, flux);
863 // cpl_table_set_double(tab, HAWKI_COL_ZPOINT_PEAK, imatch,
864 // hawki_img_zpoint_outputs.peak[labels[iframe]-1]) ;
865 // cpl_table_set_double(tab, HAWKI_COL_ZPOINT_BGD, imatch,
866 // hawki_img_zpoint_outputs.bgd[labels[iframe]-1]) ;
867  cpl_table_set_double
868  (zpoints, HAWKI_COL_ZPOINT_FWHMX, imatch, fwhm_x);
869  cpl_table_set_double
870  (zpoints, HAWKI_COL_ZPOINT_FWHMY, imatch, fwhm_y);
871  cpl_table_set_double
872  (zpoints, HAWKI_COL_ZPOINT_FWHM, imatch, fwhm);
873  cpl_table_set_double
874  (zpoints, HAWKI_COL_ZPOINT_FWHMX_AS, imatch, fwhm_x * pixscale);
875  cpl_table_set_double
876  (zpoints, HAWKI_COL_ZPOINT_FWHMY_AS, imatch, fwhm_y * pixscale);
877  cpl_table_set_double
878  (zpoints, HAWKI_COL_ZPOINT_FWHM_AS, imatch, fwhm * pixscale);
879  ++imatch;
880  }
881 
882  /* Check error and return */
883  if(!cpl_errorstate_is_equal(error_prevstate))
884  {
885  cpl_msg_error(__func__,"An error happened filling the zpoint table: %s",
886  cpl_error_get_message());
887  cpl_table_delete(zpoints);
888  return NULL;
889  }
890  return zpoints;
891 }
892 
893 /*----------------------------------------------------------------------------*/
898 /*----------------------------------------------------------------------------*/
899 static cpl_propertylist ** hawki_step_photom_2mass_qc
900 (cpl_table ** zpoint_table)
901 {
902  int idet;
903  cpl_propertylist ** qclists;
904 
905  /* Allocate the qclists */
906  qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
907 
908  /* Loop on the detectors to get the mean zpoint */
909  for(idet = 0 ; idet < HAWKI_NB_DETECTORS ; ++idet)
910  {
911  double mean_zpoint;
912 
913  /* Allocate this qclist */
914  qclists[idet] = cpl_propertylist_new() ;
915 
916  /* Compute the mean zpoint */
917  mean_zpoint = cpl_table_get_column_mean(zpoint_table[idet],
918  HAWKI_COL_ZPOINT_ZPOINT);
919 
920  cpl_propertylist_append_double
921  (qclists[idet], "ESO QC ZPOINT", mean_zpoint);
922  }
923 
924  return qclists;
925 }
926 
927 /*----------------------------------------------------------------------------*/
937 /*----------------------------------------------------------------------------*/
938 static int hawki_step_photom_2mass_save
939 (cpl_table ** zpoints,
940  cpl_parameterlist * parlist,
941  cpl_propertylist ** qclists,
942  cpl_frameset * set)
943 {
944  cpl_propertylist * protype;
945  cpl_frame * ref_frame ;
946  cpl_frameset * combinedframes;
947  int nframes ;
948  const char * recipe_name = "hawki_step_photom_2mass" ;
949 
950  /* Initialise */
951  nframes = cpl_frameset_get_size(set) ;
952 
953  /* Get the reference frame */
954  combinedframes = hawki_extract_frameset(set, HAWKI_CALPRO_COMBINED);
955  ref_frame = cpl_frameset_get_first(combinedframes);
956 
957  /* Create the protype lists */
958  protype = cpl_propertylist_new();
959  cpl_propertylist_append_string(protype, "ESO PRO TYPE",
960  HAWKI_PROTYPE_ZPOINT_TAB);
961 
962  /* Write the zpoint table */
963  hawki_tables_save(set,
964  parlist,
965  set,
966  (const cpl_table **)zpoints,
967  recipe_name,
968  HAWKI_CALPRO_ZPOINT_TAB,
969  HAWKI_PROTYPE_ZPOINT_TAB,
970  protype,
971  (const cpl_propertylist **)qclists,
972  "hawki_step_photom_2mass.fits") ;
973 
974  /* Free and return */
975  cpl_propertylist_delete(protype);
976  cpl_frameset_delete(combinedframes);
977  return 0;
978 }