FORS Pipeline Reference Manual 4.9.20
fors_resample.c
00001 /* $Id: fors_resample.c,v 1.9 2013/02/28 15:15:51 cgarcia Exp $
00002  *
00003  * This file is part of the FORS Data Reduction Pipeline
00004  * Copyright (C) 2002-2010 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 /*
00022  * $Author: cgarcia $
00023  * $Date: 2013/02/28 15:15:51 $
00024  * $Revision: 1.9 $
00025  * $Name: fors-4_9_20 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 #include <cpl.h>
00034 #include <moses.h>
00035 #include <fors_dfs.h>
00036 
00037 static int fors_resample_create(cpl_plugin *);
00038 static int fors_resample_exec(cpl_plugin *);
00039 static int fors_resample_destroy(cpl_plugin *);
00040 static int fors_resample(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_resample_description[] =
00043 "This recipe is used to resample at constant wavelength step spatially\n"
00044 "rectified spectra. The input frames are produced using either the recipe\n"
00045 "fors_extract_slits in the case of MOS/MXU multi slit exposures, or the\n"
00046 "recipes fors_remove_bias and fors_flatfield in the case of LSS or long-slit\n"
00047 "like MOS/MXU data. Only in case of LSS or LSS-like data the SLIT_LOCATION\n"
00048 "table is required in input. Please refer to the FORS Pipeline User's Manual\n"
00049 "for more details.\n"
00050 "\n"
00051 "In the table below the MXU acronym can also be read as MOS and LSS, SCI\n"
00052 "can be read as STD, and SCIENCE as STANDARD.\n\n"
00053 "Input files:\n\n"
00054 "  DO category:               Type:       Explanation:         Required:\n"
00055 "  LAMP_UNBIAS_MXU\n"
00056 "  or SCIENCE_UNBIAS_MXU\n"
00057 "  or SCIENCE_UNFLAT_MXU\n"
00058 "  or RECTIFIED_LAMP_MXU\n"
00059 "  or RECTIFIED_ALL_SCI_MXU\n"
00060 "  or RECTIFIED_SCI_MXU\n"
00061 "  or RECTIFIED_SKY_SCI_MXU   Calib       Frame to resample       Y\n"
00062 "  DISP_COEFF_MXU\n"
00063 "  or DISP_COEFF_SCI_MXU      Calib       Dispersion coefficients Y\n"
00064 "  SLIT_LOCATION_MXU          Calib       Slit location table     Y\n"
00065 "  GRISM_TABLE                Calib       Grism table             .\n\n"
00066 "Output files:\n\n"
00067 "  DO category:               Data type:  Explanation:\n"
00068 "  MAPPED_LAMP_MXU\n"
00069 "  or MAPPED_ALL_SCI_MXU\n"
00070 "  or MAPPED_SCI_MXU\n"
00071 "  or MAPPED_SKY_SCI_MXU      FITS image  Resampled spectra\n\n";
00072 
00073 #define fors_resample_exit(message)           \
00074 {                                             \
00075 if (message) cpl_msg_error(recipe, message);  \
00076 cpl_image_delete(spectra);                    \
00077 cpl_image_delete(mapped);                     \
00078 cpl_table_delete(grism_table);                \
00079 cpl_table_delete(idscoeff);                   \
00080 cpl_table_delete(slits);                      \
00081 cpl_propertylist_delete(header);              \
00082 cpl_msg_indent_less();                        \
00083 return -1;                                    \
00084 }
00085 
00086 #define fors_resample_exit_memcheck(message)    \
00087 {                                               \
00088 if (message) cpl_msg_info(recipe, message);     \
00089 printf("free spectra (%p)\n", spectra);         \
00090 cpl_image_delete(spectra);                      \
00091 printf("free mapped (%p)\n", mapped);           \
00092 cpl_image_delete(mapped);                       \
00093 printf("free grism_table (%p)\n", grism_table); \
00094 cpl_table_delete(grism_table);                  \
00095 printf("free idscoeff (%p)\n", idscoeff);       \
00096 cpl_table_delete(idscoeff);                     \
00097 printf("free slits (%p)\n", slits);             \
00098 cpl_table_delete(slits);                        \
00099 printf("free header (%p)\n", header);           \
00100 cpl_propertylist_delete(header);                \
00101 cpl_msg_indent_less();                          \
00102 return 0;                                       \
00103 }
00104 
00105 
00117 int cpl_plugin_get_info(cpl_pluginlist *list)
00118 {
00119     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00120     cpl_plugin *plugin = &recipe->interface;
00121 
00122     cpl_plugin_init(plugin,
00123                     CPL_PLUGIN_API,
00124                     FORS_BINARY_VERSION,
00125                     CPL_PLUGIN_TYPE_RECIPE,
00126                     "fors_resample",
00127                     "Resample input spectra at constant wavelength step",
00128                     fors_resample_description,
00129                     "Carlo Izzo",
00130                     PACKAGE_BUGREPORT,
00131     "This file is currently part of the FORS Instrument Pipeline\n"
00132     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00133     "This program is free software; you can redistribute it and/or modify\n"
00134     "it under the terms of the GNU General Public License as published by\n"
00135     "the Free Software Foundation; either version 2 of the License, or\n"
00136     "(at your option) any later version.\n\n"
00137     "This program is distributed in the hope that it will be useful,\n"
00138     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00139     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00140     "GNU General Public License for more details.\n\n"
00141     "You should have received a copy of the GNU General Public License\n"
00142     "along with this program; if not, write to the Free Software Foundation,\n"
00143     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00144                     fors_resample_create,
00145                     fors_resample_exec,
00146                     fors_resample_destroy);
00147 
00148     cpl_pluginlist_append(list, plugin);
00149     
00150     return 0;
00151 }
00152 
00153 
00164 static int fors_resample_create(cpl_plugin *plugin)
00165 {
00166     cpl_recipe    *recipe;
00167     cpl_parameter *p;
00168 
00169     /* 
00170      * Check that the plugin is part of a valid recipe 
00171      */
00172 
00173     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00174         recipe = (cpl_recipe *)plugin;
00175     else 
00176         return -1;
00177 
00178     /* 
00179      * Create the (empty) parameters list in the cpl_recipe object 
00180      */
00181 
00182     recipe->parameters = cpl_parameterlist_new(); 
00183 
00184     /*
00185      * Dispersion
00186      */
00187 
00188     p = cpl_parameter_new_value("fors.fors_resample.dispersion",
00189                                 CPL_TYPE_DOUBLE,
00190                                 "Expected spectral dispersion (Angstrom/pixel)",
00191                                 "fors.fors_resample",
00192                                 0.0);
00193     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
00194     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00195     cpl_parameterlist_append(recipe->parameters, p);
00196 
00197     /*
00198      * Start wavelength for spectral extraction
00199      */
00200 
00201     p = cpl_parameter_new_value("fors.fors_resample.startwavelength",
00202                                 CPL_TYPE_DOUBLE,
00203                                 "Start wavelength in spectral extraction",
00204                                 "fors.fors_resample",
00205                                 0.0);
00206     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
00207     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00208     cpl_parameterlist_append(recipe->parameters, p);
00209 
00210     /*
00211      * End wavelength for spectral extraction
00212      */
00213 
00214     p = cpl_parameter_new_value("fors.fors_resample.endwavelength",
00215                                 CPL_TYPE_DOUBLE,
00216                                 "End wavelength in spectral extraction",
00217                                 "fors.fors_resample",
00218                                 0.0);
00219     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
00220     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00221     cpl_parameterlist_append(recipe->parameters, p);
00222 
00223     /*
00224      * Flux conservation
00225      */
00226  
00227     p = cpl_parameter_new_value("fors.fors_resample.flux",
00228                                 CPL_TYPE_BOOL,
00229                                 "Apply flux conservation",
00230                                 "fors.fors_resample",
00231                                 TRUE);
00232     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux");
00233     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00234     cpl_parameterlist_append(recipe->parameters, p);
00235 
00236     return 0;
00237 }
00238 
00239 
00248 static int fors_resample_exec(cpl_plugin *plugin)
00249 {
00250     cpl_recipe *recipe;
00251     
00252     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00253         recipe = (cpl_recipe *)plugin;
00254     else 
00255         return -1;
00256 
00257     return fors_resample(recipe->parameters, recipe->frames);
00258 }
00259 
00260 
00269 static int fors_resample_destroy(cpl_plugin *plugin)
00270 {
00271     cpl_recipe *recipe;
00272     
00273     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00274         recipe = (cpl_recipe *)plugin;
00275     else 
00276         return -1;
00277 
00278     cpl_parameterlist_delete(recipe->parameters); 
00279 
00280     return 0;
00281 }
00282 
00283 
00293 static int fors_resample(cpl_parameterlist *parlist, 
00294                                cpl_frameset *frameset)
00295 {
00296 
00297     const char *recipe = "fors_resample";
00298 
00299 
00300     /*
00301      * Input parameters
00302      */
00303 
00304     double      dispersion;
00305     double      startwavelength;
00306     double      endwavelength;
00307     int         flux;
00308 
00309     /*
00310      * CPL objects
00311      */
00312 
00313     cpl_image        *spectra     = NULL;
00314     cpl_image        *mapped      = NULL;
00315     cpl_table        *grism_table = NULL;
00316     cpl_table        *maskslits   = NULL;
00317     cpl_table        *slits       = NULL;
00318     cpl_table        *idscoeff    = NULL;
00319     cpl_propertylist *header      = NULL;
00320 
00321     /*
00322      * Auxiliary variables
00323      */
00324 
00325     char        version[80];
00326     const char *disp_coeff_tag;
00327     const char *slit_location_tag;
00328     const char *rectified_tag;
00329     const char *mapped_tag;
00330     int         nframes;
00331     int         rebin;
00332     double      reference;
00333     double     *xpos;
00334     double      mxpos;
00335     int         treat_as_lss = 0;
00336     int         nslits, i;
00337     int         mxu, mos, lss;
00338     int         disp;
00339     int         dispsci;
00340     int         dispstd;
00341     int         sciall;
00342     int         stdall;
00343     int         scisky;
00344     int         stdsky;
00345     int         sci;
00346     int         std;
00347     int         lamp;
00348 
00349     char       *instrume = NULL;
00350 
00351 
00352     cpl_msg_set_indentation(2);
00353 
00354     if (dfs_files_dont_exist(frameset))
00355         fors_resample_exit(NULL);
00356 
00357 
00358     /*
00359      * Get configuration parameters
00360      */
00361 
00362     cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00363     cpl_msg_indent_more();
00364     
00365     if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00366         fors_resample_exit("Too many in input: GRISM_TABLE"); 
00367 
00368     grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00369 
00370     dispersion = dfs_get_parameter_double(parlist,
00371                     "fors.fors_resample.dispersion", grism_table);
00372 
00373     if (dispersion <= 0.0)
00374         fors_resample_exit("Invalid spectral dispersion value");
00375 
00376     startwavelength = dfs_get_parameter_double(parlist,
00377                     "fors.fors_resample.startwavelength", grism_table);
00378     if (startwavelength > 1.0)
00379         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00380             fors_resample_exit("Invalid wavelength");
00381 
00382     endwavelength = dfs_get_parameter_double(parlist,
00383                     "fors.fors_resample.endwavelength", grism_table);
00384     if (endwavelength > 1.0) {
00385         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00386             fors_resample_exit("Invalid wavelength");
00387         if (startwavelength < 1.0)
00388             fors_resample_exit("Invalid wavelength interval");
00389     }
00390 
00391     if (startwavelength > 1.0)
00392         if (endwavelength - startwavelength <= 0.0)
00393             fors_resample_exit("Invalid wavelength interval");
00394 
00395     flux = dfs_get_parameter_bool(parlist, "fors.fors_resample.flux", NULL);
00396 
00397     cpl_table_delete(grism_table); grism_table = NULL;
00398 
00399     if (cpl_error_get_code())
00400         fors_resample_exit("Failure reading the configuration parameters");
00401 
00402 
00403     cpl_msg_indent_less();
00404     cpl_msg_info(recipe, "Check input set-of-frames:");
00405     cpl_msg_indent_more();
00406 
00407     mxu  = cpl_frameset_count_tags(frameset, "DISP_COEFF_MXU");
00408     mxu += cpl_frameset_count_tags(frameset, "DISP_COEFF_SCI_MXU");
00409     mxu += cpl_frameset_count_tags(frameset, "DISP_COEFF_STD_MXU");
00410     mos  = cpl_frameset_count_tags(frameset, "DISP_COEFF_MOS");
00411     mos += cpl_frameset_count_tags(frameset, "DISP_COEFF_SCI_MOS");
00412     mos += cpl_frameset_count_tags(frameset, "DISP_COEFF_STD_MOS");
00413     lss  = cpl_frameset_count_tags(frameset, "DISP_COEFF_LSS");
00414     lss += cpl_frameset_count_tags(frameset, "DISP_COEFF_SCI_LSS");
00415     lss += cpl_frameset_count_tags(frameset, "DISP_COEFF_STD_LSS");
00416 
00417     nframes = mos + mxu + lss;
00418 
00419     if (nframes == 0) {
00420         fors_resample_exit("Missing dispersion coefficients table");
00421     }
00422     if (nframes > 1) {
00423         cpl_msg_error(recipe, 
00424                       "Too many input dispersion coefficients tables (%d > 1)",
00425                       nframes);
00426         fors_resample_exit(NULL);
00427     }
00428 
00429     disp     = cpl_frameset_count_tags(frameset, "DISP_COEFF_MXU");
00430     disp    += cpl_frameset_count_tags(frameset, "DISP_COEFF_MOS");
00431     disp    += cpl_frameset_count_tags(frameset, "DISP_COEFF_LSS");
00432     dispsci  = cpl_frameset_count_tags(frameset, "DISP_COEFF_SCI_MXU");
00433     dispsci += cpl_frameset_count_tags(frameset, "DISP_COEFF_SCI_MOS");
00434     dispsci += cpl_frameset_count_tags(frameset, "DISP_COEFF_SCI_LSS");
00435     dispstd  = cpl_frameset_count_tags(frameset, "DISP_COEFF_STD_MXU");
00436     dispstd += cpl_frameset_count_tags(frameset, "DISP_COEFF_STD_MOS");
00437     dispstd += cpl_frameset_count_tags(frameset, "DISP_COEFF_STD_LSS");
00438 
00439     if (mxu) {
00440         slit_location_tag = "SLIT_LOCATION_MXU";
00441         if (disp)
00442             disp_coeff_tag = "DISP_COEFF_MXU";
00443         else if (dispsci)
00444             disp_coeff_tag = "DISP_COEFF_SCI_MXU";
00445         else
00446             disp_coeff_tag = "DISP_COEFF_STD_MXU";
00447     }
00448     else if (mos) {
00449         slit_location_tag = "SLIT_LOCATION_MOS";
00450         if (disp)
00451             disp_coeff_tag = "DISP_COEFF_MOS";
00452         else if (dispsci)
00453             disp_coeff_tag = "DISP_COEFF_SCI_MOS";
00454         else
00455             disp_coeff_tag = "DISP_COEFF_STD_MOS";
00456     }
00457     else {
00458         slit_location_tag = "SLIT_LOCATION_LSS";
00459         if (disp)
00460             disp_coeff_tag = "DISP_COEFF_LSS";
00461         else if (dispsci)
00462             disp_coeff_tag = "DISP_COEFF_SCI_LSS";
00463         else
00464             disp_coeff_tag = "DISP_COEFF_STD_LSS";
00465     }
00466 
00467     header = dfs_load_header(frameset, disp_coeff_tag, 0);
00468 
00469     if (header == NULL)
00470         fors_resample_exit("Cannot load dispersion coefficients table header");
00471 
00472     if (mos || mxu) {
00473         int nslits_out_det = 0;
00474 
00475         if (mos)
00476             maskslits = mos_load_slits_fors_mos(header, &nslits_out_det);
00477         else
00478             maskslits = mos_load_slits_fors_mxu(header);
00479 
00480         /*
00481          * Check if all slits have the same X offset.
00482          */
00483 
00484         treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
00485 
00486         cpl_table_delete(maskslits); maskslits = NULL;
00487     }
00488 
00489     cpl_propertylist_delete(header); header = NULL;
00490 
00491     if (mxu) {
00492         if (treat_as_lss) {
00493             sciall = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU");
00494             stdall = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU");
00495             scisky = 0;
00496             stdsky = 0;
00497             sci    = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU");
00498             std    = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU");
00499             lamp   = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MXU");
00500         }
00501         else {
00502             sciall = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MXU");
00503             stdall = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MXU");
00504             scisky = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MXU");
00505             stdsky = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MXU");
00506             sci    = cpl_frameset_count_tags(frameset, "RECTIFIED_SCI_MXU");
00507             std    = cpl_frameset_count_tags(frameset, "RECTIFIED_STD_MXU");
00508             lamp   = cpl_frameset_count_tags(frameset, "RECTIFIED_LAMP_MXU");
00509         }
00510     }
00511     else if (mos) {
00512         if (treat_as_lss) {
00513             sciall = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS");
00514             stdall = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS");
00515             scisky = 0;
00516             stdsky = 0;
00517             sci    = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS");
00518             std    = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS");
00519             lamp   = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MOS");
00520         }
00521         else {
00522             sciall = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MOS");
00523             stdall = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MOS");
00524             scisky = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MOS");
00525             stdsky = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MOS");
00526             sci    = cpl_frameset_count_tags(frameset, "RECTIFIED_SCI_MOS");
00527             std    = cpl_frameset_count_tags(frameset, "RECTIFIED_STD_MOS");
00528             lamp   = cpl_frameset_count_tags(frameset, "RECTIFIED_LAMP_MOS");
00529         }
00530     }
00531     else {
00532         sciall = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_LSS");
00533         stdall = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_LSS");
00534         scisky = 0;
00535         stdsky = 0;
00536         sci    = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_LSS");
00537         std    = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_LSS");
00538         lamp   = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_LSS");
00539     }
00540 
00541     nframes = sciall + stdall + scisky + stdsky + sci + std + lamp;
00542 
00543     if (nframes == 0)
00544         fors_resample_exit("Missing input spectral frame");
00545 
00546     if (nframes > 1) {
00547         cpl_msg_error(recipe, "Too many input spectral frames (%d > 1)", 
00548                       nframes);
00549         fors_resample_exit(NULL);
00550     }
00551 
00552     if (sciall) {
00553         if (mxu) {
00554             if (treat_as_lss) {
00555                 rectified_tag = "SCIENCE_UNFLAT_MXU";
00556                 mapped_tag    = "MAPPED_ALL_SCI_MXU";
00557             }
00558             else {
00559                 rectified_tag = "RECTIFIED_ALL_SCI_MXU";
00560                 mapped_tag    = "MAPPED_ALL_SCI_MXU";
00561             }
00562         }
00563         else if (mos) {
00564             if (treat_as_lss) {
00565                 rectified_tag = "SCIENCE_UNFLAT_MOS";
00566                 mapped_tag    = "MAPPED_ALL_SCI_MOS";
00567             }
00568             else {
00569                 rectified_tag = "RECTIFIED_ALL_SCI_MOS";
00570                 mapped_tag    = "MAPPED_ALL_SCI_MOS";
00571             }
00572         }
00573         else {
00574             rectified_tag = "SCIENCE_UNFLAT_LSS";
00575             mapped_tag    = "MAPPED_ALL_SCI_LSS";
00576         }
00577     }
00578     else if (stdall) {
00579         if (mxu) {
00580             if (treat_as_lss) {
00581                 rectified_tag = "STANDARD_UNFLAT_MXU";
00582                 mapped_tag    = "MAPPED_ALL_STD_MXU";
00583             }
00584             else {
00585                 rectified_tag = "RECTIFIED_ALL_STD_MXU";
00586                 mapped_tag    = "MAPPED_ALL_STD_MXU";
00587             }
00588         }
00589         else if (mos) {
00590             if (treat_as_lss) {
00591                 rectified_tag = "STANDARD_UNFLAT_MOS";
00592                 mapped_tag    = "MAPPED_ALL_STD_MOS";
00593             }
00594             else {
00595                 rectified_tag = "RECTIFIED_ALL_STD_MOS";
00596                 mapped_tag    = "MAPPED_ALL_STD_MOS";
00597             }
00598         }
00599         else {
00600             rectified_tag = "STANDARD_UNFLAT_LSS";
00601             mapped_tag    = "MAPPED_ALL_STD_LSS";
00602         }
00603     }
00604     else if (scisky) {
00605         if (mxu) {
00606             rectified_tag = "RECTIFIED_SKY_SCI_MXU";
00607             mapped_tag    = "MAPPED_SKY_SCI_MXU";
00608         }
00609         else {
00610             rectified_tag = "RECTIFIED_SKY_SCI_MOS";
00611             mapped_tag    = "MAPPED_SKY_SCI_MOS";
00612         }
00613     }
00614     else if (stdsky) {
00615         if (mxu) {
00616             rectified_tag = "RECTIFIED_SKY_STD_MXU";
00617             mapped_tag    = "MAPPED_SKY_STD_MXU";
00618         }
00619         else {
00620             rectified_tag = "RECTIFIED_SKY_STD_MOS";
00621             mapped_tag    = "MAPPED_SKY_STD_MOS";
00622         }
00623     }
00624     else if (sci) {
00625         if (mxu) {
00626             if (treat_as_lss) {
00627                 rectified_tag = "SCIENCE_UNBIAS_MXU";
00628                 mapped_tag    = "MAPPED_ALL_SCI_MXU";
00629             }
00630             else {
00631                 rectified_tag = "RECTIFIED_SCI_MXU";
00632                 mapped_tag    = "MAPPED_SCI_MXU";
00633             }
00634         }
00635         else if (mos) {
00636             if (treat_as_lss) {
00637                 rectified_tag = "SCIENCE_UNBIAS_MOS";
00638                 mapped_tag    = "MAPPED_ALL_SCI_MOS";
00639             }
00640             else {
00641                 rectified_tag = "RECTIFIED_SCI_MOS";
00642                 mapped_tag    = "MAPPED_SCI_MOS";
00643             }
00644         }
00645         else {
00646             rectified_tag = "SCIENCE_UNBIAS_LSS";
00647             mapped_tag    = "MAPPED_ALL_SCI_LSS";
00648         }
00649     }
00650     else if (std) {
00651         if (mxu) {
00652             if (treat_as_lss) {
00653                 rectified_tag = "STANDARD_UNBIAS_MXU";
00654                 mapped_tag    = "MAPPED_ALL_STD_MXU";
00655             }
00656             else {
00657                 rectified_tag = "RECTIFIED_STD_MXU";
00658                 mapped_tag    = "MAPPED_STD_MXU";
00659             }
00660         }
00661         else if (mos) {
00662             if (treat_as_lss) {
00663                 rectified_tag = "STANDARD_UNBIAS_MOS";
00664                 mapped_tag    = "MAPPED_ALL_STD_MOS";
00665             }
00666             else {
00667                 rectified_tag = "RECTIFIED_STD_MOS";
00668                 mapped_tag    = "MAPPED_STD_MOS";
00669             }
00670         }
00671         else {
00672             rectified_tag = "STANDARD_UNBIAS_LSS";
00673             mapped_tag    = "MAPPED_ALL_STD_LSS";
00674         }
00675     }
00676     else if (lamp) {
00677         if (mxu) {
00678             if (treat_as_lss) {
00679                 rectified_tag = "LAMP_UNBIAS_MXU";
00680                 mapped_tag    = "MAPPED_LAMP_MXU";
00681             }
00682             else {
00683                 rectified_tag = "RECTIFIED_LAMP_MXU";
00684                 mapped_tag    = "MAPPED_LAMP_MXU";
00685             }
00686         }
00687         else if (mos) {
00688             if (treat_as_lss) {
00689                 rectified_tag = "LAMP_UNBIAS_MOS";
00690                 mapped_tag    = "MAPPED_LAMP_MOS";
00691             }
00692             else {
00693                 rectified_tag = "RECTIFIED_LAMP_MOS";
00694                 mapped_tag    = "MAPPED_LAMP_MOS";
00695             }
00696         }
00697         else {
00698             rectified_tag = "LAMP_UNBIAS_LSS";
00699             mapped_tag    = "MAPPED_LAMP_LSS";
00700         }
00701     }
00702 
00703     header = dfs_load_header(frameset, rectified_tag, 0);
00704 
00705     if (header == NULL)
00706         fors_resample_exit("Cannot load spectral frame header");
00707 
00708 
00709     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00710         fors_resample_exit("Input frames are not from the same grism");
00711 
00712     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00713         fors_resample_exit("Input frames are not from the same filter");
00714 
00715     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00716         fors_resample_exit("Input frames are not from the same chip");
00717 
00718 
00719     /*
00720      * Get the reference wavelength and the rebin factor along the
00721      * dispersion direction from the reference frame
00722      */
00723 
00724     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00725     if (instrume == NULL)
00726         fors_resample_exit("Missing keyword INSTRUME in reference frame "
00727                             "header");
00728 
00729     if (instrume[4] == '1')
00730         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00731     if (instrume[4] == '2')
00732         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00733 
00734     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00735 
00736     if (cpl_error_get_code() != CPL_ERROR_NONE)
00737         fors_resample_exit("Missing keyword ESO INS GRIS1 WLEN "
00738                             "in reference frame header");
00739 
00740     if (reference < 3000.0)   /* Perhaps in nanometers... */
00741         reference *= 10;
00742 
00743     if (reference < 3000.0 || reference > 13000.0) {
00744         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00745                       "keyword ESO INS GRIS1 WLEN in reference frame header",
00746                       reference);
00747         fors_resample_exit(NULL);
00748     }
00749 
00750     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00751 
00752     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00753 
00754     if (cpl_error_get_code() != CPL_ERROR_NONE)
00755         fors_resample_exit("Missing keyword ESO DET WIN1 BINX "
00756                             "in reference frame header");
00757 
00758     if (rebin != 1) {
00759         dispersion *= rebin;
00760         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00761                         "working dispersion used is %f A/pixel", rebin,
00762                         dispersion);
00763     }
00764 
00765 
00766     cpl_msg_indent_less();
00767     cpl_msg_info(recipe, "Load input frames...");
00768     cpl_msg_indent_more();
00769 
00770     spectra = dfs_load_image(frameset, rectified_tag, CPL_TYPE_FLOAT, 0, 0);
00771     if (spectra == NULL)
00772         fors_resample_exit("Cannot load input spectral frame");
00773 
00774     idscoeff = dfs_load_table(frameset, disp_coeff_tag, 1);
00775     if (idscoeff == NULL)
00776         fors_resample_exit("Cannot load dispersion solution table");
00777 
00778     if (lss || treat_as_lss) {
00779         int        first_row, last_row, ylow, yhig, nx;
00780         cpl_image *dummy;
00781 
00782         slits = dfs_load_table(frameset, slit_location_tag, 1);
00783         if (slits == NULL)
00784             fors_resample_exit("Cannot load slit location table");
00785 
00786         first_row = cpl_table_get_double(slits, "ybottom", 0, NULL);
00787         last_row = cpl_table_get_double(slits, "ytop", 0, NULL);
00788 
00789         ylow = first_row + 1;
00790         yhig = last_row + 1;
00791 
00792         nx = cpl_image_get_size_x(spectra);
00793 
00794         dummy = cpl_image_extract(spectra, 1, ylow, nx, yhig);
00795         cpl_image_delete(spectra); spectra = dummy;
00796     }
00797 
00798     cpl_msg_indent_less();
00799     cpl_msg_info(recipe, "Spectral resampling...");
00800     cpl_msg_indent_more();
00801 
00802     mapped = mos_wavelength_calibration(spectra, reference,
00803                                         startwavelength, endwavelength,
00804                                         dispersion, idscoeff, flux);
00805 
00806     cpl_table_delete(idscoeff); idscoeff = NULL;
00807     cpl_image_delete(spectra); spectra = NULL;
00808 
00809     cpl_propertylist_update_double(header, "CRPIX1", 1.0);
00810     cpl_propertylist_update_double(header, "CRPIX2", 1.0);
00811     cpl_propertylist_update_double(header, "CRVAL1",
00812                                    startwavelength + dispersion/2);
00813     cpl_propertylist_update_double(header, "CRVAL2", 1.0);
00814     /* cpl_propertylist_update_double(header, "CDELT1", dispersion);
00815     cpl_propertylist_update_double(header, "CDELT2", 1.0); */
00816     cpl_propertylist_update_double(header, "CD1_1", dispersion);
00817     cpl_propertylist_update_double(header, "CD1_2", 0.0);
00818     cpl_propertylist_update_double(header, "CD2_1", 0.0);
00819     cpl_propertylist_update_double(header, "CD2_2", 1.0);
00820     cpl_propertylist_update_string(header, "CTYPE1", "LINEAR");
00821     cpl_propertylist_update_string(header, "CTYPE2", "PIXEL");
00822 
00823     if (dfs_save_image(frameset, mapped, mapped_tag,
00824                        header, parlist, recipe, version))
00825         fors_resample_exit(NULL);
00826 
00827     cpl_image_delete(mapped); mapped = NULL;
00828     cpl_propertylist_delete(header); header = NULL;
00829 
00830     return 0;
00831 }