crires_util_wlcalib.c

00001 /* $Id: crires_util_wlcalib.c,v 1.65 2011/11/22 08:50:12 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: 2011/11/22 08:50:12 $
00024  * $Revision: 1.65 $
00025  * $Name: crire-2_2_0 $
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     cpl_size                mindeg, maxdeg ;
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, 
00350                             cpl_bivector_get_size(lines_biv),
00351                             cpl_bivector_get_x_data(lines_biv)) ;
00352                     mindeg = 1 ;
00353                     maxdeg = (cpl_size)crires_util_wlcalib_config.degree ;
00354                     cpl_polynomial_fit(poly_sol,
00355                             samppos, NULL,
00356                             cpl_bivector_get_y(lines_biv),
00357                             NULL, CPL_FALSE, 
00358                             &mindeg,
00359                             &maxdeg) ;
00360                     cpl_matrix_unwrap(samppos) ;
00361                 }
00362                 if (lines_biv != NULL) cpl_bivector_delete(lines_biv) ;
00363             } 
00364             irplib_wlxcorr_plot_solution(phdisp, disp[i], poly_sol, 1, 1024);
00365             if (poly_sol != NULL) {
00366                 real_sol = irplib_wlxcorr_gen_spc_table(spec, cat_biv,
00367                         crires_util_wlcalib_config.slitw, 
00368                         crires_util_wlcalib_config.fwhm,
00369                         phdisp, poly_sol) ;
00370                 irplib_wlxcorr_plot_spc_table(real_sol, "Real") ;
00371                 cpl_table_delete(real_sol) ;
00372             }
00373             if (poly_sol != NULL) cpl_polynomial_delete(poly_sol) ;
00374         }
00375 
00376         /* Compute the products */
00377         wl_infos[i] = irplib_wlxcorr_gen_spc_table(spec, cat_biv, 
00378                 crires_util_wlcalib_config.slitw, 
00379                 crires_util_wlcalib_config.fwhm, 
00380                 phdisp, disp[i]) ;
00381 
00382         /* Free */
00383         cpl_vector_delete(spec) ;
00384         cpl_polynomial_delete(phdisp) ;
00385     }
00386     
00387     cpl_bivector_delete(cat_biv) ;
00388        
00389     /* Create output tables */
00390     wl_tab = crires_wlcalib_gen_wltab((const cpl_polynomial **)disp) ;
00391     wl_map = crires_wlcalib_gen_wlmap((const cpl_table **)wl_tab) ;
00392     
00393     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00394         if (disp[i] != NULL) cpl_polynomial_delete(disp[i]) ;
00395     }
00396     
00397     /* Save the result */
00398     cpl_msg_info(__func__, "Save the products") ;
00399     cpl_msg_indent_more() ;
00400     if (crires_util_wlcalib_save(wl_map, (const cpl_table **)wl_tab, 
00401                 (const cpl_table **)wl_infos, parlist, frameset) == -1) {
00402         cpl_msg_error(__func__, "Cannot save products");
00403         cpl_msg_indent_less() ;
00404         cpl_imagelist_delete(wl_map) ;
00405         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00406             cpl_table_delete(wl_tab[i]) ;
00407             if (wl_infos[i] != NULL) cpl_table_delete(wl_infos[i]) ;
00408         }
00409         cpl_free(wl_tab) ;
00410         return -1 ;
00411     }
00412     cpl_msg_indent_less() ;
00413     cpl_imagelist_delete(wl_map) ;
00414     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00415         cpl_table_delete(wl_tab[i]) ;
00416         if (wl_infos[i] != NULL) cpl_table_delete(wl_infos[i]) ;
00417     }
00418     cpl_free(wl_tab) ;
00419 
00420     /* Return */
00421     if (cpl_error_get_code()) return -1 ;
00422     else return 0 ;
00423 }
00424 
00425 /*----------------------------------------------------------------------------*/
00435 /*----------------------------------------------------------------------------*/
00436 static int crires_util_wlcalib_save(
00437         const cpl_imagelist     *   ilist,
00438         const cpl_table         **  tab,
00439         const cpl_table         **  xctab,
00440         const cpl_parameterlist *   parlist,
00441         cpl_frameset            *   set)
00442 {
00443     cpl_propertylist    **  qclists ;
00444     const cpl_frame     *   ref_frame ;
00445     cpl_propertylist    *   inputlist ;
00446     const char          *   recipe_name = "crires_util_wlcalib" ;
00447     int                     i ;
00448 
00449     /* Get the reference frame */
00450     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00451 
00452     /* Create the QC lists */
00453     qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00454     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00455         qclists[i] = cpl_propertylist_new() ;
00456         cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL", 
00457                 crires_util_wlcalib_config.qc_wlcent[i]) ;
00458         cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL", 
00459                 crires_util_wlcalib_config.qc_wldisp[i]) ;
00460         cpl_propertylist_append_double(qclists[i], "ESO QC XCORR", 
00461                 crires_util_wlcalib_config.qc_wlxc[i]) ;
00462 
00463         /* Propagate some keywords from input raw frame extensions */
00464         inputlist = cpl_propertylist_load_regexp(
00465                 cpl_frame_get_filename(ref_frame), i+1,
00466                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00467         cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 
00468                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00469         cpl_propertylist_delete(inputlist) ;
00470     }
00471 
00472     /* Write the image */
00473     crires_image_save(set,
00474             parlist,
00475             set,
00476             ilist,
00477             recipe_name,
00478             CRIRES_WL_MAP_IMA,
00479             CRIRES_PROTYPE_WL_MAP,
00480             crires_util_wlcalib_config.period,
00481             NULL,
00482             (const cpl_propertylist **)qclists,
00483             PACKAGE "/" PACKAGE_VERSION,
00484             "crires_util_wlcalib_ima.fits") ;
00485 
00486     /* Write the table */
00487     crires_table_save(set,
00488             parlist,
00489             set,
00490             tab,
00491             recipe_name,
00492             CRIRES_CALPRO_WAVE,
00493             CRIRES_PROTYPE_WL_POLY,
00494             NULL,
00495             (const cpl_propertylist **)qclists,
00496             PACKAGE "/" PACKAGE_VERSION,
00497             "crires_util_wlcalib_tab.fits") ;
00498 
00499     if (xctab[0] != NULL) {
00500         /* Write the table */
00501         crires_table_save(set,
00502                 parlist,
00503                 set,
00504                 xctab,
00505                 recipe_name,
00506                 CRIRES_WL_XCORR_TAB,
00507                 CRIRES_PROTYPE_XCORR,
00508                 NULL,
00509                 (const cpl_propertylist **)qclists,
00510                 PACKAGE "/" PACKAGE_VERSION,
00511                 "crires_util_wlcalib_xctab.fits") ;
00512     }
00513 
00514     /* Free and return */
00515     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00516         cpl_propertylist_delete(qclists[i]) ;
00517     }
00518     cpl_free(qclists) ;
00519     return  0;
00520 }

Generated on 30 Jan 2012 for CRIRES Pipeline Reference Manual by  doxygen 1.6.1