CRIRES Pipeline Reference Manual  2.3.2
crires_model_refine.c
00001 /* $Id: crires_model_refine.c,v 1.55 2012-01-16 10:09:55 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: 2012-01-16 10:09:55 $
00024  * $Revision: 1.55 $
00025  * $Name: not supported by cvs2svn $
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_spectrum.h"
00039 
00040 #include "crires_model_refining.h"
00041 #include "crires_model_kernel.h"
00042 
00043 /*-----------------------------------------------------------------------------
00044                                 Define
00045  -----------------------------------------------------------------------------*/
00046 
00047 #define RECIPE_STRING "crires_model_refine"
00048 
00049 /*-----------------------------------------------------------------------------
00050                             Functions prototypes
00051  -----------------------------------------------------------------------------*/
00052 
00053 static int crires_model_refine_save(cpl_table *, const cpl_parameterlist *, 
00054         cpl_frameset *) ;
00055 
00056 static char crires_model_refine_description[] =
00057 "crires_model_refine -- Model refining recipe\n"
00058 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00059 "raw-file.fits "CRIRES_MODEL_REFINE_RAW" or\n"
00060 "THAR-file.fits "CRIRES_CALPRO_THAR_CAT" or\n"
00061 "bpm-file.fits "CRIRES_CALPRO_BPM" or\n"
00062 "flat-file.fits "CRIRES_CALPRO_FLAT" or\n"
00063 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n"
00064 "config-file.fits "CRIRES_CALPRO_MODEL_REFINE_CONF".\n" ;
00065 
00066 CRIRES_RECIPE_DEFINE(crires_model_refine,
00067              CRIRES_PARAM_DISPLAY        |
00068              CRIRES_PARAM_FWHM           |
00069              CRIRES_PARAM_SIGMA          |
00070              CRIRES_PARAM_SEARCH_BOX     |
00071              CRIRES_PARAM_MIN_MATCH,      
00072              "Model Refining recipe",
00073              crires_model_refine_description) ;
00074 
00075 /*-----------------------------------------------------------------------------
00076                             Static variables
00077  -----------------------------------------------------------------------------*/
00078 
00079 static struct {
00080     /* Inputs */
00081     int             display ;
00082     int             search_box_sz ;
00083     int             min_matches_nb ;
00084     int             fwhm ;
00085     double          sigma ;
00086     /* Outputs */
00087     crires_illum_period period ;
00088     double              penc_co1 ;
00089     double              genc_co1 ;
00090     double              sg ;
00091     double              fk ;
00092     double              cam_dis ;
00093     double              slity ;
00094 } crires_model_refine_config ;
00095 
00096 /*-----------------------------------------------------------------------------
00097                                 Functions code
00098  -----------------------------------------------------------------------------*/
00099 
00100 /*----------------------------------------------------------------------------*/
00107 /*----------------------------------------------------------------------------*/
00108 static int crires_model_refine(
00109         cpl_frameset            *   frameset,
00110         const cpl_parameterlist *   parlist)
00111 {
00112     cpl_frameset        *   rawframes ;
00113     const char          *   config ;
00114     const char          *   thar ;
00115     const char          *   bpm ;
00116     const char          *   flat ;
00117     const char          *   detlin ;
00118     const char          *   ref_fname=NULL ;
00119     cpl_frame           *   ref_frame ;
00120     cpl_vector          **  traces ;
00121     double              *   ptrace ;
00122     double              **  cust_lines=NULL;
00123     cpl_imagelist       *   ilist ;
00124     cpl_vector          *   extracted[CRIRES_NB_DETECTORS] ;
00125     cpl_vector          *   bright_lines[CRIRES_NB_DETECTORS] ;
00126     cpl_table           *   new_conf ;
00127     int                     nframes;
00128     int                     i, j, k;
00129 
00130     double y_pos_mm=-50;
00131     int coord_cnt=0;
00132     double ** temp_coord;
00133     coord msp_coord[400];
00134     int ph, cust_lines_flag;
00135     int nph=7;
00136     double y_pos_pix=0.0;
00137     FILE* scan_out;
00138 
00139     /* The Model is switched off */
00140     if (crires_model_off()) {
00141         return 0 ;
00142     }
00143 
00144     /* Initialise */
00145     rawframes = NULL ;
00146     crires_model_refine_config.penc_co1 = -1.0 ;
00147     crires_model_refine_config.genc_co1 = -1.0 ;
00148     crires_model_refine_config.sg = -1.0 ;
00149     crires_model_refine_config.fk = -1.0 ;
00150     crires_model_refine_config.cam_dis = -1.0 ;
00151     crires_model_refine_config.slity = -1.0 ;
00152     
00153     /* Retrieve input parameters */
00154     crires_model_refine_config.display = crires_parameterlist_get_int(parlist, 
00155             RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
00156     crires_model_refine_config.fwhm = crires_parameterlist_get_int(parlist, 
00157             RECIPE_STRING, CRIRES_PARAM_FWHM) ; 
00158     crires_model_refine_config.sigma = crires_parameterlist_get_double(parlist,
00159             RECIPE_STRING, CRIRES_PARAM_SIGMA) ;
00160     crires_model_refine_config.search_box_sz = crires_parameterlist_get_int(
00161             parlist, RECIPE_STRING, CRIRES_PARAM_SEARCH_BOX) ;
00162     crires_model_refine_config.min_matches_nb = crires_parameterlist_get_int(
00163             parlist, RECIPE_STRING, CRIRES_PARAM_MIN_MATCH) ;
00164 
00165     /* Identify the RAW and CALIB frames in the input frameset */
00166     if (crires_dfs_set_groups(frameset, "crires_model_refine")) {
00167         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00168         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00169         return -1 ;
00170     }
00171 
00172     /* Retrieve calibration data */
00173     config = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_REFINE_CONF);
00174     if (config == NULL) {
00175         cpl_msg_error(__func__, "Model configuration file is missing") ;
00176         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00177         return -1 ;
00178     }
00179     thar = crires_extract_filename(frameset, CRIRES_CALPRO_THAR_CAT) ;
00180     if (thar == NULL) {
00181         cpl_msg_error(__func__, "Lines catalog file is missing") ;
00182         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00183         return -1 ;
00184     }
00185     bpm         = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
00186     flat        = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
00187     detlin      = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
00188 
00189     /* Retrieve raw frames */
00190     if ((rawframes = crires_extract_frameset(frameset, 
00191                     CRIRES_MODEL_REFINE_RAW)) == NULL) {
00192         cpl_msg_error(__func__, "No raw frame in input") ;
00193         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00194         return -1 ;
00195     }
00196     nframes = cpl_frameset_get_size(rawframes) ;
00197 
00198     /* Get the detector illumination period */
00199     crires_model_refine_config.period =
00200         crires_get_detector_illum_period(
00201             cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ;
00202     if (crires_model_refine_config.period == CRIRES_ILLUM_UNKNOWN) {
00203         cpl_msg_error(__func__,
00204                 "Cannot determine the detector illumination period") ;
00205         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00206         cpl_frameset_delete(rawframes) ;
00207         return -1 ;
00208     } else {
00209         crires_display_detector_illum(crires_model_refine_config.period) ;
00210     }
00211 
00212     /* Check the number of input frames */
00213     if (nframes != 1 && nframes != 3) {
00214         cpl_msg_error(__func__, "1 or 3 raw frames expected in input") ;
00215         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00216         return -1 ;
00217     }
00218 
00219     /* Loop on the input frames */
00220     for (k=0 ; k<nframes ; k++) {
00221         /* Get the reference frame */
00222         ref_frame = cpl_frameset_get_position(rawframes, k) ;
00223         ref_fname = cpl_frame_get_filename(ref_frame) ;
00224 
00225     if (crires_model_config_check(config,ref_fname)!=0) {
00226         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00227       cpl_msg_error(__func__,
00228                 "Invalid physical model configuration file") ;
00229         cpl_frameset_delete(rawframes) ;
00230     return -1;
00231     }
00232 
00233     cust_lines_flag=0;
00234         for (ph=1;ph<=nph;ph++) {
00235       y_pos_pix=-(float)(ph);
00236       cpl_msg_info(__func__,"Raw frame %d, fibre position %d",k+1,ph);
00237       /* Get the shape of the spectrum at the detector y posn specified */
00238       cpl_msg_info(__func__, "Get the shape of the spectra") ;
00239       if ((traces = crires_model_profile(ref_fname,
00240                          config,
00241                          -1,
00242                          y_pos_pix)) != NULL) {
00243         /* Clean the traces */
00244         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00245           ptrace = cpl_vector_get_data(traces[i]) ;
00246           for (j=0 ; j<cpl_vector_get_size(traces[i]) ; j++) {
00247         if (ptrace[j] == 0.0) 
00248           ptrace[j] = cpl_vector_get_mean(traces[i]) ;
00249           }
00250         }
00251 
00252         /* Plot the shapes if requested */
00253         if (crires_model_refine_config.display>0 &&
00254         crires_model_refine_config.display <= CRIRES_NB_DETECTORS) {
00255           cpl_plot_vector("set grid;set xlabel 'Position (pixels)';set ylabel 'Position (pixels)';",
00256                  "t 'Spectrum shape' w lines", "", traces[crires_model_refine_config.display-1]);
00257         }
00258 
00259         /* Load the input images */
00260         cpl_msg_info(__func__, "Load the data") ;
00261         ilist = crires_load_file(ref_fname,
00262                      crires_model_refine_config.period, CPL_TYPE_FLOAT) ;
00263         if (ilist == NULL) {
00264           cpl_msg_error(__func__, "Cannot load the data") ;
00265         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00266           cpl_frameset_delete(rawframes) ;
00267           for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00268         cpl_vector_delete(traces[i]) ;
00269           cpl_free(traces) ;
00270           return -1 ;
00271         }
00272     
00273         /* Customise the line list */
00274         if (cust_lines_flag==0) {
00275           cpl_msg_info(__func__, "Customising the line list") ;
00276           cpl_msg_indent_more() ;
00277           if ((cust_lines=crires_model_refining_custom_lines(thar,
00278                                  crires_model_refine_config.search_box_sz,
00279                                  ref_fname, config, NULL))==NULL) {
00280         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00281           cpl_vector_delete(traces[i]) ;
00282         cpl_free(traces) ;
00283         cpl_imagelist_delete(ilist) ;
00284         cpl_frameset_delete(rawframes) ;
00285         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00286         cpl_msg_error(__func__, "Cannot customise the line list");
00287         return -1;
00288           }
00289           else {
00290         cust_lines_flag=1;
00291           }
00292         }
00293         cpl_msg_indent_less() ;
00294         
00295         /* Update the cust_lines list to have the correct predicted 
00296            detector x,y for the current pinhole*/
00297         cust_lines=crires_model_refining_fibrefix(cust_lines,ref_fname,config,ph);
00298 
00299         /* Loop on detectors */
00300         cpl_msg_indent_more() ;
00301         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00302           cpl_msg_info(__func__, "Reduce the chip number %d", i+1) ;
00303           /* Extract the spectrum using the shape */
00304           cpl_msg_info(__func__, "Extract spectrum") ;
00305           cpl_msg_indent_more() ;
00306           if ((extracted[i]=crires_model_refining_extract(cpl_imagelist_get(ilist, i),
00307                                   crires_model_refine_config.period,
00308                                   traces[i], bpm, flat, detlin, i+1)) == NULL) {
00309         cpl_msg_error(__func__, "Cannot extract spectrum");
00310         cpl_frameset_delete(rawframes) ;
00311         for (j=0 ;j<CRIRES_NB_DETECTORS; j++) 
00312           cpl_vector_delete(traces[j]) ;
00313         cpl_free(traces) ;
00314         cpl_imagelist_delete(ilist) ;
00315         for (j=0 ; j<i ; j++) cpl_vector_delete(extracted[j]) ;
00316         if ((crires_model_free2Darray(cust_lines,6))!=0) {
00317           cpl_msg_error(__func__, "Cannot free 2D array");
00318         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00319           return -1;
00320         }
00321         cpl_msg_indent_less() ;
00322         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00323         return -1 ;
00324           }
00325           cpl_msg_indent_less() ;
00326 
00327           /* Display if requested */
00328           if (crires_model_refine_config.display == i+1) {
00329         cpl_plot_vector("set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity (ADU)';",
00330                    "t 'Extracted spectrum' w lines", "", extracted[i]);
00331           }
00332 
00333           /* Detect the brightest lines */
00334           cpl_msg_info(__func__, "Detect the brightest lines") ;
00335           cpl_msg_indent_more() ;
00336           if ((bright_lines[i] = irplib_spectrum_detect_peaks(extracted[i],
00337                                   crires_model_refine_config.fwhm,
00338                                   crires_model_refine_config.sigma,
00339                                   crires_model_refine_config.display==i+1,
00340                                   NULL, NULL)) == NULL) {
00341         cpl_msg_warning(__func__, "Cannot detect lines");
00342           }
00343 /*          for (pp=0;pp<cpl_vector_get_size(bright_lines[i]);pp++){ */
00344 /*            printf("%lf %d %lf %d %lf %d %lf\n", */
00345 /*               cpl_vector_get(bright_lines[i],pp), */
00346 /*               (int)(cpl_vector_get(bright_lines[i],pp)-0.5)-1, */
00347 /*               cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp)-0.5)-1), */
00348 /*               (int)(cpl_vector_get(bright_lines[i],pp)-0.5), */
00349 /*               cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp)-0.5)), */
00350 /*               (int)(cpl_vector_get(bright_lines[i],pp)-0.5)+1, */
00351 /*               cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp)-0.5)+1)); */
00352 /*            totflux=0.0; */
00353 /*            moment=0.0; */
00354 /*            for (qq=-3;qq<4;qq++) { */
00355 /*          flux=cpl_vector_get(extracted[i],(int)(cpl_vector_get(bright_lines[i],pp))+qq); */
00356 /*          if (flux>0.0) { */
00357 /*            moment+=(float)(qq)*flux; */
00358 /*            totflux+=flux; */
00359 /*          } */
00360 /*            } */
00361 /*            cpl_vector_set(bright_lines[i],pp,(float)((int)(cpl_vector_get(bright_lines[i],pp)))+(moment/totflux)); */
00362 /*                printf("%d %lf %lf \n",pp, cpl_vector_get(bright_lines[i],pp),moment/totflux);  */
00363 /*          } */
00364           cpl_msg_indent_less() ;
00365         }
00366         cpl_imagelist_delete(ilist) ;
00367         for (j=0 ; j<CRIRES_NB_DETECTORS; j++) 
00368           cpl_vector_delete(extracted[j]) ;
00369     
00370         /* Match with the catalog */
00371         cpl_msg_info(__func__, "Match with the catalog") ;
00372         cpl_msg_indent_more() ;
00373         if ((temp_coord=crires_model_refining_match((const cpl_vector **)bright_lines,
00374                             (const cpl_vector **)traces,
00375                             cust_lines,
00376                             crires_model_refine_config.search_box_sz,
00377                             crires_model_refine_config.min_matches_nb,
00378                             ref_fname)) == NULL) {
00379           if (nph==1) {
00380         cpl_msg_error(__func__, "Cannot match %s with catalog",
00381                   ref_fname);
00382         cpl_frameset_delete(rawframes) ;
00383         for (j=0 ;j<CRIRES_NB_DETECTORS; j++) 
00384           cpl_vector_delete(traces[j]) ;
00385         cpl_free(traces) ;
00386         for (j=0 ; j<CRIRES_NB_DETECTORS; j++) 
00387           if (bright_lines[j] != NULL) 
00388             cpl_vector_delete(bright_lines[j]) ;
00389         if ((crires_model_free2Darray(cust_lines,6))!=0) {
00390           cpl_msg_error(__func__, "Cannot free 2D array");
00391         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00392           return -1;
00393         }
00394         cpl_msg_indent_less() ;
00395         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00396         return -1 ;
00397           } else { 
00398         cpl_msg_warning(__func__, "Cannot match lines for fibre %d on raw frame %d", ph, k);
00399           }
00400         }
00401         cpl_msg_indent_less() ;
00402         for (j=0 ; j<CRIRES_NB_DETECTORS; j++) 
00403           if (bright_lines[j] != NULL) 
00404         cpl_vector_delete(bright_lines[j]) ;
00405         if (temp_coord!=NULL) {
00406           i=0;
00407           while (temp_coord[0][i]!=0.0) {
00408         msp_coord[coord_cnt].wave=temp_coord[0][i];
00409         msp_coord[coord_cnt].x=temp_coord[1][i];
00410         msp_coord[coord_cnt].flux=temp_coord[2][i];
00411         msp_coord[coord_cnt].chip=(int)(temp_coord[3][i]);
00412         msp_coord[coord_cnt].mode=(int)(temp_coord[4][i]);
00413         msp_coord[coord_cnt].y=temp_coord[5][i];
00414         msp_coord[coord_cnt].penc=(int)(temp_coord[6][i]);
00415         msp_coord[coord_cnt].genc=(int)(temp_coord[7][i]);
00416         msp_coord[coord_cnt].slit_pos=ph;
00417         msp_coord[coord_cnt].counter=(int)(temp_coord[9][i]);
00418         msp_coord[coord_cnt].slitw=temp_coord[10][i];
00419         coord_cnt++;
00420         i++;
00421           }
00422           if ((crires_model_free2Darray(temp_coord,11))!=0) {
00423         cpl_msg_error(__func__, "Cannot free 2D array");
00424         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00425         return -1;
00426           }
00427           y_pos_mm=cpl_vector_get(traces[2],1024);
00428         } /*end of match check*/
00429         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00430           cpl_vector_delete(traces[i]) ;
00431         cpl_free(traces);
00432         cpl_msg_indent_less() ;
00433       } /*end of trace check*/
00434       else {
00435         cpl_msg_warning(__func__, "Cannot get the spectrum trace") ;
00436       }
00437     
00438         } /*end of ph loop*/
00439     if ((crires_model_free2Darray(cust_lines,6))!=0) {
00440       cpl_msg_error(__func__, "Cannot free 2D array");
00441         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00442       return -1;
00443     }
00444     } /*end of ds loop*/
00445     
00446     // TEMP SCAN OUTPUT
00447     if (cal_flag==1) {
00448       scan_out=fopen("coord_scan.dat","a+");
00449       for (i=0;i<coord_cnt;i++) {
00450         fprintf(scan_out,"%d %lf %lf %d %lf %d %lf %d %d %d %lf\n",i,
00451             msp_coord[i].y,
00452             msp_coord[i].x,
00453             msp_coord[i].chip,
00454             msp_coord[i].flux,
00455             msp_coord[i].slit_pos,
00456             msp_coord[i].wave*1000000.0,
00457             -msp_coord[i].mode,
00458             msp_coord[i].penc,
00459             msp_coord[i].genc,
00460             msp_coord[i].slitw);
00461       }
00462       fclose(scan_out);
00463     }
00464 
00465     cpl_msg_info(__func__, "slit position in mm: %lf",y_pos_mm);
00466     /* Compute the new configuration file */
00467     cpl_msg_info(__func__, "Compute the new configuration file") ;
00468     cpl_msg_indent_more() ;
00469     if ((new_conf = crires_model_refining_anneal(msp_coord,
00470                     coord_cnt,
00471                     y_pos_mm,
00472                     ref_fname,
00473                     config)) == NULL) {
00474         cpl_msg_error(__func__, "Cannot compute the new configuration file");
00475         cpl_msg_indent_less() ;
00476         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00477         return -1; 
00478     }
00479     cpl_msg_indent_less() ;
00480     cpl_frameset_delete(rawframes) ;
00481 
00482     /* Save the new configuration file */
00483     cpl_msg_info(__func__, "Save the new configuration file") ;
00484     if (crires_model_refine_save(new_conf, parlist, frameset) == -1) {
00485         cpl_msg_error(__func__, "Cannot save the product");
00486         cpl_table_delete(new_conf) ;
00487         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00488         return -1 ;
00489     }
00490     cpl_table_delete(new_conf) ;
00491    
00492     /* Return */
00493     if (cpl_error_get_code()) return -1 ;
00494     else return 0 ;
00495 }
00496     
00497     
00498 /*----------------------------------------------------------------------------*/
00506 /*----------------------------------------------------------------------------*/
00507 static int crires_model_refine_save(
00508         cpl_table               *   out_table,
00509         const cpl_parameterlist *   parlist,
00510         cpl_frameset            *   set)
00511 {
00512     cpl_propertylist    *   plist ;
00513     const char          *   recipe_name = "crires_model_refine" ;
00514 
00515     plist = cpl_propertylist_new();
00516     cpl_propertylist_append_string(plist, "INSTRUME", "CRIRES") ;
00517     cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG,
00518             CRIRES_CALPRO_MODEL_CONFIG) ;
00519     cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE,
00520             CRIRES_PROTYPE_MOD_CONF) ;
00521 
00522 
00523     /* Save */
00524     if (cpl_dfs_save_table(set, NULL, parlist, set, NULL, out_table,
00525                 NULL, recipe_name, plist, NULL, PACKAGE "/" PACKAGE_VERSION,
00526                 "crires_model_refine.fits") != CPL_ERROR_NONE) {
00527         cpl_msg_error(__func__, "Cannot save the table") ;
00528         return -1 ;
00529     }
00530 
00531     /* Return */
00532     cpl_propertylist_delete(plist) ;
00533     return 0 ;
00534 }
00535