HAWKI Pipeline Reference Manual 1.8.6
hawki_util_extinction.c
00001 /* $Id: hawki_util_extinction.c,v 1.3 2011/12/22 14:28: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: 2011/12/22 14:28:43 $
00024  * $Revision: 1.3 $
00025  * $Name: hawki-1_8_6 $
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_strehl.h"
00042 #include "irplib_stdstar.h"
00043 #include "irplib_cat.h"
00044 
00045 #include "hawki_utils.h"
00046 #include "hawki_calib.h"
00047 #include "hawki_load.h"
00048 #include "hawki_save.h"
00049 #include "hawki_pfits.h"
00050 #include "hawki_dfs.h"
00051 #include "hawki_alloc.h"
00052 
00053 /*-----------------------------------------------------------------------------
00054                             Functions prototypes
00055  -----------------------------------------------------------------------------*/
00056 
00057 static int hawki_util_extinction_create(cpl_plugin *) ;
00058 static int hawki_util_extinction_exec(cpl_plugin *) ;
00059 static int hawki_util_extinction_destroy(cpl_plugin *) ;
00060 static int hawki_util_extinction(cpl_parameterlist *, cpl_frameset *) ;
00061 
00062 static cpl_table ** hawki_util_extinction_reduce
00063 (cpl_frameset    *   set,
00064  const char      *   stdstars,
00065  const char      *   bpm,
00066  const char      *   flat,
00067  cpl_table       **  raw_zpoint_stats,
00068  int             *   star_labels,
00069  int             *   det_labels,
00070  cpl_imagelist   **  images);
00071 static int hawki_util_extinction_save_photsol
00072 (cpl_table           **  photsol_table,
00073  cpl_frameset        *   zpoint_frames,
00074  cpl_parameterlist   *   parlist,
00075  cpl_frameset        *   set);
00076 static cpl_table ** hawki_util_extinction_photom
00077 (cpl_frameset *   std_stars_photom);
00078 static cpl_table * hawki_util_extinction_get_photomsol
00079 (cpl_table * std_stars_photom);
00080 static int hawki_util_extinction_compute_keywords
00081 (cpl_frameset * set, 
00082  int          * det_labels);
00083 
00084 /*-----------------------------------------------------------------------------
00085                             Static variables
00086  -----------------------------------------------------------------------------*/
00087 
00088 
00089 static char hawki_util_extinction_description[] =
00090 "hawki_util_extinction -- Zero point recipe with extinction\n"
00091 "The input of the recipe files listed in the Set Of Frames (sof-file)\n"
00092 "must be tagged as:\n"
00093 "hawki_util_extinction.fits ("HAWKI_CALPRO_ZPOINT_TAB"): Zero point solution table\n"
00094 "The recipe creates as an output:\n"
00095 "hawki_cal_photom.fits ("HAWKI_CALPRO_PHOT_TAB"): Photometric solution\n"
00096 "Return code:\n"
00097 "esorex exits with an error code of 0 if the recipe completes successfully\n"
00098 "or 1 otherwise";
00099 
00100 /*-----------------------------------------------------------------------------
00101                                 Functions code
00102  -----------------------------------------------------------------------------*/
00103 
00104 /*----------------------------------------------------------------------------*/
00112 /*----------------------------------------------------------------------------*/
00113 int cpl_plugin_get_info(cpl_pluginlist * list)
00114 {
00115     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
00116     cpl_plugin  *   plugin = &recipe->interface ;
00117 
00118     cpl_plugin_init(plugin,
00119                     CPL_PLUGIN_API,
00120                     HAWKI_BINARY_VERSION,
00121                     CPL_PLUGIN_TYPE_RECIPE,
00122                     "hawki_util_extinction",
00123                     "Zero point with extinction computation recipe",
00124                     hawki_util_extinction_description,
00125                     "Cesar Enrique Garcia Dabo",
00126                     "cgarcia@eso.org",
00127                     hawki_get_license(),
00128                     hawki_util_extinction_create,
00129                     hawki_util_extinction_exec,
00130                     hawki_util_extinction_destroy) ;
00131 
00132     cpl_pluginlist_append(list, plugin) ;
00133 
00134     return 0;
00135 }
00136 
00137 /*----------------------------------------------------------------------------*/
00146 /*----------------------------------------------------------------------------*/
00147 static int hawki_util_extinction_create(cpl_plugin * plugin)
00148 {
00149     cpl_recipe      * recipe ;
00150     cpl_parameter   * p ;
00151 
00152     /* Get the recipe out of the plugin */
00153     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00154         recipe = (cpl_recipe *)plugin ;
00155     else return -1 ;
00156 
00157     /* Create the parameters list in the cpl_recipe object */
00158     recipe->parameters = cpl_parameterlist_new() ;
00159     if (recipe->parameters == NULL)
00160         return 1;
00161 
00162     /* Fill the parameters list */
00163 
00164     /* Return */
00165     return 0;
00166 }
00167 
00168 /*----------------------------------------------------------------------------*/
00174 /*----------------------------------------------------------------------------*/
00175 static int hawki_util_extinction_exec(cpl_plugin * plugin)
00176 {
00177     cpl_recipe  *   recipe ;
00178 
00179     /* Get the recipe out of the plugin */
00180     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00181         recipe = (cpl_recipe *)plugin ;
00182     else return -1 ;
00183 
00184     /* Issue a banner */
00185     hawki_print_banner();
00186 
00187     return hawki_util_extinction(recipe->parameters, recipe->frames) ;
00188 }
00189 
00190 /*----------------------------------------------------------------------------*/
00196 /*----------------------------------------------------------------------------*/
00197 static int hawki_util_extinction_destroy(cpl_plugin * plugin)
00198 {
00199     cpl_recipe  *   recipe ;
00200 
00201     /* Get the recipe out of the plugin */
00202     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00203         recipe = (cpl_recipe *)plugin ;
00204     else return -1 ;
00205 
00206     cpl_parameterlist_delete(recipe->parameters) ;
00207     return 0 ;
00208 }
00209 
00210 /*----------------------------------------------------------------------------*/
00217 /*----------------------------------------------------------------------------*/
00218 static int hawki_util_extinction(
00219         cpl_parameterlist   *   parlist,
00220         cpl_frameset        *   framelist)
00221 {
00222     cpl_frameset    *   std_stars_photom ;
00223     cpl_table       **  zpoint_tables;
00224 
00225     /* Initialise Output */
00226     std_stars_photom = NULL ;
00227 
00228     /* Identify the RAW and CALIB frames in the input frameset */
00229     if (hawki_dfs_set_groups(framelist)) {
00230         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00231         return -1 ;
00232     }
00233 
00234     /* Retrieve zpoint tables */
00235     if ((std_stars_photom = hawki_extract_frameset
00236             (framelist, HAWKI_CALPRO_ZPOINT_TAB)) == NULL)
00237     {
00238         cpl_msg_error(__func__, "Cannot find std stars info (%s)",
00239                       HAWKI_CALPRO_ZPOINT_TAB);
00240         return -1 ;
00241     }
00242 
00243     /* Compute the zpoint values */
00244     cpl_msg_info(__func__, "Reduce the data") ;
00245     cpl_msg_indent_more() ;
00246     if ((zpoint_tables = hawki_util_extinction_photom(std_stars_photom))==NULL)
00247     {
00248         cpl_msg_error(__func__, "Cannot compute photometric solution") ;
00249         cpl_frameset_delete(std_stars_photom) ;
00250         cpl_msg_indent_less() ;
00251         return -1 ;
00252     }
00253     cpl_msg_indent_less() ;
00254 
00255     /* Save the products */
00256     cpl_msg_info(__func__, "Save the products");
00257     cpl_msg_indent_more() ;
00258     if (hawki_util_extinction_save_photsol
00259             (zpoint_tables, std_stars_photom,
00260              parlist, framelist) == -1)
00261     {
00262         cpl_msg_warning(__func__, "Data could not be saved. "
00263                         "Check permisions or disk space") ;
00264         hawki_table_delete(zpoint_tables) ;
00265         cpl_frameset_delete(std_stars_photom);
00266         cpl_msg_indent_less() ;
00267         return -1 ;
00268     }
00269     cpl_msg_indent_less() ;
00270 
00271     /* Free and return */
00272     cpl_frameset_delete(std_stars_photom);
00273     hawki_table_delete(zpoint_tables);
00274 
00275     /* Return */
00276     if (cpl_error_get_code()) return -1 ;
00277     else return 0 ;
00278 }
00279 
00280 /*----------------------------------------------------------------------------*/
00290 /*----------------------------------------------------------------------------*/
00291 static cpl_table ** hawki_util_extinction_photom
00292 (cpl_frameset *   std_stars_photom)
00293 
00294 {
00295     cpl_table **        photsol;
00296     int                 nframes;
00297     double              extinction;
00298     cpl_bivector    *   iqe_res ;
00299     int                 iframe;
00300     int                 idet;
00301     int                 jdet;
00302     int                 iext;
00303     int                 ext_nb;
00304     cpl_frame       *   ref_frame;
00305 
00306     /* Test entries */
00307     if (std_stars_photom == NULL) return NULL ;
00308 
00309     /* Initialise */
00310     photsol = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table*));
00311     nframes = cpl_frameset_get_size(std_stars_photom) ;
00312 
00313     /* Get reference */
00314     ref_frame = cpl_frameset_get_first(std_stars_photom);
00315     nframes = cpl_frameset_get_size(std_stars_photom);
00316 
00317     /* Loop on detectors */
00318     for (idet=0 ; idet<HAWKI_NB_DETECTORS; idet++)
00319     {
00320         cpl_table * merged_std_stars_photom;
00321 
00322         cpl_msg_info(cpl_func, "Working on detector %d", idet +1);
00323         cpl_msg_indent_more();
00324         /* Get the extension */
00325         ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), idet+1);
00326 
00327         /* Load all the tables and merge them */
00328         for( iframe = 0 ; iframe < nframes ; ++iframe)
00329         {
00330             cpl_frame * this_frame;
00331             cpl_table * this_table;
00332             /* Get the current image */
00333             this_frame = cpl_frameset_get_frame(std_stars_photom, iframe);
00334             if(iframe == 0)
00335                 merged_std_stars_photom = cpl_table_load
00336                     (cpl_frame_get_filename(this_frame),ext_nb, 1);
00337             else
00338             {
00339                 cpl_table * this_table =
00340                         cpl_table_load(cpl_frame_get_filename(this_frame),ext_nb, 1);
00341                 cpl_table_insert(merged_std_stars_photom, this_table,
00342                                  cpl_table_get_nrow(merged_std_stars_photom));
00343                 cpl_table_delete(this_table);
00344             }
00345         }
00346 
00347         if(cpl_table_get_nrow(merged_std_stars_photom) < 2)
00348         {
00349             cpl_msg_error(__func__, "%d stars found. At least 2 stars must be present",
00350                     cpl_table_get_nrow(merged_std_stars_photom));
00351             cpl_table_delete(merged_std_stars_photom);
00352             return NULL;
00353         }
00354         cpl_msg_info(__func__,"Number of star measurements %d",
00355                      cpl_table_get_nrow(merged_std_stars_photom));
00356 
00357         if((photsol[idet] = hawki_util_extinction_get_photomsol
00358                 (merged_std_stars_photom)) == NULL)
00359         {
00360             cpl_table_delete(merged_std_stars_photom);
00361             for(jdet=0; jdet < idet; jdet++)
00362                 cpl_table_delete(photsol[jdet]);
00363             cpl_free(photsol);
00364             return NULL;
00365         }
00366 
00367         cpl_table_delete(merged_std_stars_photom);
00368         cpl_msg_indent_less();
00369     }
00370     return photsol;
00371 }
00372 
00373 static cpl_table * hawki_util_extinction_get_photomsol
00374 (cpl_table * std_stars_photom)
00375 {
00376     const double    * instrmag;
00377     const double    * airmass;
00378     const double    * catmag;
00379     cpl_table       * photsol;
00380     double            zeropoint;
00381     double            extcoeff;
00382     cpl_matrix      * xpos;
00383     cpl_vector      * ypos;
00384     cpl_polynomial  * phot_coeff;
00385     int               nstars;
00386     int               istar;
00387     const cpl_boolean sampsym = CPL_TRUE;
00388     const cpl_size         mindeg1d = 0;
00389     const cpl_size         maxdeg1d = 1;
00390     cpl_size               pows;
00391 
00392 
00393     nstars = cpl_table_get_nrow(std_stars_photom);
00394 
00395     photsol = cpl_table_new(1);
00396     instrmag = cpl_table_get_data_double_const
00397             (std_stars_photom, HAWKI_COL_ZPOINT_INSTRMAG);
00398     airmass = cpl_table_get_data_double_const
00399             (std_stars_photom, HAWKI_COL_ZPOINT_AIRMASS);
00400     catmag = cpl_table_get_data_double_const
00401             (std_stars_photom, HAWKI_COL_ZPOINT_STARMAG);
00402 
00403     if(instrmag == NULL || airmass == NULL || catmag == NULL)
00404     {
00405         cpl_msg_error(cpl_func, "Some of the following columns not found "
00406                       "in table: %s, %s, %s", HAWKI_COL_ZPOINT_INSTRMAG,
00407                       HAWKI_COL_ZPOINT_AIRMASS, HAWKI_COL_ZPOINT_STARMAG);
00408         cpl_table_delete(photsol);
00409         return NULL;
00410     }
00411 
00412     cpl_table_new_column(photsol, HAWKI_COL_PHOT_FILTER, CPL_TYPE_STRING);
00413     cpl_table_new_column(photsol, HAWKI_COL_PHOT_ZEROPOINT, CPL_TYPE_DOUBLE);
00414     cpl_table_set_column_unit(photsol,HAWKI_COL_PHOT_ZEROPOINT,"mag");
00415     cpl_table_new_column(photsol, HAWKI_COL_PHOT_EXTCOEFF, CPL_TYPE_DOUBLE);
00416     cpl_table_set_column_unit(photsol,HAWKI_COL_PHOT_EXTCOEFF,"mag/airmass");
00417         
00418     /* Make the fit to get the coefficients */
00419     xpos = cpl_matrix_new(1, nstars);
00420     ypos = cpl_vector_new(nstars);
00421     for(istar = 0; istar < nstars; ++istar)
00422     {
00423         double y;
00424         cpl_matrix_set(xpos, 0, istar, airmass[istar]);
00425         y = catmag[istar] + instrmag[istar];
00426         cpl_vector_set(ypos, istar, y);
00427     }
00428     /* phot_coeff[0] --> ZP
00429      * phot_coeff[1] --> -extcoeff
00430      */
00431     phot_coeff = cpl_polynomial_new(1);
00432     if(cpl_polynomial_fit(phot_coeff, xpos, NULL, ypos, NULL,
00433                           CPL_FALSE, &mindeg1d, &maxdeg1d) != CPL_ERROR_NONE)
00434     {
00435         cpl_msg_error(cpl_func,"Cannot get the photometric solution");
00436         cpl_table_delete(photsol);
00437         return NULL;
00438     }
00439     cpl_matrix_delete(xpos);
00440     cpl_vector_delete(ypos);
00441     pows = 0;
00442     zeropoint = cpl_polynomial_get_coeff(phot_coeff, &pows);
00443     pows = 1;
00444     extcoeff  = -cpl_polynomial_get_coeff(phot_coeff, &pows);
00445     cpl_polynomial_delete(phot_coeff);
00446 
00447     cpl_table_set_double(photsol, HAWKI_COL_PHOT_ZEROPOINT, 0,
00448                          zeropoint);
00449     cpl_table_set_double(photsol, HAWKI_COL_PHOT_EXTCOEFF, 0,
00450                          extcoeff);
00451 
00452     /* Output results */
00453     cpl_msg_indent_more();
00454     cpl_msg_info(__func__, "Zero point: %f", zeropoint);
00455     cpl_msg_info(__func__, "Extinction coefficient: %f", extcoeff);
00456     cpl_msg_indent_less();
00457 
00458     return photsol;
00459 }
00460 
00461 /*----------------------------------------------------------------------------*/
00470 /*----------------------------------------------------------------------------*/
00471 static int hawki_util_extinction_save_photsol
00472 (cpl_table           **  photsol_table,
00473  cpl_frameset        *   zpoint_frames,
00474  cpl_parameterlist   *   parlist,
00475  cpl_frameset        *   set)
00476 {
00477     cpl_propertylist    **  qclists ;
00478     const char          *   ref_filename;
00479     cpl_propertylist    *   inputlist ;
00480     int                     ext_nb, nframes ;
00481     const char          *   recipe_name = "hawki_util_extinction" ;
00482     int                     idet;
00483     int                     iframe;
00484     cpl_errorstate          error_prevstate = cpl_errorstate_get();
00485 
00486 
00487     /* Initialise */
00488     nframes = cpl_frameset_get_size(set) ;
00489 
00490     /* Get the reference frame */
00491     ref_filename = hawki_get_extref_file(set);
00492 
00493     /* Create the QC lists for the extensions */
00494     qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00495     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00496     {
00497         int            this_iframe = -1;
00498 
00499         qclists[idet] = cpl_propertylist_new() ;
00500         /* These QC are common to all extensions */
00501 
00502 
00503         /* Propagate some keywords from input raw frame extensions */
00504         ext_nb=hawki_get_ext_from_detector(ref_filename, idet+1);
00505         inputlist = cpl_propertylist_load_regexp(ref_filename, ext_nb,
00506                 HAWKI_HEADER_EXT_FORWARD, 0) ;
00507         cpl_propertylist_append(qclists[idet], inputlist) ;
00508         cpl_propertylist_delete(inputlist) ;
00509 
00510     }
00511     
00512     /* Write the photometric table  */
00513     hawki_tables_save(set,
00514                       parlist,
00515                       zpoint_frames,
00516                       (const cpl_table **)photsol_table,
00517                       recipe_name,
00518                       HAWKI_CALPRO_PHOT_TAB,
00519                       HAWKI_PROTYPE_PHOT_TAB,
00520                       NULL,
00521                       (const cpl_propertylist **)qclists,
00522                       "hawki_util_extinction.fits");
00523 
00524     /* Free */
00525     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
00526         cpl_propertylist_delete(qclists[idet]) ;
00527     }
00528     cpl_free(qclists) ;
00529 
00530     /* Free */
00531     if(!cpl_errorstate_is_equal(error_prevstate))
00532     {
00533         cpl_errorstate_set(CPL_ERROR_NONE);
00534         return -1;
00535     }
00536     return  0;
00537 }