HAWKI Pipeline Reference Manual 1.8.12
hawki_step_refine_offsets.c
00001 /* $Id: hawki_step_refine_offsets.c,v 1.17 2011/10/24 10:42:12 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: 2011/10/24 10:42:12 $
00024  * $Revision: 1.17 $
00025  * $Name: hawki-1_8_12 $
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 #include "irplib_calib.h"
00042 
00043 #include "hawki_utils.h"
00044 #include "hawki_calib.h"
00045 #include "hawki_load.h"
00046 #include "hawki_save.h"
00047 #include "hawki_pfits.h"
00048 #include "hawki_dfs.h"
00049 #include "hawki_saa.h"
00050 #include "hawki_bkg.h"
00051 #include "hawki_distortion.h"
00052 #include "hawki_properties_tel.h"
00053 #include "hawki_image_stats.h"
00054 
00055 /*-----------------------------------------------------------------------------
00056                                 Define
00057  -----------------------------------------------------------------------------*/
00058 
00059 #define NEGLIG_OFF_DIFF     0.1
00060 #define SQR(x) ((x)*(x))
00061 
00062 /*-----------------------------------------------------------------------------
00063                             Functions prototypes
00064  -----------------------------------------------------------------------------*/
00065 
00066 static int hawki_step_refine_offsets_create(cpl_plugin *) ;
00067 static int hawki_step_refine_offsets_exec(cpl_plugin *) ;
00068 static int hawki_step_refine_offsets_destroy(cpl_plugin *) ;
00069 static int hawki_step_refine_offsets(cpl_parameterlist *, cpl_frameset *) ;
00070 
00071 static int hawki_step_refine_offsets_retrieve_input_param
00072 (cpl_parameterlist  *  parlist);
00073 static int hawki_step_refine_offsets_fine
00074 (const cpl_frameset  *  science_objects_frames,
00075  const cpl_frameset  *  reference_objects_frames,
00076  cpl_bivector        ** refined_offsets,
00077  cpl_vector          ** correl);
00078 
00079 static int hawki_step_refine_offsets_save
00080 (cpl_bivector      ** refined_offsets,
00081  cpl_vector        ** correlations,
00082  cpl_parameterlist *  recipe_parlist,
00083  cpl_frameset      *  recipe_frameset);
00084 
00085 static cpl_bivector ** hawki_step_refine_offsets_read_select_objects
00086 (const cpl_frameset *  reference_obj_frames,
00087  double                first_image_off_x,
00088  double                first_image_off_y,
00089  int                   nx,
00090  int                   ny);
00091 
00092 /*-----------------------------------------------------------------------------
00093                             Static variables
00094  -----------------------------------------------------------------------------*/
00095 
00096 static struct 
00097 {
00098     /* Inputs */
00099     int                 nbrightest;
00100     int                 sx ;
00101     int                 sy ;
00102     int                 mx ;
00103     int                 my ;
00104 } hawki_step_refine_offsets_config;
00105 
00106 static char hawki_step_refine_offsets_description[] =
00107 "hawki_step_refine_offsets -- utility to refine the nominal offsets.\n"
00108 "This utility will take the offsets in the header as a first approach\n"
00109 "and tries to refine them correlating the input images at the points\n"
00110 "given by the detected objects.\n"
00111 "The input of the recipe files listed in the Set Of Frames (sof-file)\n"
00112 "must be tagged as:\n"
00113 "images.fits "HAWKI_CALPRO_DIST_CORRECTED" or\n"
00114 "images.fits "HAWKI_CALPRO_BKG_SUBTRACTED" and\n"
00115 "det_obj_stats.fits "HAWKI_CALPRO_OBJ_PARAM"\n"
00116 "The recipe creates as an output:\n"
00117 "hawki_step_refine_offsets.fits ("HAWKI_CALPRO_OFFSETS"): Table with refined offsets\n"
00118 "Return code:\n"
00119 "esorex exits with an error code of 0 if the recipe completes successfully\n"
00120 "or 1 otherwise";
00121 
00122 
00123 /*-----------------------------------------------------------------------------
00124                                 Functions code
00125  -----------------------------------------------------------------------------*/
00126 
00127 /*----------------------------------------------------------------------------*/
00135 /*----------------------------------------------------------------------------*/
00136 int cpl_plugin_get_info(cpl_pluginlist * list)
00137 {
00138     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
00139     cpl_plugin  *   plugin = &recipe->interface ;
00140 
00141     cpl_plugin_init(plugin,
00142                     CPL_PLUGIN_API,
00143                     HAWKI_BINARY_VERSION,
00144                     CPL_PLUGIN_TYPE_RECIPE,
00145                     "hawki_step_refine_offsets",
00146                     "Jitter recipe",
00147                     hawki_step_refine_offsets_description,
00148                     "Cesar Enrique Garcia Dabo",
00149                     PACKAGE_BUGREPORT,  
00150                     hawki_get_license(),
00151                     hawki_step_refine_offsets_create,
00152                     hawki_step_refine_offsets_exec,
00153                     hawki_step_refine_offsets_destroy) ;
00154 
00155     cpl_pluginlist_append(list, plugin) ;
00156     
00157     return 0;
00158 }
00159 
00160 /*----------------------------------------------------------------------------*/
00169 /*----------------------------------------------------------------------------*/
00170 static int hawki_step_refine_offsets_create(cpl_plugin * plugin)
00171 {
00172     cpl_recipe      * recipe ;
00173     cpl_parameter   * p ;
00174 
00175     /* Get the recipe out of the plugin */
00176     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00177         recipe = (cpl_recipe *)plugin ;
00178     else return -1 ;
00179 
00180     /* Create the parameters list in the cpl_recipe object */
00181     recipe->parameters = cpl_parameterlist_new() ;
00182     if (recipe->parameters == NULL)
00183         return 1;
00184 
00185     /* Fill the parameters list */
00186     /* --xcorr */
00187     p = cpl_parameter_new_value("hawki.hawki_step_refine_offsets.xcorr",
00188                                 CPL_TYPE_STRING,
00189                                 "Cross correlation search and measure sizes",
00190                                 "hawki.hawki_step_refine_offsets",
00191                                 "20,20,25,25") ;
00192     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcorr") ;
00193     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00194     cpl_parameterlist_append(recipe->parameters, p) ;
00195 
00196     /* --nbrightest */
00197     p = cpl_parameter_new_value("hawki.hawki_step_refine_offsets.nbrightest",
00198                                 CPL_TYPE_INT,
00199                                 "Number of brightest objects to use",
00200                                 "hawki.hawki_step_refine_offsets",
00201                                 3);
00202     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nbrightest") ;
00203     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00204     cpl_parameterlist_append(recipe->parameters, p) ;
00205 
00206     /* Return */
00207     return 0;
00208 }
00209 
00210 /*----------------------------------------------------------------------------*/
00216 /*----------------------------------------------------------------------------*/
00217 static int hawki_step_refine_offsets_exec(cpl_plugin * plugin)
00218 {
00219     cpl_recipe  *   recipe ;
00220 
00221     /* Get the recipe out of the plugin */
00222     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00223         recipe = (cpl_recipe *)plugin ;
00224     else return -1 ;
00225 
00226     /* Issue a banner */
00227     hawki_print_banner();
00228 
00229     return hawki_step_refine_offsets(recipe->parameters, recipe->frames) ;
00230 }
00231 
00232 /*----------------------------------------------------------------------------*/
00238 /*----------------------------------------------------------------------------*/
00239 static int hawki_step_refine_offsets_destroy(cpl_plugin * plugin)
00240 {
00241     cpl_recipe  *   recipe ;
00242 
00243     /* Get the recipe out of the plugin */
00244     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00245         recipe = (cpl_recipe *)plugin ;
00246     else return -1 ;
00247 
00248     cpl_parameterlist_delete(recipe->parameters) ;
00249     return 0 ;
00250 }
00251 
00252 /*----------------------------------------------------------------------------*/
00259 /*----------------------------------------------------------------------------*/
00260 static int hawki_step_refine_offsets(
00261         cpl_parameterlist   *   parlist, 
00262         cpl_frameset        *   framelist)
00263 {
00264     cpl_frameset    *   science_obj_frames ;
00265     cpl_frameset    *   reference_obj_frames ;
00266     cpl_bivector    **  refined_offsets;
00267     cpl_vector      **  correl;
00268     int                 idet;
00269 
00270     /* Retrieve input parameters */
00271     if(hawki_step_refine_offsets_retrieve_input_param(parlist))
00272     {
00273         cpl_msg_error(__func__, "Wrong parameters");
00274         return -1;
00275     }
00276 
00277     /* Identify the RAW and CALIB frames in the input frameset */
00278     if (hawki_dfs_set_groups(framelist)) {
00279         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00280         return -1 ;
00281     }
00282 
00283     /* Get the object images frames */
00284     cpl_msg_info(__func__, "Identifying input frames");
00285     science_obj_frames = 
00286         hawki_extract_frameset(framelist, HAWKI_CALPRO_DIST_CORRECTED);
00287     if (science_obj_frames == NULL)
00288     {
00289         science_obj_frames =
00290                 hawki_extract_frameset(framelist, HAWKI_CALPRO_BKG_SUBTRACTED);
00291         if (science_obj_frames == NULL)
00292         {
00293             cpl_msg_error(__func__, "No science object frames provided (%s)",
00294                     HAWKI_CALPRO_DIST_CORRECTED);
00295             return -1 ;
00296         }
00297     }
00298     
00299     /* Get the detected "objects" frame */
00300     reference_obj_frames = 
00301         hawki_extract_frameset(framelist, HAWKI_CALPRO_OBJ_PARAM);
00302     if(cpl_frameset_get_size(reference_obj_frames) != 1)
00303     {
00304         cpl_msg_error(__func__, "One object parameters frame must be provided (%s)",
00305                 HAWKI_CALPRO_OBJ_PARAM);
00306         cpl_frameset_delete(science_obj_frames) ;
00307         if(reference_obj_frames != NULL)
00308             cpl_frameset_delete(reference_obj_frames);
00309         return -1 ;
00310     }
00311     
00312     /* Get the offsets refinement */
00313     refined_offsets = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *));
00314     correl          = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_vector *));
00315     for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00316     {
00317         refined_offsets[idet] = cpl_bivector_new
00318             (cpl_frameset_get_size(science_obj_frames));
00319         correl[idet] = cpl_vector_new
00320             (cpl_frameset_get_size(science_obj_frames));
00321     }
00322     if (hawki_step_refine_offsets_fine
00323             (science_obj_frames, reference_obj_frames, 
00324              refined_offsets, correl) == -1) 
00325    {
00326         cpl_msg_error(__func__, "Cannot refine the objects") ;
00327         cpl_frameset_delete(reference_obj_frames) ;
00328         cpl_frameset_delete(science_obj_frames) ;
00329         for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00330         {
00331             cpl_bivector_delete(refined_offsets[idet]);
00332             cpl_vector_delete(correl[idet]);
00333         }
00334         cpl_free(refined_offsets);
00335         cpl_free(correl);
00336         return -1 ;
00337     }
00338 
00339     /* Save the products */
00340     cpl_msg_info(__func__, "Save the products") ;
00341     if (hawki_step_refine_offsets_save
00342             (refined_offsets, correl, parlist, framelist) == -1)
00343     {
00344         cpl_msg_warning(__func__,"Some data could not be saved. "
00345                                  "Check permisions or disk space");
00346         cpl_frameset_delete(science_obj_frames);
00347         cpl_frameset_delete(reference_obj_frames);
00348         for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00349         {
00350             cpl_bivector_delete(refined_offsets[idet]);
00351             cpl_vector_delete(correl[idet]);
00352         }
00353         cpl_free(refined_offsets);
00354         cpl_free(correl);
00355         return -1 ;
00356     }
00357     
00358     /* Free and return */
00359     cpl_frameset_delete(science_obj_frames);
00360     cpl_frameset_delete(reference_obj_frames);
00361     for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00362     {
00363         cpl_bivector_delete(refined_offsets[idet]);
00364         cpl_vector_delete(correl[idet]);
00365     }
00366     cpl_free(refined_offsets);
00367     cpl_free(correl);
00368     
00369     /* Return */
00370     if (cpl_error_get_code())
00371     {
00372         cpl_msg_error(__func__,
00373                       "HAWK-I pipeline could not recover from previous errors");
00374         return -1 ;
00375     }
00376     else return 0 ;
00377 }
00378 
00379 int hawki_step_refine_offsets_retrieve_input_param
00380 (cpl_parameterlist  *  parlist)
00381 {
00382     cpl_parameter   *   par ;
00383     const char      *   sval ;
00384     par = NULL ;
00385     par = cpl_parameterlist_find
00386         (parlist, "hawki.hawki_step_refine_offsets.nbrightest");
00387     hawki_step_refine_offsets_config.nbrightest =
00388         cpl_parameter_get_int(par);
00389     par = cpl_parameterlist_find
00390         (parlist, "hawki.hawki_step_refine_offsets.xcorr");
00391     sval = cpl_parameter_get_string(par);
00392     if (sscanf(sval, "%d,%d,%d,%d",
00393                &hawki_step_refine_offsets_config.sx,
00394                &hawki_step_refine_offsets_config.sy,
00395                &hawki_step_refine_offsets_config.mx,
00396                &hawki_step_refine_offsets_config.my)!=4)
00397     {
00398         return -1;
00399     }
00400     return 0;
00401 }
00402 
00403 
00404 
00405 /*----------------------------------------------------------------------------*/
00410 /*----------------------------------------------------------------------------*/
00411 static int hawki_step_refine_offsets_fine
00412 (const cpl_frameset  *  science_obj_frames,
00413  const cpl_frameset  *  reference_obj_frames,
00414  cpl_bivector        ** refined_offsets,
00415  cpl_vector          ** correl)
00416 {
00417     cpl_imagelist    *   in ;
00418     cpl_bivector     *   nominal_offsets ;
00419     cpl_bivector     **  reference_objects;
00420     double           *   offs_est_x ;
00421     double           *   offs_est_y ;
00422     double               off_0_x;
00423     double               off_0_y;
00424     double               max_x, max_y ;
00425     int                  idet;
00426     int                  ioff;
00427     cpl_propertylist *   header;
00428     int                  nx;
00429     int                  ny;
00430 
00431     /* Get the nominal offsets from the header */
00432     cpl_msg_info(__func__,"Getting the nominal offsets");
00433     nominal_offsets = hawki_get_header_tel_offsets(science_obj_frames); 
00434     if (nominal_offsets  == NULL) 
00435     {
00436         cpl_msg_error(__func__, "Cannot load the header offsets") ;
00437         return -1;
00438     }
00439     offs_est_x = cpl_bivector_get_x_data(nominal_offsets);
00440     offs_est_y = cpl_bivector_get_y_data(nominal_offsets);
00441     
00442     /* Print the header offsets */
00443     cpl_msg_indent_more();
00444     for (ioff=0 ; ioff<cpl_bivector_get_size(nominal_offsets) ; ioff++) 
00445     {
00446         cpl_msg_info(__func__, "Telescope offsets (Frame %d): %g %g", ioff+1,
00447                 offs_est_x[ioff], offs_est_y[ioff]) ;
00448     }
00449     cpl_msg_indent_less();
00450     
00451     /* Get the size of the detectors of the first extension */
00452     header = cpl_propertylist_load
00453         (cpl_frame_get_filename
00454                 (cpl_frameset_get_first_const(science_obj_frames)), 1);
00455     nx = hawki_pfits_get_naxis1(header);
00456     ny = hawki_pfits_get_naxis2(header);
00457     cpl_propertylist_delete(header);
00458 
00459     /* Get the first offset to all offsets */
00460     off_0_x = offs_est_x[0];
00461     off_0_y = offs_est_y[0];
00462 
00463     /* Get the objects (anchor points)*/
00464     /* They are already in the "first image" reference system */
00465     reference_objects = 
00466         hawki_step_refine_offsets_read_select_objects(reference_obj_frames,
00467                                                       off_0_x,
00468                                                       off_0_y,
00469                                                       nx,
00470                                                       ny);
00471     if(reference_objects == NULL)
00472     {
00473         cpl_msg_error(__func__,"Error reading the reference objects");
00474         cpl_bivector_delete(nominal_offsets);
00475         return -1;
00476     }
00477 
00478     /* Subtract the first offset to all offsets */
00479     max_x = max_y = 0.0 ;
00480     for (ioff=1 ; ioff<cpl_bivector_get_size(nominal_offsets) ; ioff++) 
00481     {
00482         offs_est_x[ioff] -= off_0_x;
00483         offs_est_y[ioff] -= off_0_y;
00484         if (fabs(offs_est_x[ioff]) > max_x) max_x = fabs(offs_est_x[ioff]) ;
00485         if (fabs(offs_est_y[ioff]) > max_y) max_y = fabs(offs_est_y[ioff]) ;
00486     }
00487     offs_est_x[0] = offs_est_y[0] = 0.00 ;
00488 
00489     /* Get the opposite offsets. This is to change from 
00490      * telescope convention to cpl convention */ 
00491     cpl_vector_multiply_scalar(cpl_bivector_get_x(nominal_offsets), -1.0);
00492     cpl_vector_multiply_scalar(cpl_bivector_get_y(nominal_offsets), -1.0);
00493 
00494     /* Loop on the detectors */
00495     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00496     {
00497         cpl_msg_info(__func__, "Working on detector number %d", idet+1) ;
00498         cpl_msg_indent_more();
00499         
00500         /* Load the input data */
00501         cpl_msg_info(__func__, "Loading the input data") ;
00502         cpl_msg_indent_more() ;
00503         if ((in = hawki_load_detector(science_obj_frames,
00504                                   idet+1, CPL_TYPE_FLOAT)) == NULL) 
00505         {
00506             cpl_msg_error(__func__, "Cannot load chip %d", idet+1) ;
00507             cpl_bivector_delete(nominal_offsets) ;
00508             for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00509             {
00510                 cpl_bivector_delete(reference_objects[idet]);
00511             }
00512             cpl_free(reference_objects);
00513             cpl_msg_indent_less() ;
00514             cpl_msg_indent_less() ;
00515             return -1;
00516         }
00517 
00518         /* Get the refinement */
00519         cpl_msg_info(__func__, "Getting the refinement");
00520         cpl_msg_indent_more() ;
00521         if (hawki_geom_refine_images_offsets
00522                 (in, 
00523                  nominal_offsets,
00524                  reference_objects[idet],
00525                  hawki_step_refine_offsets_config.sx,
00526                  hawki_step_refine_offsets_config.sy,
00527                  hawki_step_refine_offsets_config.mx,
00528                  hawki_step_refine_offsets_config.my,
00529                  refined_offsets[idet],
00530                  correl[idet]) == -1)
00531         {
00532             cpl_msg_error(__func__, "Cannot apply the shift and add") ;
00533             cpl_imagelist_delete(in) ;
00534             cpl_bivector_delete(nominal_offsets) ;
00535             for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00536                 cpl_bivector_delete(reference_objects[idet]);
00537             cpl_free(reference_objects);
00538             cpl_msg_indent_less() ;
00539             cpl_msg_indent_less() ;
00540             return -1;
00541         }
00542         
00543         /* Convert to "telescope criteria" */
00544         /* Also add the offset of the first image */
00545         cpl_vector_multiply_scalar
00546             (cpl_bivector_get_x(refined_offsets[idet]), -1.0);
00547         cpl_vector_multiply_scalar
00548             (cpl_bivector_get_y(refined_offsets[idet]), -1.0);
00549         cpl_vector_add_scalar
00550             (cpl_bivector_get_x(refined_offsets[idet]), off_0_x);
00551         cpl_vector_add_scalar
00552             (cpl_bivector_get_y(refined_offsets[idet]), off_0_y);
00553 
00554         /* Print the new offsets */
00555         for (ioff=0 ; ioff<cpl_bivector_get_size(refined_offsets[idet]); ioff++) 
00556         {
00557             cpl_msg_info(__func__,"Refined telescope offsets (Frame %d): %g %g",
00558                          ioff+1,
00559                          cpl_vector_get(cpl_bivector_get_x
00560                                         (refined_offsets[idet]), ioff),
00561                          cpl_vector_get(cpl_bivector_get_y
00562                                         (refined_offsets[idet]), ioff));
00563         }
00564         cpl_imagelist_delete(in) ;
00565         cpl_msg_indent_less() ;
00566         cpl_msg_indent_less() ;
00567     }
00568     
00569     /* Freeing */
00570     cpl_bivector_delete(nominal_offsets);
00571     for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00572         cpl_bivector_delete(reference_objects[idet]);
00573     cpl_free(reference_objects);
00574 
00575     return 0;
00576 }
00577 
00578 /*----------------------------------------------------------------------------*/
00586 /*----------------------------------------------------------------------------*/
00587 
00588 static int hawki_step_refine_offsets_save
00589 (cpl_bivector      ** refined_offsets,
00590  cpl_vector        ** correlations,
00591  cpl_parameterlist *  recipe_parlist,
00592  cpl_frameset      *  recipe_frameset)
00593 {
00594     cpl_table        ** offset_tables;
00595     int                 ioff;
00596     int                 idet;
00597     int                 noff;
00598     const char       *  recipe_name = "hawki_step_refine_offsets";
00599     cpl_errorstate      error_prevstate = cpl_errorstate_get();
00600     
00601     
00602     /* Convert the offsets to a table */
00603     offset_tables = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *));
00604     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00605     {
00606         offset_tables[idet] = cpl_table_new
00607             (cpl_bivector_get_size(refined_offsets[idet]));
00608         cpl_table_new_column(offset_tables[idet], 
00609                              HAWKI_COL_OFFSET_X, CPL_TYPE_FLOAT);
00610         cpl_table_set_column_unit(offset_tables[idet],HAWKI_COL_OFFSET_X,"pix");
00611         cpl_table_new_column(offset_tables[idet], 
00612                              HAWKI_COL_OFFSET_Y, CPL_TYPE_FLOAT);
00613         cpl_table_set_column_unit(offset_tables[idet],HAWKI_COL_OFFSET_Y,"pix");
00614         cpl_table_new_column(offset_tables[idet], 
00615                              HAWKI_COL_CORRELATION, CPL_TYPE_FLOAT);
00616         noff = cpl_bivector_get_size(refined_offsets[idet]);
00617         for(ioff = 0; ioff < noff; ++ioff)
00618         {
00619             double xoffset, yoffset, corr;
00620             xoffset = cpl_vector_get
00621                 (cpl_bivector_get_x(refined_offsets[idet]), ioff);
00622             yoffset = cpl_vector_get
00623                 (cpl_bivector_get_y(refined_offsets[idet]), ioff);
00624             corr    = cpl_vector_get(correlations[idet], ioff);
00625             cpl_table_set
00626                 (offset_tables[idet], HAWKI_COL_OFFSET_X, ioff, xoffset);
00627             cpl_table_set
00628                 (offset_tables[idet], HAWKI_COL_OFFSET_Y, ioff, yoffset);
00629             cpl_table_set
00630                 (offset_tables[idet], HAWKI_COL_CORRELATION, ioff, corr);
00631         }
00632     }
00633     
00634     /* Write the table with the statistics */
00635     if (hawki_tables_save(recipe_frameset, 
00636                           recipe_parlist,
00637                           recipe_frameset,
00638                           (const cpl_table **)offset_tables,
00639                           recipe_name,
00640                           HAWKI_CALPRO_OFFSETS,
00641                           HAWKI_PROTYPE_OFFSETS,
00642                           NULL,
00643                           NULL,
00644                           "hawki_step_refine_offsets.fits") != CPL_ERROR_NONE) 
00645     {
00646         cpl_msg_error(__func__, "Cannot save the first extension table") ;
00647         for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00648             cpl_table_delete(offset_tables[idet]);
00649         cpl_free(offset_tables);
00650         return -1 ;
00651     }
00652 
00653     /* Free and return */
00654     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00655         cpl_table_delete(offset_tables[idet]);
00656     cpl_free(offset_tables);
00657     if(!cpl_errorstate_is_equal(error_prevstate))
00658     {
00659         cpl_errorstate_set(CPL_ERROR_NONE);
00660         return -1;
00661     }
00662     return  0;
00663 }
00664 
00665 /*----------------------------------------------------------------------------*/
00680 /*----------------------------------------------------------------------------*/
00681 static cpl_bivector ** hawki_step_refine_offsets_read_select_objects
00682 (const cpl_frameset *  reference_obj_frames,
00683  double                first_image_off_x,
00684  double                first_image_off_y,
00685  int                   nx,
00686  int                   ny)
00687 {
00688     const cpl_frame        *  reference_obj_frame;
00689     cpl_table              ** obj_param;
00690     cpl_propertylist       *  sort_column;
00691     cpl_bivector           ** reference_objects;
00692     int                    idet;
00693     
00694     /* Get the objects */
00695     cpl_msg_info(__func__,"Getting the reference object positions");
00696     reference_obj_frame = cpl_frameset_get_first_const(reference_obj_frames);
00697     obj_param = hawki_load_tables(reference_obj_frame);
00698     if(obj_param == NULL)
00699     {
00700         cpl_msg_error(__func__,"Could not read the reference objects parameters");
00701         return NULL;
00702     }
00703     
00704     /* Create the sorting criteria: by flux */
00705     sort_column = cpl_propertylist_new();
00706     cpl_propertylist_append_bool(sort_column, HAWKI_COL_OBJ_FLUX, CPL_TRUE);
00707 
00708     /* Allocate partially the reference objects */
00709     reference_objects = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *));
00710     
00711     /* Loop on detectors */
00712     cpl_msg_indent_more();
00713     for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00714     {
00715         cpl_propertylist * objects_plist;
00716         cpl_vector       * obj_x;
00717         cpl_vector       * obj_y;
00718         int                nobj;
00719         int                nselect;
00720         int                iobj;
00721         int                ext_nb;
00722         double             reference_offset_x;
00723         double             reference_offset_y;
00724         
00725         /* Get the global offset */
00726         /* This allows to know which is the reference point of the detected 
00727          * objects positions (which are referred in general to the combined image */
00728         ext_nb=hawki_get_ext_from_detector
00729             (cpl_frame_get_filename(reference_obj_frame), idet + 1);
00730         objects_plist = cpl_propertylist_load
00731              (cpl_frame_get_filename(reference_obj_frame), ext_nb);
00732         reference_offset_x =
00733             hawki_pfits_get_comb_cumoffsetx(objects_plist);
00734         reference_offset_y = 
00735             hawki_pfits_get_comb_cumoffsety(objects_plist);
00736         if(cpl_error_get_code() != CPL_ERROR_NONE)
00737         {
00738             cpl_msg_error(__func__,"Could not find keywords "
00739                           "ESO QC COMBINED CUMOFFSETX,Y in reference objects frame");            
00740             cpl_propertylist_delete(objects_plist);
00741             cpl_propertylist_delete(sort_column);
00742             return NULL;
00743         }
00744         cpl_msg_info(__func__,"Objects offsets wrt telescope: %f %f", 
00745                      reference_offset_x, reference_offset_y);
00746         cpl_propertylist_delete(objects_plist);
00747         
00748         /* Sort the table by flux */
00749         cpl_table_sort(obj_param[idet], sort_column);
00750         nobj = cpl_table_get_nrow(obj_param[idet]); 
00751         
00752         /* Allocate objects vector */
00753         reference_objects[idet] = cpl_bivector_new(nobj);
00754         obj_x = cpl_bivector_get_x(reference_objects[idet]);
00755         obj_y = cpl_bivector_get_y(reference_objects[idet]);
00756         cpl_msg_info(__func__, "Number of objects in chip %d: %d", idet+1,nobj);
00757         
00758         /* Keep only those objects within the first image */
00759         cpl_table_unselect_all(obj_param[idet]);
00760         for(iobj = 0 ; iobj < nobj; ++iobj)
00761         {
00762             double xpos_orig = cpl_table_get
00763                 (obj_param[idet], HAWKI_COL_OBJ_POSX, iobj, NULL);
00764             double ypos_orig = cpl_table_get
00765                 (obj_param[idet], HAWKI_COL_OBJ_POSY, iobj, NULL);
00766             double xpos_rel = xpos_orig - reference_offset_x + first_image_off_x;
00767             double ypos_rel = ypos_orig - reference_offset_y + first_image_off_y;
00768             if(xpos_rel < 0.0 || xpos_rel >= nx ||
00769                ypos_rel < 0.0 || ypos_rel >= ny)
00770             {
00771                 cpl_table_select_row(obj_param[idet], iobj);
00772             }
00773         }
00774         cpl_table_erase_selected(obj_param[idet]);
00775         nobj = cpl_table_get_nrow(obj_param[idet]);
00776         cpl_msg_info(__func__, "Number of objects within limits of detector "
00777                                "in chip %d: %d", idet+1,nobj);
00778         
00779         /* Apply the flux criteria */
00780         nselect = hawki_step_refine_offsets_config.nbrightest;
00781         if(nselect < 0 || nselect > nobj)
00782             nselect = nobj;
00783         cpl_msg_info(__func__, "Number of selected objects: %d", nselect);
00784         for(iobj = 0 ; iobj < nselect; ++iobj)
00785         {
00786             double xpos_orig = cpl_table_get
00787                 (obj_param[idet], HAWKI_COL_OBJ_POSX, iobj, NULL);
00788             double ypos_orig = cpl_table_get
00789                 (obj_param[idet], HAWKI_COL_OBJ_POSY, iobj, NULL);
00790 
00791             cpl_vector_set
00792                 (obj_x, iobj, xpos_orig - reference_offset_x + first_image_off_x);
00793             cpl_vector_set
00794                 (obj_y, iobj, ypos_orig - reference_offset_y + first_image_off_y);
00795             cpl_msg_debug(__func__,"Using anchor point at %f,%f",
00796                           cpl_vector_get(obj_x,iobj),
00797                           cpl_vector_get(obj_y,iobj));
00798             
00799         }
00800         cpl_vector_set_size(obj_x, nselect);
00801         cpl_vector_set_size(obj_y, nselect);
00802         
00803     }
00804     cpl_msg_indent_less();
00805     
00806     /* Freeing */
00807     for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++) 
00808         cpl_table_delete(obj_param[idet]);
00809     cpl_free(obj_param);
00810     cpl_propertylist_delete(sort_column);
00811     
00812     return reference_objects;
00813 }