HAWKI Pipeline Reference Manual 1.8.12
hawki_cal_zpoint.c
00001 /* $Id: hawki_cal_zpoint.c,v 1.36 2013/02/01 16:51: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: 2013/02/01 16:51:43 $
00024  * $Revision: 1.36 $
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 <string.h>
00037 #include <math.h>
00038 #include <cpl.h>
00039 
00040 #include "irplib_utils.h"
00041 #include "irplib_calib.h"
00042 #include "irplib_strehl.h"
00043 #include "irplib_stdstar.h"
00044 #include "irplib_cat.h"
00045 #include "irplib_wcs.h"
00046 
00047 #include "hawki_image_stats.h"
00048 #include "hawki_utils.h"
00049 #include "hawki_calib.h"
00050 #include "hawki_load.h"
00051 #include "hawki_save.h"
00052 #include "hawki_pfits.h"
00053 #include "hawki_dfs.h"
00054 #include "hawki_alloc.h"
00055 
00056 /*-----------------------------------------------------------------------------
00057                             Functions prototypes
00058  -----------------------------------------------------------------------------*/
00059 
00060 #ifdef __cplusplus
00061 extern "C"
00062 #endif
00063 int cpl_plugin_get_info(cpl_pluginlist * list);
00064 
00065 static int hawki_cal_zpoint_create(cpl_plugin *) ;
00066 static int hawki_cal_zpoint_exec(cpl_plugin *) ;
00067 static int hawki_cal_zpoint_destroy(cpl_plugin *) ;
00068 static int hawki_cal_zpoint(cpl_parameterlist *, cpl_frameset *) ;
00069 
00070 static void hawki_cal_zpoint_output_init(void);
00071 static int hawki_cal_zpoint_retrieve_input_param
00072 (cpl_parameterlist  *  parlist);
00073 static cpl_table ** hawki_cal_zpoint_reduce
00074 (cpl_frameset    *   set,
00075  const char      *   stdstars,
00076  const char      *   bpm,
00077  const char      *   flat,
00078  cpl_table       **  raw_zpoint_stats,
00079  int             *   labels,
00080  cpl_imagelist   **  images);
00081 static int hawki_cal_zpoint_save
00082 (cpl_table           **  zpoint_tables,
00083  int                 *   labels,
00084  cpl_imagelist       *   images,
00085  cpl_table           **  raw_zpoint_stats,
00086  cpl_frameset        *   zpoint_frames,
00087  cpl_frameset        *   calib_frames,
00088  const cpl_frame     *   stars_frame,
00089  cpl_parameterlist   *   parlist,
00090  cpl_frameset        *   set);
00091 static int hawki_cal_zpoint_compute_qc
00092 (cpl_propertylist *   qcmainparams, 
00093  cpl_propertylist **  qcextparams,
00094  cpl_frameset     *   set);
00095 static cpl_table ** hawki_cal_zpoint_photom
00096 (cpl_imagelist       *   ilist,
00097  cpl_bivector        *   pos,
00098  int                 *   labels);
00099 static int hawki_cal_zpoint_get_mag(const char *, double, double, hawki_band) ;
00100 static int hawki_cal_zpoint_compute_keywords
00101 (cpl_frameset * set, 
00102  int          * labels);
00103 static cpl_error_code  hawki_cal_zpoint_get_expected_pos
00104 (cpl_frameset * set,
00105  int          * labels);
00106 int hawki_cal_zpoint_check_epoch_equinox(cpl_propertylist * plist);
00107 
00108 /*-----------------------------------------------------------------------------
00109                             Static variables
00110  -----------------------------------------------------------------------------*/
00111 
00112 static struct {
00113     /* Inputs */
00114     double      xcoord[HAWKI_NB_DETECTORS] ;
00115     double      ycoord[HAWKI_NB_DETECTORS] ;
00116     double      target_ra;
00117     double      target_dec;
00118     double      stdstar_given_magnitude;
00119     double      detect_sigma ;
00120     int         sx ;
00121     int         sy ;
00122     double      phot_star_radius ;
00123     double      phot_bg_r1 ;
00124     double      phot_bg_r2 ;
00125 } hawki_cal_zpoint_config;
00126 
00127 static struct {
00128     /* Outputs */
00129     double      dit;
00130     double      pixscale;
00131     char        filter[512];
00132     hawki_band  band;
00133     char        starname[512];
00134     char        sptype[512];
00135     char        catalog[512];
00136     double      humidity;
00137     double      airmass[HAWKI_NB_DETECTORS];
00138     double      zpoint[HAWKI_NB_DETECTORS];
00139     double      atx0[HAWKI_NB_DETECTORS];
00140     double      posx[HAWKI_NB_DETECTORS];
00141     double      posy[HAWKI_NB_DETECTORS];
00142     double      flux[HAWKI_NB_DETECTORS];
00143     double      instrmag[HAWKI_NB_DETECTORS];
00144     double      peak[HAWKI_NB_DETECTORS];
00145     double      bgd[HAWKI_NB_DETECTORS];
00146     double      fwhmx[HAWKI_NB_DETECTORS];
00147     double      fwhmy[HAWKI_NB_DETECTORS];
00148     double      fwhm[HAWKI_NB_DETECTORS];
00149     double      fwhmx_as[HAWKI_NB_DETECTORS];
00150     double      fwhmy_as[HAWKI_NB_DETECTORS];
00151     double      fwhm_as[HAWKI_NB_DETECTORS];
00152     double      mean_zpoint;
00153     double      mean_atx0;
00154     double      mean_airmass;
00155     double      ext_coeff;
00156     double      stdstar_ra;
00157     double      stdstar_dec;
00158     double      stdstar_mag_filter;
00159     double      stdstar_mag_H;
00160     double      stdstar_mag_J;
00161     double      stdstar_mag_K;
00162     double      stdstar_mag_Y;
00163     int         stdstar_incat_found;
00164     int         stdstar_mag_available;
00165     int         stdstar_image_detected[HAWKI_NB_DETECTORS];
00166     int         zpoint_computable[HAWKI_NB_DETECTORS];
00167     int         zpoint_mean_computable;
00168 } hawki_cal_zpoint_outputs;
00169 
00170 static char hawki_cal_zpoint_description[] =
00171 "hawki_cal_zpoint -- Zero point recipe\n"
00172 "The input of the recipe files listed in the Set Of Frames (sof-file)\n"
00173 "must be tagged as:\n"
00174 "raw-file.fits "HAWKI_CAL_ZPOINT_RAW" or\n"
00175 "stdstars-file.fits "HAWKI_CALPRO_STDSTARS" or\n"
00176 "flat-file.fits "HAWKI_CALPRO_FLAT" or\n"
00177 "bpm-file.fits "HAWKI_CALPRO_BPM"\n"
00178 "The recipe creates as an output:\n"
00179 "hawki_cal_zpoint.fits ("HAWKI_CALPRO_ZPOINT_TAB"): Zero point solution table\n"
00180 "hawki_cal_zpoint_check.fits ("HAWKI_CALPRO_ZPOINT_IMA"): Standard star images corrected (for checking purposes)\n"
00181 "hawki_cal_zpoint_stats.fits ("HAWKI_CALPRO_ZPOINT_STATS"): Statistics of the raw standard star images\n"
00182 "Return code:\n"
00183 "esorex exits with an error code of 0 if the recipe completes successfully\n"
00184 "or 1 otherwise";
00185 
00186 /*-----------------------------------------------------------------------------
00187                                 Functions code
00188  -----------------------------------------------------------------------------*/
00189 
00190 /*----------------------------------------------------------------------------*/
00198 /*----------------------------------------------------------------------------*/
00199 int cpl_plugin_get_info(cpl_pluginlist * list)
00200 {
00201     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe));
00202     cpl_plugin  *   plugin = &recipe->interface;
00203 
00204     cpl_plugin_init(plugin,
00205                     CPL_PLUGIN_API,
00206                     HAWKI_BINARY_VERSION,
00207                     CPL_PLUGIN_TYPE_RECIPE,
00208                     "hawki_cal_zpoint",
00209                     "Zero point computation recipe",
00210                     hawki_cal_zpoint_description,
00211                     "Cesar Enrique Garcia Dabo",
00212                     PACKAGE_BUGREPORT,
00213                     hawki_get_license(),
00214                     hawki_cal_zpoint_create,
00215                     hawki_cal_zpoint_exec,
00216                     hawki_cal_zpoint_destroy) ;
00217 
00218     cpl_pluginlist_append(list, plugin) ;
00219 
00220     return 0;
00221 }
00222 
00223 /*----------------------------------------------------------------------------*/
00232 /*----------------------------------------------------------------------------*/
00233 static int hawki_cal_zpoint_create(cpl_plugin * plugin)
00234 {
00235     cpl_recipe      * recipe ;
00236     cpl_parameter   * p ;
00237 
00238     /* Get the recipe out of the plugin */
00239     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00240         recipe = (cpl_recipe *)plugin ;
00241     else return -1 ;
00242 
00243     /* Create the parameters list in the cpl_recipe object */
00244     recipe->parameters = cpl_parameterlist_new();
00245     if (recipe->parameters == NULL)
00246         return 1;
00247 
00248     /* Fill the parameters list */
00249     /* --detect_sigma */
00250     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.detect_sigma",
00251             CPL_TYPE_DOUBLE, "the sigma value for object detection",
00252             "hawki.hawki_cal_zpoint", 7.0);
00253     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detect_sigma") ;
00254     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00255     cpl_parameterlist_append(recipe->parameters, p) ;
00256     /* --star_r */
00257     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.star_r",CPL_TYPE_DOUBLE,
00258             "the star radius", "hawki.hawki_cal_zpoint", -1.0) ;
00259     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "star_r") ;
00260     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00261     cpl_parameterlist_append(recipe->parameters, p) ;
00262     /* --bg_r1 */
00263     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.bg_r1", CPL_TYPE_DOUBLE,
00264             "the internal background radius", "hawki.hawki_cal_zpoint", -1.0) ;
00265     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bg_r1") ;
00266     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00267     cpl_parameterlist_append(recipe->parameters, p) ;
00268     /* --bg_r2 */
00269     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.bg_r2", CPL_TYPE_DOUBLE,
00270             "the external background radius", "hawki.hawki_cal_zpoint", -1.0) ;
00271     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bg_r2") ;
00272     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00273     cpl_parameterlist_append(recipe->parameters, p) ;
00274     /* --ra */
00275     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.ra", CPL_TYPE_DOUBLE,
00276             "RA in degrees", "hawki.hawki_cal_zpoint", 999.0) ;
00277     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ra") ;
00278     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00279     cpl_parameterlist_append(recipe->parameters, p) ;
00280     /* --dec */
00281     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.dec", CPL_TYPE_DOUBLE,
00282             "DEC in degrees", "hawki.hawki_cal_zpoint", 999.0) ;
00283     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dec") ;
00284     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00285     cpl_parameterlist_append(recipe->parameters, p) ;
00286     /* --mag */
00287     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.mag", CPL_TYPE_DOUBLE,
00288             "magnitude", "hawki.hawki_cal_zpoint", 99.0) ;
00289     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "mag") ;
00290     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00291     cpl_parameterlist_append(recipe->parameters, p) ;
00292     /* --sx */
00293     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.sx", CPL_TYPE_INT,
00294             "x half-size of the search box", "hawki.hawki_cal_zpoint", 100) ;
00295     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sx") ;
00296     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00297     cpl_parameterlist_append(recipe->parameters, p) ;
00298     /* --sy */
00299     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.sy", CPL_TYPE_INT,
00300             "y half-size of the search box", "hawki.hawki_cal_zpoint", 100) ;
00301     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sy") ;
00302     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00303     cpl_parameterlist_append(recipe->parameters, p) ;
00304     /* --xcoord */
00305     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.xcoord", CPL_TYPE_STRING,
00306             "Coordinates in X where the standard star is located. If -1 use WCS",
00307             "hawki.hawki_cal_zpoint", "-1., -1., -1., -1.");
00308     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcoord") ;
00309     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00310     cpl_parameterlist_append(recipe->parameters, p) ;
00311     /* --ycoord */
00312     p = cpl_parameter_new_value("hawki.hawki_cal_zpoint.ycoord", CPL_TYPE_STRING,
00313             "Coordinates in Y where the standard star is located. If -1 use WCS",
00314             "hawki.hawki_cal_zpoint", "-1., -1., -1., -1.") ;
00315     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ycoord") ;
00316     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00317     cpl_parameterlist_append(recipe->parameters, p) ;
00318 
00319     /* Return */
00320     return 0;
00321 }
00322 
00323 /*----------------------------------------------------------------------------*/
00329 /*----------------------------------------------------------------------------*/
00330 static int hawki_cal_zpoint_exec(cpl_plugin * plugin)
00331 {
00332     cpl_recipe  *   recipe ;
00333 
00334     /* Get the recipe out of the plugin */
00335     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00336         recipe = (cpl_recipe *)plugin ;
00337     else return -1 ;
00338 
00339     /* Issue a banner */
00340     hawki_print_banner();
00341 
00342     return hawki_cal_zpoint(recipe->parameters, recipe->frames) ;
00343 }
00344 
00345 /*----------------------------------------------------------------------------*/
00351 /*----------------------------------------------------------------------------*/
00352 static int hawki_cal_zpoint_destroy(cpl_plugin * plugin)
00353 {
00354     cpl_recipe  *   recipe ;
00355 
00356     /* Get the recipe out of the plugin */
00357     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00358         recipe = (cpl_recipe *)plugin ;
00359     else return -1 ;
00360 
00361     cpl_parameterlist_delete(recipe->parameters) ;
00362     return 0 ;
00363 }
00364 
00365 /*----------------------------------------------------------------------------*/
00372 /*----------------------------------------------------------------------------*/
00373 static int hawki_cal_zpoint(
00374         cpl_parameterlist   *   parlist,
00375         cpl_frameset        *   framelist)
00376 {
00377     cpl_parameter   *   par ;
00378     const char      *   flat ;
00379     const char      *   bpm ;
00380     const char      *   stdstars ;
00381     cpl_frameset    *   zpoint_frames ;
00382     cpl_frameset    *   calib_frames ;
00383     const cpl_frame *   stars_frame;
00384     cpl_table       **  raw_zpoint_stats;
00385     cpl_table       **  zpoint_tables;
00386     cpl_imagelist   *   std_star_images ;
00387     int             *   labels;
00388     int                 idet;
00389 
00390     /* Initialise Output */
00391     hawki_cal_zpoint_output_init();
00392     zpoint_frames = NULL ;
00393     par = NULL ;
00394 
00395     /* Retrieve input parameters */
00396     if(hawki_cal_zpoint_retrieve_input_param(parlist))
00397     {
00398         cpl_msg_error(__func__, "Wrong parameters");
00399         return -1;
00400     }
00401 
00402     /* Identify the RAW and CALIB frames in the input frameset */
00403     if (hawki_dfs_set_groups(framelist)) {
00404         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00405         return -1 ;
00406     }
00407 
00408     /* Retrieve calibration data */
00409     calib_frames = cpl_frameset_new();
00410     flat = hawki_extract_first_filename(framelist, HAWKI_CALPRO_FLAT) ;
00411     if(flat)
00412         cpl_frameset_insert(calib_frames, cpl_frame_duplicate(
00413                 cpl_frameset_find_const(framelist, HAWKI_CALPRO_FLAT)));
00414     bpm = hawki_extract_first_filename(framelist, HAWKI_CALPRO_BPM) ;
00415     if(bpm)
00416         cpl_frameset_insert(calib_frames, cpl_frame_duplicate(
00417                 cpl_frameset_find_const(framelist, HAWKI_CALPRO_BPM)));
00418 
00419     /* STD stars catalog requested */
00420     stars_frame = cpl_frameset_find_const(framelist, HAWKI_CALPRO_STDSTARS);
00421     if (stars_frame  == NULL) 
00422     {
00423         cpl_msg_error(__func__,"Cannot find the catalog in the input list (%s)",
00424                       HAWKI_CALPRO_STDSTARS);
00425         cpl_frameset_delete(calib_frames);
00426         return -1 ;
00427     }
00428     stdstars = cpl_frame_get_filename(stars_frame);
00429 
00430     /* Retrieve raw frames */
00431     if ((zpoint_frames = hawki_extract_frameset(framelist,
00432                     HAWKI_CAL_ZPOINT_RAW)) != NULL) {
00433     } else {
00434         cpl_msg_error(__func__, "Cannot find raw frames in the input list (%s)",
00435                       HAWKI_CAL_ZPOINT_RAW);
00436         cpl_frameset_delete(calib_frames);
00437         return -1 ;
00438     }
00439 
00440     /* Exactly 4 images are expected */
00441     if (cpl_frameset_get_size(zpoint_frames) != 4) {
00442         cpl_msg_error(__func__, 
00443                       "4 input raw frames are expected, not %"CPL_SIZE_FORMAT,
00444                       cpl_frameset_get_size(zpoint_frames)) ;
00445         cpl_frameset_delete(zpoint_frames) ;
00446         cpl_frameset_delete(calib_frames);
00447         return -1 ;
00448     }
00449 
00450     /* Create the statistics table */
00451     raw_zpoint_stats = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table *));
00452     for(idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00453     {
00454         raw_zpoint_stats[idet] = cpl_table_new(
00455             cpl_frameset_get_size(zpoint_frames));
00456     }
00457     hawki_image_stats_initialize(raw_zpoint_stats);
00458 
00459     /* Compute the zpoint values */
00460     cpl_msg_info(__func__, "Reduce the data") ;
00461     cpl_msg_indent_more() ;
00462     labels = cpl_calloc(cpl_frameset_get_size(zpoint_frames), sizeof(int)) ;
00463     if ((zpoint_tables = hawki_cal_zpoint_reduce(zpoint_frames, stdstars, 
00464              bpm, flat, raw_zpoint_stats, labels, &std_star_images))==NULL)
00465     {
00466         cpl_msg_error(__func__, "Cannot reduce the data") ;
00467         cpl_frameset_delete(zpoint_frames) ;
00468         cpl_frameset_delete(calib_frames);
00469         hawki_table_delete(raw_zpoint_stats);
00470         cpl_free(labels);
00471         cpl_msg_indent_less() ;
00472         return -1 ;
00473     }
00474     cpl_msg_indent_less() ;
00475 
00476     /* Save the products */
00477     cpl_msg_info(__func__, "Save the products") ;
00478     cpl_msg_indent_more() ;
00479     if (hawki_cal_zpoint_save
00480             (zpoint_tables, labels, std_star_images, raw_zpoint_stats, 
00481              zpoint_frames, calib_frames, stars_frame,
00482              parlist, framelist) == -1)
00483     {
00484         cpl_msg_warning(__func__, "Data could not be saved. "
00485                         "Check permisions or disk space") ;
00486         cpl_frameset_delete(zpoint_frames);
00487         hawki_table_delete(zpoint_tables) ;
00488         cpl_imagelist_delete(std_star_images) ;
00489         cpl_frameset_delete(calib_frames);
00490         hawki_table_delete(raw_zpoint_stats);
00491         cpl_free(labels);
00492         cpl_msg_indent_less() ;
00493         return -1 ;
00494     }
00495     cpl_msg_indent_less() ;
00496 
00497     /* Free and return */
00498     cpl_frameset_delete(zpoint_frames);
00499     cpl_frameset_delete(calib_frames);
00500     cpl_imagelist_delete(std_star_images);
00501     hawki_table_delete(zpoint_tables);
00502     hawki_table_delete(raw_zpoint_stats);
00503     cpl_free(labels);
00504 
00505     /* Return */
00506     if (cpl_error_get_code())
00507     {
00508         cpl_msg_error(__func__,
00509                       "HAWK-I pipeline could not recover from previous errors");
00510         return -1 ;
00511     }
00512     else return 0 ;
00513 }
00514 
00515 /*----------------------------------------------------------------------------*/
00525 /*----------------------------------------------------------------------------*/
00526 static cpl_table ** hawki_cal_zpoint_reduce
00527 (cpl_frameset    *   set,
00528  const char      *   stdstars,
00529  const char      *   bpm,
00530  const char      *   flat,
00531  cpl_table       **  raw_zpoint_stats,
00532  int             *   labels,
00533  cpl_imagelist   **  star_images)
00534 {
00535     cpl_frame           *   cur_frame ;
00536     cpl_propertylist    *   plist ;
00537     const char          *   sval ;
00538     cpl_imagelist       *   star_images_frame_order ;
00539     int                     nima ;
00540     cpl_bivector        *   positions ;
00541     cpl_image           *   filt_ima ;
00542     cpl_mask            *   kernel;
00543     int                     size_x, size_y ;
00544     double                  pos_x, pos_y, pos_x_cen, pos_y_cen, dist, min_dist ;
00545     cpl_apertures       *   aperts ;
00546     cpl_table           **  zpoint_tables;
00547     cpl_image           *   tmp_ima ;
00548     int                     iaper;
00549     int                     idet;
00550     int                     iframe;
00551     int                     iframe_star = -1;
00552     int                     nframes;
00553     char                    rastr[32];
00554     char                    decstr[32];
00555     cpl_errorstate          error_prevstate;
00556     int                     return_code;
00557 
00558     /* Check inputs */
00559     if (set == NULL) return NULL ;
00560     if (stdstars == NULL) return NULL ;
00561     if (star_images == NULL) return NULL ;
00562 
00563     /* Get the filter name, DIT, Target RA and DEC  */
00564     error_prevstate = cpl_errorstate_get();
00565     cur_frame = cpl_frameset_get_frame(set, 0) ;
00566     plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0) ;
00567     if ((sval = hawki_pfits_get_filter(plist)) == NULL) return NULL ;
00568     else sprintf(hawki_cal_zpoint_outputs.filter, sval) ;
00569     if (hawki_cal_zpoint_config.target_ra > 998.0)
00570     {
00571         hawki_cal_zpoint_config.target_ra = hawki_pfits_get_targ_alpha(plist);
00572         //hawki_cal_zpoint_config.target_ra = hawki_pfits_get_ra(plist) -
00573         //hawki_pfits_get_cumoffseta(plist) / 3600.;// Not valid before Nov 2008
00574         if(hawki_cal_zpoint_check_epoch_equinox(plist) == -1)
00575         {
00576             cpl_propertylist_delete(plist);
00577             return NULL;
00578         }
00579     }
00580     if (hawki_cal_zpoint_config.target_dec > 998.0)
00581     {
00582         hawki_cal_zpoint_config.target_dec = hawki_pfits_get_targ_delta(plist);
00583         //hawki_cal_zpoint_config.target_dec = hawki_pfits_get_dec(plist) -
00584         //hawki_pfits_get_cumoffsetd(plist) / 3600.;// Not valid before Nov 2008
00585         if(hawki_cal_zpoint_check_epoch_equinox(plist) == -1)
00586         {
00587             cpl_propertylist_delete(plist);
00588             return NULL;
00589         }
00590     }
00591     hawki_cal_zpoint_outputs.dit = hawki_pfits_get_dit(plist) ;
00592     hawki_cal_zpoint_outputs.pixscale = hawki_pfits_get_pixscale(plist) ;
00593     cpl_propertylist_delete(plist) ;
00594     if(!cpl_errorstate_is_equal(error_prevstate))
00595     {
00596         cpl_msg_error(__func__, "Cannot get keywords from main header:");
00597         cpl_msg_indent_more();
00598         cpl_msg_error(__func__, "%s",cpl_error_get_message());
00599         cpl_msg_indent_less();
00600         return NULL ;
00601     }
00602     cpl_msg_info(__func__,"Searching catalog stars closest to target:");
00603     cpl_msg_indent_more();
00604     hawki_utils_ra2str(rastr, 32, hawki_cal_zpoint_config.target_ra);
00605     hawki_utils_dec2str(decstr, 32, hawki_cal_zpoint_config.target_dec);
00606     cpl_msg_info(__func__,"RA = %g (%s); DEC = %g (%s)",
00607                  hawki_cal_zpoint_config.target_ra, rastr,
00608                  hawki_cal_zpoint_config.target_dec, decstr);
00609     cpl_msg_info(__func__,"HAWK-I Filter: %s", hawki_cal_zpoint_outputs.filter);
00610     cpl_msg_indent_less();
00611 
00612     /* Get the band */
00613     if ((hawki_cal_zpoint_outputs.band =
00614                 hawki_get_band(hawki_cal_zpoint_outputs.filter)) ==
00615             HAWKI_BAND_UNKNOWN) {
00616         cpl_msg_error(__func__, "Cannot associate the filter %s to a band",
00617                 hawki_cal_zpoint_outputs.filter) ;
00618         return NULL ;
00619     }
00620 
00621     /* Get the standard star information from database */
00622     cpl_msg_indent_more();
00623     return_code = hawki_cal_zpoint_get_mag(stdstars,
00624             hawki_cal_zpoint_config.target_ra,
00625             hawki_cal_zpoint_config.target_dec,
00626             hawki_cal_zpoint_outputs.band);
00627     if (return_code == -1)
00628     {
00629         cpl_msg_error(__func__, "Could not open star database");
00630         return NULL ;
00631     }   
00632     else if(return_code == 1)
00633     {
00634         cpl_msg_warning(__func__,"No suitable star found in catalog");
00635         cpl_msg_warning(__func__,"Using the target coordinates "
00636                         "as the standard star coordinates: ");
00637         hawki_cal_zpoint_outputs.stdstar_ra = 
00638                 hawki_cal_zpoint_config.target_ra;
00639         hawki_cal_zpoint_outputs.stdstar_dec = 
00640                 hawki_cal_zpoint_config.target_dec;
00641         hawki_utils_ra2str(rastr, 32, hawki_cal_zpoint_outputs.stdstar_ra);
00642         hawki_utils_dec2str(decstr, 32, hawki_cal_zpoint_outputs.stdstar_dec);
00643         cpl_msg_info(__func__, " RA = %g (%s) ; DEC = %g (%s)",
00644                      hawki_cal_zpoint_outputs.stdstar_ra, rastr,
00645                      hawki_cal_zpoint_outputs.stdstar_dec, decstr);
00646     }
00647     else
00648     {    
00649         cpl_msg_info(__func__, "Catalog where the star was found: %s",
00650                      hawki_cal_zpoint_outputs.catalog);
00651         cpl_msg_info(__func__, "Star name: %s",
00652                      hawki_cal_zpoint_outputs.starname);
00653         if(hawki_cal_zpoint_outputs.stdstar_mag_available == 1)
00654         {
00655             cpl_msg_info(__func__, "Star magnitude in filter %s : %g [mag]",
00656                     hawki_cal_zpoint_outputs.filter,
00657                     hawki_cal_zpoint_outputs.stdstar_mag_filter);
00658         }
00659         hawki_utils_ra2str(rastr, 32, hawki_cal_zpoint_outputs.stdstar_ra);
00660         hawki_utils_dec2str(decstr, 32, hawki_cal_zpoint_outputs.stdstar_dec);
00661         cpl_msg_info(__func__, "Star coordinates: RA = %g (%s) ; DEC = %g (%s)",
00662                      hawki_cal_zpoint_outputs.stdstar_ra, rastr,
00663                      hawki_cal_zpoint_outputs.stdstar_dec, decstr);
00664     }
00665     if (hawki_cal_zpoint_config.stdstar_given_magnitude < 98.0) 
00666     {
00667         hawki_cal_zpoint_outputs.stdstar_mag_available = 1;
00668         hawki_cal_zpoint_outputs.stdstar_mag_filter = 
00669                 hawki_cal_zpoint_config.stdstar_given_magnitude;
00670         cpl_msg_info(__func__, "Using user defined "
00671                      "star magnitude in filter %s : %g [mag]",
00672                      hawki_cal_zpoint_outputs.filter,
00673                      hawki_cal_zpoint_outputs.stdstar_mag_filter);
00674     }
00675     cpl_msg_indent_less();
00676 
00677     /* Labelise frames */
00678     cpl_msg_info(__func__, "Guessing which frame the STD is in for each chip");
00679     hawki_detectors_locate_star
00680         (set, hawki_cal_zpoint_outputs.stdstar_ra,
00681          hawki_cal_zpoint_outputs.stdstar_dec, labels);
00682     if (labels == NULL)
00683     {
00684         cpl_msg_error(__func__, "Cannot determine which frame the STD is on") ;
00685         return NULL ;
00686     }
00687 
00688     /* Compute the expected position of the star in pixels */
00689     /* This is stored in hawki_cal_zpoint_config.xcoord, ycoord */
00690     cpl_msg_indent_more();
00691     if(hawki_cal_zpoint_get_expected_pos(set, labels) != CPL_ERROR_NONE)
00692     {
00693         cpl_msg_error(__func__,"Could not determine where the star is located");
00694         cpl_msg_indent_less();
00695         return NULL;
00696     }
00697     cpl_msg_indent_less();
00698     
00699     /* Fetch the airmass and humidity */
00700     hawki_cal_zpoint_compute_keywords(set, labels);
00701 
00702     /* Create the positions vector */
00703     nima = cpl_frameset_get_size(set) ;
00704     positions = cpl_bivector_new(nima) ;
00705 
00706     /* Initialize */
00707     *star_images = cpl_imagelist_new();
00708 
00709     /* Loop on the detectors */
00710     nframes = cpl_frameset_get_size(set) ;
00711     cpl_msg_info(__func__,"Loop on the chips");
00712     cpl_msg_indent_more() ;
00713     for(idet = 0; idet < HAWKI_NB_DETECTORS; ++idet)
00714     {
00715         cpl_imagelist * sky_images;
00716         cpl_image     * star_ima = NULL;
00717         cpl_image     * sky;
00718         cpl_image     * flat_im;
00719         int             ext_nb;
00720 
00721         cpl_msg_info(__func__, "Loading the chip %d", idet+1);
00722         cpl_msg_indent_more() ;
00723 
00724         /* Allocate */
00725         sky_images = cpl_imagelist_new();
00726 
00727         cpl_msg_indent_more() ;
00728         for (iframe=0 ; iframe<nframes ; iframe++)
00729         {
00730             cpl_image * ima_cur;
00731 
00732             /* Load the image */
00733             ima_cur = hawki_load_image(set, iframe, idet+1, CPL_TYPE_FLOAT) ;
00734             if(ima_cur == NULL)
00735             {
00736                 cpl_bivector_delete(positions) ;
00737                 cpl_imagelist_delete(*star_images);
00738                 cpl_imagelist_delete(sky_images) ;
00739                 cpl_msg_error(__func__, "Error reading image");
00740                 return NULL;
00741             }
00742             /* Get image statistics */
00743             size_x = cpl_image_get_size_x(ima_cur) ;
00744             size_y = cpl_image_get_size_y(ima_cur) ;
00745             if(hawki_image_stats_fill_from_image
00746                 (raw_zpoint_stats,
00747                  ima_cur,
00748                  1,
00749                  1,
00750                  size_x,
00751                  size_y,
00752                  idet,
00753                  iframe) !=0 )
00754             {
00755                 cpl_msg_error(__func__,"Cannot compute stats on ima %d det %d",
00756                               iframe+1, idet+1);
00757                 cpl_bivector_delete(positions) ;
00758                 cpl_imagelist_delete(*star_images);
00759                 cpl_imagelist_delete(sky_images) ;
00760                 cpl_image_delete(ima_cur);
00761                 cpl_msg_indent_less() ;
00762                 return NULL ;
00763             }
00764 
00765             /* Add the image to either the sky images or the star image */
00766             if(labels[iframe] == idet + 1)
00767             {
00768                 star_ima = ima_cur;
00769                 iframe_star = iframe;
00770             }
00771             else
00772                 cpl_imagelist_set(sky_images, ima_cur,
00773                                   cpl_imagelist_get_size(sky_images));
00774         }
00775         cpl_msg_indent_less();
00776 
00777         /* Create the sky */
00778         cpl_msg_info(__func__, "Correct for the sky");
00779         sky = cpl_imagelist_collapse_median_create(sky_images);
00780         cpl_imagelist_delete(sky_images) ;
00781 
00782         /* Subtract the sky */
00783         cpl_image_subtract(star_ima, sky) ;
00784         cpl_image_delete(sky) ;
00785 
00786         /* Divide by the flatfield if one is provided */
00787         if (flat) {
00788             cpl_msg_info(__func__, "Correct for the flat") ;
00789 
00790             /* Get the extension with the current chip */
00791             if ((ext_nb = hawki_get_ext_from_detector(flat, idet + 1)) == -1)
00792             {
00793                 cpl_msg_error(__func__, "Cannot get the extension with chip %d",
00794                               idet + 1);
00795                 cpl_imagelist_delete(*star_images) ;
00796                 cpl_bivector_delete(positions) ;
00797                 return NULL ;
00798             }
00799             /* Load */
00800             flat_im = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, ext_nb) ;
00801             cpl_image_divide(star_ima, flat_im) ;
00802             cpl_image_delete(flat_im) ;
00803         }
00804 
00805         /* Correct the bad pixels */
00806         if (bpm) {
00807             cpl_msg_info(__func__, "Correct for the bad pixels") ;
00808             if (hawki_bpm_calib(star_ima, bpm, idet + 1) == -1)
00809             {
00810                 cpl_msg_error(__func__, "Cannot correct the BPM for chip %d",
00811                               idet + 1);
00812                 cpl_imagelist_delete(*star_images) ;
00813                 cpl_bivector_delete(positions) ;
00814                 return NULL ;
00815             }
00816         }
00817 
00818         /* Put the result in the image list */
00819         cpl_imagelist_set(*star_images, star_ima,
00820                           cpl_imagelist_get_size(*star_images)) ;
00821 
00822         /* Object detection */
00823         cpl_msg_info(__func__,"For chip %d the STD should be on frame %d",
00824                      idet + 1, iframe_star+1);
00825         pos_x_cen = pos_y_cen = -1.0 ;
00826         size_x = cpl_image_get_size_x(star_ima) ;
00827         size_y = cpl_image_get_size_y(star_ima) ;
00828 
00829         /* Filtering the image*/
00830         kernel = cpl_mask_new(3, 3);
00831         cpl_mask_not(kernel);
00832         filt_ima = cpl_image_new(cpl_image_get_size_x(star_ima),
00833                                  cpl_image_get_size_y(star_ima),
00834                                  cpl_image_get_type(star_ima));
00835         cpl_image_filter_mask(filt_ima, star_ima, kernel, CPL_FILTER_MEDIAN, 
00836                               CPL_BORDER_FILTER);
00837         cpl_mask_delete(kernel);
00838 
00839         /* Looking for apertures */
00840         aperts = cpl_apertures_extract_sigma(filt_ima,
00841                 hawki_cal_zpoint_config.detect_sigma) ;
00842         cpl_image_delete(filt_ima) ;
00843         if (aperts == NULL)
00844         {
00845             cpl_msg_error(__func__, "Cannot find the central object") ;
00846             cpl_imagelist_delete(*star_images) ;
00847             cpl_bivector_delete(positions) ;
00848             return NULL ;
00849         }
00850         min_dist = size_x * size_x + size_y * size_y ;
00851         for (iaper=0 ; iaper<cpl_apertures_get_size(aperts) ; iaper++) {
00852             pos_x = cpl_apertures_get_centroid_x(aperts, iaper+1) ;
00853             pos_y = cpl_apertures_get_centroid_y(aperts, iaper+1) ;
00854             dist = (pos_x-hawki_cal_zpoint_config.xcoord[idet])*
00855                     (pos_x-hawki_cal_zpoint_config.xcoord[idet]) +
00856                    (pos_y-hawki_cal_zpoint_config.ycoord[idet])*
00857                     (pos_y-hawki_cal_zpoint_config.ycoord[idet]);
00858             if (dist<min_dist) {
00859                 min_dist = dist ;
00860                 pos_x_cen = pos_x ;
00861                 pos_y_cen = pos_y ;
00862             }
00863         }
00864         cpl_apertures_delete(aperts) ;
00865 
00866         cpl_vector_set(cpl_bivector_get_x(positions), iframe_star, pos_x_cen) ;
00867         cpl_vector_set(cpl_bivector_get_y(positions), iframe_star, pos_y_cen) ;
00868         cpl_msg_info(__func__, "Expected star position: %g %g",
00869                 hawki_cal_zpoint_config.xcoord[idet],
00870                 hawki_cal_zpoint_config.ycoord[idet]);
00871         cpl_msg_info(__func__, "Bright object position: %g %g",
00872                 pos_x_cen, pos_y_cen) ;
00873 
00874         /* Check that the star is within the search window */
00875         if(fabs(pos_x_cen - hawki_cal_zpoint_config.xcoord[idet]) >
00876                 hawki_cal_zpoint_config.sx                        ||
00877            fabs(pos_y_cen - hawki_cal_zpoint_config.ycoord[idet]) >
00878                 hawki_cal_zpoint_config.sy)
00879         {
00880             hawki_cal_zpoint_outputs.stdstar_image_detected[idet] = 0;
00881             cpl_msg_warning(cpl_func,"No object has been found within the box"
00882                             "limits [%d, %d] around the expected position",
00883                             hawki_cal_zpoint_config.sx,
00884                             hawki_cal_zpoint_config.sy);
00885         }
00886         else
00887         {
00888             hawki_cal_zpoint_outputs.stdstar_image_detected[idet] = 1;
00889         }
00890 
00891         /* Free */
00892         cpl_msg_indent_less() ;
00893     }
00894     cpl_msg_indent_less() ;
00895 
00896     /* Reorder the images (frame order) */
00897     star_images_frame_order = cpl_imagelist_new() ;
00898     for (iframe=0 ; iframe< nframes; iframe++)
00899     {
00900         tmp_ima = cpl_image_duplicate
00901             (cpl_imagelist_get(*star_images, labels[iframe] -1 ));
00902         cpl_imagelist_set(star_images_frame_order, tmp_ima, iframe);
00903     }
00904 
00905     /* Compute the photometry */
00906     cpl_msg_info(__func__, "Compute the photometry") ;
00907     cpl_msg_indent_more() ;
00908     if ((zpoint_tables = hawki_cal_zpoint_photom
00909             (star_images_frame_order, positions, labels))==NULL) {
00910         cpl_msg_error(__func__, "Cannot reduce") ;
00911         cpl_bivector_delete(positions) ;
00912         cpl_imagelist_delete(star_images_frame_order) ;
00913         cpl_msg_indent_less() ;
00914         return NULL ;
00915     }
00916 
00917 
00918     /* Free and exit */
00919     cpl_msg_indent_less() ;
00920     cpl_bivector_delete(positions) ;
00921     cpl_imagelist_delete(star_images_frame_order) ;
00922 
00923     return zpoint_tables;
00924 }
00925 
00926 /*----------------------------------------------------------------------------*/
00936 /*----------------------------------------------------------------------------*/
00937 static cpl_table ** hawki_cal_zpoint_photom(
00938         cpl_imagelist       *   ilist,
00939         cpl_bivector        *   pos,
00940         int                 *   labels)
00941 {
00942     cpl_table **        zpoint;
00943     int                 nframes;
00944     double              r, r1, r2;
00945     double              stdstar_mag;
00946     double              dit;
00947     double              extinction;
00948     double              pixscale;
00949     cpl_image       *   ima ;
00950     double          *   pos_x ;
00951     double          *   pos_y ;
00952     double              bgd, fl, zp, peak, fwhm_x, fwhm_y ;
00953     cpl_bivector    *   iqe_res ;
00954     int                 iframe;
00955     int                 idet;
00956 
00957     /* Test entries */
00958     if (ilist == NULL) return NULL ;
00959     if (pos == NULL) return NULL ;
00960 
00961     /* Initialise */
00962     nframes = cpl_imagelist_get_size(ilist) ;
00963     stdstar_mag = hawki_cal_zpoint_outputs.stdstar_mag_filter;
00964     dit = hawki_cal_zpoint_outputs.dit ;
00965     pixscale = hawki_cal_zpoint_outputs.pixscale ;
00966 
00967     /* Get extinction */
00968     switch (hawki_cal_zpoint_outputs.band) {
00969         case HAWKI_BAND_J:      extinction = 0.098 ; break ;
00970         case HAWKI_BAND_H:      extinction = 0.039 ; break ;
00971         case HAWKI_BAND_K:      extinction = 0.065 ; break ;
00972         case HAWKI_BAND_Y:      extinction = 0.00 ; break ;
00973         default:                extinction = 0.00 ; break ;
00974     }
00975     hawki_cal_zpoint_outputs.ext_coeff = extinction;
00976     cpl_msg_info(__func__,"Using tabulated extinction for band %s: %f",
00977                  hawki_cal_zpoint_outputs.filter, extinction);
00978 
00979     /* Loop on the images */
00980     for (iframe=0 ; iframe<nframes ; iframe++) {
00981         idet = labels[iframe]-1;
00982         if(hawki_cal_zpoint_outputs.stdstar_image_detected[idet] == 1)
00983         {
00984             /* Get the current image */
00985             ima = cpl_imagelist_get(ilist, iframe) ;
00986 
00987             /* Get the current position */
00988             pos_x = cpl_bivector_get_x_data(pos) ;
00989             pos_y = cpl_bivector_get_y_data(pos) ;
00990 
00991             /* FWHM_X / FWHM_Y */
00992             iqe_res = cpl_image_iqe
00993                     (ima, (int)(pos_x[iframe]-10.0), (int)(pos_y[iframe]-10.0),
00994                           (int)(pos_x[iframe]+10.0), (int)(pos_y[iframe]+10.0));
00995             if (iqe_res == NULL)
00996             {
00997                 cpl_msg_debug(__func__,"Cannot compute FWHM for chip %d",
00998                         idet + 1);
00999                 fwhm_x = fwhm_y = -1.0 ;
01000                 cpl_error_reset() ;
01001             } else {
01002                 fwhm_x = cpl_vector_get(cpl_bivector_get_x(iqe_res), 2) ;
01003                 fwhm_y = cpl_vector_get(cpl_bivector_get_x(iqe_res), 3) ;
01004                 cpl_bivector_delete(iqe_res) ;
01005             }
01006 
01007             /* Determine the radii */
01008             r = hawki_cal_zpoint_config.phot_star_radius ;
01009             if (r < 0) {
01010                 if (fwhm_x>0 && fwhm_y>0)   r = 5*(fwhm_x+fwhm_y)/2.0 ;
01011                 else                        r = HAWKI_PHOT_STAR_RADIUS ;
01012             }
01013             r1 = hawki_cal_zpoint_config.phot_bg_r1 ;
01014             r2 = hawki_cal_zpoint_config.phot_bg_r2 ;
01015             if (r1 < 0) r1 = r + 10.0 ;
01016             if (r2 < 0) r2 = r1 + 20.0 ;
01017             //cpl_msg_info(__func__, "Use radii for star: %g and background: %g, %g",
01018             //        r, r1, r2) ;
01019 
01020             /* Compute the photometry */
01021             /* Background */
01022             bgd = irplib_strehl_ring_background(ima, (int)(pos_x[iframe]),
01023                (int)(pos_y[iframe]), (int)r1, (int)r2, IRPLIB_BG_METHOD_MEDIAN);
01024             /* Flux */
01025             fl = irplib_strehl_disk_flux(ima,
01026                     (int)(pos_x[iframe]), (int)(pos_y[iframe]), (int)r, bgd);
01027             
01028             //cpl_msg_info(__func__, "Zero point in chip %d:   %g", labels[iframe], zp) ;
01029             /* Peak */
01030             peak = cpl_image_get_max_window(ima,
01031                     (int)(pos_x[iframe]-5), (int)(pos_y[iframe]-5),
01032                     (int)(pos_x[iframe]+5), (int)(pos_y[iframe]+5));
01033 
01034             /* Zero Point */
01035             if (hawki_cal_zpoint_outputs.stdstar_mag_available == 1)
01036             {
01037                 if (fl > 0 && dit > 0)
01038                 {
01039                     hawki_cal_zpoint_outputs.zpoint_computable[idet] = 1;
01040                     zp = stdstar_mag + 2.5 * log10(fl) - 2.5 * log10(dit);
01041 
01042                     hawki_cal_zpoint_outputs.zpoint[idet] = zp;
01043                     hawki_cal_zpoint_outputs.atx0[idet] = zp + 
01044                             extinction * hawki_cal_zpoint_outputs.airmass[idet];
01045                 }
01046                 else
01047                     hawki_cal_zpoint_outputs.zpoint_computable[idet] = 0;
01048             }
01049             hawki_cal_zpoint_outputs.posx[idet] = pos_x[iframe];
01050             hawki_cal_zpoint_outputs.posy[idet] = pos_y[iframe];
01051             hawki_cal_zpoint_outputs.flux[idet] = fl;
01052             hawki_cal_zpoint_outputs.instrmag[idet] = 2.5 * log10(fl/dit);
01053             hawki_cal_zpoint_outputs.peak[idet] = peak;
01054             hawki_cal_zpoint_outputs.bgd[idet] = bgd;
01055             hawki_cal_zpoint_outputs.fwhmx[idet] = fwhm_x;
01056             hawki_cal_zpoint_outputs.fwhmy[idet] = fwhm_y;
01057             if (fwhm_x > 0 && fwhm_y > 0)
01058                 hawki_cal_zpoint_outputs.fwhm[idet] = sqrt(fwhm_x*fwhm_y);
01059             else
01060                 hawki_cal_zpoint_outputs.fwhm[idet] = -1.0;
01061             hawki_cal_zpoint_outputs.fwhmx_as[idet] = fwhm_x * pixscale;
01062             hawki_cal_zpoint_outputs.fwhmy_as[idet] = fwhm_y * pixscale;
01063             if (fwhm_x > 0 && fwhm_y > 0)
01064                 hawki_cal_zpoint_outputs.fwhm_as[idet] =
01065                         sqrt(fwhm_x*fwhm_y*pixscale*pixscale);
01066             else
01067                 hawki_cal_zpoint_outputs.fwhm_as[labels[iframe]-1] = -1.0;
01068         }
01069         else
01070         {
01071             cpl_msg_warning(cpl_func,"Standard star not detected in chip %d. "
01072                     "No zeropoint computed.", idet + 1);
01073         }
01074 
01075     }
01076 
01077     /* Create the table */
01078     zpoint = hawki_table_new(1);
01079     //tab = cpl_table_new(nframes) ;
01080     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
01081         cpl_table_new_column(zpoint[idet], 
01082                              HAWKI_COL_ZPOINT_CHIP, CPL_TYPE_INT);
01083         cpl_table_new_column(zpoint[idet], 
01084                              HAWKI_COL_ZPOINT_STARNAME, CPL_TYPE_STRING);
01085         cpl_table_new_column(zpoint[idet], 
01086                              HAWKI_COL_ZPOINT_POSX, CPL_TYPE_DOUBLE);
01087         cpl_table_set_column_unit(zpoint[idet],
01088                                   HAWKI_COL_ZPOINT_POSX,"pix");
01089         cpl_table_new_column(zpoint[idet], 
01090                              HAWKI_COL_ZPOINT_POSY, CPL_TYPE_DOUBLE);
01091         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_POSY,"pix");
01092         cpl_table_new_column(zpoint[idet], 
01093                              HAWKI_COL_ZPOINT_ZPOINT, CPL_TYPE_DOUBLE);
01094         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_ZPOINT,"mag");
01095         cpl_table_new_column(zpoint[idet], 
01096                              HAWKI_COL_ZPOINT_ATX0, CPL_TYPE_DOUBLE);
01097         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_ATX0,"mag");
01098         cpl_table_new_column(zpoint[idet], 
01099                              HAWKI_COL_ZPOINT_AIRMASS, CPL_TYPE_DOUBLE);
01100         cpl_table_new_column(zpoint[idet], 
01101                              HAWKI_COL_ZPOINT_FLUX, CPL_TYPE_DOUBLE);
01102         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_FLUX,"ADU");
01103         cpl_table_new_column(zpoint[idet], 
01104                              HAWKI_COL_ZPOINT_INSTRMAG, CPL_TYPE_DOUBLE);
01105         cpl_table_set_column_unit(zpoint[idet],
01106                                   HAWKI_COL_ZPOINT_INSTRMAG,"log(ADU/s)");
01107         cpl_table_new_column(zpoint[idet], 
01108                              HAWKI_COL_ZPOINT_FILTER, CPL_TYPE_STRING);
01109         cpl_table_new_column(zpoint[idet], 
01110                              HAWKI_COL_ZPOINT_PEAK, CPL_TYPE_DOUBLE);
01111         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_PEAK,"ADU");
01112         cpl_table_new_column(zpoint[idet], 
01113                              HAWKI_COL_ZPOINT_BGD, CPL_TYPE_DOUBLE);
01114         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_BGD,"ADU");
01115         cpl_table_new_column(zpoint[idet], 
01116                              HAWKI_COL_ZPOINT_FWHMX, CPL_TYPE_DOUBLE);
01117         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_FWHMX,"pix");
01118         cpl_table_new_column(zpoint[idet], 
01119                              HAWKI_COL_ZPOINT_FWHMY, CPL_TYPE_DOUBLE);
01120         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_FWHMY,"pix");
01121         cpl_table_new_column(zpoint[idet], 
01122                              HAWKI_COL_ZPOINT_FWHM, CPL_TYPE_DOUBLE);
01123         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_FWHM,"pix");
01124         cpl_table_new_column(zpoint[idet], 
01125                              HAWKI_COL_ZPOINT_FWHMX_AS, CPL_TYPE_DOUBLE);
01126         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_FWHMX_AS,"arcsec");
01127         cpl_table_new_column(zpoint[idet], 
01128                              HAWKI_COL_ZPOINT_FWHMY_AS, CPL_TYPE_DOUBLE);
01129         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_FWHMY_AS,"arcsec");
01130         cpl_table_new_column(zpoint[idet], 
01131                              HAWKI_COL_ZPOINT_FWHM_AS, CPL_TYPE_DOUBLE);
01132         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_FWHM_AS,"arcsec");
01133         cpl_table_new_column(zpoint[idet], 
01134                              HAWKI_COL_ZPOINT_STARMAG, CPL_TYPE_DOUBLE);
01135         cpl_table_set_column_unit(zpoint[idet],HAWKI_COL_ZPOINT_STARMAG,"mag");
01136         
01137         cpl_table_set_int(zpoint[idet], HAWKI_COL_ZPOINT_CHIP, 0, idet+1) ;
01138         cpl_table_set_string(zpoint[idet], HAWKI_COL_ZPOINT_FILTER, 0,
01139                 hawki_cal_zpoint_outputs.filter);
01140         cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_AIRMASS, 0,
01141                 hawki_cal_zpoint_outputs.airmass[idet]) ;
01142         if(hawki_cal_zpoint_outputs.stdstar_incat_found== 1)
01143         {
01144             cpl_table_set_string(zpoint[idet], HAWKI_COL_ZPOINT_STARNAME, 0,
01145                     hawki_cal_zpoint_outputs.starname) ;
01146             if(hawki_cal_zpoint_outputs.stdstar_mag_available== 1)
01147             {
01148                 cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_STARMAG, 0,
01149                         hawki_cal_zpoint_outputs.stdstar_mag_filter);
01150             }
01151         }
01152         if(hawki_cal_zpoint_outputs.stdstar_image_detected[idet] == 1)
01153         {
01154             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_POSX, 0,
01155                     hawki_cal_zpoint_outputs.posx[idet]) ;
01156             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_POSY, 0,
01157                                  hawki_cal_zpoint_outputs.posy[idet]) ;
01158             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_FLUX, 0,
01159                                  hawki_cal_zpoint_outputs.flux[idet]) ;
01160             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_INSTRMAG, 0,
01161                                  hawki_cal_zpoint_outputs.instrmag[idet]) ;
01162             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_PEAK, 0,
01163                                  hawki_cal_zpoint_outputs.peak[idet]) ;
01164             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_BGD, 0,
01165                                  hawki_cal_zpoint_outputs.bgd[idet]) ;
01166             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_FWHMX, 0,
01167                                  hawki_cal_zpoint_outputs.fwhmx[idet]) ;
01168             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_FWHMY, 0,
01169                                  hawki_cal_zpoint_outputs.fwhmy[idet]) ;
01170             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_FWHM, 0,
01171                                  hawki_cal_zpoint_outputs.fwhm[idet]) ;
01172             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_FWHMX_AS, 0,
01173                                  hawki_cal_zpoint_outputs.fwhmx_as[idet]) ;
01174             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_FWHMY_AS, 0,
01175                                  hawki_cal_zpoint_outputs.fwhmy_as[idet]) ;
01176             cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_FWHM_AS, 0,
01177                                  hawki_cal_zpoint_outputs.fwhm_as[idet]) ;
01178             if(hawki_cal_zpoint_outputs.zpoint_computable[idet] == 1)
01179             {
01180                 cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_ZPOINT, 0,
01181                         hawki_cal_zpoint_outputs.zpoint[idet]);
01182                 cpl_table_set_double(zpoint[idet], HAWKI_COL_ZPOINT_ATX0, 0,
01183                         hawki_cal_zpoint_outputs.atx0[idet]);
01184             }
01185         }
01186     }
01187 
01188     /* Mean values */
01189     if(hawki_cal_zpoint_outputs.stdstar_mag_available == 1)
01190     {
01191         int nzpoint = 0;
01192         hawki_cal_zpoint_outputs.mean_zpoint = 0.0 ;
01193         hawki_cal_zpoint_outputs.mean_atx0 = 0.0 ;
01194         for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
01195             if(hawki_cal_zpoint_outputs.zpoint_computable[idet] == 1)
01196             {
01197 
01198                 hawki_cal_zpoint_outputs.mean_zpoint +=
01199                         hawki_cal_zpoint_outputs.zpoint[idet] ;
01200                 hawki_cal_zpoint_outputs.mean_atx0  +=
01201                         hawki_cal_zpoint_outputs.atx0[idet] ;
01202                 nzpoint++;
01203             }
01204         }
01205         if(nzpoint > 0)
01206         {
01207             hawki_cal_zpoint_outputs.zpoint_mean_computable = 1;
01208             hawki_cal_zpoint_outputs.mean_zpoint /= nzpoint ;
01209             hawki_cal_zpoint_outputs.mean_atx0 /= nzpoint ;
01210         }
01211     }
01212     
01213     /* Output results */
01214     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01215     {
01216         if(hawki_cal_zpoint_outputs.zpoint_computable[idet] == 1)
01217         {
01218             cpl_msg_info(__func__, "Zero point [at airmass=1] in chip %d:",
01219                     idet + 1);
01220             cpl_msg_indent_more();
01221             cpl_msg_info(__func__,"   ZP: %g [%g]",
01222                          hawki_cal_zpoint_outputs.zpoint[idet],
01223                          hawki_cal_zpoint_outputs.atx0[idet]);
01224             cpl_msg_info(__func__,"   Flux of star: %f",
01225                          hawki_cal_zpoint_outputs.flux[idet]);
01226             cpl_msg_indent_less();
01227         }
01228         else
01229             cpl_msg_info(__func__, "Zero point not available for chip %d",
01230                     idet + 1);
01231 
01232     }
01233 
01234     return zpoint;
01235 }
01236 
01237 /*----------------------------------------------------------------------------*/
01245 /*----------------------------------------------------------------------------*/
01246 static int hawki_cal_zpoint_get_mag(
01247         const char  *       std_file,
01248         double              pointing_ra,
01249         double              pointing_dec,
01250         hawki_band          band)
01251 {
01252     cpl_table      * catalogue;
01253     char           * star_name;
01254     char           * used_catname;
01255     char           * star_type;
01256     double           stdstar_ra;
01257     double           stdstar_dec;
01258     double           mag_filter;
01259     double           mag_J;
01260     double           mag_H;
01261     double           mag_K;
01262     double           mag_Y;
01263     int              mag_invalid;
01264     int              star_ind;
01265 
01266     hawki_cal_zpoint_outputs.stdstar_incat_found = 0;    
01267     
01268     /* Load the catalog */
01269     if ((catalogue = irplib_stdstar_load_catalog(std_file, "all")) == NULL) {
01270         cpl_msg_error(cpl_func,"Cannot read catalogue file %s",std_file);
01271         return -1;
01272     }
01273 
01274     /* Check that the columns are there */
01275     if (irplib_stdstar_check_columns_exist(catalogue) != CPL_ERROR_NONE) {
01276         cpl_msg_error(cpl_func,"Note all the columns are present"
01277                       " in the  catalogue file %s",std_file);
01278         return -1;
01279     }    
01280     
01281     /* Select stars within a given distance */
01282     if (irplib_stdstar_select_stars_dist(catalogue, 
01283             pointing_ra, pointing_dec, 5.0) == -1) {
01284         cpl_table_delete(catalogue) ;
01285         return 1;
01286     }
01287 
01288     /* Take the closest */
01289     if ((star_ind=irplib_stdstar_find_closest(catalogue, 
01290             pointing_ra, pointing_dec)) < 0) {
01291         cpl_table_delete(catalogue) ;
01292         return 1;
01293     }
01294 
01295     /* Retrieve the star information */
01296     hawki_cal_zpoint_outputs.stdstar_incat_found = 1;    
01297     star_name = cpl_strdup(cpl_table_get_string(catalogue,
01298                                             IRPLIB_STDSTAR_STAR_COL, star_ind));
01299     used_catname = cpl_strdup(cpl_table_get_string
01300                               (catalogue, IRPLIB_STDSTAR_CAT_COL, star_ind));
01301     star_type = cpl_strdup(cpl_table_get_string(catalogue, 
01302             IRPLIB_STDSTAR_TYPE_COL, star_ind));
01303     stdstar_ra  = cpl_table_get_double(catalogue, 
01304             IRPLIB_STDSTAR_RA_COL, star_ind, NULL);
01305     stdstar_dec = cpl_table_get_double(catalogue, 
01306             IRPLIB_STDSTAR_DEC_COL, star_ind, NULL);
01307     mag_filter = cpl_table_get_double(catalogue, hawki_std_band_name(band), 
01308             star_ind, &mag_invalid);
01309     mag_H = cpl_table_get_double(catalogue, hawki_std_band_name(HAWKI_BAND_H),
01310             star_ind, NULL);
01311     mag_J = cpl_table_get_double(catalogue, hawki_std_band_name(HAWKI_BAND_J), 
01312             star_ind, NULL);
01313     mag_K = cpl_table_get_double(catalogue, hawki_std_band_name(HAWKI_BAND_K), 
01314             star_ind, NULL);
01315     mag_Y = cpl_table_get_double(catalogue, hawki_std_band_name(HAWKI_BAND_Y), 
01316             star_ind, NULL);
01317     
01318     /* Store results */
01319     strncpy(hawki_cal_zpoint_outputs.starname, star_name, 510);
01320     strncpy(hawki_cal_zpoint_outputs.sptype, star_type, 510);
01321     strncpy(hawki_cal_zpoint_outputs.catalog, used_catname, 510);
01322     hawki_cal_zpoint_outputs.stdstar_ra = stdstar_ra;
01323     hawki_cal_zpoint_outputs.stdstar_dec = stdstar_dec;
01324     if(mag_invalid == 0)
01325     {
01326         hawki_cal_zpoint_outputs.stdstar_mag_available = 1;
01327         hawki_cal_zpoint_outputs.stdstar_mag_filter = mag_filter;
01328     }
01329     else
01330         hawki_cal_zpoint_outputs.stdstar_mag_available = 0;
01331     hawki_cal_zpoint_outputs.stdstar_mag_H = mag_H;
01332     hawki_cal_zpoint_outputs.stdstar_mag_J = mag_J;
01333     hawki_cal_zpoint_outputs.stdstar_mag_K = mag_K;
01334     hawki_cal_zpoint_outputs.stdstar_mag_Y = mag_Y;
01335     cpl_free(star_name);
01336     cpl_free(star_type);
01337     cpl_free(used_catname);
01338     cpl_table_delete(catalogue);
01339     
01340     return 0;
01341 }
01342 
01343 /*----------------------------------------------------------------------------*/
01352 /*----------------------------------------------------------------------------*/
01353 static int hawki_cal_zpoint_save
01354 (cpl_table           **  zpoint_tables,
01355  int                 *   labels,
01356  cpl_imagelist       *   images,
01357  cpl_table           **  raw_zpoint_stats,
01358  cpl_frameset        *   zpoint_frames,
01359  cpl_frameset        *   calib_frames,
01360  const cpl_frame     *   stars_frame,
01361  cpl_parameterlist   *   parlist,
01362  cpl_frameset        *   set)
01363 {
01364     cpl_propertylist    *   qcmainparams;
01365     cpl_propertylist    **  qcextparams;
01366     cpl_propertylist    *   mainheader;
01367     cpl_propertylist    **  extheaders;
01368     cpl_propertylist    **  statsqcextparams;
01369     cpl_propertylist    **  statsextheaders;
01370     cpl_frameset        *   used_frames;
01371     const char          *   ref_filename;
01372     const char          *   recipe_name = "hawki_cal_zpoint" ;
01373     int                     idet;
01374     int                     iframe;
01375     cpl_errorstate          error_prevstate = cpl_errorstate_get();
01376 
01377 
01378     /* Get the reference frame */
01379     ref_filename = hawki_get_extref_file(set);
01380 
01381     /* Create QC parameters for the zpoint table */
01382     qcmainparams = cpl_propertylist_new();
01383     qcextparams = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
01384     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01385         qcextparams[idet] = cpl_propertylist_new();
01386     /* Write QC parameters */
01387     hawki_cal_zpoint_compute_qc(qcmainparams, qcextparams, set);
01388     
01389     /* Create QC parameters for the stats table: Statistics of the raw images */
01390     statsqcextparams = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
01391     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01392         statsqcextparams[idet] = cpl_propertylist_new();
01393     hawki_image_stats_stats(raw_zpoint_stats, statsqcextparams);    
01394     
01395     /* Create the main and extension headers for the zpoint table*/
01396     mainheader = cpl_propertylist_new();
01397     extheaders = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
01398     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01399         extheaders[idet] = cpl_propertylist_new();
01400     /* Copy QC params to the headers */
01401     cpl_propertylist_append(mainheader, qcmainparams);
01402     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01403         cpl_propertylist_append(extheaders[idet], qcextparams[idet]) ;
01404     
01405     /* Create the  extension headers for the stats table*/
01406     statsextheaders = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
01407     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01408         statsextheaders[idet] = cpl_propertylist_duplicate(statsqcextparams[idet]);
01409     
01410     /* Write additional keywords to the headers */
01411     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01412     {
01413         cpl_propertylist    *   inputlist;
01414         cpl_propertylist    *   wcslist;
01415         int                     this_iframe = -1;
01416         int                     ext_nb;
01417 
01418         /* Propagate some keywords from input raw frame extensions */
01419         ext_nb=hawki_get_ext_from_detector(ref_filename, idet+1);
01420         inputlist = cpl_propertylist_load_regexp(ref_filename, ext_nb,
01421                 HAWKI_HEADER_EXT_FORWARD, 0);
01422         cpl_propertylist_append(extheaders[idet], inputlist);
01423         cpl_propertylist_append(statsextheaders[idet], inputlist);
01424         cpl_propertylist_delete(inputlist);
01425 
01426         /* Propagate WCS keywords */
01427         for(iframe=0; iframe<cpl_frameset_get_size(zpoint_frames); iframe++)
01428             if(labels[iframe] == idet + 1)
01429                 this_iframe = iframe;
01430         wcslist = cpl_propertylist_load_regexp
01431             (cpl_frame_get_filename(cpl_frameset_get_frame(zpoint_frames, this_iframe)),
01432                                     ext_nb, HAWKI_HEADER_WCS, 0);
01433         cpl_propertylist_copy_property_regexp
01434             (extheaders[idet], wcslist, HAWKI_HEADER_WCS, 0);
01435         cpl_propertylist_delete(wcslist);
01436     }
01437     
01438     /* Write the zpoint table  */
01439     used_frames = cpl_frameset_duplicate(zpoint_frames);
01440     for(iframe = 0; iframe< cpl_frameset_get_size(calib_frames); ++iframe)
01441         cpl_frameset_insert(used_frames, cpl_frame_duplicate(
01442                 cpl_frameset_get_frame(calib_frames, iframe)));
01443     cpl_frameset_insert(used_frames, cpl_frame_duplicate(stars_frame));
01444     hawki_tables_save(set,
01445                       parlist,
01446                       used_frames,
01447                       (const cpl_table **)zpoint_tables,
01448                       recipe_name,
01449                       HAWKI_CALPRO_ZPOINT_TAB,
01450                       HAWKI_PROTYPE_ZPOINT_TAB,
01451                       mainheader,
01452                       (const cpl_propertylist **)extheaders,
01453                       "hawki_cal_zpoint.fits");
01454     cpl_frameset_delete(used_frames);
01455     
01456     /* Write the table with the raw zpoint objects statistics */
01457     used_frames = cpl_frameset_duplicate(zpoint_frames);
01458     hawki_tables_save(set,
01459                       parlist,
01460                       used_frames,
01461                       (const cpl_table **)raw_zpoint_stats,
01462                       recipe_name,
01463                       HAWKI_CALPRO_ZPOINT_STATS,
01464                       HAWKI_PROTYPE_ZPOINT_STATS,
01465                       NULL,
01466                       (const cpl_propertylist **)statsextheaders,
01467                       "hawki_cal_zpoint_stats.fits");
01468 
01469     /* Write the images  */
01470     for(iframe = 0; iframe< cpl_frameset_get_size(calib_frames); ++iframe)
01471         cpl_frameset_insert(used_frames, cpl_frame_duplicate(
01472                 cpl_frameset_get_frame(calib_frames, iframe)));
01473     hawki_imagelist_save(set,
01474                          parlist,
01475                          used_frames,
01476                          images,
01477                          recipe_name,
01478                          HAWKI_CALPRO_ZPOINT_IMA,
01479                          HAWKI_PROTYPE_ZPOINT_IMA,
01480                          NULL,
01481                          NULL,
01482                          "hawki_cal_zpoint_check.fits") ;
01483     cpl_frameset_delete(used_frames);
01484 
01485     /* Free */
01486     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
01487         cpl_propertylist_delete(extheaders[idet]) ;
01488         cpl_propertylist_delete(qcextparams[idet]) ;
01489         cpl_propertylist_delete(statsqcextparams[idet]);
01490         cpl_propertylist_delete(statsextheaders[idet]);
01491     }
01492     cpl_propertylist_delete(mainheader);
01493     cpl_propertylist_delete(qcmainparams);
01494     cpl_free(extheaders);
01495     cpl_free(qcextparams);
01496     cpl_free(statsqcextparams);
01497     cpl_free(statsextheaders);
01498 
01499     /* Free */
01500     if(!cpl_errorstate_is_equal(error_prevstate))
01501     {
01502         cpl_errorstate_set(CPL_ERROR_NONE);
01503         return -1;
01504     }
01505     return  0;
01506 }
01507 
01508 /*----------------------------------------------------------------------------*/
01515 /*----------------------------------------------------------------------------*/
01516 static int hawki_cal_zpoint_compute_qc
01517 (cpl_propertylist *   qcmainparams, 
01518  cpl_propertylist **  qcextparams,
01519  cpl_frameset     *   set)
01520 {
01521     int  idet;
01522     int  nframes;
01523 
01524     
01525     nframes = cpl_frameset_get_size(set) ;
01526 
01527     /* Check inputs */
01528     if (qcmainparams == NULL) return -1;
01529     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01530         if (qcextparams[idet] == NULL) return -1;
01531     
01532     /* Write the QC params common to all extensions in the main header */
01533     cpl_propertylist_append_string(qcmainparams, "ESO QC FILTER OBS",
01534             hawki_cal_zpoint_outputs.filter);
01535     cpl_propertylist_set_comment(qcmainparams, "ESO QC FILTER OBS",
01536                                  "Observation filter");
01537     cpl_propertylist_append_string(qcmainparams, "ESO QC FILTER REF",
01538             hawki_std_band_name(hawki_cal_zpoint_outputs.band)) ;
01539     cpl_propertylist_set_comment(qcmainparams, "ESO QC FILTER REF",
01540                                  "Reference filter");
01541     cpl_propertylist_append_double(qcmainparams, "ESO QC AMBI RHUM AVG",
01542             hawki_cal_zpoint_outputs.humidity);
01543     cpl_propertylist_set_comment(qcmainparams, "ESO QC AMBI RHUM AVG",
01544                      "(percent) ambient relative humidity @ 30/2 m");
01545     cpl_propertylist_append_double(qcmainparams, "ESO QC AIRMASS MEAN",
01546             hawki_cal_zpoint_outputs.mean_airmass) ;
01547     cpl_propertylist_set_comment(qcmainparams, "ESO QC AIRMASS MEAN",
01548                                  "Average airmass");
01549     cpl_propertylist_append_double(qcmainparams, "ESO QC DATANCOM",
01550                                    nframes);
01551     cpl_propertylist_set_comment(qcmainparams, "ESO QC DATANCOM",
01552                                  "Number of files used for the reduction");
01553     if(hawki_cal_zpoint_outputs.stdstar_incat_found == 1)
01554     {
01555         cpl_propertylist_append_string(qcmainparams, "ESO QC STDNAME",
01556                 hawki_cal_zpoint_outputs.starname) ;
01557         cpl_propertylist_set_comment(qcmainparams, "ESO QC STDNAME",
01558                                      "Standard star name");
01559         cpl_propertylist_append_string(qcmainparams, "ESO QC SPECTYPE",
01560                                        hawki_cal_zpoint_outputs.sptype) ;
01561         cpl_propertylist_set_comment(qcmainparams, "ESO QC SPECTYPE",
01562                                      "Standard star spectral type");
01563         cpl_propertylist_append_double(qcmainparams, "ESO QC STARMAG H",
01564                                        hawki_cal_zpoint_outputs.stdstar_mag_H) ;
01565         cpl_propertylist_set_comment(qcmainparams, "ESO QC STARMAG H",
01566                                      "Standard star magnitude in H");
01567         cpl_propertylist_append_double(qcmainparams, "ESO QC STARMAG J",
01568                                        hawki_cal_zpoint_outputs.stdstar_mag_J) ;
01569         cpl_propertylist_set_comment(qcmainparams, "ESO QC STARMAG J",
01570                                      "Standard star magnitude in J");
01571         cpl_propertylist_append_double(qcmainparams, "ESO QC STARMAG K",
01572                                        hawki_cal_zpoint_outputs.stdstar_mag_K) ;
01573         cpl_propertylist_set_comment(qcmainparams, "ESO QC STARMAG K",
01574                                      "Standard star magnitude in K");
01575         cpl_propertylist_append_double(qcmainparams, "ESO QC STARMAG Y",
01576                                        hawki_cal_zpoint_outputs.stdstar_mag_Y) ;
01577         cpl_propertylist_set_comment(qcmainparams, "ESO QC STARMAG Y",
01578                                      "Standard star magnitude in Y");
01579         cpl_propertylist_append_string(qcmainparams, "ESO QC CATNAME",
01580                                        hawki_cal_zpoint_outputs.catalog) ;
01581         cpl_propertylist_set_comment(qcmainparams, "ESO QC CATNAME",
01582                                      "Standard star catalogue name");
01583     }
01584     if(hawki_cal_zpoint_outputs.stdstar_mag_available == 1)
01585     {
01586         cpl_propertylist_append_double(qcmainparams, "ESO QC STARMAG",
01587                 hawki_cal_zpoint_outputs.stdstar_mag_filter) ;
01588         cpl_propertylist_set_comment(qcmainparams, "ESO QC STARMAG",
01589                                  "Standard star magnitude in observed filter");
01590     }
01591     if(hawki_cal_zpoint_outputs.zpoint_mean_computable == 1)
01592     {
01593         cpl_propertylist_append_double(qcmainparams, "ESO QC ZPOINT MEAN",
01594                 hawki_cal_zpoint_outputs.mean_zpoint) ;
01595         cpl_propertylist_set_comment(qcmainparams, "ESO QC ZPOINT MEAN",
01596                             "Mean measured zero-point for all the chips [mag]");
01597         cpl_propertylist_append_double(qcmainparams, "ESO QC ATX0 MEAN",
01598                                        hawki_cal_zpoint_outputs.mean_atx0);
01599         cpl_propertylist_set_comment(qcmainparams, "ESO QC ATX0 MEAN",
01600                "Mean extinction corrected zero-point for all the chips [mag]");
01601         cpl_propertylist_append_double(qcmainparams, "ESO QC ZPOINT EXT COEFF",
01602                                        hawki_cal_zpoint_outputs.ext_coeff);
01603         cpl_propertylist_set_comment(qcmainparams, "ESO QC ZPOINT EXT COEFF",
01604                "Extinction coefficient used in the computation of ATX0");
01605     }
01606         
01607     /* Write QC params that are specific of the extension */
01608     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01609     {
01610         if(hawki_cal_zpoint_outputs.zpoint_computable[idet] == 1)
01611         {
01612             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT",
01613                     hawki_cal_zpoint_outputs.zpoint[idet]) ;
01614             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT",
01615                                  "Measured zero-point for a given chip [mag]");
01616             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ATX0",
01617                                            hawki_cal_zpoint_outputs.atx0[idet]);
01618             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ATX0",
01619                      "Extinction corrected zero-point for a given chip [mag]");
01620         }
01621         if(hawki_cal_zpoint_outputs.stdstar_image_detected[idet] == 1)
01622         {
01623             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT POSX",
01624                                            hawki_cal_zpoint_outputs.posx[idet]);
01625             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT POSX",
01626                                     "X position of the standard star [pixel]");
01627             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT POSY",
01628                                            hawki_cal_zpoint_outputs.posy[idet]);
01629             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT POSY",
01630                                     "Y position of the standard star [pixel]");
01631             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT FLUX",
01632                                         hawki_cal_zpoint_outputs.flux[idet]);
01633             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT FLUX",
01634                     "Flux of the standard star [ADU]");
01635             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT PEAK",
01636                                            hawki_cal_zpoint_outputs.peak[idet]) ;
01637             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT PEAK",
01638                                          "Peak of the standard star [ADU]");
01639             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT BGD",
01640                                            hawki_cal_zpoint_outputs.bgd[idet]) ;
01641             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT BGD",
01642                                    "Background around the standard star [ADU]");
01643             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT FWHMX",
01644                                         hawki_cal_zpoint_outputs.fwhmx[idet]);
01645             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT FWHMX",
01646                                          "X FWHM of the standard star [pixel]");
01647             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT FWHMY",
01648                                          hawki_cal_zpoint_outputs.fwhmy[idet]);
01649             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT FWHMY",
01650                                          "Y FWHM of the standard star [pixel]");
01651             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT FWHM",
01652                                            hawki_cal_zpoint_outputs.fwhm[idet]);
01653             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT FWHM",
01654                                          "FWHM of the standard star [pixel]");
01655             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT FWHMX_AS",
01656                                       hawki_cal_zpoint_outputs.fwhmx_as[idet]);
01657             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT FWHMX_AS",
01658                                        "X FWHM of the standard star [arcsec]");
01659             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT FWHMY_AS",
01660                                     hawki_cal_zpoint_outputs.fwhmy_as[idet]);
01661             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT FWHMY_AS",
01662                                       "Y FWHM of the standard star [arcsec]");
01663             cpl_propertylist_append_double(qcextparams[idet], "ESO QC ZPOINT FWHM_AS",
01664                                        hawki_cal_zpoint_outputs.fwhm_as[idet]);
01665             cpl_propertylist_set_comment(qcextparams[idet], "ESO QC ZPOINT FWHM_AS",
01666                                          "FWHM of the standard star [arcsec]");
01667         }
01668     }
01669     return 0;
01670 }
01671 
01672 /*----------------------------------------------------------------------------*/
01678 /*----------------------------------------------------------------------------*/
01679 static int hawki_cal_zpoint_compute_keywords(
01680         cpl_frameset    *   set,
01681         int             *   labels)
01682 {
01683     int                     nframes ;
01684     cpl_vector          *   hum_vec ;
01685     cpl_frame           *   cur_frame ;
01686     cpl_propertylist    *   plist ;
01687     int                     iframe;
01688 
01689     /* Test inputs  */
01690     if (set == NULL) return -1 ;
01691 
01692     /* Initialize */
01693     nframes = cpl_frameset_get_size(set) ;
01694     hawki_cal_zpoint_outputs.mean_airmass   = 0.0 ;
01695 
01696     hum_vec = cpl_vector_new(nframes) ;
01697 
01698     for (iframe=0 ; iframe<nframes ; iframe++) {
01699         if (cpl_error_get_code()) {
01700             cpl_vector_delete(hum_vec) ;
01701             return -1 ;
01702         }
01703         cur_frame = cpl_frameset_get_frame(set, iframe) ;
01704         plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0) ;
01705         if (iframe==0) 
01706             hawki_cal_zpoint_outputs.mean_airmass += 
01707                 hawki_pfits_get_airmass_start(plist) ; 
01708         if (iframe==nframes-1) 
01709             hawki_cal_zpoint_outputs.mean_airmass += 
01710                 hawki_pfits_get_airmass_end(plist);
01711         hawki_cal_zpoint_outputs.airmass[labels[iframe] - 1] = 
01712             (hawki_pfits_get_airmass_start(plist) + 
01713              hawki_pfits_get_airmass_end(plist)) / 2.;
01714         cpl_vector_set(hum_vec,  iframe, hawki_pfits_get_humidity_level(plist));
01715         cpl_propertylist_delete(plist) ;
01716         if (cpl_error_get_code()) {
01717             cpl_vector_delete(hum_vec) ;
01718             cpl_error_reset() ;
01719             return -1 ;
01720         }
01721     }
01722     hawki_cal_zpoint_outputs.humidity  = cpl_vector_get_mean(hum_vec) ;
01723     hawki_cal_zpoint_outputs.mean_airmass /= 2 ;
01724 
01725     /* Free and return */
01726     cpl_vector_delete(hum_vec) ;
01727     if (cpl_error_get_code()) return -1 ;
01728     return 0 ;
01729 }
01730 
01731 static cpl_error_code hawki_cal_zpoint_get_expected_pos
01732 (cpl_frameset * set,
01733  int          * labels)
01734 {
01735     const char *  filename;
01736     int           iframe;
01737 
01738     for(iframe=0 ; iframe<HAWKI_NB_DETECTORS ; iframe++)
01739     {
01740         cpl_propertylist * wcs_plist;
01741         cpl_wcs          * wcs;
01742         int                idet;
01743 
01744         idet = labels[iframe];
01745         if(hawki_cal_zpoint_config.xcoord[idet - 1] == -1 ||
01746                 hawki_cal_zpoint_config.ycoord[idet - 1] == -1)
01747         {
01748             filename = cpl_frame_get_filename
01749                 (cpl_frameset_get_frame_const(set, iframe));
01750             wcs_plist = cpl_propertylist_load
01751                 (filename, hawki_get_ext_from_detector(filename, idet));
01752             wcs = cpl_wcs_new_from_propertylist(wcs_plist);
01753             cpl_propertylist_delete(wcs_plist);
01754             if(wcs == NULL)
01755             {
01756                 cpl_msg_error(__func__, "Could not get WCS info");
01757                 cpl_wcs_delete(wcs);
01758                 return CPL_ERROR_ILLEGAL_INPUT;
01759             }
01760             if(irplib_wcs_radectoxy(wcs,
01761                                     hawki_cal_zpoint_outputs.stdstar_ra,
01762                                     hawki_cal_zpoint_outputs.stdstar_dec,
01763                                     &(hawki_cal_zpoint_config.xcoord[idet - 1]),
01764                                     &(hawki_cal_zpoint_config.ycoord[idet - 1]))
01765                     != CPL_ERROR_NONE)
01766             {
01767                 cpl_msg_error(__func__,"Could not get the expected position of star");
01768                 cpl_wcs_delete(wcs);
01769                 return CPL_ERROR_UNSPECIFIED;
01770             }
01771             cpl_msg_info(cpl_func,
01772                          "Star expected position in detector %d is X=%f Y=%f",
01773                          idet, hawki_cal_zpoint_config.xcoord[idet - 1],
01774                          hawki_cal_zpoint_config.ycoord[idet - 1]);
01775 
01776             /* Free */
01777             cpl_wcs_delete(wcs);
01778         }
01779         else
01780         {
01781             cpl_msg_info(cpl_func,
01782                         "Using given star position in detector %d: X=%f Y=%f",
01783                          idet,
01784                          hawki_cal_zpoint_config.xcoord[idet - 1],
01785                          hawki_cal_zpoint_config.ycoord[idet - 1]);
01786 
01787         }
01788     }
01789 
01790     return 0;
01791 }
01792 
01793 
01794 static void hawki_cal_zpoint_output_init(void)
01795 {
01796     int idet;
01797 
01798     hawki_cal_zpoint_outputs.starname[0] = (char)0 ;
01799     hawki_cal_zpoint_outputs.sptype[0] = (char)0 ;
01800     hawki_cal_zpoint_outputs.filter[0] = (char)0 ;
01801     hawki_cal_zpoint_outputs.catalog[0] = (char)0 ;
01802     hawki_cal_zpoint_outputs.pixscale = -1.0 ;
01803     hawki_cal_zpoint_outputs.dit = -1.0 ;
01804     hawki_cal_zpoint_outputs.humidity = -1.0 ;
01805     hawki_cal_zpoint_outputs.mean_airmass = -1.0 ;
01806     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
01807     {
01808         hawki_cal_zpoint_outputs.airmass[idet] = -1.0 ;
01809         hawki_cal_zpoint_outputs.zpoint[idet] = -1.0 ;
01810         hawki_cal_zpoint_outputs.atx0[idet] = -1.0 ;
01811         hawki_cal_zpoint_outputs.posx[idet] = -1.0 ;
01812         hawki_cal_zpoint_outputs.posy[idet] = -1.0 ;
01813         hawki_cal_zpoint_outputs.flux[idet] = -1.0 ;
01814         hawki_cal_zpoint_outputs.peak[idet] = -1.0 ;
01815         hawki_cal_zpoint_outputs.bgd[idet] = -1.0 ;
01816         hawki_cal_zpoint_outputs.fwhmx[idet] = -1.0 ;
01817         hawki_cal_zpoint_outputs.fwhmy[idet] = -1.0 ;
01818         hawki_cal_zpoint_outputs.fwhm[idet] = -1.0 ;
01819         hawki_cal_zpoint_outputs.fwhmx_as[idet] = -1.0 ;
01820         hawki_cal_zpoint_outputs.fwhmy_as[idet] = -1.0 ;
01821         hawki_cal_zpoint_outputs .fwhm_as[idet] = -1.0 ;
01822     }
01823 }
01824 
01825 int hawki_cal_zpoint_retrieve_input_param
01826 (cpl_parameterlist  *  parlist)
01827 {
01828     cpl_parameter   *   par ;
01829     const char      *   sval ;
01830 
01831     par = NULL ;
01832 
01833     /* --ra */
01834     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.ra") ;
01835     hawki_cal_zpoint_config.target_ra = cpl_parameter_get_double(par) ;
01836     /* --dec */
01837     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.dec") ;
01838     hawki_cal_zpoint_config.target_dec = cpl_parameter_get_double(par) ;
01839     /* --mag */
01840     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.mag") ;
01841     hawki_cal_zpoint_config.stdstar_given_magnitude = 
01842             cpl_parameter_get_double(par) ;
01843     /* --detect_sigma */
01844     par = cpl_parameterlist_find(parlist,"hawki.hawki_cal_zpoint.detect_sigma");
01845     hawki_cal_zpoint_config.detect_sigma = cpl_parameter_get_double(par) ;
01846     /* --sx */
01847     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.sx") ;
01848     hawki_cal_zpoint_config.sx = cpl_parameter_get_int(par) ;
01849     /* --sy */
01850     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.sy") ;
01851     hawki_cal_zpoint_config.sy = cpl_parameter_get_int(par) ;
01852     /* --star_r */
01853     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.star_r") ;
01854     hawki_cal_zpoint_config.phot_star_radius = cpl_parameter_get_double(par) ;
01855     /* --bg_r1 */
01856     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.bg_r1") ;
01857     hawki_cal_zpoint_config.phot_bg_r1 = cpl_parameter_get_double(par) ;
01858     /* --bg_r2 */
01859     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.bg_r2") ;
01860     hawki_cal_zpoint_config.phot_bg_r2 = cpl_parameter_get_double(par) ;
01861     /* --xcoord */
01862     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.xcoord");
01863     sval = cpl_parameter_get_string(par);
01864     if (sscanf(sval, "%lf,%lf,%lf,%lf",
01865                hawki_cal_zpoint_config.xcoord,
01866                hawki_cal_zpoint_config.xcoord+1,
01867                hawki_cal_zpoint_config.xcoord+2,
01868                hawki_cal_zpoint_config.xcoord+3)!=4)
01869     {
01870         return -1;
01871     }
01872     /* --ycoord */
01873     par = cpl_parameterlist_find(parlist, "hawki.hawki_cal_zpoint.ycoord");
01874     sval = cpl_parameter_get_string(par);
01875     if (sscanf(sval, "%lf,%lf,%lf,%lf",
01876                hawki_cal_zpoint_config.ycoord,
01877                hawki_cal_zpoint_config.ycoord+1,
01878                hawki_cal_zpoint_config.ycoord+2,
01879                hawki_cal_zpoint_config.ycoord+3)!=4)
01880     {
01881         return -1;
01882     }
01883 
01884     return 0;
01885 }
01886 
01887 int hawki_cal_zpoint_check_epoch_equinox(cpl_propertylist * plist)
01888 {
01889     if(hawki_pfits_get_targ_epoch(plist) != 2000. ||
01890        hawki_pfits_get_targ_equinox(plist) != 2000.)
01891     {
01892         cpl_msg_error(__func__,"Epoch and equinox must be 2000.");
01893         return -1;
01894     }
01895     else
01896         return 0;
01897 }