HAWKI Pipeline Reference Manual 1.8.12
hawki_util_extinction.c
00001 /* $Id: hawki_util_extinction.c,v 1.4 2013/03/11 11:03:00 cgarcia Exp $
00002  *
00003  * This file is part of the HAWKI Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: cgarcia $
00023  * $Date: 2013/03/11 11:03:00 $
00024  * $Revision: 1.4 $
00025  * $Name: hawki-1_8_12 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <string.h>
00037 #include <math.h>
00038 #include <cpl.h>
00039 
00040 #include "irplib_utils.h"
00041 #include "irplib_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 #ifdef __cplusplus
00058 extern "C"
00059 #endif
00060 int cpl_plugin_get_info(cpl_pluginlist * list);
00061 
00062 static int hawki_util_extinction_create(cpl_plugin *) ;
00063 static int hawki_util_extinction_exec(cpl_plugin *) ;
00064 static int hawki_util_extinction_destroy(cpl_plugin *) ;
00065 static int hawki_util_extinction(cpl_parameterlist *, cpl_frameset *) ;
00066 
00067 static cpl_table ** hawki_util_extinction_reduce
00068 (cpl_frameset    *   set,
00069  const char      *   stdstars,
00070  const char      *   bpm,
00071  const char      *   flat,
00072  cpl_table       **  raw_zpoint_stats,
00073  int             *   star_labels,
00074  int             *   det_labels,
00075  cpl_imagelist   **  images);
00076 static int hawki_util_extinction_save_photsol
00077 (cpl_table           **  photsol_table,
00078  cpl_frameset        *   zpoint_frames,
00079  cpl_parameterlist   *   parlist,
00080  cpl_frameset        *   set);
00081 static cpl_table ** hawki_util_extinction_photom
00082 (cpl_frameset *   std_stars_photom);
00083 static cpl_table * hawki_util_extinction_get_photomsol
00084 (cpl_table * std_stars_photom);
00085 static int hawki_util_extinction_compute_keywords
00086 (cpl_frameset * set, 
00087  int          * det_labels);
00088 
00089 /*-----------------------------------------------------------------------------
00090                             Static variables
00091  -----------------------------------------------------------------------------*/
00092 
00093 
00094 static char hawki_util_extinction_description[] =
00095 "hawki_util_extinction -- Zero point recipe with extinction\n"
00096 "The input of the recipe files listed in the Set Of Frames (sof-file)\n"
00097 "must be tagged as:\n"
00098 "hawki_util_extinction.fits ("HAWKI_CALPRO_ZPOINT_TAB"): Zero point solution table\n"
00099 "The recipe creates as an output:\n"
00100 "hawki_cal_photom.fits ("HAWKI_CALPRO_PHOT_TAB"): Photometric solution\n"
00101 "Return code:\n"
00102 "esorex exits with an error code of 0 if the recipe completes successfully\n"
00103 "or 1 otherwise";
00104 
00105 /*-----------------------------------------------------------------------------
00106                                 Functions code
00107  -----------------------------------------------------------------------------*/
00108 
00109 /*----------------------------------------------------------------------------*/
00117 /*----------------------------------------------------------------------------*/
00118 int cpl_plugin_get_info(cpl_pluginlist * list)
00119 {
00120     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
00121     cpl_plugin  *   plugin = &recipe->interface ;
00122 
00123     cpl_plugin_init(plugin,
00124                     CPL_PLUGIN_API,
00125                     HAWKI_BINARY_VERSION,
00126                     CPL_PLUGIN_TYPE_RECIPE,
00127                     "hawki_util_extinction",
00128                     "Zero point with extinction computation recipe",
00129                     hawki_util_extinction_description,
00130                     "Cesar Enrique Garcia Dabo",
00131                     "cgarcia@eso.org",
00132                     hawki_get_license(),
00133                     hawki_util_extinction_create,
00134                     hawki_util_extinction_exec,
00135                     hawki_util_extinction_destroy) ;
00136 
00137     cpl_pluginlist_append(list, plugin) ;
00138 
00139     return 0;
00140 }
00141 
00142 /*----------------------------------------------------------------------------*/
00151 /*----------------------------------------------------------------------------*/
00152 static int hawki_util_extinction_create(cpl_plugin * plugin)
00153 {
00154     cpl_recipe      * recipe ;
00155     cpl_parameter   * p ;
00156 
00157     /* Get the recipe out of the plugin */
00158     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00159         recipe = (cpl_recipe *)plugin ;
00160     else return -1 ;
00161 
00162     /* Create the parameters list in the cpl_recipe object */
00163     recipe->parameters = cpl_parameterlist_new() ;
00164     if (recipe->parameters == NULL)
00165         return 1;
00166 
00167     /* Fill the parameters list */
00168 
00169     /* Return */
00170     return 0;
00171 }
00172 
00173 /*----------------------------------------------------------------------------*/
00179 /*----------------------------------------------------------------------------*/
00180 static int hawki_util_extinction_exec(cpl_plugin * plugin)
00181 {
00182     cpl_recipe  *   recipe ;
00183 
00184     /* Get the recipe out of the plugin */
00185     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00186         recipe = (cpl_recipe *)plugin ;
00187     else return -1 ;
00188 
00189     /* Issue a banner */
00190     hawki_print_banner();
00191 
00192     return hawki_util_extinction(recipe->parameters, recipe->frames) ;
00193 }
00194 
00195 /*----------------------------------------------------------------------------*/
00201 /*----------------------------------------------------------------------------*/
00202 static int hawki_util_extinction_destroy(cpl_plugin * plugin)
00203 {
00204     cpl_recipe  *   recipe ;
00205 
00206     /* Get the recipe out of the plugin */
00207     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00208         recipe = (cpl_recipe *)plugin ;
00209     else return -1 ;
00210 
00211     cpl_parameterlist_delete(recipe->parameters) ;
00212     return 0 ;
00213 }
00214 
00215 /*----------------------------------------------------------------------------*/
00222 /*----------------------------------------------------------------------------*/
00223 static int hawki_util_extinction(
00224         cpl_parameterlist   *   parlist,
00225         cpl_frameset        *   framelist)
00226 {
00227     cpl_frameset    *   std_stars_photom ;
00228     cpl_table       **  zpoint_tables;
00229 
00230     /* Initialise Output */
00231     std_stars_photom = NULL ;
00232 
00233     /* Identify the RAW and CALIB frames in the input frameset */
00234     if (hawki_dfs_set_groups(framelist)) {
00235         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00236         return -1 ;
00237     }
00238 
00239     /* Retrieve zpoint tables */
00240     if ((std_stars_photom = hawki_extract_frameset
00241             (framelist, HAWKI_CALPRO_ZPOINT_TAB)) == NULL)
00242     {
00243         cpl_msg_error(__func__, "Cannot find std stars info (%s)",
00244                       HAWKI_CALPRO_ZPOINT_TAB);
00245         return -1 ;
00246     }
00247 
00248     /* Compute the zpoint values */
00249     cpl_msg_info(__func__, "Reduce the data") ;
00250     cpl_msg_indent_more() ;
00251     if ((zpoint_tables = hawki_util_extinction_photom(std_stars_photom))==NULL)
00252     {
00253         cpl_msg_error(__func__, "Cannot compute photometric solution") ;
00254         cpl_frameset_delete(std_stars_photom) ;
00255         cpl_msg_indent_less() ;
00256         return -1 ;
00257     }
00258     cpl_msg_indent_less() ;
00259 
00260     /* Save the products */
00261     cpl_msg_info(__func__, "Save the products");
00262     cpl_msg_indent_more() ;
00263     if (hawki_util_extinction_save_photsol
00264             (zpoint_tables, std_stars_photom,
00265              parlist, framelist) == -1)
00266     {
00267         cpl_msg_warning(__func__, "Data could not be saved. "
00268                         "Check permisions or disk space") ;
00269         hawki_table_delete(zpoint_tables) ;
00270         cpl_frameset_delete(std_stars_photom);
00271         cpl_msg_indent_less() ;
00272         return -1 ;
00273     }
00274     cpl_msg_indent_less() ;
00275 
00276     /* Free and return */
00277     cpl_frameset_delete(std_stars_photom);
00278     hawki_table_delete(zpoint_tables);
00279 
00280     /* Return */
00281     if (cpl_error_get_code()) return -1 ;
00282     else return 0 ;
00283 }
00284 
00285 /*----------------------------------------------------------------------------*/
00295 /*----------------------------------------------------------------------------*/
00296 static cpl_table ** hawki_util_extinction_photom
00297 (cpl_frameset *   std_stars_photom)
00298 
00299 {
00300     cpl_table **        photsol;
00301     int                 nframes;
00302     double              extinction;
00303     cpl_bivector    *   iqe_res ;
00304     int                 iframe;
00305     int                 idet;
00306     int                 jdet;
00307     int                 iext;
00308     int                 ext_nb;
00309     cpl_frame       *   ref_frame;
00310 
00311     /* Test entries */
00312     if (std_stars_photom == NULL) return NULL ;
00313 
00314     /* Initialise */
00315     photsol = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_table*));
00316     nframes = cpl_frameset_get_size(std_stars_photom) ;
00317 
00318     /* Get reference */
00319     ref_frame = cpl_frameset_get_first(std_stars_photom);
00320     nframes = cpl_frameset_get_size(std_stars_photom);
00321 
00322     /* Loop on detectors */
00323     for (idet=0 ; idet<HAWKI_NB_DETECTORS; idet++)
00324     {
00325         cpl_table * merged_std_stars_photom;
00326 
00327         cpl_msg_info(cpl_func, "Working on detector %d", idet +1);
00328         cpl_msg_indent_more();
00329         /* Get the extension */
00330         ext_nb=hawki_get_ext_from_detector(cpl_frame_get_filename(ref_frame), idet+1);
00331 
00332         /* Load all the tables and merge them */
00333         for( iframe = 0 ; iframe < nframes ; ++iframe)
00334         {
00335             cpl_frame * this_frame;
00336             cpl_table * this_table;
00337             /* Get the current image */
00338             this_frame = cpl_frameset_get_frame(std_stars_photom, iframe);
00339             if(iframe == 0)
00340                 merged_std_stars_photom = cpl_table_load
00341                     (cpl_frame_get_filename(this_frame),ext_nb, 1);
00342             else
00343             {
00344                 cpl_table * this_table =
00345                         cpl_table_load(cpl_frame_get_filename(this_frame),ext_nb, 1);
00346                 cpl_table_insert(merged_std_stars_photom, this_table,
00347                                  cpl_table_get_nrow(merged_std_stars_photom));
00348                 cpl_table_delete(this_table);
00349             }
00350         }
00351 
00352         if(cpl_table_get_nrow(merged_std_stars_photom) < 2)
00353         {
00354             cpl_msg_error(__func__, "%d stars found. At least 2 stars must be present",
00355                     cpl_table_get_nrow(merged_std_stars_photom));
00356             cpl_table_delete(merged_std_stars_photom);
00357             return NULL;
00358         }
00359         cpl_msg_info(__func__,"Number of star measurements %d",
00360                      cpl_table_get_nrow(merged_std_stars_photom));
00361 
00362         if((photsol[idet] = hawki_util_extinction_get_photomsol
00363                 (merged_std_stars_photom)) == NULL)
00364         {
00365             cpl_table_delete(merged_std_stars_photom);
00366             for(jdet=0; jdet < idet; jdet++)
00367                 cpl_table_delete(photsol[jdet]);
00368             cpl_free(photsol);
00369             return NULL;
00370         }
00371 
00372         cpl_table_delete(merged_std_stars_photom);
00373         cpl_msg_indent_less();
00374     }
00375     return photsol;
00376 }
00377 
00378 static cpl_table * hawki_util_extinction_get_photomsol
00379 (cpl_table * std_stars_photom)
00380 {
00381     const double    * instrmag;
00382     const double    * airmass;
00383     const double    * catmag;
00384     cpl_table       * photsol;
00385     double            zeropoint;
00386     double            extcoeff;
00387     cpl_matrix      * xpos;
00388     cpl_vector      * ypos;
00389     cpl_polynomial  * phot_coeff;
00390     int               nstars;
00391     int               istar;
00392     const cpl_boolean sampsym = CPL_TRUE;
00393     const cpl_size         mindeg1d = 0;
00394     const cpl_size         maxdeg1d = 1;
00395     cpl_size               pows;
00396 
00397 
00398     nstars = cpl_table_get_nrow(std_stars_photom);
00399 
00400     photsol = cpl_table_new(1);
00401     instrmag = cpl_table_get_data_double_const
00402             (std_stars_photom, HAWKI_COL_ZPOINT_INSTRMAG);
00403     airmass = cpl_table_get_data_double_const
00404             (std_stars_photom, HAWKI_COL_ZPOINT_AIRMASS);
00405     catmag = cpl_table_get_data_double_const
00406             (std_stars_photom, HAWKI_COL_ZPOINT_STARMAG);
00407 
00408     if(instrmag == NULL || airmass == NULL || catmag == NULL)
00409     {
00410         cpl_msg_error(cpl_func, "Some of the following columns not found "
00411                       "in table: %s, %s, %s", HAWKI_COL_ZPOINT_INSTRMAG,
00412                       HAWKI_COL_ZPOINT_AIRMASS, HAWKI_COL_ZPOINT_STARMAG);
00413         cpl_table_delete(photsol);
00414         return NULL;
00415     }
00416 
00417     cpl_table_new_column(photsol, HAWKI_COL_PHOT_FILTER, CPL_TYPE_STRING);
00418     cpl_table_new_column(photsol, HAWKI_COL_PHOT_ZEROPOINT, CPL_TYPE_DOUBLE);
00419     cpl_table_set_column_unit(photsol,HAWKI_COL_PHOT_ZEROPOINT,"mag");
00420     cpl_table_new_column(photsol, HAWKI_COL_PHOT_EXTCOEFF, CPL_TYPE_DOUBLE);
00421     cpl_table_set_column_unit(photsol,HAWKI_COL_PHOT_EXTCOEFF,"mag/airmass");
00422         
00423     /* Make the fit to get the coefficients */
00424     xpos = cpl_matrix_new(1, nstars);
00425     ypos = cpl_vector_new(nstars);
00426     for(istar = 0; istar < nstars; ++istar)
00427     {
00428         double y;
00429         cpl_matrix_set(xpos, 0, istar, airmass[istar]);
00430         y = catmag[istar] + instrmag[istar];
00431         cpl_vector_set(ypos, istar, y);
00432     }
00433     /* phot_coeff[0] --> ZP
00434      * phot_coeff[1] --> -extcoeff
00435      */
00436     phot_coeff = cpl_polynomial_new(1);
00437     if(cpl_polynomial_fit(phot_coeff, xpos, NULL, ypos, NULL,
00438                           CPL_FALSE, &mindeg1d, &maxdeg1d) != CPL_ERROR_NONE)
00439     {
00440         cpl_msg_error(cpl_func,"Cannot get the photometric solution");
00441         cpl_table_delete(photsol);
00442         return NULL;
00443     }
00444     cpl_matrix_delete(xpos);
00445     cpl_vector_delete(ypos);
00446     pows = 0;
00447     zeropoint = cpl_polynomial_get_coeff(phot_coeff, &pows);
00448     pows = 1;
00449     extcoeff  = -cpl_polynomial_get_coeff(phot_coeff, &pows);
00450     cpl_polynomial_delete(phot_coeff);
00451 
00452     cpl_table_set_double(photsol, HAWKI_COL_PHOT_ZEROPOINT, 0,
00453                          zeropoint);
00454     cpl_table_set_double(photsol, HAWKI_COL_PHOT_EXTCOEFF, 0,
00455                          extcoeff);
00456 
00457     /* Output results */
00458     cpl_msg_indent_more();
00459     cpl_msg_info(__func__, "Zero point: %f", zeropoint);
00460     cpl_msg_info(__func__, "Extinction coefficient: %f", extcoeff);
00461     cpl_msg_indent_less();
00462 
00463     return photsol;
00464 }
00465 
00466 /*----------------------------------------------------------------------------*/
00475 /*----------------------------------------------------------------------------*/
00476 static int hawki_util_extinction_save_photsol
00477 (cpl_table           **  photsol_table,
00478  cpl_frameset        *   zpoint_frames,
00479  cpl_parameterlist   *   parlist,
00480  cpl_frameset        *   set)
00481 {
00482     cpl_propertylist    **  qclists ;
00483     const char          *   ref_filename;
00484     cpl_propertylist    *   inputlist ;
00485     int                     ext_nb, nframes ;
00486     const char          *   recipe_name = "hawki_util_extinction" ;
00487     int                     idet;
00488     int                     iframe;
00489     cpl_errorstate          error_prevstate = cpl_errorstate_get();
00490 
00491 
00492     /* Initialise */
00493     nframes = cpl_frameset_get_size(set) ;
00494 
00495     /* Get the reference frame */
00496     ref_filename = hawki_get_extref_file(set);
00497 
00498     /* Create the QC lists for the extensions */
00499     qclists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00500     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
00501     {
00502         int            this_iframe = -1;
00503 
00504         qclists[idet] = cpl_propertylist_new() ;
00505         /* These QC are common to all extensions */
00506 
00507 
00508         /* Propagate some keywords from input raw frame extensions */
00509         ext_nb=hawki_get_ext_from_detector(ref_filename, idet+1);
00510         inputlist = cpl_propertylist_load_regexp(ref_filename, ext_nb,
00511                 HAWKI_HEADER_EXT_FORWARD, 0) ;
00512         cpl_propertylist_append(qclists[idet], inputlist) ;
00513         cpl_propertylist_delete(inputlist) ;
00514 
00515     }
00516     
00517     /* Write the photometric table  */
00518     hawki_tables_save(set,
00519                       parlist,
00520                       zpoint_frames,
00521                       (const cpl_table **)photsol_table,
00522                       recipe_name,
00523                       HAWKI_CALPRO_PHOT_TAB,
00524                       HAWKI_PROTYPE_PHOT_TAB,
00525                       NULL,
00526                       (const cpl_propertylist **)qclists,
00527                       "hawki_util_extinction.fits");
00528 
00529     /* Free */
00530     for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
00531         cpl_propertylist_delete(qclists[idet]) ;
00532     }
00533     cpl_free(qclists) ;
00534 
00535     /* Free */
00536     if(!cpl_errorstate_is_equal(error_prevstate))
00537     {
00538         cpl_errorstate_set(CPL_ERROR_NONE);
00539         return -1;
00540     }
00541     return  0;
00542 }