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