HAWKI Pipeline Reference Manual 1.8.2

hawki_step_refine_offsets.c

00001 /* $Id: hawki_step_refine_offsets.c,v 1.16 2011/03/09 15:06: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: 2011/03/09 15:06:45 $
00024  * $Revision: 1.16 $
00025  * $Name: hawki-1_8_2 $
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 
00183     /* Fill the parameters list */
00184     /* --xcorr */
00185     p = cpl_parameter_new_value("hawki.hawki_step_refine_offsets.xcorr",
00186                                 CPL_TYPE_STRING,
00187                                 "Cross correlation search and measure sizes",
00188                                 "hawki.hawki_step_refine_offsets",
00189                                 "20,20,25,25") ;
00190     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcorr") ;
00191     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00192     cpl_parameterlist_append(recipe->parameters, p) ;
00193 
00194     /* --nbrightest */
00195     p = cpl_parameter_new_value("hawki.hawki_step_refine_offsets.nbrightest",
00196                                 CPL_TYPE_INT,
00197                                 "Number of brightest objects to use",
00198                                 "hawki.hawki_step_refine_offsets",
00199                                 3);
00200     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nbrightest") ;
00201     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00202     cpl_parameterlist_append(recipe->parameters, p) ;
00203 
00204     /* Return */
00205     return 0;
00206 }
00207 
00208 /*----------------------------------------------------------------------------*/
00214 /*----------------------------------------------------------------------------*/
00215 static int hawki_step_refine_offsets_exec(cpl_plugin * plugin)
00216 {
00217     cpl_recipe  *   recipe ;
00218 
00219     /* Get the recipe out of the plugin */
00220     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00221         recipe = (cpl_recipe *)plugin ;
00222     else return -1 ;
00223 
00224     /* Issue a banner */
00225     hawki_print_banner();
00226 
00227     return hawki_step_refine_offsets(recipe->parameters, recipe->frames) ;
00228 }
00229 
00230 /*----------------------------------------------------------------------------*/
00236 /*----------------------------------------------------------------------------*/
00237 static int hawki_step_refine_offsets_destroy(cpl_plugin * plugin)
00238 {
00239     cpl_recipe  *   recipe ;
00240 
00241     /* Get the recipe out of the plugin */
00242     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00243         recipe = (cpl_recipe *)plugin ;
00244     else return -1 ;
00245 
00246     cpl_parameterlist_delete(recipe->parameters) ;
00247     return 0 ;
00248 }
00249 
00250 /*----------------------------------------------------------------------------*/
00257 /*----------------------------------------------------------------------------*/
00258 static int hawki_step_refine_offsets(
00259         cpl_parameterlist   *   parlist, 
00260         cpl_frameset        *   framelist)
00261 {
00262     cpl_frameset    *   science_obj_frames ;
00263     cpl_frameset    *   reference_obj_frames ;
00264     cpl_bivector    **  refined_offsets;
00265     cpl_vector      **  correl;
00266     int                 idet;
00267 
00268     /* Retrieve input parameters */
00269     if(hawki_step_refine_offsets_retrieve_input_param(parlist))
00270     {
00271         cpl_msg_error(__func__, "Wrong parameters");
00272         return -1;
00273     }
00274 
00275     /* Identify the RAW and CALIB frames in the input frameset */
00276     if (hawki_dfs_set_groups(framelist)) {
00277         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00278         return -1 ;
00279     }
00280 
00281     /* Get the object images frames */
00282     cpl_msg_info(__func__, "Identifying input frames");
00283     science_obj_frames = 
00284         hawki_extract_frameset(framelist, HAWKI_CALPRO_DIST_CORRECTED);
00285     if (science_obj_frames == NULL)
00286     {
00287         science_obj_frames =
00288                 hawki_extract_frameset(framelist, HAWKI_CALPRO_BKG_SUBTRACTED);
00289         if (science_obj_frames == NULL)
00290         {
00291             cpl_msg_error(__func__, "No science object frames provided (%s)",
00292                     HAWKI_CALPRO_DIST_CORRECTED);
00293             return -1 ;
00294         }
00295     }
00296     
00297     /* Get the detected "objects" frame */
00298     reference_obj_frames = 
00299         hawki_extract_frameset(framelist, HAWKI_CALPRO_OBJ_PARAM);
00300     if(cpl_frameset_get_size(reference_obj_frames) != 1)
00301     {
00302         cpl_msg_error(__func__, "One object parameters frame must be provided (%s)",
00303                 HAWKI_CALPRO_OBJ_PARAM);
00304         cpl_frameset_delete(science_obj_frames) ;
00305         if(reference_obj_frames != NULL)
00306             cpl_frameset_delete(reference_obj_frames);
00307         return -1 ;
00308     }
00309     
00310     /* Get the offsets refinement */
00311     refined_offsets = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *));
00312     correl          = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_vector *));
00313     for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00314     {
00315         refined_offsets[idet] = cpl_bivector_new
00316             (cpl_frameset_get_size(science_obj_frames));
00317         correl[idet] = cpl_vector_new
00318             (cpl_frameset_get_size(science_obj_frames));
00319     }
00320     if (hawki_step_refine_offsets_fine
00321             (science_obj_frames, reference_obj_frames, 
00322              refined_offsets, correl) == -1) 
00323    {
00324         cpl_msg_error(__func__, "Cannot refine the objects") ;
00325         cpl_frameset_delete(reference_obj_frames) ;
00326         cpl_frameset_delete(science_obj_frames) ;
00327         for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00328         {
00329             cpl_bivector_delete(refined_offsets[idet]);
00330             cpl_vector_delete(correl[idet]);
00331         }
00332         cpl_free(refined_offsets);
00333         cpl_free(correl);
00334         return -1 ;
00335     }
00336 
00337     /* Save the products */
00338     cpl_msg_info(__func__, "Save the products") ;
00339     if (hawki_step_refine_offsets_save
00340             (refined_offsets, correl, parlist, framelist) == -1)
00341     {
00342         cpl_msg_warning(__func__,"Some data could not be saved. "
00343                                  "Check permisions or disk space");
00344         cpl_frameset_delete(science_obj_frames);
00345         cpl_frameset_delete(reference_obj_frames);
00346         for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00347         {
00348             cpl_bivector_delete(refined_offsets[idet]);
00349             cpl_vector_delete(correl[idet]);
00350         }
00351         cpl_free(refined_offsets);
00352         cpl_free(correl);
00353         return -1 ;
00354     }
00355     
00356     /* Free and return */
00357     cpl_frameset_delete(science_obj_frames);
00358     cpl_frameset_delete(reference_obj_frames);
00359     for(idet = 0 ; idet < HAWKI_NB_DETECTORS; ++idet)
00360     {
00361         cpl_bivector_delete(refined_offsets[idet]);
00362         cpl_vector_delete(correl[idet]);
00363     }
00364     cpl_free(refined_offsets);
00365     cpl_free(correl);
00366     
00367     /* Return */
00368     if (cpl_error_get_code())
00369     {
00370         cpl_msg_error(__func__,
00371                       "HAWK-I pipeline could not recover from previous errors");
00372         return -1 ;
00373     }
00374     else return 0 ;
00375 }
00376 
00377 int hawki_step_refine_offsets_retrieve_input_param
00378 (cpl_parameterlist  *  parlist)
00379 {
00380     cpl_parameter   *   par ;
00381     const char      *   sval ;
00382     par = NULL ;
00383     par = cpl_parameterlist_find
00384         (parlist, "hawki.hawki_step_refine_offsets.nbrightest");
00385     hawki_step_refine_offsets_config.nbrightest =
00386         cpl_parameter_get_int(par);
00387     par = cpl_parameterlist_find
00388         (parlist, "hawki.hawki_step_refine_offsets.xcorr");
00389     sval = cpl_parameter_get_string(par);
00390     if (sscanf(sval, "%d,%d,%d,%d",
00391                &hawki_step_refine_offsets_config.sx,
00392                &hawki_step_refine_offsets_config.sy,
00393                &hawki_step_refine_offsets_config.mx,
00394                &hawki_step_refine_offsets_config.my)!=4)
00395     {
00396         return -1;
00397     }
00398     return 0;
00399 }
00400 
00401 
00402 
00403 /*----------------------------------------------------------------------------*/
00408 /*----------------------------------------------------------------------------*/
00409 static int hawki_step_refine_offsets_fine
00410 (const cpl_frameset  *  science_obj_frames,
00411  const cpl_frameset  *  reference_obj_frames,
00412  cpl_bivector        ** refined_offsets,
00413  cpl_vector          ** correl)
00414 {
00415     cpl_imagelist    *   in ;
00416     cpl_bivector     *   nominal_offsets ;
00417     cpl_bivector     **  reference_objects;
00418     double           *   offs_est_x ;
00419     double           *   offs_est_y ;
00420     double               off_0_x;
00421     double               off_0_y;
00422     double               max_x, max_y ;
00423     int                  idet;
00424     int                  ioff;
00425     cpl_propertylist *   header;
00426     int                  nx;
00427     int                  ny;
00428 
00429     /* Get the nominal offsets from the header */
00430     cpl_msg_info(__func__,"Getting the nominal offsets");
00431     nominal_offsets = hawki_get_header_tel_offsets(science_obj_frames); 
00432     if (nominal_offsets  == NULL) 
00433     {
00434         cpl_msg_error(__func__, "Cannot load the header offsets") ;
00435         return -1;
00436     }
00437     offs_est_x = cpl_bivector_get_x_data(nominal_offsets);
00438     offs_est_y = cpl_bivector_get_y_data(nominal_offsets);
00439     
00440     /* Print the header offsets */
00441     cpl_msg_indent_more();
00442     for (ioff=0 ; ioff<cpl_bivector_get_size(nominal_offsets) ; ioff++) 
00443     {
00444         cpl_msg_info(__func__, "Telescope offsets (Frame %d): %g %g", ioff+1,
00445                 offs_est_x[ioff], offs_est_y[ioff]) ;
00446     }
00447     cpl_msg_indent_less();
00448     
00449     /* Get the size of the detectors of the first extension */
00450     header = cpl_propertylist_load
00451         (cpl_frame_get_filename
00452                 (cpl_frameset_get_first_const(science_obj_frames)), 1);
00453     nx = hawki_pfits_get_naxis1(header);
00454     ny = hawki_pfits_get_naxis2(header);
00455     cpl_propertylist_delete(header);
00456 
00457     /* Get the first offset to all offsets */
00458     off_0_x = offs_est_x[0];
00459     off_0_y = offs_est_y[0];
00460 
00461     /* Get the objects (anchor points)*/
00462     /* They are already in the "first image" reference system */
00463     reference_objects = 
00464         hawki_step_refine_offsets_read_select_objects(reference_obj_frames,
00465                                                       off_0_x,
00466                                                       off_0_y,
00467                                                       nx,
00468                                                       ny);
00469     if(reference_objects == NULL)
00470     {
00471         cpl_msg_error(__func__,"Error reading the reference objects");
00472         cpl_bivector_delete(nominal_offsets);
00473         return -1;
00474     }
00475 
00476     /* Subtract the first offset to all offsets */
00477     max_x = max_y = 0.0 ;
00478     for (ioff=1 ; ioff<cpl_bivector_get_size(nominal_offsets) ; ioff++) 
00479     {
00480         offs_est_x[ioff] -= off_0_x;
00481         offs_est_y[ioff] -= off_0_y;
00482         if (fabs(offs_est_x[ioff]) > max_x) max_x = fabs(offs_est_x[ioff]) ;
00483         if (fabs(offs_est_y[ioff]) > max_y) max_y = fabs(offs_est_y[ioff]) ;
00484     }
00485     offs_est_x[0] = offs_est_y[0] = 0.00 ;
00486 
00487     /* Get the opposite offsets. This is to change from 
00488      * telescope convention to cpl convention */ 
00489     cpl_vector_multiply_scalar(cpl_bivector_get_x(nominal_offsets), -1.0);
00490     cpl_vector_multiply_scalar(cpl_bivector_get_y(nominal_offsets), -1.0);
00491 
00492     /* Loop on the detectors */
00493     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00494     {
00495         cpl_msg_info(__func__, "Working on detector number %d", idet+1) ;
00496         cpl_msg_indent_more();
00497         
00498         /* Load the input data */
00499         cpl_msg_info(__func__, "Loading the input data") ;
00500         cpl_msg_indent_more() ;
00501         if ((in = hawki_load_detector(science_obj_frames,
00502                                   idet+1, CPL_TYPE_FLOAT)) == NULL) 
00503         {
00504             cpl_msg_error(__func__, "Cannot load chip %d", idet+1) ;
00505             cpl_bivector_delete(nominal_offsets) ;
00506             for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00507             {
00508                 cpl_bivector_delete(reference_objects[idet]);
00509             }
00510             cpl_free(reference_objects);
00511             cpl_msg_indent_less() ;
00512             cpl_msg_indent_less() ;
00513             return -1;
00514         }
00515 
00516         /* Get the refinement */
00517         cpl_msg_info(__func__, "Getting the refinement");
00518         cpl_msg_indent_more() ;
00519         if (hawki_geom_refine_images_offsets
00520                 (in, 
00521                  nominal_offsets,
00522                  reference_objects[idet],
00523                  hawki_step_refine_offsets_config.sx,
00524                  hawki_step_refine_offsets_config.sy,
00525                  hawki_step_refine_offsets_config.mx,
00526                  hawki_step_refine_offsets_config.my,
00527                  refined_offsets[idet],
00528                  correl[idet]) == -1)
00529         {
00530             cpl_msg_error(__func__, "Cannot apply the shift and add") ;
00531             cpl_imagelist_delete(in) ;
00532             cpl_bivector_delete(nominal_offsets) ;
00533             for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00534                 cpl_bivector_delete(reference_objects[idet]);
00535             cpl_free(reference_objects);
00536             cpl_msg_indent_less() ;
00537             cpl_msg_indent_less() ;
00538             return -1;
00539         }
00540         
00541         /* Convert to "telescope criteria" */
00542         /* Also add the offset of the first image */
00543         cpl_vector_multiply_scalar
00544             (cpl_bivector_get_x(refined_offsets[idet]), -1.0);
00545         cpl_vector_multiply_scalar
00546             (cpl_bivector_get_y(refined_offsets[idet]), -1.0);
00547         cpl_vector_add_scalar
00548             (cpl_bivector_get_x(refined_offsets[idet]), off_0_x);
00549         cpl_vector_add_scalar
00550             (cpl_bivector_get_y(refined_offsets[idet]), off_0_y);
00551 
00552         /* Print the new offsets */
00553         for (ioff=0 ; ioff<cpl_bivector_get_size(refined_offsets[idet]); ioff++) 
00554         {
00555             cpl_msg_info(__func__,"Refined telescope offsets (Frame %d): %g %g",
00556                          ioff+1,
00557                          cpl_vector_get(cpl_bivector_get_x
00558                                         (refined_offsets[idet]), ioff),
00559                          cpl_vector_get(cpl_bivector_get_y
00560                                         (refined_offsets[idet]), ioff));
00561         }
00562         cpl_imagelist_delete(in) ;
00563         cpl_msg_indent_less() ;
00564         cpl_msg_indent_less() ;
00565     }
00566     
00567     /* Freeing */
00568     cpl_bivector_delete(nominal_offsets);
00569     for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00570         cpl_bivector_delete(reference_objects[idet]);
00571     cpl_free(reference_objects);
00572 
00573     return 0;
00574 }
00575 
00576 /*----------------------------------------------------------------------------*/
00584 /*----------------------------------------------------------------------------*/
00585 
00586 static int hawki_step_refine_offsets_save
00587 (cpl_bivector      ** refined_offsets,
00588  cpl_vector        ** correlations,
00589  cpl_parameterlist *  recipe_parlist,
00590  cpl_frameset      *  recipe_frameset)
00591 {
00592     cpl_table        ** offset_tables;
00593     int                 ioff;
00594     int                 idet;
00595     int                 noff;
00596     const char       *  recipe_name = "hawki_step_refine_offsets";
00597     cpl_errorstate      error_prevstate = cpl_errorstate_get();
00598     
00599     
00600     /* Convert the offsets to a table */
00601     offset_tables = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *));
00602     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00603     {
00604         offset_tables[idet] = cpl_table_new
00605             (cpl_bivector_get_size(refined_offsets[idet]));
00606         cpl_table_new_column(offset_tables[idet], 
00607                              HAWKI_COL_OFFSET_X, CPL_TYPE_FLOAT);
00608         cpl_table_set_column_unit(offset_tables[idet],HAWKI_COL_OFFSET_X,"pix");
00609         cpl_table_new_column(offset_tables[idet], 
00610                              HAWKI_COL_OFFSET_Y, CPL_TYPE_FLOAT);
00611         cpl_table_set_column_unit(offset_tables[idet],HAWKI_COL_OFFSET_Y,"pix");
00612         cpl_table_new_column(offset_tables[idet], 
00613                              HAWKI_COL_CORRELATION, CPL_TYPE_FLOAT);
00614         noff = cpl_bivector_get_size(refined_offsets[idet]);
00615         for(ioff = 0; ioff < noff; ++ioff)
00616         {
00617             double xoffset, yoffset, corr;
00618             xoffset = cpl_vector_get
00619                 (cpl_bivector_get_x(refined_offsets[idet]), ioff);
00620             yoffset = cpl_vector_get
00621                 (cpl_bivector_get_y(refined_offsets[idet]), ioff);
00622             corr    = cpl_vector_get(correlations[idet], ioff);
00623             cpl_table_set
00624                 (offset_tables[idet], HAWKI_COL_OFFSET_X, ioff, xoffset);
00625             cpl_table_set
00626                 (offset_tables[idet], HAWKI_COL_OFFSET_Y, ioff, yoffset);
00627             cpl_table_set
00628                 (offset_tables[idet], HAWKI_COL_CORRELATION, ioff, corr);
00629         }
00630     }
00631     
00632     /* Write the table with the statistics */
00633     if (hawki_tables_save(recipe_frameset, 
00634                           recipe_parlist,
00635                           recipe_frameset,
00636                           (const cpl_table **)offset_tables,
00637                           recipe_name,
00638                           HAWKI_CALPRO_OFFSETS,
00639                           HAWKI_PROTYPE_OFFSETS,
00640                           NULL,
00641                           NULL,
00642                           "hawki_step_refine_offsets.fits") != CPL_ERROR_NONE) 
00643     {
00644         cpl_msg_error(__func__, "Cannot save the first extension table") ;
00645         for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00646             cpl_table_delete(offset_tables[idet]);
00647         cpl_free(offset_tables);
00648         return -1 ;
00649     }
00650 
00651     /* Free and return */
00652     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00653         cpl_table_delete(offset_tables[idet]);
00654     cpl_free(offset_tables);
00655     if(!cpl_errorstate_is_equal(error_prevstate))
00656     {
00657         cpl_errorstate_set(CPL_ERROR_NONE);
00658         return -1;
00659     }
00660     return  0;
00661 }
00662 
00663 /*----------------------------------------------------------------------------*/
00678 /*----------------------------------------------------------------------------*/
00679 static cpl_bivector ** hawki_step_refine_offsets_read_select_objects
00680 (const cpl_frameset *  reference_obj_frames,
00681  double                first_image_off_x,
00682  double                first_image_off_y,
00683  int                   nx,
00684  int                   ny)
00685 {
00686     const cpl_frame        *  reference_obj_frame;
00687     cpl_table              ** obj_param;
00688     cpl_propertylist       *  sort_column;
00689     cpl_bivector           ** reference_objects;
00690     int                    idet;
00691     
00692     /* Get the objects */
00693     cpl_msg_info(__func__,"Getting the reference object positions");
00694     reference_obj_frame = cpl_frameset_get_first_const(reference_obj_frames);
00695     obj_param = hawki_load_tables(reference_obj_frame);
00696     if(obj_param == NULL)
00697     {
00698         cpl_msg_error(__func__,"Could not read the reference objects parameters");
00699         return NULL;
00700     }
00701     
00702     /* Create the sorting criteria: by flux */
00703     sort_column = cpl_propertylist_new();
00704     cpl_propertylist_append_bool(sort_column, HAWKI_COL_OBJ_FLUX, CPL_TRUE);
00705 
00706     /* Allocate partially the reference objects */
00707     reference_objects = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_bivector *));
00708     
00709     /* Loop on detectors */
00710     cpl_msg_indent_more();
00711     for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++)
00712     {
00713         cpl_propertylist * objects_plist;
00714         cpl_vector       * obj_x;
00715         cpl_vector       * obj_y;
00716         int                nobj;
00717         int                nselect;
00718         int                iobj;
00719         int                ext_nb;
00720         double             reference_offset_x;
00721         double             reference_offset_y;
00722         
00723         /* Get the global offset */
00724         /* This allows to know which is the reference point of the detected 
00725          * objects positions (which are referred in general to the combined image */
00726         ext_nb=hawki_get_ext_from_detector
00727             (cpl_frame_get_filename(reference_obj_frame), idet + 1);
00728         objects_plist = cpl_propertylist_load
00729              (cpl_frame_get_filename(reference_obj_frame), ext_nb);
00730         reference_offset_x =
00731             hawki_pfits_get_comb_cumoffsetx(objects_plist);
00732         reference_offset_y = 
00733             hawki_pfits_get_comb_cumoffsety(objects_plist);
00734         if(cpl_error_get_code() != CPL_ERROR_NONE)
00735         {
00736             cpl_msg_error(__func__,"Could not find keywords "
00737                           "ESO QC COMBINED CUMOFFSETX,Y in reference objects frame");            
00738             cpl_propertylist_delete(objects_plist);
00739             cpl_propertylist_delete(sort_column);
00740             return NULL;
00741         }
00742         cpl_msg_info(__func__,"Objects offsets wrt telescope: %f %f", 
00743                      reference_offset_x, reference_offset_y);
00744         cpl_propertylist_delete(objects_plist);
00745         
00746         /* Sort the table by flux */
00747         cpl_table_sort(obj_param[idet], sort_column);
00748         nobj = cpl_table_get_nrow(obj_param[idet]); 
00749         
00750         /* Allocate objects vector */
00751         reference_objects[idet] = cpl_bivector_new(nobj);
00752         obj_x = cpl_bivector_get_x(reference_objects[idet]);
00753         obj_y = cpl_bivector_get_y(reference_objects[idet]);
00754         cpl_msg_info(__func__, "Number of objects in chip %d: %d", idet+1,nobj);
00755         
00756         /* Keep only those objects within the first image */
00757         cpl_table_unselect_all(obj_param[idet]);
00758         for(iobj = 0 ; iobj < nobj; ++iobj)
00759         {
00760             double xpos_orig = cpl_table_get
00761                 (obj_param[idet], HAWKI_COL_OBJ_POSX, iobj, NULL);
00762             double ypos_orig = cpl_table_get
00763                 (obj_param[idet], HAWKI_COL_OBJ_POSY, iobj, NULL);
00764             double xpos_rel = xpos_orig - reference_offset_x + first_image_off_x;
00765             double ypos_rel = ypos_orig - reference_offset_y + first_image_off_y;
00766             if(xpos_rel < 0.0 || xpos_rel >= nx ||
00767                ypos_rel < 0.0 || ypos_rel >= ny)
00768             {
00769                 cpl_table_select_row(obj_param[idet], iobj);
00770             }
00771         }
00772         cpl_table_erase_selected(obj_param[idet]);
00773         nobj = cpl_table_get_nrow(obj_param[idet]);
00774         cpl_msg_info(__func__, "Number of objects within limits of detector "
00775                                "in chip %d: %d", idet+1,nobj);
00776         
00777         /* Apply the flux criteria */
00778         nselect = hawki_step_refine_offsets_config.nbrightest;
00779         if(nselect < 0 || nselect > nobj)
00780             nselect = nobj;
00781         cpl_msg_info(__func__, "Number of selected objects: %d", nselect);
00782         for(iobj = 0 ; iobj < nselect; ++iobj)
00783         {
00784             double xpos_orig = cpl_table_get
00785                 (obj_param[idet], HAWKI_COL_OBJ_POSX, iobj, NULL);
00786             double ypos_orig = cpl_table_get
00787                 (obj_param[idet], HAWKI_COL_OBJ_POSY, iobj, NULL);
00788 
00789             cpl_vector_set
00790                 (obj_x, iobj, xpos_orig - reference_offset_x + first_image_off_x);
00791             cpl_vector_set
00792                 (obj_y, iobj, ypos_orig - reference_offset_y + first_image_off_y);
00793             cpl_msg_debug(__func__,"Using anchor point at %f,%f",
00794                           cpl_vector_get(obj_x,iobj),
00795                           cpl_vector_get(obj_y,iobj));
00796             
00797         }
00798         cpl_vector_set_size(obj_x, nselect);
00799         cpl_vector_set_size(obj_y, nselect);
00800         
00801     }
00802     cpl_msg_indent_less();
00803     
00804     /* Freeing */
00805     for (idet=0 ; idet< HAWKI_NB_DETECTORS ; idet++) 
00806         cpl_table_delete(obj_param[idet]);
00807     cpl_free(obj_param);
00808     cpl_propertylist_delete(sort_column);
00809     
00810     return reference_objects;
00811 }