HAWKI Pipeline Reference Manual 1.8.10
hawki_step_photom_2mass.c
00001 /* $Id: hawki_step_photom_2mass.c,v 1.17 2012/04/23 10:08:45 cgarcia Exp $
00002  *
00003  * This file is part of the HAWKI Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: cgarcia $
00023  * $Date: 2012/04/23 10:08:45 $
00024  * $Revision: 1.17 $
00025  * $Name: hawki-1_8_10 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <math.h>
00037 #include <cpl.h>
00038 #include <string.h>
00039 
00040 #include "irplib_utils.h"
00041 
00042 #include "hawki_alloc.h"
00043 #include "hawki_utils.h"
00044 #include "hawki_load.h"
00045 #include "hawki_save.h"
00046 #include "hawki_pfits.h"
00047 #include "hawki_dfs.h"
00048 #include "irplib_cat.h"
00049 #include "irplib_stdstar.h"
00050 
00051 /*-----------------------------------------------------------------------------
00052                             Functions prototypes
00053  -----------------------------------------------------------------------------*/
00054 
00055 static int hawki_step_photom_2mass_create(cpl_plugin *) ;
00056 static int hawki_step_photom_2mass_exec(cpl_plugin *) ;
00057 static int hawki_step_photom_2mass_destroy(cpl_plugin *) ;
00058 static int hawki_step_photom_2mass(cpl_parameterlist   *   parlist,
00059                                    cpl_frameset        *   frameset);
00060 
00061 
00062 cpl_table ** hawki_step_photom_2mass_get_zpoints
00063 (cpl_frameset *     cat_2mass,
00064  cpl_frameset *     obj_param,
00065  cpl_frameset *     obj_ima);
00066 
00067 static cpl_table * hawki_step_photom_2mass_retrieve_stars
00068 (cpl_frameset *     cat_2mass,
00069  cpl_propertylist * wcs_keywords);
00070 
00071 static cpl_array *  hawki_step_photom_2mass_ppm
00072 (cpl_table *  stars_2mass,
00073  cpl_table *  obj_det);
00074 
00075 static cpl_table * hawki_step_photom_2mass_fill_zpoint_table
00076 (cpl_table *        stars_2mass,
00077  cpl_table *        obj_det_param,
00078  cpl_array *        matches,
00079  cpl_propertylist * plist,
00080  int                idet);
00081 
00082 static cpl_propertylist ** hawki_step_photom_2mass_qc
00083 (cpl_table ** zpoint_table);
00084 
00085 static int hawki_step_photom_2mass_save
00086 (cpl_table **              zpoints,
00087  cpl_parameterlist *       parlist,
00088  cpl_propertylist **       qclists,
00089  cpl_frameset *            set);
00090 
00091 /*-----------------------------------------------------------------------------
00092                             Static variables
00093  -----------------------------------------------------------------------------*/
00094 
00095 static char hawki_step_photom_2mass_description[] = 
00096 "hawki_step_photom_2mass -- HAWK-I photometric autocalibration using 2MASS.\n"
00097 "The input files must be tagged:\n"
00098 "obj_param.fits "HAWKI_CALPRO_OBJ_PARAM"\n"
00099 "image.fits "HAWKI_CALPRO_COMBINED"\n"
00100 "2mass_master_index.fits "HAWKI_UTIL_CAT_2MASS"\n"
00101 "The recipe creates as an output:\n"
00102 "hawki_cal_photom_2mass.fits ("HAWKI_CALPRO_ZPOINT_TAB"): \n"
00103 "The recipe does the following steps:\n"
00104 "-Search the 2MASS catalogue for stars in the FOV\n"
00105 "-Matches the input detected object catalogue and the 2MASS stars\n"
00106 "-Computes photometric characteristics for each matched star\n"
00107 "Return code:\n"
00108 "esorex exits with an error code of 0 if the recipe completes successfully\n"
00109 "or 1 otherwise";
00110 
00111 /*-----------------------------------------------------------------------------
00112                                 Functions code
00113  -----------------------------------------------------------------------------*/
00114 
00115 /*----------------------------------------------------------------------------*/
00123 /*----------------------------------------------------------------------------*/
00124 int cpl_plugin_get_info(cpl_pluginlist * list)
00125 {
00126     cpl_recipe *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
00127     cpl_plugin *   plugin = &recipe->interface ;
00128 
00129     cpl_plugin_init(plugin,
00130                     CPL_PLUGIN_API,
00131                     HAWKI_BINARY_VERSION,
00132                     CPL_PLUGIN_TYPE_RECIPE,
00133                     "hawki_step_photom_2mass",
00134                     "2MASS photometric calibration",
00135                     hawki_step_photom_2mass_description,
00136                     "Cesar Enrique Garcia Dabo",
00137                     PACKAGE_BUGREPORT,  
00138                     hawki_get_license(),
00139                     hawki_step_photom_2mass_create,
00140                     hawki_step_photom_2mass_exec,
00141                     hawki_step_photom_2mass_destroy);
00142 
00143     cpl_pluginlist_append(list, plugin) ;
00144     
00145     return 0;
00146 }
00147 
00148 /*----------------------------------------------------------------------------*/
00157 /*----------------------------------------------------------------------------*/
00158 static int hawki_step_photom_2mass_create(cpl_plugin * plugin)
00159 {
00160     cpl_recipe *   recipe ;
00161 
00162     /* Get the recipe out of the plugin */
00163     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00164         recipe = (cpl_recipe *)plugin ;
00165     else return -1 ;
00166 
00167     /* Create the parameters list in the cpl_recipe object */
00168     recipe->parameters = cpl_parameterlist_new() ;
00169     if (recipe->parameters == NULL)
00170         return 1;
00171 
00172     /* Return */
00173     return 0;
00174 }
00175 
00176 /*----------------------------------------------------------------------------*/
00182 /*----------------------------------------------------------------------------*/
00183 static int hawki_step_photom_2mass_exec(cpl_plugin * plugin)
00184 {
00185     cpl_recipe  *   recipe ;
00186 
00187     /* Get the recipe out of the plugin */
00188     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00189         recipe = (cpl_recipe *)plugin ;
00190     else return -1 ;
00191 
00192     /* Issue a banner */
00193     hawki_print_banner();
00194 
00195     return hawki_step_photom_2mass(recipe->parameters, recipe->frames) ;
00196 }
00197 
00198 /*----------------------------------------------------------------------------*/
00204 /*----------------------------------------------------------------------------*/
00205 static int hawki_step_photom_2mass_destroy(cpl_plugin * plugin)
00206 {
00207     cpl_recipe  *   recipe ;
00208 
00209     /* Get the recipe out of the plugin */
00210     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00211         recipe = (cpl_recipe *)plugin ;
00212     else return -1 ;
00213 
00214     cpl_parameterlist_delete(recipe->parameters) ;
00215     return 0 ;
00216 }
00217 
00218 /*----------------------------------------------------------------------------*/
00224 /*----------------------------------------------------------------------------*/
00225 static int hawki_step_photom_2mass(cpl_parameterlist *   parlist,
00226                                    cpl_frameset *        frameset)
00227 {
00228     cpl_frameset *      cat_2mass;
00229     cpl_frameset *      obj_param;
00230     cpl_frameset *      obj_ima;
00231     cpl_table **        zpoint_table;
00232     cpl_propertylist ** qclists;
00233     int                 idet;
00234     
00235     /* Identify the RAW and CALIB frames in the input frameset */
00236     if (hawki_dfs_set_groups(frameset)) {
00237         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00238         return -1 ;
00239     }
00240 
00241     /* Retrieve 2MASS catalogue */
00242     if ((cat_2mass = hawki_extract_frameset(frameset,
00243                     HAWKI_UTIL_CAT_2MASS)) == NULL) 
00244     {
00245         cpl_msg_error(__func__, "Cannot find 2MASS catalogue (%s)",
00246                 HAWKI_UTIL_CAT_2MASS);
00247         return -1 ;
00248     }
00249 
00250     /* Retrieve obj param */
00251     if ((obj_param = hawki_extract_frameset
00252             (frameset, HAWKI_CALPRO_OBJ_PARAM)) == NULL) 
00253     {
00254         cpl_msg_error(__func__, "Cannot find object parameters (%s)",
00255                 HAWKI_CALPRO_OBJ_PARAM);
00256         return -1 ;
00257     }
00258 
00259     /* Retrieve reference image */
00260     if ((obj_ima = hawki_extract_frameset
00261             (frameset, HAWKI_CALPRO_COMBINED)) == NULL) 
00262     {
00263         cpl_msg_error(__func__, "Cannot find combined image (%s) ",
00264                 HAWKI_CALPRO_COMBINED);
00265         return -1 ;
00266     }
00267 
00268     /* Compute the zpoints */
00269     zpoint_table = hawki_step_photom_2mass_get_zpoints
00270         (cat_2mass, obj_param, obj_ima);
00271     if(zpoint_table == NULL)
00272     {
00273         cpl_msg_error(__func__,"Could not get the zpoints");
00274         cpl_frameset_delete(cat_2mass);
00275         cpl_frameset_delete(obj_param);
00276         cpl_frameset_delete(obj_ima);
00277         return -1;
00278     }
00279     
00280     /* Get some QC */
00281     qclists =  hawki_step_photom_2mass_qc(zpoint_table);
00282     if(zpoint_table == NULL)
00283     {
00284         cpl_msg_error(__func__,"Could not compute quality controls");
00285         cpl_frameset_delete(cat_2mass);
00286         cpl_frameset_delete(obj_param);
00287         cpl_frameset_delete(obj_ima);
00288         hawki_table_delete(zpoint_table);
00289         return -1;
00290     }
00291     
00292     /* Save the products */
00293     cpl_msg_info(__func__,"Saving products");
00294     if(hawki_step_photom_2mass_save(zpoint_table, parlist, qclists, frameset) == -1)
00295     {
00296         cpl_msg_error(__func__,"Could not save products");
00297         cpl_frameset_delete(cat_2mass);
00298         cpl_frameset_delete(obj_param);
00299         cpl_frameset_delete(obj_ima);
00300         hawki_table_delete(zpoint_table);
00301         return -1;
00302     }
00303     
00304     /* Free and return */
00305     cpl_frameset_delete(cat_2mass);
00306     cpl_frameset_delete(obj_param);
00307     cpl_frameset_delete(obj_ima);
00308     hawki_table_delete(zpoint_table);
00309     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) 
00310         cpl_propertylist_delete(qclists[idet]);
00311     cpl_free(qclists);
00312 
00313     /* Return */
00314     if (cpl_error_get_code())
00315     {
00316         cpl_msg_error(__func__,
00317                       "HAWK-I pipeline could not recover from previous errors");
00318         return -1 ;
00319     }
00320     else return 0 ;
00321 }
00322 
00323 cpl_table ** hawki_step_photom_2mass_get_zpoints
00324 (cpl_frameset *     cat_2mass,
00325  cpl_frameset *     obj_param,
00326  cpl_frameset *     obj_ima)
00327 {
00328     cpl_table **       zpoint_table;
00329     cpl_table **       obj_det_param;
00330     cpl_propertylist * plist;
00331     int                idet;
00332     cpl_errorstate     error_prevstate = cpl_errorstate_get();
00333     
00334     /* Allocate zpoint_table */
00335     zpoint_table = cpl_malloc(sizeof(cpl_table *) * HAWKI_NB_DETECTORS);
00336 
00337     /* Load detected obj */
00338     obj_det_param = hawki_load_tables(cpl_frameset_get_first(obj_param));
00339      
00340     /* Read the main header */
00341     plist = cpl_propertylist_load
00342         (cpl_frame_get_filename(cpl_frameset_get_first(obj_ima)), 0);
00343     /* Loop on detectors */    
00344     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00345     {
00346         cpl_propertylist * wcs_info;
00347         cpl_table        * stars_2mass;
00348         cpl_array        * matches;
00349         int                ext_nb;
00350 
00351         cpl_msg_info(__func__,"Working on chip %d", idet + 1);
00352         cpl_msg_indent_more();
00353          
00354         /* Retrieve stars */
00355         ext_nb=hawki_get_ext_from_detector
00356             (cpl_frame_get_filename(cpl_frameset_get_first(obj_ima)),idet+1);
00357         wcs_info = cpl_propertylist_load
00358             (cpl_frame_get_filename(cpl_frameset_get_first(obj_ima)), ext_nb);
00359         stars_2mass = 
00360             hawki_step_photom_2mass_retrieve_stars(cat_2mass, wcs_info);        
00361         if(stars_2mass == NULL)
00362         {
00363             int jdet;
00364             cpl_msg_error(__func__, "Cannot retrieve stars");
00365             cpl_propertylist_delete(plist);
00366             cpl_propertylist_delete(wcs_info);
00367             hawki_table_delete(obj_det_param);
00368             for(jdet = 0; jdet <idet; ++jdet)
00369                 cpl_table_delete(zpoint_table[jdet]);
00370             cpl_free(zpoint_table);
00371             return NULL;
00372         }
00373          
00374         /* Pattern matching btw stars in 2MASS and detected ones */
00375         cpl_msg_info(__func__,"Matching %"CPL_SIZE_FORMAT
00376                      " 2MASS stars and %"CPL_SIZE_FORMAT" detections",
00377                      cpl_table_get_nrow(stars_2mass),
00378                      cpl_table_get_nrow(obj_det_param[idet]));
00379         matches = hawki_step_photom_2mass_ppm(stars_2mass, obj_det_param[idet]);
00380         
00381         /* Fill the zpoint table */
00382         cpl_msg_info(__func__,"Computing zero points");
00383         zpoint_table[idet] = hawki_step_photom_2mass_fill_zpoint_table
00384             (stars_2mass, obj_det_param[idet], matches, plist, idet);
00385         if(zpoint_table[idet] == NULL)
00386         {
00387             int jdet;
00388             cpl_msg_error(__func__, "Could not compute the zero points");
00389             cpl_propertylist_delete(plist);
00390             cpl_propertylist_delete(wcs_info);
00391             hawki_table_delete(obj_det_param);
00392             cpl_table_delete(stars_2mass);
00393             for(jdet = 0; jdet <idet; ++jdet)
00394                 cpl_table_delete(zpoint_table[jdet]);
00395             cpl_free(zpoint_table);
00396             cpl_array_delete(matches);
00397             return NULL;
00398         }
00399         
00400         /* Cleaning resources */
00401         cpl_msg_indent_less();
00402         cpl_propertylist_delete(wcs_info);
00403         cpl_table_delete(stars_2mass);
00404         cpl_array_delete(matches);
00405     }
00406     
00407     /* Free and return */
00408     hawki_table_delete(obj_det_param);
00409     cpl_propertylist_delete(plist);
00410     if(!cpl_errorstate_is_equal(error_prevstate))
00411     {
00412         int jdet;
00413         for(jdet = 0; jdet <HAWKI_NB_DETECTORS; ++jdet)
00414             cpl_table_delete(zpoint_table[jdet]);
00415         cpl_free(zpoint_table);
00416         cpl_msg_error(__func__, "A problem happened computing the zero point");
00417         cpl_errorstate_set(CPL_ERROR_NONE);
00418         return NULL;
00419     }
00420     return zpoint_table;
00421 }
00422 
00423 static cpl_table *  hawki_step_photom_2mass_retrieve_stars
00424 (cpl_frameset *     cat_2mass,
00425  cpl_propertylist * wcs_keywords)
00426 {
00427     char *          catpath;
00428     char *          catname;
00429     cpl_table *     stars;
00430     cpl_wcs *       wcs;
00431     int             nstars;
00432     int             istar;
00433     double          ra1;
00434     double          ra2;
00435     double          dec1;
00436     double          dec2;
00437     double          extra_search = 0.;
00438     cpl_matrix *    from_coord;
00439     cpl_matrix *    to_coord;
00440     cpl_array *     status;
00441     
00442 
00443     /* Extract the catalog path */
00444     if (irplib_2mass_get_catpars(cpl_frameset_get_first(cat_2mass),
00445                                  &catpath, &catname) != CPL_ERROR_NONE) 
00446         return NULL;
00447     
00448     /* Get the WCS info */
00449     wcs = cpl_wcs_new_from_propertylist(wcs_keywords);
00450     if(cpl_error_get_code() == CPL_ERROR_NO_WCS)
00451     {
00452         cpl_msg_error(__func__,"Not compiled with WCS support.");
00453         return NULL;
00454     }
00455     
00456     /* Get the limits to search */
00457     if(irplib_cat_get_image_limits(wcs, extra_search, 
00458                                    &ra1, &ra2, &dec1, &dec2) == 
00459                                        CPL_ERROR_DATA_NOT_FOUND)
00460     {
00461         cpl_msg_error(__func__,"No WCS information found");
00462         cpl_free(catname);
00463         cpl_free(catpath);
00464         cpl_wcs_delete(wcs);
00465         return NULL;
00466     }
00467     cpl_msg_info(__func__,"Searching stars in RA=[%f,%f] DEC=[%f,%f]",
00468                  ra1/15., ra2/15., dec1, dec2);
00469     
00470     
00471     /* Search the stars */
00472     stars = irplib_2mass_extract(catpath, ra1, ra2, dec1, dec2);
00473     if(stars == NULL)
00474     {
00475         cpl_msg_error(__func__,"Error retrieving 2mass stars: %s ",
00476                       cpl_error_get_message());
00477         cpl_free(catname);
00478         cpl_free(catpath);
00479         cpl_wcs_delete(wcs);
00480         return NULL;
00481     }
00482     nstars = cpl_table_get_nrow(stars);
00483     cpl_msg_indent_more();
00484     cpl_msg_info(__func__, "%d 2MASS stars found", nstars);
00485 
00486     /* Convert Ra, Dec to X,Y using the WCS information from image */
00487     from_coord = cpl_matrix_new(nstars, 2);
00488     for (istar=0; istar<nstars; istar++)
00489     {
00490         cpl_matrix_set(from_coord, istar, 0, cpl_table_get_float
00491                        (stars, HAWKI_COL_2MASS_RA, istar, NULL));
00492         cpl_matrix_set(from_coord, istar, 1, cpl_table_get_float
00493                        (stars, HAWKI_COL_2MASS_DEC, istar, NULL));
00494     }
00495 
00496     to_coord = NULL;
00497     status   = NULL;
00498     if(cpl_wcs_convert(wcs, from_coord, &to_coord, 
00499                        &status, CPL_WCS_WORLD2PHYS) != CPL_ERROR_NONE)
00500     {
00501         cpl_array_delete(status);
00502         cpl_matrix_delete(from_coord);
00503         cpl_matrix_delete(to_coord);
00504         cpl_free(catname);
00505         cpl_free(catpath);
00506         cpl_wcs_delete(wcs);
00507         cpl_msg_error(cpl_func,"Error in cpl_wcs conversion. %s",
00508                       cpl_error_get_message());
00509         return NULL;
00510     }
00511 
00512     /* Add the predicted x,y coordinate columns to the  2MASS table */
00513     cpl_table_new_column(stars, HAWKI_COL_2MASS_XPREDICT, CPL_TYPE_FLOAT);
00514     cpl_table_set_column_unit(stars,HAWKI_COL_2MASS_XPREDICT, "pixels");
00515     cpl_table_new_column(stars, HAWKI_COL_2MASS_YPREDICT, CPL_TYPE_FLOAT);
00516     cpl_table_set_column_unit(stars, HAWKI_COL_2MASS_YPREDICT, "pixels");
00517     for(istar=0; istar< nstars; istar++)
00518     {
00519         float xpredict = (float)cpl_matrix_get(to_coord, istar, 0);
00520         float ypredict = (float)cpl_matrix_get(to_coord, istar, 1);
00521         cpl_table_set_float(stars,"xpredict", istar, xpredict);
00522         cpl_table_set_float(stars,"ypredict", istar, ypredict);
00523     }
00524     
00525     /* Free and return */
00526     cpl_array_delete(status);
00527     cpl_matrix_delete(from_coord);
00528     cpl_matrix_delete(to_coord);
00529     cpl_wcs_delete(wcs);
00530     cpl_free(catname);
00531     cpl_free(catpath);
00532     cpl_msg_indent_less();
00533     return stars;
00534 }
00535 
00536 /*----------------------------------------------------------------------------*/
00542 /*----------------------------------------------------------------------------*/
00543 static cpl_array *   hawki_step_photom_2mass_ppm
00544 (cpl_table *  stars_2mass,
00545  cpl_table *  obj_det)
00546 {
00547     int                istar;
00548     int                iobj;
00549     int                iter;
00550     int                nstars_2mass;
00551     int                nstars_2mass_used_match;
00552     int                nobj;
00553     int                nobj_used_match;
00554     int                nmatches;
00555     int                nmax_match_pattern = 30;
00556     cpl_matrix *       pattern;
00557     cpl_array *        matches;
00558     double             tol = 0.1;
00559     double             pradius = 30.0;
00560     double             mean_data_pos_err = 5.;
00561     int                ppm_max_iter = 5;
00562     double             scale = 1;
00563     double             angle;
00564     cpl_matrix *       obj_pos;
00565     cpl_propertylist * sort_prop;
00566     
00567     
00568     /* Sort the detected objects */
00569     cpl_msg_indent_more();
00570     sort_prop = cpl_propertylist_new();
00571     cpl_propertylist_append_bool(sort_prop, HAWKI_COL_OBJ_FLUX, 1);
00572     if (cpl_table_sort(obj_det, sort_prop) != CPL_ERROR_NONE) 
00573     {
00574         cpl_msg_error(cpl_func,"Cannot sort detected sources table");
00575         cpl_propertylist_delete(sort_prop);
00576         return NULL;
00577     }
00578 
00579     /* Create matrix of X,Y coordinates of detected objects*/
00580     nobj = cpl_table_get_nrow(obj_det);
00581     obj_pos = cpl_matrix_new(2, nobj);
00582     for (iobj=0; iobj<nobj; iobj++)
00583     {
00584         float xim = cpl_table_get_double
00585             (obj_det, HAWKI_COL_OBJ_POSX, iobj, NULL); 
00586         float yim = cpl_table_get_double
00587             (obj_det, HAWKI_COL_OBJ_POSY, iobj, NULL);
00588         cpl_matrix_set(obj_pos, 0, iobj, xim);
00589         cpl_matrix_set(obj_pos, 1, iobj, yim);
00590     }
00591 
00592     /* Sort the 2MASS stars by magnitude */
00593     cpl_propertylist_empty(sort_prop);
00594     cpl_propertylist_append_bool(sort_prop, HAWKI_COL_2MASS_K_MAG, 0);
00595     if (cpl_table_sort(stars_2mass, sort_prop) != CPL_ERROR_NONE) 
00596     {
00597         cpl_msg_error(cpl_func,"Cannot sort 2MASS stars table");
00598         cpl_propertylist_delete(sort_prop);
00599         return NULL;
00600     }
00601 
00602     /* Prepare the 2MASS matrix for the pattern matching */
00603     nstars_2mass = cpl_table_get_nrow(stars_2mass);
00604     pattern = cpl_matrix_new(2, nstars_2mass);
00605     for(istar=0; istar<nstars_2mass ; istar++)
00606     {
00607         float x = cpl_table_get_float
00608             (stars_2mass, HAWKI_COL_2MASS_XPREDICT, istar, NULL);
00609         float y = cpl_table_get_float
00610             (stars_2mass, HAWKI_COL_2MASS_YPREDICT, istar, NULL);
00611         cpl_matrix_set(pattern, 0, istar, x);
00612         cpl_matrix_set(pattern, 1, istar, y);
00613     }
00614     
00615     /* Do the ppm */
00616     nstars_2mass_used_match = nmax_match_pattern;
00617     if(nstars_2mass < nmax_match_pattern)
00618         nstars_2mass_used_match = nstars_2mass;
00619     nobj_used_match = (int)(1.7 * nstars_2mass_used_match);
00620     if(nobj_used_match > nobj)
00621         nobj_used_match = nobj;
00622     if(nobj_used_match < nstars_2mass_used_match)
00623         nobj_used_match = nstars_2mass_used_match;
00624     cpl_msg_info(__func__,"The first step match will use %d stars "
00625                  "and %d objects", nstars_2mass_used_match,nobj_used_match);
00626     for (iter = 0; iter < ppm_max_iter; iter++)
00627     {
00628         int nmatchsize;
00629         nmatches = 0;
00630         matches = cpl_ppm_match_points(obj_pos, nobj_used_match, 
00631                                        mean_data_pos_err,
00632                                        pattern, nstars_2mass_used_match,
00633                                        1, tol, pradius,
00634                                        NULL, NULL, &scale, &angle);
00635         if(matches != NULL)
00636         {
00637             nmatchsize = cpl_array_get_size(matches);
00638             nmatches = nmatchsize -
00639                 cpl_array_count_invalid(matches);
00640         }
00641         else
00642         {
00643             nmatchsize = 0;
00644             nmatches = 0;
00645         }
00646         
00647         cpl_msg_info(cpl_func,"Total matches: %d. Valid matches: %d",
00648                      nmatchsize, nmatches);
00649         cpl_msg_info(cpl_func,"Scale=%g angle=%g", scale, angle);
00650         if((matches == NULL) || (nmatches < floor(nobj_used_match*0.1))) 
00651         {
00652             nobj_used_match = nobj_used_match + 10;
00653             cpl_msg_info(cpl_func,
00654                          "Increasing number of detections used in PPM to %d",
00655                          nobj_used_match);
00656             continue;
00657         }
00658         else
00659             break;
00660     }
00661 
00662     /* Output debug messages */
00663     cpl_msg_indent_more();
00664     cpl_msg_debug(__func__,"Matched stars:");
00665     cpl_msg_indent_more();
00666     cpl_msg_debug(__func__,"X_OBJ  Y_OBJ    X_STAR Y_STAR   X_DIFF Y_DIFF:");
00667     for(istar=0; istar < nstars_2mass; ++istar)
00668     {
00669         int  null;
00670         double x_obj, y_obj, x_star, y_star, x_diff, y_diff;
00671         iobj  = cpl_array_get_int(matches, istar, &null);
00672         
00673         if(null != 0)
00674             continue;
00675         x_obj = cpl_matrix_get(obj_pos, 0, iobj);
00676         y_obj = cpl_matrix_get(obj_pos, 1, iobj);
00677         x_star = cpl_matrix_get(pattern, 0, istar);
00678         y_star = cpl_matrix_get(pattern, 1, istar);
00679         x_diff = x_obj - x_star;
00680         y_diff = y_obj - y_star;
00681         cpl_msg_debug(__func__,"%6.1f %6.1f  %6.1f %6.1f   %6.1f %6.1f\n",
00682                       x_obj, y_obj, x_star, y_star, x_diff, y_diff);
00683     }
00684     cpl_msg_indent_less();    
00685     cpl_msg_indent_less();
00686     
00687     cpl_matrix_delete(pattern);
00688     cpl_msg_info(cpl_func, "%d points matched", nmatches);
00689 
00690     if(matches == NULL || nmatches == 0)
00691     {
00692         if(nmatches == 0)
00693             cpl_array_delete(matches);
00694         cpl_msg_error(cpl_func,"Error in PPM. %s",cpl_error_get_message());
00695         cpl_matrix_delete(obj_pos);
00696         cpl_propertylist_delete(sort_prop);
00697         cpl_msg_indent_less();
00698         return NULL;
00699     }
00700     
00701     if(nmatches < floor(nobj_used_match*0.1))
00702     {
00703         cpl_msg_warning(cpl_func,"PPM detected matched only %d objects."
00704                         " Results could be unreliable",nmatches);
00705     }
00706     
00707     /* Free and return */
00708     cpl_matrix_delete(obj_pos);
00709     cpl_propertylist_delete(sort_prop);
00710     cpl_msg_indent_less();
00711     return matches;
00712 }
00713 
00714 /*----------------------------------------------------------------------------*/
00719 /*----------------------------------------------------------------------------*/
00720 static cpl_table * hawki_step_photom_2mass_fill_zpoint_table
00721 (cpl_table *        stars_2mass,
00722  cpl_table *        obj_det_param,
00723  cpl_array *        matches,
00724  cpl_propertylist * plist,
00725  int                idet)
00726 {
00727     cpl_table    * zpoints;
00728     int            nmatches;
00729     int            nstars;
00730     int            imatch;
00731     int            istar;
00732     const char   * filter;
00733     char           magcol_2mass[100];
00734     char           magerrcol_2mass[100];
00735     double         dit;
00736     double         airmass;
00737     double         pixscale;
00738     double         extinction;
00739     cpl_errorstate error_prevstate = cpl_errorstate_get();
00740     
00741     /* Read parameters from the propertylist */
00742     airmass  = (hawki_pfits_get_airmass_start(plist) +
00743                 hawki_pfits_get_airmass_end(plist)) / 2.;
00744     filter   = hawki_pfits_get_filter(plist);
00745     dit      = hawki_pfits_get_dit(plist);
00746     pixscale = hawki_pfits_get_pixscale(plist);
00747     switch (hawki_get_band(filter))
00748     {
00749         case HAWKI_BAND_J:    
00750             extinction = 0.098;
00751             strcpy(magcol_2mass, HAWKI_COL_2MASS_J_MAG);
00752             strcpy(magerrcol_2mass, HAWKI_COL_2MASS_J_MAGSIG);
00753             break ;
00754         case HAWKI_BAND_H:
00755             extinction = 0.039;
00756             strcpy(magcol_2mass, HAWKI_COL_2MASS_H_MAG);
00757             strcpy(magerrcol_2mass, HAWKI_COL_2MASS_H_MAGSIG);
00758             break ;
00759         case HAWKI_BAND_K:
00760             extinction = 0.065;
00761             strcpy(magcol_2mass, HAWKI_COL_2MASS_K_MAG);
00762             strcpy(magerrcol_2mass, HAWKI_COL_2MASS_K_MAGSIG);
00763             break ;
00764         default: 
00765             extinction = 0.00;
00766             cpl_msg_warning(__func__,"The filter %s does not exist in 2MASS. "
00767                             "The 2MASS K band will be used instead. "
00768                             "Columns %s, %s, %s and %s in product will not "
00769                             "be accurate", filter, 
00770                             HAWKI_COL_ZPOINT_MAG, HAWKI_COL_ZPOINT_ERRMAG,
00771                             HAWKI_COL_ZPOINT_ZPOINT, HAWKI_COL_ZPOINT_ATX0);
00772             strcpy(magcol_2mass, HAWKI_COL_2MASS_K_MAG);
00773             strcpy(magerrcol_2mass, HAWKI_COL_2MASS_K_MAGSIG);
00774             break ;
00775     }
00776                 
00777     /* Select only stars in 2MASS that have the given magnitude */
00778     //irplib_stdstar_select_stars_mag(stars_2mass, magcol_2mass);
00779     //cpl_msg_warning(__func__,"Paso irplib");
00780     
00781     /* Create the table */
00782     nstars = cpl_table_get_nrow(stars_2mass);
00783     nmatches = cpl_array_get_size(matches) - cpl_array_count_invalid(matches);
00784     zpoints = cpl_table_new(nmatches) ;
00785     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_CHIP, CPL_TYPE_INT) ;
00786     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_POSX, CPL_TYPE_DOUBLE) ;
00787     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_POSY, CPL_TYPE_DOUBLE) ;
00788     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_ZPOINT, CPL_TYPE_DOUBLE) ;
00789     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_ATX0, CPL_TYPE_DOUBLE) ;
00790     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_MAG, CPL_TYPE_DOUBLE) ;
00791     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_ERRMAG, CPL_TYPE_DOUBLE) ;
00792     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_AIRMASS, CPL_TYPE_DOUBLE) ;
00793     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FLUX, CPL_TYPE_DOUBLE) ;
00794     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FILTER, CPL_TYPE_STRING) ;
00795 //    cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_PEAK, CPL_TYPE_DOUBLE) ;
00796 //    cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_BGD, CPL_TYPE_DOUBLE) ;
00797     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMX, CPL_TYPE_DOUBLE) ;
00798     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMY, CPL_TYPE_DOUBLE) ;
00799     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHM, CPL_TYPE_DOUBLE) ;
00800     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMX_AS, CPL_TYPE_DOUBLE) ;
00801     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHMY_AS, CPL_TYPE_DOUBLE) ;
00802     cpl_table_new_column(zpoints, HAWKI_COL_ZPOINT_FWHM_AS, CPL_TYPE_DOUBLE) ;
00803     imatch = 0;
00804     
00805     for (istar=0; istar<nstars; istar++) 
00806     {
00807         int      iobj;
00808         int      null;
00809         double   zpoint;
00810         double   atx0;
00811         double   flux;
00812         double   mag;
00813         double   errmag;
00814         double   fwhm_x;
00815         double   fwhm_y;
00816         double   fwhm;
00817         
00818         iobj  = cpl_array_get_int(matches, istar, &null);
00819         
00820         if(null != 0)
00821             continue;
00822         if(!cpl_table_is_selected(stars_2mass, istar))
00823             continue;
00824        
00825         flux = cpl_table_get_double
00826             (obj_det_param, HAWKI_COL_OBJ_FLUX, iobj, NULL);
00827         mag = cpl_table_get_float
00828             (stars_2mass, magcol_2mass, istar, NULL); 
00829         errmag = cpl_table_get_float
00830             (stars_2mass, magerrcol_2mass, istar, NULL);
00831         zpoint = mag + 2.5 * log10(flux) - 2.5 * log10(dit);
00832         atx0 = zpoint + airmass * extinction;
00833         fwhm_x = cpl_table_get_double
00834             (obj_det_param, HAWKI_COL_OBJ_FWHM_MAJAX, iobj, NULL);
00835         fwhm_y = cpl_table_get_double
00836             (obj_det_param, HAWKI_COL_OBJ_FWHM_MINAX, iobj, NULL);
00837         fwhm   = sqrt(fwhm_x*fwhm_y); 
00838 
00839         cpl_table_set_int(zpoints, HAWKI_COL_ZPOINT_CHIP, imatch, idet + 1) ;
00840         cpl_table_set_double
00841             (zpoints, HAWKI_COL_ZPOINT_MAG, imatch, mag);
00842         cpl_table_set_double
00843             (zpoints, HAWKI_COL_ZPOINT_ERRMAG, imatch, errmag);
00844         cpl_table_set_string
00845             (zpoints, HAWKI_COL_ZPOINT_FILTER, imatch, filter);
00846         cpl_table_set_double
00847             (zpoints, HAWKI_COL_ZPOINT_AIRMASS, imatch, airmass);
00848         cpl_table_set_double
00849             (zpoints, HAWKI_COL_ZPOINT_POSX, imatch, cpl_table_get_double
00850              (obj_det_param, HAWKI_COL_OBJ_POSX, iobj, NULL));
00851         cpl_table_set_double
00852             (zpoints, HAWKI_COL_ZPOINT_POSY, imatch, cpl_table_get_double
00853              (obj_det_param, HAWKI_COL_OBJ_POSY, iobj, NULL));
00854         cpl_table_set_double(zpoints, HAWKI_COL_ZPOINT_ZPOINT, imatch, zpoint);
00855         cpl_table_set_double(zpoints, HAWKI_COL_ZPOINT_ATX0, imatch, atx0);
00856         cpl_table_set_double
00857             (zpoints, HAWKI_COL_ZPOINT_FLUX, imatch, flux);
00858 //        cpl_table_set_double(tab, HAWKI_COL_ZPOINT_PEAK, imatch, 
00859 //                hawki_img_zpoint_outputs.peak[labels[iframe]-1]) ;
00860 //        cpl_table_set_double(tab, HAWKI_COL_ZPOINT_BGD, imatch, 
00861 //                hawki_img_zpoint_outputs.bgd[labels[iframe]-1]) ;
00862         cpl_table_set_double
00863             (zpoints, HAWKI_COL_ZPOINT_FWHMX, imatch, fwhm_x);
00864         cpl_table_set_double
00865             (zpoints, HAWKI_COL_ZPOINT_FWHMY, imatch, fwhm_y);
00866         cpl_table_set_double
00867             (zpoints, HAWKI_COL_ZPOINT_FWHM, imatch, fwhm);
00868         cpl_table_set_double
00869             (zpoints, HAWKI_COL_ZPOINT_FWHMX_AS, imatch, fwhm_x * pixscale);
00870         cpl_table_set_double
00871             (zpoints, HAWKI_COL_ZPOINT_FWHMY_AS, imatch, fwhm_y * pixscale);
00872         cpl_table_set_double
00873             (zpoints, HAWKI_COL_ZPOINT_FWHM_AS, imatch, fwhm * pixscale);
00874         ++imatch;
00875     }
00876     
00877     /* Check error and return */
00878     if(!cpl_errorstate_is_equal(error_prevstate))
00879     {
00880         cpl_msg_error(__func__,"An error happened filling the zpoint table: %s",
00881                       cpl_error_get_message());
00882         cpl_table_delete(zpoints);
00883         return NULL;
00884     }
00885     return zpoints;
00886 }
00887 
00888 /*----------------------------------------------------------------------------*/
00893 /*----------------------------------------------------------------------------*/
00894 static cpl_propertylist ** hawki_step_photom_2mass_qc
00895 (cpl_table ** zpoint_table)
00896 {
00897     int idet;
00898     cpl_propertylist ** qclists;
00899     
00900     /* Allocate the qclists */
00901     qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00902     
00903     /* Loop on the detectors to get the mean zpoint */
00904     for(idet = 0 ; idet < HAWKI_NB_DETECTORS ; ++idet)
00905     {
00906         double mean_zpoint;
00907 
00908         /* Allocate this qclist */
00909         qclists[idet] = cpl_propertylist_new() ;
00910         
00911         /* Compute the mean zpoint */
00912         mean_zpoint = cpl_table_get_column_mean(zpoint_table[idet],
00913                                                 HAWKI_COL_ZPOINT_ZPOINT);
00914         
00915         cpl_propertylist_append_double
00916             (qclists[idet], "ESO QC ZPOINT", mean_zpoint);
00917     }
00918     
00919     return qclists;
00920 }
00921 
00922 /*----------------------------------------------------------------------------*/
00932 /*----------------------------------------------------------------------------*/
00933 static int hawki_step_photom_2mass_save
00934 (cpl_table **         zpoints,
00935  cpl_parameterlist *  parlist,
00936  cpl_propertylist **  qclists,
00937  cpl_frameset *       set)
00938 {
00939     cpl_propertylist *   protype;
00940     cpl_frame *          ref_frame ;
00941     cpl_frameset *       combinedframes;
00942     int                  nframes ;
00943     const char *         recipe_name = "hawki_step_photom_2mass" ;
00944 
00945     /* Initialise */
00946     nframes = cpl_frameset_get_size(set) ;
00947 
00948     /* Get the reference frame */
00949     combinedframes = hawki_extract_frameset(set, HAWKI_CALPRO_COMBINED);
00950     ref_frame = cpl_frameset_get_first(combinedframes);
00951 
00952     /* Create the protype lists */
00953     protype = cpl_propertylist_new();
00954     cpl_propertylist_append_string(protype, "ESO PRO TYPE",
00955             HAWKI_PROTYPE_ZPOINT_TAB);
00956 
00957     /* Write the zpoint table  */
00958     hawki_tables_save(set,
00959                       parlist,
00960                       set,
00961                       (const cpl_table **)zpoints,
00962                       recipe_name,
00963                       HAWKI_CALPRO_ZPOINT_TAB,
00964                       HAWKI_PROTYPE_ZPOINT_TAB,
00965                       protype,
00966                       (const cpl_propertylist **)qclists,
00967                       "hawki_step_photom_2mass.fits") ;
00968 
00969     /* Free and return */
00970     cpl_propertylist_delete(protype);
00971     cpl_frameset_delete(combinedframes);
00972     return  0;
00973 }