isaac_spc_wlcalib.c

00001 /* $Id: isaac_spc_wlcalib.c,v 1.25 2012/01/12 11:57:51 llundin Exp $
00002  *
00003  * This file is part of the ISAAC 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: llundin $
00023  * $Date: 2012/01/12 11:57:51 $
00024  * $Revision: 1.25 $
00025  * $Name: isaac-6_1_0 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <math.h>
00037 #include <cpl.h>
00038 
00039 #include "irplib_utils.h"
00040 
00041 #include "isaac_utils.h"
00042 #include "isaac_wavelength.h"
00043 #include "isaac_physicalmodel.h"
00044 #include "isaac_pfits.h"
00045 #include "isaac_dfs.h"
00046 
00047 /*-----------------------------------------------------------------------------
00048                             Functions prototypes
00049  -----------------------------------------------------------------------------*/
00050 
00051 static int isaac_spc_wlcalib_create(cpl_plugin *);
00052 static int isaac_spc_wlcalib_exec(cpl_plugin *);
00053 static int isaac_spc_wlcalib_destroy(cpl_plugin *);
00054 static int isaac_spc_wlcalib(cpl_parameterlist *, cpl_frameset *);
00055 static cpl_table * isaac_spc_wlcalib_compute(const char *, const char *, 
00056         const char *, const char *);
00057 static int isaac_spc_wlcalib_save(const cpl_table *, int, cpl_parameterlist *, 
00058         cpl_frameset *);
00059  
00060 /*-----------------------------------------------------------------------------
00061                             Static variables
00062  -----------------------------------------------------------------------------*/
00063 
00064 static struct {
00065     /* Inputs */
00066     int         rej_left;
00067     int         rej_right;
00068     int         rej_bottom;
00069     int         rej_top;
00070     int         max_offset;
00071     int         lines_table;
00072     /* Outputs */
00073     double      disprel_cc;
00074     int         disprel_clines;
00075     int         disprel_dlines;
00076     double      disprel_rms;
00077 } isaac_spc_wlcalib_config;
00078 
00079 static char isaac_spc_wlcalib_description[] = 
00080 "isaac_spc_wlcalib -- ISAAC wavelength calibration recipe\n" 
00081 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00082 "oh-cat.fits "ISAAC_CALPRO_OH_CAT" or\n"
00083 "xe-cat.fits "ISAAC_CALPRO_XE_CAT" or\n"
00084 "ar-cat.fits "ISAAC_CALPRO_AR_CAT"\n";
00085 
00086 /*-----------------------------------------------------------------------------
00087                                 Functions code
00088  -----------------------------------------------------------------------------*/
00089 
00090 /*----------------------------------------------------------------------------*/
00098 /*----------------------------------------------------------------------------*/
00099 int cpl_plugin_get_info(cpl_pluginlist * list)
00100 {
00101     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe));
00102     cpl_plugin  *   plugin = &recipe->interface;
00103 
00104     cpl_plugin_init(plugin,
00105                     CPL_PLUGIN_API,
00106                     ISAAC_BINARY_VERSION,
00107                     CPL_PLUGIN_TYPE_RECIPE,
00108                     "isaac_spc_wlcalib",
00109                     "Spectro wavelength calibration",
00110                     isaac_spc_wlcalib_description,
00111                     "Lars Lundin",
00112                     PACKAGE_BUGREPORT,
00113                     isaac_get_license(),
00114                     isaac_spc_wlcalib_create,
00115                     isaac_spc_wlcalib_exec,
00116                     isaac_spc_wlcalib_destroy);
00117 
00118     cpl_pluginlist_append(list, plugin);
00119     
00120     return 0;
00121 }
00122 
00123 /*----------------------------------------------------------------------------*/
00132 /*----------------------------------------------------------------------------*/
00133 static int isaac_spc_wlcalib_create(cpl_plugin * plugin)
00134 {
00135     cpl_recipe      * recipe;
00136     cpl_parameter   * p;
00137 
00138     /* Get the recipe out of the plugin */
00139     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00140         recipe = (cpl_recipe *)plugin;
00141     else return -1;
00142 
00143     /* Create the parameters list in the cpl_recipe object */
00144     recipe->parameters = cpl_parameterlist_new();
00145 
00146     /* Fill the parameters list */
00147     /* --rejected */
00148     p = cpl_parameter_new_value("isaac.isaac_spc_wlcalib.rejected",
00149             CPL_TYPE_STRING, "left right bottom top rejections", 
00150             "isaac.isaac_spc_wlcalib", "-1 -1 100 100");
00151     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rej");
00152     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00153     cpl_parameterlist_append(recipe->parameters, p);
00154     /* --max_offset */
00155     p = cpl_parameter_new_value("isaac.isaac_spc_wlcalib.max_offset",
00156             CPL_TYPE_INT, "maximum offset from the physical model "
00157             "allowed in pixels", "isaac.isaac_spc_wlcalib", 50);
00158     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "max_offset");
00159     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00160     cpl_parameterlist_append(recipe->parameters, p);
00161     /* --lines */
00162     p = cpl_parameter_new_value("isaac.isaac_spc_wlcalib.lines", CPL_TYPE_INT, 
00163             "1 for oh, 2 for xe, 3 for ar, 4 for xe+ar",
00164             "isaac.isaac_spc_wlcalib", -1);
00165     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lines");
00166     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00167     cpl_parameterlist_append(recipe->parameters, p);
00168     return 0;
00169 }
00170 
00171 /*----------------------------------------------------------------------------*/
00177 /*----------------------------------------------------------------------------*/
00178 static int isaac_spc_wlcalib_exec(cpl_plugin * plugin)
00179 {
00180     cpl_recipe  *   recipe;
00181 
00182     /* Get the recipe out of the plugin */
00183     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00184         recipe = (cpl_recipe *)plugin;
00185     else return -1;
00186 
00187     return isaac_spc_wlcalib(recipe->parameters, recipe->frames);
00188 }
00189 
00190 /*----------------------------------------------------------------------------*/
00196 /*----------------------------------------------------------------------------*/
00197 static int isaac_spc_wlcalib_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 isaac_spc_wlcalib(
00219         cpl_parameterlist   *   parlist, 
00220         cpl_frameset        *   framelist)
00221 {
00222     cpl_parameter       *   par;
00223     cpl_frame           *   cur_frame;
00224     const char          *   cur_fname;
00225     const char          *   sval;
00226     const char          *   oh;
00227     const char          *   xe;
00228     const char          *   ar;
00229     cpl_table           *   tab;
00230     
00231     /* Initialise */
00232     par = NULL;
00233 
00234     /* Retrieve input parameters */
00235     /* Rejection parameters */
00236     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_wlcalib.rejected");
00237     sval = cpl_parameter_get_string(par);
00238     if (sscanf(sval, "%d %d %d %d",
00239                     &isaac_spc_wlcalib_config.rej_left,
00240                     &isaac_spc_wlcalib_config.rej_right,
00241                     &isaac_spc_wlcalib_config.rej_bottom,
00242                     &isaac_spc_wlcalib_config.rej_top) != 4) {
00243         return -1;
00244     }
00245 
00246     /* Max offset in pixels */
00247     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_wlcalib.max_offset");
00248     isaac_spc_wlcalib_config.max_offset = cpl_parameter_get_int(par);
00249 
00250     /* --lines */
00251     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_wlcalib.lines");
00252     isaac_spc_wlcalib_config.lines_table=cpl_parameter_get_int(par);
00253 
00254     /* Check lines */
00255     if (isaac_spc_wlcalib_config.lines_table < 1) {
00256         cpl_msg_error(cpl_func, "Please specify the catalog");
00257         return -1;
00258     }
00259 
00260     /* Retrieve calibration data */
00261     oh = isaac_extract_filename(framelist, ISAAC_CALPRO_OH_CAT);
00262     xe = isaac_extract_filename(framelist, ISAAC_CALPRO_XE_CAT);
00263     ar = isaac_extract_filename(framelist, ISAAC_CALPRO_AR_CAT);
00264     
00265     /* Reduce the images */
00266     cur_frame = cpl_frameset_get_frame(framelist, 0);
00267     cur_fname = cpl_frame_get_filename(cur_frame);
00268     cpl_msg_info(cpl_func, "Reduce %s", cur_fname);
00269     cpl_msg_indent_more();
00270 
00271     /* Apply the wl calib */
00272     if ((tab = isaac_spc_wlcalib_compute(cur_fname, oh, ar, xe)) == NULL) {
00273         cpl_msg_warning(cpl_func, "cannot reduce");
00274     } else {
00275         /* Save the file */
00276         if (isaac_spc_wlcalib_save(tab, 1, parlist, framelist) != 0) {
00277              cpl_msg_warning(cpl_func, "cannot save");
00278         }
00279         cpl_table_delete(tab);
00280     }
00281     cpl_msg_indent_less();
00282     
00283     /* Free and return */
00284     return 0;
00285 }
00286 
00287 /*----------------------------------------------------------------------------*/
00297 /*----------------------------------------------------------------------------*/
00298 static cpl_table * isaac_spc_wlcalib_compute(
00299         const char          *   in_name,
00300         const char          *   oh,
00301         const char          *   ar,
00302         const char          *   xe)
00303 {
00304     double                  slit_width;
00305     int                     order;
00306     double              *   phdisprel;
00307     cpl_image           *   in;
00308     computed_disprel    *   disprel;
00309     cpl_table           *   out_tab;
00310     const char          *   lines_tab;
00311 
00312     /* Compute the slit_width */
00313     if ((slit_width = isaac_get_slitwidth(in_name)) == -1) {
00314         cpl_msg_error(cpl_func, "cannot get the slit width");
00315         return NULL;
00316     }
00317 
00318     /* Get the order */
00319     if ((order = isaac_find_order(in_name)) == -1) {
00320         cpl_msg_error(cpl_func, "cannot get the order");
00321         return NULL;
00322     }
00323 
00324     /* First estimation using a physical model */
00325     cpl_msg_info(cpl_func, "Compute the physical model");
00326     cpl_msg_indent_more();
00327     if ((phdisprel = isaac_get_disprel_estimate(in_name, 3)) == NULL) {
00328         cpl_msg_error(cpl_func, "cannot estimate the dispersion relation");
00329         cpl_msg_indent_less();
00330         return NULL;
00331     }
00332     cpl_msg_info(cpl_func, "f(x)=%g + %g*x + %g*x^2 + %g*x^3",
00333             phdisprel[0], phdisprel[1], phdisprel[2], phdisprel[3]);
00334     cpl_msg_indent_less();
00335 
00336     /* Load the image */
00337     if ((in = cpl_image_load(in_name, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00338         cpl_msg_error(cpl_func, "cannot load the image");
00339         cpl_free(phdisprel);
00340         return NULL;
00341     }
00342     
00343     /* Compute the dispersion relation */
00344     switch (isaac_spc_wlcalib_config.lines_table) {
00345         case 1: lines_tab = "oh"; break;
00346         case 2: lines_tab = "Xe"; break;
00347         case 3: lines_tab = "Ar"; break;
00348         case 4: lines_tab = "Xe+Ar"; break;
00349         default: 
00350                 cpl_image_delete(in);
00351                 return NULL;
00352     }
00353     cpl_msg_info(cpl_func, "Compute the dispersion relation");
00354     cpl_msg_indent_more();
00355     if ((disprel = spectro_compute_disprel(in, 
00356                     isaac_spc_wlcalib_config.rej_bottom,
00357                     isaac_spc_wlcalib_config.rej_top,
00358                     isaac_spc_wlcalib_config.rej_left,
00359                     isaac_spc_wlcalib_config.rej_right,
00360                     isaac_spc_wlcalib_config.max_offset,
00361                     isaac_has_thermal(in_name) > 0,
00362                     lines_tab, oh, ar, xe, slit_width, order, 
00363                     (int)(cpl_msg_get_level() == CPL_MSG_DEBUG), 
00364                     phdisprel)) == NULL) {
00365         cpl_msg_error(cpl_func, "cannot compute the dispersion relation");
00366         cpl_image_delete(in);
00367         cpl_free(phdisprel);
00368         cpl_msg_indent_less();
00369         return NULL;
00370     }
00371     cpl_image_delete(in);
00372     cpl_free(phdisprel);
00373     
00374     cpl_msg_info(cpl_func, "Cross correlation factor: %g", disprel->cc);
00375     cpl_msg_info(cpl_func, "f(x)=%g + %g*x + %g*x^2 + %g*x^3",
00376             disprel->poly[0], disprel->poly[1], disprel->poly[2],
00377             disprel->poly[3]);
00378     cpl_msg_indent_less();
00379     
00380     /* Create the output table and store the relevant information */
00381     out_tab = cpl_table_new(4);
00382     
00383     /* Fill dispersion relation */
00384     cpl_table_new_column(out_tab, "WL_coefficients", CPL_TYPE_DOUBLE);
00385     cpl_table_set_double(out_tab, "WL_coefficients", 0, disprel->poly[0]);
00386     cpl_table_set_double(out_tab, "WL_coefficients", 1, disprel->poly[1]);
00387     cpl_table_set_double(out_tab, "WL_coefficients", 2, disprel->poly[2]);
00388     cpl_table_set_double(out_tab, "WL_coefficients", 3, disprel->poly[3]);
00389     isaac_spc_wlcalib_config.disprel_cc     = disprel->cc;
00390     isaac_spc_wlcalib_config.disprel_clines = disprel->clines;
00391     isaac_spc_wlcalib_config.disprel_dlines = disprel->dlines;
00392     isaac_spc_wlcalib_config.disprel_rms    = disprel->rms;
00393 
00394     /* Free and return */
00395     if (disprel->poly != NULL) cpl_free(disprel->poly);
00396     cpl_free(disprel);
00397     return out_tab;
00398 }
00399 
00400 /*----------------------------------------------------------------------------*/
00409 /*----------------------------------------------------------------------------*/
00410 static int isaac_spc_wlcalib_save(
00411         const cpl_table     *   tab,
00412         int                     nb,
00413         cpl_parameterlist   *   parlist,
00414         cpl_frameset        *   set)
00415 {
00416     cpl_propertylist    *   plist;
00417     cpl_propertylist    *   qclist;
00418     cpl_propertylist    *   paflist;
00419     const cpl_frame           *   ref_frame;
00420     const char          *   sval;
00421     char                *   filename;
00422 
00423     /* Get the QC params in qclist */
00424     qclist = cpl_propertylist_new();
00425 
00426     /* Get the reference frame */
00427     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00428     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00429                     0)) == NULL) {
00430         cpl_msg_error(cpl_func, "getting header from reference frame");
00431         cpl_propertylist_delete(qclist);
00432         return -1;
00433     }
00434     /* Test the status */
00435     if (cpl_error_get_code()) {
00436         cpl_propertylist_delete(qclist);
00437         cpl_propertylist_delete(plist);
00438         return -1;
00439     }
00440     sval = isaac_pfits_get_filter(plist);
00441     if (cpl_error_get_code()) cpl_error_reset();
00442     else cpl_propertylist_append_string(plist, "ESO QC FILTER OBS", sval);
00443     cpl_propertylist_delete(plist);
00444     cpl_propertylist_append_int(plist, "ESO QC LAMP", 
00445             isaac_spc_wlcalib_config.lines_table);
00446     cpl_propertylist_append_double(plist, "ESO QC DISP XCORR", 
00447             isaac_spc_wlcalib_config.disprel_cc);
00448     cpl_propertylist_append_int(plist, "ESO QC DISP NUMCAT", 
00449             isaac_spc_wlcalib_config.disprel_clines);
00450     cpl_propertylist_append_int(plist, "ESO QC DISP NUMMATCH", 
00451             isaac_spc_wlcalib_config.disprel_dlines);
00452     cpl_propertylist_append_double(plist, "ESO QC DISP STDEV", 
00453             isaac_spc_wlcalib_config.disprel_rms);
00454     cpl_propertylist_append_double(plist, "ESO QC DISPCO1", 
00455             cpl_table_get_double(tab, "WL_coefficients", 0, NULL));
00456     cpl_propertylist_append_double(plist, "ESO QC DISPCO2", 
00457             cpl_table_get_double(tab, "WL_coefficients", 1, NULL));
00458     cpl_propertylist_append_double(plist, "ESO QC DISPCO3", 
00459             cpl_table_get_double(tab, "WL_coefficients", 2, NULL));
00460     cpl_propertylist_append_double(plist, "ESO QC DISPCO4", 
00461             cpl_table_get_double(tab, "WL_coefficients", 3, NULL));
00462     cpl_propertylist_append_double(plist, "ESO QC WLEN",
00463         (double)(cpl_table_get_double(tab, "WL_coefficients", 0, NULL) +
00464              512*cpl_table_get_double(tab, "WL_coefficients", 1, NULL) +
00465          512*512*cpl_table_get_double(tab, "WL_coefficients", 2, NULL) +
00466      512*512*512*cpl_table_get_double(tab, "WL_coefficients", 3, NULL)));
00467  
00468     /* Write the table  */
00469     filename = cpl_sprintf("isaac_spc_wlcalib_%d.fits", nb);
00470     irplib_dfs_save_table(set,
00471             parlist,
00472             set,
00473             tab,
00474             NULL,
00475             "isaac_spc_wlcalib",
00476             ISAAC_SPC_WLCALIB_RES,
00477             qclist,
00478             NULL,
00479             PACKAGE "/" PACKAGE_VERSION,
00480             filename);
00481     cpl_free(filename);
00482     
00483     /* Get the reference frame */
00484     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00485 
00486     /* Get FITS header from reference file */
00487     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00488                     0)) == NULL) {
00489         cpl_msg_error(cpl_func, "getting header from reference frame");
00490         cpl_propertylist_delete(qclist);
00491         return -1;
00492     }
00493     
00494     /* Get the keywords for the paf file */
00495     paflist = cpl_propertylist_new();
00496     cpl_propertylist_copy_property_regexp(paflist, plist, 
00497         "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
00498         "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
00499         "ESO INS GRAT WLEN|ESO INS GRAT ORDER|ESO INS MODE|"
00500         "ESO INS OPTI1 ID)$", 0);
00501     cpl_propertylist_delete(plist);
00502 
00503     /* Copy the QC in paflist */
00504     cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00505     cpl_propertylist_delete(qclist);
00506 
00507     /* PRO.CATG */
00508     cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG,
00509                                    ISAAC_SPC_WLCALIB_RES);
00510 
00511     /* Save the PAF file */
00512     filename = cpl_sprintf("isaac_spc_wlcalib_%d.paf", nb);
00513     cpl_dfs_save_paf("ISAAC",
00514             "isaac_spc_wlcalib",
00515             paflist,
00516             filename);
00517     cpl_free(filename);
00518     cpl_propertylist_delete(paflist);
00519     return  0;
00520 }
00521 

Generated on Mon Feb 6 14:44:02 2012 for ISAAC Pipeline Reference Manual by  doxygen 1.5.8