crires_util_wlcalib.c

00001 /* $Id: crires_util_wlcalib.c,v 1.64 2010/04/23 08:58:43 yjung Exp $
00002  *
00003  * This file is part of the crires 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: yjung $
00023  * $Date: 2010/04/23 08:58:43 $
00024  * $Revision: 1.64 $
00025  * $Name: crire-2_1_1 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include "crires_recipe.h"
00037 
00038 #include "irplib_wlxcorr.h"
00039 #include "crires_wlcalib.h"
00040 #include "crires_wlestimate.h"
00041 
00042 /*-----------------------------------------------------------------------------
00043                                 Define
00044  -----------------------------------------------------------------------------*/
00045 
00046 #define RECIPE_STRING "crires_util_wlcalib"
00047 
00048 /*-----------------------------------------------------------------------------
00049                             Functions prototypes
00050  -----------------------------------------------------------------------------*/
00051 
00052 static int crires_util_wlcalib_save(const cpl_imagelist *, const cpl_table **, 
00053         const cpl_table **, const cpl_parameterlist *, cpl_frameset *) ;
00054 
00055 static char crires_util_wlcalib_description[] = 
00056 "This recipe accepts 2 parameters:\n"
00057 "First parameter:   the extracted spectrum in pixels.\n"
00058 "                   (PRO TYPE = "CRIRES_PROTYPE_SPEC_PIX")\n"
00059 "Second parameter:  the table with the lines catalog.\n"
00060 "                   (PRO TYPE = "CRIRES_PROTYPE_CATALOG")\n"
00061 "\n"
00062 "This recipe produces 2 files:\n"
00063 "First product:     the image with the wavelength values.\n"
00064 "                   (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n"
00065 "Second product:    the table with the wavelength polynomial coefficients.\n"
00066 "                   (PRO TYPE = "CRIRES_PROTYPE_WL_POLY")\n" ;
00067 
00068 CRIRES_RECIPE_DEFINE(crires_util_wlcalib,
00069         CRIRES_PARAM_WAVES          |
00070         CRIRES_PARAM_DISPLAY        |
00071         CRIRES_PARAM_WL_LOG         |
00072         CRIRES_PARAM_WL_NOLIMIT     |
00073         CRIRES_PARAM_WL_ERROR       |
00074         CRIRES_PARAM_XC_LIMIT       |
00075         CRIRES_PARAM_WL_NBSAMPLES   |
00076         CRIRES_PARAM_DEGREE         |
00077         CRIRES_PARAM_WL_CLEAN       |
00078         CRIRES_PARAM_LINES,
00079         "Wavelength calibration of a spectrum",
00080         crires_util_wlcalib_description) ;
00081 
00082 /*-----------------------------------------------------------------------------
00083                             Static variables
00084  -----------------------------------------------------------------------------*/
00085 
00086 static struct {
00087     /* Inputs */
00088     double                  wstart[CRIRES_NB_DETECTORS] ;
00089     double                  wstop[CRIRES_NB_DETECTORS] ;
00090     int                     display ;
00091     int                     degree ;
00092     int                     wl_nolimit ;
00093     int                     wl_log ;
00094     double                  wl_err ;
00095     int                     wl_nsamples ;
00096     int                     wl_clean ;
00097     double                  wl_xclimit ;
00098     int                     use_ppm ;
00099     int                     slitw ;
00100     int                     fwhm ;
00101     const char          *   lines ;
00102     /* Output */
00103     crires_illum_period     period ;
00104     double                  qc_wlcent[CRIRES_NB_DETECTORS] ;
00105     double                  qc_wldisp[CRIRES_NB_DETECTORS] ;
00106     double                  qc_wlxc[CRIRES_NB_DETECTORS] ;
00107 } crires_util_wlcalib_config ;
00108 
00109 /*-----------------------------------------------------------------------------
00110                                 Functions code
00111  -----------------------------------------------------------------------------*/
00112 
00113 /*----------------------------------------------------------------------------*/
00120 /*----------------------------------------------------------------------------*/
00121 static int crires_util_wlcalib(
00122         cpl_frameset            *   frameset,
00123         const cpl_parameterlist *   parlist)
00124 {
00125     cpl_table           *   ext_spec ;
00126     const char          *   fname ;
00127     cpl_propertylist    *   plist ;
00128     double                  wmin, wmax ;
00129     cpl_vector          *   spec ;
00130     double              *   pspec ;
00131     cpl_polynomial      *   phdisp ;
00132     cpl_polynomial      *   poly_sol ;
00133     cpl_matrix          *   samppos ;
00134     int                     mindeg ;
00135     cpl_bivector        *   lines_biv ;
00136     cpl_table           *   cat ;
00137     double                  val ;
00138     cpl_table           *   real_sol ;
00139     int                     nrows ;
00140     cpl_bivector        *   cat_biv ;
00141     double              *   cat_biv_x ;
00142     double              *   cat_biv_y ;
00143     const char          *   sval ;
00144     cpl_frame           *   fr ;
00145     cpl_polynomial      *   disp[CRIRES_NB_DETECTORS] ;
00146     cpl_table           *   wl_infos[CRIRES_NB_DETECTORS] ;
00147     cpl_table           **  wl_tab ;
00148     cpl_imagelist       *   wl_map ;
00149     int                     i, j ;
00150     
00151     /* Initialise */
00152     crires_util_wlcalib_config.lines = NULL ;
00153     crires_util_wlcalib_config.use_ppm = 0 ;
00154     crires_util_wlcalib_config.slitw = 2 ;
00155     crires_util_wlcalib_config.fwhm = 2 ;
00156     
00157     /* Retrieve input parameters */
00158     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
00159             CRIRES_PARAM_WAVES) ;
00160     if (sscanf(sval, "%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg",
00161                     &crires_util_wlcalib_config.wstart[0],
00162                     &crires_util_wlcalib_config.wstop[0],
00163                     &crires_util_wlcalib_config.wstart[1],
00164                     &crires_util_wlcalib_config.wstop[1],
00165                     &crires_util_wlcalib_config.wstart[2],
00166                     &crires_util_wlcalib_config.wstop[2],
00167                     &crires_util_wlcalib_config.wstart[3],
00168                 &crires_util_wlcalib_config.wstop[3])!=2*CRIRES_NB_DETECTORS){
00169         return -1 ;
00170     }
00171     crires_util_wlcalib_config.display = crires_parameterlist_get_int(parlist,
00172             RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
00173     crires_util_wlcalib_config.degree = crires_parameterlist_get_int(parlist,
00174             RECIPE_STRING, CRIRES_PARAM_DEGREE) ;
00175     crires_util_wlcalib_config.wl_log = crires_parameterlist_get_bool(parlist,
00176             RECIPE_STRING, CRIRES_PARAM_WL_LOG) ;
00177     crires_util_wlcalib_config.wl_nolimit = crires_parameterlist_get_bool(
00178             parlist, RECIPE_STRING, CRIRES_PARAM_WL_NOLIMIT) ;
00179     crires_util_wlcalib_config.wl_err = crires_parameterlist_get_double(parlist,
00180             RECIPE_STRING, CRIRES_PARAM_WL_ERROR) ;
00181     crires_util_wlcalib_config.wl_xclimit = crires_parameterlist_get_double(
00182             parlist, RECIPE_STRING, CRIRES_PARAM_XC_LIMIT) ;
00183     crires_util_wlcalib_config.wl_nsamples = crires_parameterlist_get_int(
00184             parlist, RECIPE_STRING, CRIRES_PARAM_WL_NBSAMPLES) ;
00185     crires_util_wlcalib_config.wl_clean = crires_parameterlist_get_bool(parlist,
00186             RECIPE_STRING, CRIRES_PARAM_WL_CLEAN) ;
00187    crires_util_wlcalib_config.lines = crires_parameterlist_get_string(parlist, 
00188            RECIPE_STRING, CRIRES_PARAM_LINES) ;
00189  
00190     /* Identify the RAW and CALIB frames in the input frameset */
00191     if (crires_dfs_set_groups(frameset, NULL)) {
00192         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00193         return -1 ;
00194     }
00195     
00196     /* Check that we have 2 files in input */
00197     if (cpl_frameset_get_size(frameset) != 2) {
00198         cpl_msg_error(__func__, "Expects 2 files in input") ;
00199         return -1 ;
00200     }
00201 
00202     /* Get the detector illumination period */
00203     fr = cpl_frameset_get_frame(frameset, 0);
00204     crires_util_wlcalib_config.period =
00205         crires_get_detector_illum_period(cpl_frame_get_filename(fr)) ;
00206     if (crires_util_wlcalib_config.period == CRIRES_ILLUM_UNKNOWN) {
00207         cpl_msg_error(__func__,
00208                 "Cannot determine the detector illumination period") ;
00209         return -1 ;
00210     } else {
00211         crires_display_detector_illum(crires_util_wlcalib_config.period) ;
00212     }
00213 
00214     /* Load the second file */
00215     cpl_msg_info(__func__, "Second frame validity check") ;
00216     cpl_msg_indent_more() ;
00217     fr = cpl_frameset_get_frame(frameset, 1);
00218     cat = crires_load_table_check(cpl_frame_get_filename(fr), 1,
00219             CRIRES_PROTYPE_CATALOG, -1, -1, 0) ;
00220     if (cat == NULL) {
00221         cpl_msg_error(__func__, "Second frame is incorrect") ;
00222         cpl_msg_indent_less() ;
00223         return -1 ;
00224     }
00225     cpl_msg_indent_less() ;
00226     
00227     /* Create the catalog spectrum in a bivector */
00228     nrows = cpl_table_get_nrow(cat) ;
00229     cat_biv = cpl_bivector_new(nrows) ;
00230     cat_biv_x = cpl_bivector_get_x_data(cat_biv) ;
00231     cat_biv_y = cpl_bivector_get_y_data(cat_biv) ;
00232     for (i=0 ; i<nrows ; i++) {
00233         cat_biv_x[i] = cpl_table_get(cat, CRIRES_COL_WAVELENGTH, i, NULL) ;
00234         val = cpl_table_get(cat, CRIRES_COL_EMISSION, i, NULL) ;
00235         if (crires_util_wlcalib_config.wl_log && val > 0)
00236             cat_biv_y[i] = log10(val) ;
00237         else 
00238             cat_biv_y[i] = val ;
00239     }
00240     cpl_table_delete(cat) ;
00241 
00242     /* Get the raw file name */
00243     fr = cpl_frameset_get_frame(frameset, 0);
00244     fname = cpl_frame_get_filename(fr) ;
00245 
00246     /* Get the Minimum and Maximum wavelengths */
00247     if (crires_util_wlcalib_config.wl_nolimit == 0) {
00248         plist = cpl_propertylist_load(fname, 0) ;
00249         wmin = crires_pfits_get_wlen_min(plist) ;
00250         wmax = crires_pfits_get_wlen_max(plist) ;
00251         cpl_propertylist_delete(plist) ;
00252         if (cpl_error_get_code()) {
00253             wmin = wmax = -1.0 ;
00254             cpl_error_reset() ;
00255         }
00256     } else {
00257         wmin = wmax = -1.0 ;
00258     }
00259 
00260     /* Loop on the spectra to calibrate */
00261     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00262         cpl_msg_info(__func__, "Wavelength calibration for chip %d", i+1) ;
00263         
00264         /* Initialise */
00265         disp[i] = NULL ;
00266         wl_infos[i] = NULL ;
00267         crires_util_wlcalib_config.qc_wlcent[i] = -1.0 ;
00268         crires_util_wlcalib_config.qc_wldisp[i] = -1.0 ;
00269         crires_util_wlcalib_config.qc_wlxc[i] = -1.0 ;
00270         
00271         /* Load the first file in table */
00272         cpl_msg_info(__func__, "Load the extracted table") ;
00273         cpl_msg_indent_more() ;
00274         if ((ext_spec=crires_load_table_check(fname, i+1, 
00275                     CRIRES_PROTYPE_SPEC_PIX, -1, -1, 0)) == NULL) {
00276             cpl_msg_warning(__func__, "Empty extension") ;
00277             cpl_msg_indent_less() ;
00278             continue ;
00279         }
00280         cpl_msg_indent_less() ;
00281         
00282         /* Get the physical model solution */
00283         cpl_msg_info(__func__, "Wavelength estimation") ;
00284         cpl_msg_indent_more() ;
00285         if ((phdisp = crires_wlestimate_compute(
00286                         crires_util_wlcalib_config.wstart[i],
00287                         crires_util_wlcalib_config.wstop[i])) == NULL) {
00288             if ((phdisp = crires_wlestimate_get(fname, i+1)) == NULL) {
00289                 cpl_msg_error(__func__, "Cannot get the wavelength estimate") ;
00290                 cpl_msg_indent_less() ;
00291                 cpl_table_delete(ext_spec) ;
00292                 continue ;
00293             }
00294         }
00295         cpl_msg_indent_less() ;
00296 
00297         /* Convert to vector */
00298         nrows = cpl_table_get_nrow(ext_spec) ;
00299         spec = cpl_vector_new(nrows) ;
00300         pspec = cpl_vector_get_data(spec) ;
00301         for (j=0 ; j<nrows ; j++) {
00302             pspec[j] = cpl_table_get(ext_spec, CRIRES_COL_EXTRACT_INT_RECT, j, 
00303                     NULL);
00304         }
00305         cpl_table_delete(ext_spec) ;
00306 
00307         /* Wavelength calibration */
00308         cpl_msg_info(__func__, "Wavelength calibration computation") ;
00309         cpl_msg_indent_more() ;
00310         if ((disp[i] = crires_wlcalib_engine(spec, cat_biv, phdisp,
00311                         crires_util_wlcalib_config.slitw, 
00312                         crires_util_wlcalib_config.fwhm,
00313                         crires_util_wlcalib_config.degree,
00314                         wmin, wmax,
00315                         crires_util_wlcalib_config.wl_err,
00316                         crires_util_wlcalib_config.wl_nsamples,
00317                         crires_util_wlcalib_config.wl_clean, 
00318                         crires_util_wlcalib_config.wl_xclimit,
00319                         crires_util_wlcalib_config.use_ppm, 
00320                         (i+1==crires_util_wlcalib_config.display),
00321                         &((crires_util_wlcalib_config.qc_wlxc)[i]),
00322                         NULL)) == NULL) {
00323             cpl_msg_error(__func__, "Wavelength calibration failed") ;
00324             cpl_msg_indent_less() ;
00325             cpl_vector_delete(spec) ;
00326             cpl_polynomial_delete(phdisp) ;
00327             continue ;
00328         }
00329         cpl_msg_indent_less() ;
00330         
00331         /* Compute the QC parameters */
00332         crires_util_wlcalib_config.qc_wlcent[i] = 
00333             cpl_polynomial_eval_1d(disp[i], (double)512, NULL) ;
00334         crires_util_wlcalib_config.qc_wldisp[i] = 
00335             (cpl_polynomial_eval_1d(disp[i], (double)1024, NULL) -
00336              cpl_polynomial_eval_1d(disp[i], (double)1, NULL)) / 1024 ;
00337         
00338         /* Plot the result */
00339         if (crires_util_wlcalib_config.display==i+1) {
00340             /* Compute the solution from the passed associated lines if passed*/
00341             poly_sol = NULL ;
00342             if (crires_util_wlcalib_config.lines != NULL && 
00343                     crires_util_wlcalib_config.lines[0] != (char)0) {
00344                 lines_biv = 
00345                     cpl_bivector_read((char*)crires_util_wlcalib_config.lines);
00346                 if ((lines_biv != NULL) && 
00347         (cpl_bivector_get_size(lines_biv)>crires_util_wlcalib_config.degree)) {
00348                     poly_sol = cpl_polynomial_new(1);
00349                     samppos = cpl_matrix_wrap(1, cpl_bivector_get_size(lines_biv),
00350                             cpl_bivector_get_x_data(lines_biv)) ;
00351                     mindeg = 1 ;
00352                     cpl_polynomial_fit(poly_sol,
00353                             samppos, NULL,
00354                             cpl_bivector_get_y(lines_biv),
00355                             NULL, CPL_FALSE, 
00356                             &mindeg,
00357                             &(crires_util_wlcalib_config.degree)) ;
00358                     cpl_matrix_unwrap(samppos) ;
00359                 }
00360                 if (lines_biv != NULL) cpl_bivector_delete(lines_biv) ;
00361             } 
00362             irplib_wlxcorr_plot_solution(phdisp, disp[i], poly_sol, 1, 1024);
00363             if (poly_sol != NULL) {
00364                 real_sol = irplib_wlxcorr_gen_spc_table(spec, cat_biv,
00365                         crires_util_wlcalib_config.slitw, 
00366                         crires_util_wlcalib_config.fwhm,
00367                         phdisp, poly_sol) ;
00368                 irplib_wlxcorr_plot_spc_table(real_sol, "Real") ;
00369                 cpl_table_delete(real_sol) ;
00370             }
00371             if (poly_sol != NULL) cpl_polynomial_delete(poly_sol) ;
00372         }
00373 
00374         /* Compute the products */
00375         wl_infos[i] = irplib_wlxcorr_gen_spc_table(spec, cat_biv, 
00376                 crires_util_wlcalib_config.slitw, 
00377                 crires_util_wlcalib_config.fwhm, 
00378                 phdisp, disp[i]) ;
00379 
00380         /* Free */
00381         cpl_vector_delete(spec) ;
00382         cpl_polynomial_delete(phdisp) ;
00383     }
00384     
00385     cpl_bivector_delete(cat_biv) ;
00386        
00387     /* Create output tables */
00388     wl_tab = crires_wlcalib_gen_wltab((const cpl_polynomial **)disp) ;
00389     wl_map = crires_wlcalib_gen_wlmap((const cpl_table **)wl_tab) ;
00390     
00391     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00392         if (disp[i] != NULL) cpl_polynomial_delete(disp[i]) ;
00393     }
00394     
00395     /* Save the result */
00396     cpl_msg_info(__func__, "Save the products") ;
00397     cpl_msg_indent_more() ;
00398     if (crires_util_wlcalib_save(wl_map, (const cpl_table **)wl_tab, 
00399                 (const cpl_table **)wl_infos, parlist, frameset) == -1) {
00400         cpl_msg_error(__func__, "Cannot save products");
00401         cpl_msg_indent_less() ;
00402         cpl_imagelist_delete(wl_map) ;
00403         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00404             cpl_table_delete(wl_tab[i]) ;
00405             if (wl_infos[i] != NULL) cpl_table_delete(wl_infos[i]) ;
00406         }
00407         cpl_free(wl_tab) ;
00408         return -1 ;
00409     }
00410     cpl_msg_indent_less() ;
00411     cpl_imagelist_delete(wl_map) ;
00412     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00413         cpl_table_delete(wl_tab[i]) ;
00414         if (wl_infos[i] != NULL) cpl_table_delete(wl_infos[i]) ;
00415     }
00416     cpl_free(wl_tab) ;
00417 
00418     /* Return */
00419     if (cpl_error_get_code()) return -1 ;
00420     else return 0 ;
00421 }
00422 
00423 /*----------------------------------------------------------------------------*/
00433 /*----------------------------------------------------------------------------*/
00434 static int crires_util_wlcalib_save(
00435         const cpl_imagelist     *   ilist,
00436         const cpl_table         **  tab,
00437         const cpl_table         **  xctab,
00438         const cpl_parameterlist *   parlist,
00439         cpl_frameset            *   set)
00440 {
00441     cpl_propertylist    **  qclists ;
00442     const cpl_frame     *   ref_frame ;
00443     cpl_propertylist    *   inputlist ;
00444     const char          *   recipe_name = "crires_util_wlcalib" ;
00445     int                     i ;
00446 
00447     /* Get the reference frame */
00448     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00449 
00450     /* Create the QC lists */
00451     qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00452     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00453         qclists[i] = cpl_propertylist_new() ;
00454         cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL", 
00455                 crires_util_wlcalib_config.qc_wlcent[i]) ;
00456         cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL", 
00457                 crires_util_wlcalib_config.qc_wldisp[i]) ;
00458         cpl_propertylist_append_double(qclists[i], "ESO QC XCORR", 
00459                 crires_util_wlcalib_config.qc_wlxc[i]) ;
00460 
00461         /* Propagate some keywords from input raw frame extensions */
00462         inputlist = cpl_propertylist_load_regexp(
00463                 cpl_frame_get_filename(ref_frame), i+1,
00464                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00465         cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 
00466                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00467         cpl_propertylist_delete(inputlist) ;
00468     }
00469 
00470     /* Write the image */
00471     crires_image_save(set,
00472             parlist,
00473             set,
00474             ilist,
00475             recipe_name,
00476             CRIRES_WL_MAP_IMA,
00477             CRIRES_PROTYPE_WL_MAP,
00478             crires_util_wlcalib_config.period,
00479             NULL,
00480             (const cpl_propertylist **)qclists,
00481             PACKAGE "/" PACKAGE_VERSION,
00482             "crires_util_wlcalib_ima.fits") ;
00483 
00484     /* Write the table */
00485     crires_table_save(set,
00486             parlist,
00487             set,
00488             tab,
00489             recipe_name,
00490             CRIRES_CALPRO_WAVE,
00491             CRIRES_PROTYPE_WL_POLY,
00492             NULL,
00493             (const cpl_propertylist **)qclists,
00494             PACKAGE "/" PACKAGE_VERSION,
00495             "crires_util_wlcalib_tab.fits") ;
00496 
00497     if (xctab[0] != NULL) {
00498         /* Write the table */
00499         crires_table_save(set,
00500                 parlist,
00501                 set,
00502                 xctab,
00503                 recipe_name,
00504                 CRIRES_WL_XCORR_TAB,
00505                 CRIRES_PROTYPE_XCORR,
00506                 NULL,
00507                 (const cpl_propertylist **)qclists,
00508                 PACKAGE "/" PACKAGE_VERSION,
00509                 "crires_util_wlcalib_xctab.fits") ;
00510     }
00511 
00512     /* Free and return */
00513     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00514         cpl_propertylist_delete(qclists[i]) ;
00515     }
00516     cpl_free(qclists) ;
00517     return  0;
00518 }

Generated on 22 Mar 2011 for CRIRES Pipeline Reference Manual by  doxygen 1.6.1