HAWKI Pipeline Reference Manual 1.8.12
hawki_cal_illum.c
00001 /* $Id: hawki_cal_illum.c,v 1.8 2010/06/04 09:45:43 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: 2010/06/04 09:45:43 $
00024  * $Revision: 1.8 $
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 
00039 #include "irplib_utils.h"
00040 #include "irplib_strehl.h"
00041 
00042 #include "hawki_utils.h"
00043 #include "hawki_calib.h"
00044 #include "hawki_pfits.h"
00045 #include "hawki_dfs.h"
00046 #include "hawki_load.h"
00047 #include "hawki_save.h"
00048 
00049 /*-----------------------------------------------------------------------------
00050                             Functions prototypes
00051  -----------------------------------------------------------------------------*/
00052 
00053 static int hawki_cal_illum_create(cpl_plugin *) ;
00054 static int hawki_cal_illum_exec(cpl_plugin *) ;
00055 static int hawki_cal_illum_destroy(cpl_plugin *) ;
00056 static int hawki_cal_illum(cpl_parameterlist *, cpl_frameset *) ;
00057 static int hawki_cal_illum_save(const cpl_image **, const cpl_table **, 
00058         cpl_parameterlist *, cpl_frameset *) ;
00059 static cpl_image * hawki_cal_illum_compute(cpl_frameset *, int, 
00060         const char *, const char *, cpl_table **) ;
00061 static cpl_vector * hawki_cal_illum_phot(cpl_imagelist *, cpl_bivector *, 
00062         int *) ;
00063 static cpl_bivector * hawki_cal_illum_find_pos(cpl_imagelist *, 
00064         cpl_bivector *, int) ;
00065 
00066 /*-----------------------------------------------------------------------------
00067                             Static variables
00068  -----------------------------------------------------------------------------*/
00069 
00070 static struct {
00071     /* Inputs */
00072     int         subtract ;
00073     int         degree ;
00074     int         s_hx ;
00075     int         s_hy ;
00076     double      star_r ;
00077     double      bg_r1 ;
00078     double      bg_r2 ;
00079 } hawki_cal_illum_config ;
00080 
00081 static char hawki_cal_illum_description[] =
00082 "hawki_cal_illum -- Illumination recipe\n"
00083 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00084 "raw-file.fits "HAWKI_CAL_ILLUM_RAW" or\n"
00085 "flat-file.fits "HAWKI_CALPRO_FLAT" or\n"
00086 "bpm-file.fits "HAWKI_CALPRO_BPM"\n" ;
00087 
00088 /*-----------------------------------------------------------------------------
00089                                 Functions code
00090  -----------------------------------------------------------------------------*/
00091 
00092 /*----------------------------------------------------------------------------*/
00101 /*----------------------------------------------------------------------------*/
00102 int cpl_plugin_get_info(cpl_pluginlist * list)
00103 {
00104     cpl_recipe  *   recipe = cpl_calloc(1, sizeof *recipe ) ;
00105     cpl_plugin  *   plugin = &recipe->interface ;
00106 
00107     cpl_plugin_init(plugin,
00108                     CPL_PLUGIN_API,
00109                     HAWKI_BINARY_VERSION,
00110                     CPL_PLUGIN_TYPE_RECIPE,
00111                     "hawki_cal_illum",
00112                     "Illumination recipe",
00113                     hawki_cal_illum_description,
00114                     "Yves Jung",
00115                     PACKAGE_BUGREPORT,  
00116                     hawki_get_license(),
00117                     hawki_cal_illum_create,
00118                     hawki_cal_illum_exec,
00119                     hawki_cal_illum_destroy) ;
00120 
00121     cpl_pluginlist_append(list, plugin) ;
00122     
00123     return 0;
00124 }
00125 
00126 /*----------------------------------------------------------------------------*/
00134 /*----------------------------------------------------------------------------*/
00135 static int hawki_cal_illum_create(cpl_plugin * plugin)
00136 {
00137     cpl_recipe      *   recipe ;
00138     cpl_parameter   *   p ;
00139         
00140     /* Check that the plugin is part of a valid recipe */
00141     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00142         recipe = (cpl_recipe *)plugin ;
00143     else return -1 ;
00144 
00145     /* Create the parameters list in the cpl_recipe object */
00146     recipe->parameters = cpl_parameterlist_new() ; 
00147 
00148     /* Fill the parameters list */
00149     /* --subtract */
00150     p = cpl_parameter_new_value("hawki.hawki_cal_illum.subtract",
00151             CPL_TYPE_BOOL, "Flag to subtract the next images",
00152             "hawki.hawki_cal_illum", TRUE) ;
00153     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "subtract") ;
00154     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00155     cpl_parameterlist_append(recipe->parameters, p) ;
00156     /* --degree */
00157     p = cpl_parameter_new_value("hawki.hawki_cal_illum.degree",
00158             CPL_TYPE_INT, "Polynomial degree for the fit",
00159             "hawki.hawki_cal_illum", 3) ;
00160     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "degree") ;
00161     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00162     cpl_parameterlist_append(recipe->parameters, p) ;
00163        /* --star_r */
00164     p = cpl_parameter_new_value("hawki.hawki_cal_illum.star_r", CPL_TYPE_DOUBLE,
00165             "the star radius", "hawki.hawki_cal_illum", -1.0) ;
00166     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "star_r") ;
00167     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00168     cpl_parameterlist_append(recipe->parameters, p) ;
00169     /* --bg_r1 */
00170     p = cpl_parameter_new_value("hawki.hawki_cal_illum.bg_r1", CPL_TYPE_DOUBLE,
00171             "the internal background radius", "hawki.hawki_cal_illum", -1.0) ;
00172     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bg_r1") ;
00173     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00174     cpl_parameterlist_append(recipe->parameters, p) ;
00175     /* --bg_r2 */
00176     p = cpl_parameter_new_value("hawki.hawki_cal_illum.bg_r2", CPL_TYPE_DOUBLE,
00177             "the external background radius", "hawki.hawki_cal_illum", -1.0) ;
00178     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bg_r2") ;
00179     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00180     cpl_parameterlist_append(recipe->parameters, p) ;
00181     /* --s_hx */
00182     p = cpl_parameter_new_value("hawki.hawki_cal_illum.s_hx", CPL_TYPE_INT,
00183             "Half size of the seach box in x", "hawki.hawki_cal_illum", 50) ;
00184     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "s_hx") ;
00185     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00186     cpl_parameterlist_append(recipe->parameters, p) ;
00187     /* --s_hy */
00188     p = cpl_parameter_new_value("hawki.hawki_cal_illum.s_hy", CPL_TYPE_INT,
00189             "Half size of the seach box in y", "hawki.hawki_cal_illum", 50) ;
00190     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "s_hy") ;
00191     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00192     cpl_parameterlist_append(recipe->parameters, p) ;
00193  
00194     /* Return */
00195     return 0;
00196 }
00197 
00198 /*----------------------------------------------------------------------------*/
00204 /*----------------------------------------------------------------------------*/
00205 static int hawki_cal_illum_exec(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     /* Issue a banner */
00215     hawki_print_banner();
00216 
00217     return hawki_cal_illum(recipe->parameters, recipe->frames) ;
00218 }
00219 
00220 /*----------------------------------------------------------------------------*/
00226 /*----------------------------------------------------------------------------*/
00227 static int hawki_cal_illum_destroy(cpl_plugin * plugin)
00228 {
00229     cpl_recipe  *   recipe ;
00230     
00231     /* Get the recipe out of the plugin */
00232     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00233         recipe = (cpl_recipe *)plugin ;
00234     else return -1 ;
00235 
00236     cpl_parameterlist_delete(recipe->parameters) ; 
00237     return 0 ;
00238 }
00239 
00240 /*----------------------------------------------------------------------------*/
00247 /*----------------------------------------------------------------------------*/
00248 static int hawki_cal_illum(
00249         cpl_parameterlist   *   parlist, 
00250         cpl_frameset        *   frameset)
00251 {
00252     cpl_parameter       *   par ;
00253     const char          *   flat ;
00254     const char          *   bpm ;
00255     cpl_frameset        *   rawframes ;
00256     cpl_frameset        *   cur_frames ;
00257     int                 *   labels ;
00258     cpl_image           *   illum[HAWKI_NB_DETECTORS] ;
00259     cpl_table           *   flux[HAWKI_NB_DETECTORS] ;
00260     int                     i ;
00261 
00262     /* Initialise */
00263     rawframes = NULL ;
00264 
00265     /* Retrieve input parameters */
00266     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.subtract") ;
00267     hawki_cal_illum_config.subtract = cpl_parameter_get_bool(par) ;
00268     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.degree") ;
00269     hawki_cal_illum_config.degree = cpl_parameter_get_int(par) ;
00270     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.s_hx") ;
00271     hawki_cal_illum_config.s_hx = cpl_parameter_get_int(par) ;
00272     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.s_hy") ;
00273     hawki_cal_illum_config.s_hy = cpl_parameter_get_int(par) ;
00274     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.star_r") ;
00275     hawki_cal_illum_config.star_r = cpl_parameter_get_double(par) ;
00276     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.bg_r1") ;
00277     hawki_cal_illum_config.bg_r1 = cpl_parameter_get_double(par) ;
00278     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_illum.bg_r2") ;
00279     hawki_cal_illum_config.bg_r2 = cpl_parameter_get_double(par) ;
00280  
00281     /* Identify the RAW and CALIB frames in the input frameset */
00282     if (hawki_dfs_set_groups(frameset)) {
00283         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00284         return -1 ;
00285     }
00286 
00287     /* Retrieve calibration data */
00288     flat = hawki_extract_first_filename(frameset, HAWKI_CALPRO_FLAT) ;
00289     bpm = hawki_extract_first_filename(frameset, HAWKI_CALPRO_BPM) ;
00290 
00291     /* Retrieve raw frames */
00292     if ((rawframes = hawki_extract_frameset(frameset, 
00293                     HAWKI_CAL_ILLUM_RAW)) == NULL) {
00294         cpl_msg_error(__func__, "No raw frame in input") ;
00295         return -1 ;
00296     }
00297 
00298     /* Labelise frames */
00299     cpl_msg_info(__func__, "Labelise the frames") ;
00300     if ((labels = hawki_detectors_labelise(rawframes)) == NULL) {
00301         cpl_msg_error(__func__, "Cannot labelise") ;
00302         cpl_frameset_delete(rawframes) ;
00303         return -1 ;
00304     }
00305 
00306     /* Loop on the chips */
00307     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00308         cpl_msg_info(__func__, "Reduce chip nb %d", i+1) ;
00309         
00310         /* Initialise */
00311         illum[i] = NULL ;
00312 
00313         /* Get the frames for which the star is in chip number i+1 */
00314         if ((cur_frames = cpl_frameset_extract(rawframes, labels,
00315                         i+1)) == NULL) {
00316             cpl_msg_warning(__func__, "No frames for chip nb %d", i+1) ;
00317             /* Create the flux table */
00318             flux[i] = cpl_table_new(1) ;
00319             cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSX, CPL_TYPE_DOUBLE);
00320             cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSY, CPL_TYPE_DOUBLE);
00321             cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_FLUX, CPL_TYPE_DOUBLE);
00322         } else {
00323             /* Create the flux table */
00324             flux[i] = cpl_table_new(cpl_frameset_get_size(cur_frames)) ;
00325             cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSX, CPL_TYPE_DOUBLE);
00326             cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_POSY, CPL_TYPE_DOUBLE);
00327             cpl_table_new_column(flux[i],HAWKI_COL_ILLUM_FLUX, CPL_TYPE_DOUBLE);
00328 
00329             /* Get the illumination */
00330             if ((illum[i] = hawki_cal_illum_compute(cur_frames, i+1, 
00331                             bpm, flat, &(flux[i]))) == NULL) {
00332                 cpl_msg_warning(__func__, "Cannot compute for chip %d", i+1) ;
00333                 cpl_error_reset() ;
00334             }
00335             cpl_frameset_delete(cur_frames) ;
00336         }
00337     }
00338     cpl_frameset_delete(rawframes) ;
00339     cpl_free(labels) ;
00340     
00341     /* Save the product */
00342     cpl_msg_info(__func__, "Save the product") ;
00343     cpl_msg_indent_more() ;
00344     if (hawki_cal_illum_save((const cpl_image **)illum, 
00345                 (const cpl_table **)flux, parlist, frameset)) {
00346         cpl_msg_error(__func__, "Cannot save the product") ;
00347         for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_table_delete(flux[i]) ;
00348         for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_image_delete(illum[i]) ;
00349         cpl_msg_indent_less() ;
00350         return -1 ;
00351     }
00352     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_table_delete(flux[i]) ;
00353     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) cpl_image_delete(illum[i]) ;
00354     cpl_msg_indent_less() ;
00355 
00356     /* Return */
00357     if (cpl_error_get_code()) return -1 ;
00358     else return 0 ;
00359 }
00360 
00361 /*----------------------------------------------------------------------------*/
00371 /*----------------------------------------------------------------------------*/
00372 static cpl_image * hawki_cal_illum_compute(
00373         cpl_frameset    *   raw,
00374         int                 chip,
00375         const char      *   bpm,
00376         const char      *   flat,
00377         cpl_table       **  fl)
00378 {
00379     cpl_bivector    *   offsets ;
00380     cpl_imagelist   *   in ;
00381     cpl_image       *   ima1 ;
00382     cpl_image       *   ima2 ;
00383     cpl_bivector    *   positions ;
00384     cpl_bivector    *   purged_pos ;
00385     double          *   positions_x,
00386                     *   positions_y,
00387                     *   purged_pos_x,
00388                     *   purged_pos_y ;
00389     cpl_vector      *   flux ;
00390     cpl_vector      *   purged_flux ;
00391     cpl_polynomial  *   poly ;
00392     cpl_image       *   poly_ima ;
00393     int                 nval, nx, ny ;
00394     double              val ;
00395     int                 ival ;
00396     int                 i, j ;
00397     
00398     /* Check entries */
00399     if (chip < 1 || chip > HAWKI_NB_DETECTORS) return NULL ;
00400     if (raw == NULL) return NULL ;
00401     if (fl == NULL) return NULL ;
00402          
00403     /* Get the offsets from the raw frames */
00404     cpl_msg_info(__func__, "Get the offsets from the files headers") ;
00405     cpl_msg_indent_more() ;
00406     if ((offsets = hawki_get_header_tel_offsets(raw)) == NULL) {
00407         cpl_msg_error(__func__, "Cannot get the offsets") ;
00408         cpl_msg_indent_less() ;
00409         return NULL ;
00410     }
00411     cpl_msg_indent_less() ;
00412 
00413     /* Load the input data */
00414     cpl_msg_info(__func__, "Load the input data") ;
00415     cpl_msg_indent_more() ;
00416     if ((in = hawki_load_detector(raw, chip, CPL_TYPE_FLOAT)) == NULL) {
00417         cpl_msg_error(__func__, "Cannot load input data") ;
00418         cpl_bivector_delete(offsets) ;
00419         cpl_msg_indent_less() ;
00420         return NULL ;
00421     }
00422     cpl_msg_indent_less() ;
00423 
00424     /* Apply the calibrations */
00425     if (flat || bpm) {
00426         cpl_msg_indent_more() ;
00427         if (hawki_flat_bpm_detector_calib(in, flat, bpm) == -1) {
00428             cpl_msg_error(__func__, "Cannot apply calibrations") ;
00429             cpl_bivector_delete(offsets) ;
00430             cpl_imagelist_delete(in) ;
00431             cpl_msg_indent_less() ;
00432             return NULL ;
00433         }
00434         cpl_msg_indent_less() ;
00435     }
00436 
00437     /* Subtract the consecutive frames */
00438     if (hawki_cal_illum_config.subtract) {
00439         cpl_msg_info(__func__, "Subtract the next images") ;
00440         ima1 = cpl_image_duplicate(cpl_imagelist_get(in, 0)) ;
00441         for (i=0 ; i<cpl_imagelist_get_size(in) ; i++) {
00442             if (i==cpl_imagelist_get_size(in)-1) {
00443                 ima2 = ima1 ;
00444             } else {
00445                 ima2 = cpl_imagelist_get(in, i+1) ;
00446             }
00447             cpl_image_subtract(cpl_imagelist_get(in, i), ima2) ;
00448         }
00449         cpl_image_delete(ima1) ;
00450     }
00451 
00452     /* Find the positions */
00453     cpl_msg_info(__func__, "Find the positions") ;
00454     cpl_msg_indent_more() ;
00455     if ((positions=hawki_cal_illum_find_pos(in, offsets, chip)) == NULL) {
00456         cpl_msg_error(__func__, "Cannot find the positions") ;
00457         cpl_imagelist_delete(in) ;
00458         cpl_bivector_delete(offsets) ;
00459         cpl_msg_indent_less() ;
00460         return NULL ;
00461     }
00462     cpl_bivector_delete(offsets) ;
00463     cpl_msg_indent_less() ;
00464 
00465     /* Compute the photometry */
00466     cpl_msg_info(__func__, "Compute the photometry") ;
00467     cpl_msg_indent_more() ;
00468     if ((flux=hawki_cal_illum_phot(in, positions, &nval)) == NULL) {
00469         cpl_msg_error(__func__, "Cannot find the positions") ;
00470         cpl_imagelist_delete(in) ;
00471         cpl_bivector_delete(positions) ;
00472         cpl_msg_indent_less() ;
00473         return NULL ;
00474     }
00475     nx = cpl_image_get_size_x(cpl_imagelist_get(in, 0)) ;
00476     ny = cpl_image_get_size_y(cpl_imagelist_get(in, 0)) ;
00477     cpl_imagelist_delete(in) ;
00478     cpl_msg_indent_less() ;
00479     if (nval < 1) {
00480         cpl_msg_error(__func__, "No flux computed") ;
00481         cpl_bivector_delete(positions) ;
00482         cpl_vector_delete(flux) ;
00483         return NULL ;
00484     }
00485     
00486     /* Purge positions */
00487     purged_pos = cpl_bivector_new(nval) ;
00488     purged_pos_x = cpl_bivector_get_x_data(purged_pos) ;
00489     purged_pos_y = cpl_bivector_get_y_data(purged_pos) ;
00490     positions_x = cpl_bivector_get_x_data(positions) ;
00491     positions_y = cpl_bivector_get_y_data(positions) ;
00492     purged_flux = cpl_vector_new(nval) ;
00493     j = 0 ;
00494     for (i=0 ; i<cpl_vector_get_size(flux) ; i++) {
00495         if (fabs(cpl_vector_get(flux, i)) > 0) {
00496             purged_pos_x[j] = positions_x[i] ;
00497             purged_pos_y[j] = positions_y[i] ;
00498             cpl_vector_set(purged_flux, j, cpl_vector_get(flux, i)) ;
00499             j++ ;
00500         }
00501     }
00502 
00503     /* Fill the flux table */
00504     for (i=0 ; i<cpl_vector_get_size(flux) ; i++) {
00505         cpl_table_set_double(*fl, HAWKI_COL_ILLUM_POSX, i, positions_x[i]) ;
00506         cpl_table_set_double(*fl, HAWKI_COL_ILLUM_POSY, i, positions_y[i]) ;
00507         cpl_table_set_double(*fl, HAWKI_COL_ILLUM_FLUX, i, 
00508                 cpl_vector_get(flux, i)) ;
00509     }
00510     cpl_bivector_delete(positions) ;
00511     cpl_vector_delete(flux) ;
00512     
00513     /* Fit the polynomial */
00514     cpl_msg_info(__func__, "Compute the polynomial") ;
00515     if ((poly = cpl_polynomial_fit_2d_create(purged_pos, purged_flux,
00516             hawki_cal_illum_config.degree, NULL)) == NULL) {
00517         cpl_msg_error(__func__, "Cannot fit the polynomial") ;
00518         cpl_bivector_delete(purged_pos) ;
00519         cpl_vector_delete(purged_flux) ;
00520         return NULL ;
00521     }
00522     cpl_bivector_delete(purged_pos) ;
00523     cpl_vector_delete(purged_flux) ;
00524    
00525     /* Create the polynomial image */
00526     poly_ima = cpl_image_new(nx, ny, CPL_TYPE_FLOAT) ;
00527     cpl_image_fill_polynomial(poly_ima, poly, 1.0, 1.0, 1.0, 1.0) ;
00528     cpl_polynomial_delete(poly) ;
00529 
00530     /* Normalise the image */
00531     val = cpl_image_get(poly_ima, 1024, 1024, &ival) ;
00532     cpl_image_divide_scalar(poly_ima, val) ;
00533 
00534     return poly_ima ;
00535 }
00536 
00537 /*----------------------------------------------------------------------------*/
00545 /*----------------------------------------------------------------------------*/
00546 static cpl_vector * hawki_cal_illum_phot(
00547         cpl_imagelist   *   ilist,
00548         cpl_bivector    *   positions,
00549         int             *   nvalid)
00550 {
00551     cpl_vector          *   flux ;
00552     cpl_image           *   cur_ima ;
00553     double              *   pos_x ;
00554     double              *   pos_y ;
00555     int                     ni ;
00556     int                     nok ;
00557     double                  bg, fl ;
00558     cpl_bivector        *   iqe_res ;
00559     double                  fwhm_x, fwhm_y, r, r1, r2 ;
00560     int                     i ;
00561 
00562     /* Test entries */
00563     if (ilist == NULL || positions == NULL || nvalid == NULL) return NULL ;
00564     ni = cpl_imagelist_get_size(ilist) ;
00565     pos_x = cpl_bivector_get_x_data(positions) ;
00566     pos_y = cpl_bivector_get_y_data(positions) ;
00567     nok = 0 ;
00568 
00569     /* Create the flux vector */
00570     flux = cpl_vector_new(ni) ;
00571 
00572     /* Loop on the frames */
00573     for (i=0 ; i<ni ; i++) {
00574         cur_ima = cpl_imagelist_get(ilist, i) ;
00575 
00576         /* FWHM_X / FWHM_Y */
00577         if ((iqe_res = cpl_image_iqe(cur_ima,
00578                         (int)(pos_x[i]-10.0), (int)(pos_y[i]-10.0),
00579                         (int)(pos_x[i]+10.0), (int)(pos_y[i]+10.0))) == NULL) {
00580             cpl_msg_debug(__func__,"Cannot get FWHM for image %d", i+1);
00581             fwhm_x = fwhm_y = -1.0 ;
00582             cpl_error_reset() ;
00583         } else {
00584             fwhm_x = cpl_vector_get(cpl_bivector_get_x(iqe_res), 2) ;
00585             fwhm_y = cpl_vector_get(cpl_bivector_get_x(iqe_res), 3) ;
00586             cpl_bivector_delete(iqe_res) ;
00587         }
00588 
00589         /* Determine the radii */
00590         r = hawki_cal_illum_config.star_r ;
00591         if (r < 0) {
00592             if (fwhm_x>0 && fwhm_y>0)   r = 5*(fwhm_x+fwhm_y)/2.0 ;
00593             else                        r = HAWKI_PHOT_STAR_RADIUS ;
00594         }
00595         r1 = hawki_cal_illum_config.bg_r1 ;
00596         r2 = hawki_cal_illum_config.bg_r2 ;
00597         if (r1 < 0) r1 = r + 10.0 ;
00598         if (r2 < 0) r2 = r1 + 20.0 ;
00599 
00600         bg = irplib_strehl_ring_background(cur_ima, (int)pos_x[i],
00601                 (int)pos_y[i], r1, r2, IRPLIB_BG_METHOD_MEDIAN) ;
00602         fl = irplib_strehl_disk_flux(cur_ima, (int)pos_x[i], (int)pos_y[i], 
00603                 r, bg) ;
00604         cpl_vector_set(flux, i, fl); 
00605         if (fabs(fl)>1e-3) nok++ ; 
00606         cpl_msg_info(__func__, "Flux for image %d: %g (r=%g, r1=%g, r2=%g)", 
00607                 i+1, fl, r, r1, r2) ;
00608     }
00609     *nvalid = nok ;
00610     return flux ;
00611 }
00612  
00613 /*----------------------------------------------------------------------------*/
00621 /*----------------------------------------------------------------------------*/
00622 static cpl_bivector * hawki_cal_illum_find_pos(
00623         cpl_imagelist   *   ilist,
00624         cpl_bivector    *   offsets,
00625         int                 chip)
00626 {
00627     cpl_bivector        *   positions ;
00628     double              *   positions_x ;
00629     double              *   positions_y ;
00630     double              *   offsets_x ;
00631     double              *   offsets_y ;
00632     cpl_image           *   tmp_ima ;
00633     cpl_image           *   cur_ima ;
00634     cpl_image           *   filtered_ima ;
00635     cpl_matrix          *   kernel ;
00636     int                     nx, ny, ni ;
00637     int                     llx, lly, urx, ury, posx, posy, gap ;
00638     int                     i ;
00639 
00640     /* Test entries */
00641     if (ilist == NULL || offsets == NULL) return NULL ;
00642     if (chip < 1 || chip > HAWKI_NB_DETECTORS) return NULL ;
00643     ni = cpl_imagelist_get_size(ilist) ;
00644     gap = 147 ;
00645 
00646     /* Create the positions bivector */
00647     positions = cpl_bivector_new(ni) ;
00648     positions_x = cpl_bivector_get_x_data(positions) ;
00649     positions_y = cpl_bivector_get_y_data(positions) ;
00650     offsets_x = cpl_bivector_get_x_data(offsets) ;
00651     offsets_y = cpl_bivector_get_y_data(offsets) ;
00652 
00653     /* Create the kernel */
00654     kernel = cpl_matrix_new(3, 3) ;
00655     cpl_matrix_fill(kernel, 1.0) ;
00656     
00657     /* Loop on all the images */
00658     for (i=0 ; i<ni ; i++) {
00659         cur_ima = cpl_imagelist_get(ilist, i) ;
00660         nx = cpl_image_get_size_x(cur_ima) ;
00661         ny = cpl_image_get_size_y(cur_ima) ;
00662 
00663         /* Define zone */
00664         if (chip == 1) {
00665             llx = nx + gap/2.0 + offsets_x[i] - hawki_cal_illum_config.s_hx ;
00666             urx = nx + gap/2.0 + offsets_x[i] + hawki_cal_illum_config.s_hx ;
00667             lly = ny + gap/2.0 + offsets_y[i] - hawki_cal_illum_config.s_hy ;
00668             ury = ny + gap/2.0 + offsets_y[i] + hawki_cal_illum_config.s_hy ;
00669         } else if (chip == 2) {
00670             llx = offsets_x[i] - gap/2.0 - hawki_cal_illum_config.s_hx ;
00671             urx = offsets_x[i] - gap/2.0 + hawki_cal_illum_config.s_hx ;
00672             lly = ny + gap/2.0 + offsets_y[i] - hawki_cal_illum_config.s_hy ;
00673             ury = ny + gap/2.0 + offsets_y[i] + hawki_cal_illum_config.s_hy ;
00674         } else if (chip == 3) {
00675             llx = offsets_x[i] - gap/2.0 - hawki_cal_illum_config.s_hx ;
00676             urx = offsets_x[i] - gap/2.0 + hawki_cal_illum_config.s_hx ;
00677             lly = offsets_y[i] - gap/2.0 - hawki_cal_illum_config.s_hy ;
00678             ury = offsets_y[i] - gap/2.0 + hawki_cal_illum_config.s_hy ;
00679         } else if (chip == 4) {
00680             llx = nx + gap/2.0 + offsets_x[i] - hawki_cal_illum_config.s_hx ;
00681             urx = nx + gap/2.0 + offsets_x[i] + hawki_cal_illum_config.s_hx ;
00682             lly = offsets_y[i] - gap/2.0 - hawki_cal_illum_config.s_hy ;
00683             ury = offsets_y[i] - gap/2.0 + hawki_cal_illum_config.s_hy ;
00684         }
00685 
00686         /* Test zone */
00687         if (llx>urx || lly>ury || llx<1 || urx>nx || lly<1 || ury>ny) {
00688             cpl_msg_error(__func__, "Bad specified zone") ;
00689             cpl_bivector_delete(positions) ;
00690             cpl_matrix_delete(kernel) ;
00691             return NULL ;
00692         }
00693         
00694         /* Extract */
00695         tmp_ima = cpl_image_extract(cur_ima, llx, lly, urx, ury) ;
00696         filtered_ima =cpl_image_filter_median(tmp_ima, kernel) ;
00697         cpl_image_delete(tmp_ima) ;
00698 
00699         /* Find the max */
00700         cpl_image_get_maxpos(filtered_ima, &posx, &posy) ;
00701         positions_x[i] = llx + posx ;
00702         positions_y[i] = lly + posy ;
00703         cpl_image_delete(filtered_ima) ;
00704         cpl_msg_info(__func__, "Star found at pos %g, %g in image %d",
00705                 positions_x[i], positions_y[i], i+1) ;
00706     }
00707     cpl_matrix_delete(kernel) ;
00708 
00709     return positions ;
00710 }
00711 
00712 /*----------------------------------------------------------------------------*/
00721 /*----------------------------------------------------------------------------*/
00722 static int hawki_cal_illum_save(
00723         const cpl_image     **  illum,
00724         const cpl_table     **  flux,
00725         cpl_parameterlist   *   parlist,
00726         cpl_frameset        *   set)
00727 {
00728     cpl_propertylist    **  qclists ;
00729     cpl_propertylist    *   paflist ;
00730     cpl_propertylist    *   paflist_cur ;
00731     const cpl_frame     *   ref_frame ;
00732     cpl_propertylist    *   inputlist ;
00733     int                     ext_nb ;
00734     char                *   filename ;
00735     char                    sval[16] ;
00736     const char          *   recipe_name = "hawki_cal_illum" ;
00737     int                     i;
00738 
00739     /* Get the reference frame */
00740     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00741 
00742     /* Create the QC lists */
00743     qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00744     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00745         qclists[i] = cpl_propertylist_new() ;
00746         cpl_propertylist_append_double(qclists[i], "ESO QC DATANCOM",
00747                 cpl_frameset_get_size(set)) ;
00748 
00749         /* Propagate some keywords from input raw frame extensions */
00750         ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1);
00751         inputlist = cpl_propertylist_load_regexp(
00752                 cpl_frame_get_filename(ref_frame), ext_nb,
00753                 HAWKI_HEADER_EXT_FORWARD, 0) ;
00754         cpl_propertylist_copy_property_regexp(qclists[i], inputlist, "", 0) ;
00755         cpl_propertylist_delete(inputlist) ;
00756     }
00757 
00758     /* Write the image */
00759     hawki_images_save(set,
00760                       parlist,
00761                       set,
00762                       (const cpl_image **)illum, 
00763                       recipe_name,
00764                       HAWKI_CALPRO_ILLUM, 
00765                       HAWKI_PROTYPE_ILLUM,
00766                       NULL,
00767                       (const cpl_propertylist**)qclists,
00768                       "hawki_cal_illum.fits") ;
00769     /* To handle cases where a chip is missing */
00770     if (cpl_error_get_code() == CPL_ERROR_NULL_INPUT) cpl_error_reset() ;
00771 
00772     /* Write the flux table */
00773     hawki_tables_save(set,
00774                       parlist,
00775                       set,
00776                       (const cpl_table **)flux,
00777                       recipe_name,
00778                       HAWKI_CALPRO_ILLUM_PHOTOM,
00779                       HAWKI_PROTYPE_ILLUM_PHOTOM,
00780                       NULL,
00781                       (const cpl_propertylist**)qclists,
00782                       "hawki_cal_illum_photom.fits") ;
00783     /* To handle cases where a chip is missing */
00784     if (cpl_error_get_code() == CPL_ERROR_NULL_INPUT) cpl_error_reset() ;
00785    
00786     /* Remove the keywords for the FITS extensions */
00787     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00788         cpl_propertylist_erase_regexp(qclists[i], HAWKI_HEADER_EXT_FORWARD, 0) ;
00789     }
00790 
00791     /* Get FITS header from reference file */
00792     paflist = cpl_propertylist_load_regexp(cpl_frame_get_filename(ref_frame),
00793             0, HAWKI_HEADER_PRI_TOPAF, 0) ;
00794 
00795     /* Add the PRO REC1 ID in the paf files */
00796     cpl_propertylist_prepend_string(paflist, "PRO REC1 ID", recipe_name) ;
00797 
00798     /* Add the PRO CATG keyword. This is a workaround, since the current 
00799      * implemented behaviour is not to have PAF files associated to products.
00800      * All this will be removed with the FITS2PAF utility in esorex 
00801      */
00802     cpl_propertylist_prepend_string(paflist, "PRO CATG", HAWKI_CALPRO_ILLUM);
00803 
00804     /* Write the extension PAF files */
00805     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00806         /* Duplicate paflist */
00807         paflist_cur = cpl_propertylist_duplicate(paflist) ;
00808 
00809         /* Add the EXTNAME keyword in the PAF */
00810         sprintf(sval, "CHIP%d.INT1", i+1) ;
00811         cpl_propertylist_prepend_string(paflist_cur, "EXTNAME", sval) ;
00812 
00813         /* Get FITS header from reference file extension */
00814         ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), i+1);
00815         inputlist = cpl_propertylist_load_regexp(
00816                 cpl_frame_get_filename(ref_frame), ext_nb,
00817                 HAWKI_HEADER_EXT_TOPAF, 0) ;
00818         cpl_propertylist_copy_property_regexp(paflist_cur, inputlist, "", 0) ;
00819         cpl_propertylist_delete(inputlist) ;
00820 
00821         /* End of Workaround */
00822 
00823         /* Copy the QC in paflist */
00824         cpl_propertylist_copy_property_regexp(paflist_cur, qclists[i], "", 0) ;
00825 
00826         /* Paf file name */
00827         filename = cpl_sprintf("%s_%02d.paf", recipe_name, i+1) ;
00828 
00829         /* Save the PAF file */
00830         cpl_dfs_save_paf("HAWKI",
00831                 recipe_name,
00832                 paflist_cur,
00833                 filename) ;
00834         cpl_free(filename) ;
00835         cpl_propertylist_delete(paflist_cur) ;
00836     }
00837 
00838     /* Free and return */
00839     for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
00840         cpl_propertylist_delete(qclists[i]) ;
00841     }
00842     cpl_free(qclists) ;
00843     cpl_propertylist_delete(paflist) ;
00844     return  0;
00845 }
00846