fors_extract_slits.c

00001 /* $Id: fors_extract_slits.c,v 1.8 2013-08-20 17:02:58 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-08-20 17:02:58 $
00024  * $Revision: 1.8 $
00025  * $Name: not supported by cvs2svn $
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_extract_slits_create(cpl_plugin *);
00038 static int fors_extract_slits_exec(cpl_plugin *);
00039 static int fors_extract_slits_destroy(cpl_plugin *);
00040 static int fors_extract_slits(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_extract_slits_description[] =
00043 "This recipe is used to extract MOS/MXU slit spectra, following their\n"
00044 "curvature, and to remap them into a spatially rectified image.\n"
00045 "Please refer to the FORS Pipeline User's Manual for details about\n"
00046 "the spectra remapping technique. Note however that the interpolation\n"
00047 "is done exclusively along the spatial direction, and therefore the\n"
00048 "output rectified image will have the same x size of the input spectral\n" 
00049 "image.\n"
00050 "\n"
00051 "In the table below the MXU acronym can be alternatively read as MOS.\n\n"
00052 "Input files:\n\n"
00053 "  DO category:               Type:       Explanation:         Required:\n"
00054 "  LAMP_UNBIAS_MXU\n"
00055 "  or SCIENCE_UNBIAS_MXU\n"
00056 "  or SCIENCE_UNFLAT_MXU\n"
00057 "  or STANDARD_UNBIAS_MXU\n"
00058 "  or STANDARD_UNFLAT_MXU\n"
00059 "  or UNMAPPED_SCI_MXU\n"
00060 "  or UNMAPPED_STD_MXU\n"
00061 "  or UNMAPPED_SKY_SCI_MXU\n"
00062 "  or UNMAPPED_SKY_STD_MXU    Calib       Spectral frame          Y\n"
00063 "  SLIT_LOCATION_DETECT_MXU\n"
00064 "  or SLIT_LOCATION_MXU       Calib       Master flat frame       Y\n"
00065 "  CURV_COEFF_MXU             Calib       Spectral curvature      Y\n"
00066 "  GRISM_TABLE                Calib       Grism table             .\n\n"
00067 "Output files:\n\n"
00068 "  DO category:               Data type:  Explanation:\n"
00069 "  RECTIFIED_LAMP_MXU\n"
00070 "  or RECTIFIED_ALL_SCI_MXU\n"
00071 "  or RECTIFIED_ALL_STD_MXU\n"
00072 "  or RECTIFIED_SCI_MXU\n"
00073 "  or RECTIFIED_STD_MXU\n"
00074 "  or RECTIFIED_SKY_SCI_MXU\n"
00075 "  or RECTIFIED_SKY_STD_MXU   FITS image  Rectified slit spectra\n\n";
00076 
00077 #define fors_extract_slits_exit(message)      \
00078 {                                             \
00079 if ((const char *)message != NULL) cpl_msg_error(recipe, message);  \
00080 cpl_image_delete(spectra);                    \
00081 cpl_image_delete(spatial);                    \
00082 cpl_table_delete(grism_table);                \
00083 cpl_table_delete(maskslits);                  \
00084 cpl_table_delete(slits);                      \
00085 cpl_table_delete(polytraces);                 \
00086 cpl_propertylist_delete(header);              \
00087 cpl_msg_indent_less();                        \
00088 return -1;                                    \
00089 }
00090 
00091 #define fors_extract_slits_exit_memcheck(message)  \
00092 {                                               \
00093 if ((const char *)message != NULL) cpl_msg_info(recipe, message);     \
00094 printf("free spectra (%p)\n", spectra);         \
00095 cpl_image_delete(spectra);                      \
00096 printf("free spatial (%p)\n", spatial);         \
00097 cpl_image_delete(spatial);                      \
00098 printf("free grism_table (%p)\n", grism_table); \
00099 cpl_table_delete(grism_table);                  \
00100 printf("free maskslits (%p)\n", maskslits);     \
00101 cpl_table_delete(maskslits);                    \
00102 printf("free slits (%p)\n", slits);             \
00103 cpl_table_delete(slits);                        \
00104 printf("free polytraces (%p)\n", polytraces);   \
00105 cpl_table_delete(polytraces);                   \
00106 printf("free header (%p)\n", header);           \
00107 cpl_propertylist_delete(header);                \
00108 cpl_msg_indent_less();                          \
00109 return 0;                                       \
00110 }
00111 
00112 
00124 int cpl_plugin_get_info(cpl_pluginlist *list)
00125 {
00126     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00127     cpl_plugin *plugin = &recipe->interface;
00128 
00129     cpl_plugin_init(plugin,
00130                     CPL_PLUGIN_API,
00131                     FORS_BINARY_VERSION,
00132                     CPL_PLUGIN_TYPE_RECIPE,
00133                     "fors_extract_slits",
00134                     "Spatial rectification of spectral image",
00135                     fors_extract_slits_description,
00136                     "Carlo Izzo",
00137                     PACKAGE_BUGREPORT,
00138     "This file is currently part of the FORS Instrument Pipeline\n"
00139     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00140     "This program is free software; you can redistribute it and/or modify\n"
00141     "it under the terms of the GNU General Public License as published by\n"
00142     "the Free Software Foundation; either version 2 of the License, or\n"
00143     "(at your option) any later version.\n\n"
00144     "This program is distributed in the hope that it will be useful,\n"
00145     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00146     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00147     "GNU General Public License for more details.\n\n"
00148     "You should have received a copy of the GNU General Public License\n"
00149     "along with this program; if not, write to the Free Software Foundation,\n"
00150     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00151                     fors_extract_slits_create,
00152                     fors_extract_slits_exec,
00153                     fors_extract_slits_destroy);
00154 
00155     cpl_pluginlist_append(list, plugin);
00156     
00157     return 0;
00158 }
00159 
00160 
00171 static int fors_extract_slits_create(cpl_plugin *plugin)
00172 {
00173     cpl_recipe    *recipe;
00174     cpl_parameter *p;
00175 
00176     /* 
00177      * Check that the plugin is part of a valid recipe 
00178      */
00179 
00180     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00181         recipe = (cpl_recipe *)plugin;
00182     else 
00183         return -1;
00184 
00185     /* 
00186      * Create the (empty) parameters list in the cpl_recipe object 
00187      */
00188 
00189     recipe->parameters = cpl_parameterlist_new(); 
00190 
00191     /*
00192      * Dispersion
00193      */
00194 
00195     p = cpl_parameter_new_value("fors.fors_extract_slits.dispersion",
00196                                 CPL_TYPE_DOUBLE,
00197                                 "Expected spectral dispersion (Angstrom/pixel)",
00198                                 "fors.fors_extract_slits",
00199                                 0.0);
00200     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
00201     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00202     cpl_parameterlist_append(recipe->parameters, p);
00203 
00204     /*
00205      * Start wavelength for spectral extraction
00206      */
00207 
00208     p = cpl_parameter_new_value("fors.fors_extract_slits.startwavelength",
00209                                 CPL_TYPE_DOUBLE,
00210                                 "Start wavelength in spectral extraction",
00211                                 "fors.fors_extract_slits",
00212                                 0.0);
00213     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
00214     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00215     cpl_parameterlist_append(recipe->parameters, p);
00216 
00217     /*
00218      * End wavelength for spectral extraction
00219      */
00220 
00221     p = cpl_parameter_new_value("fors.fors_extract_slits.endwavelength",
00222                                 CPL_TYPE_DOUBLE,
00223                                 "End wavelength in spectral extraction",
00224                                 "fors.fors_extract_slits",
00225                                 0.0);
00226     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
00227     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00228     cpl_parameterlist_append(recipe->parameters, p);
00229 
00230     /*
00231      * Flux conservation
00232      */
00233  
00234     p = cpl_parameter_new_value("fors.fors_extract_slits.flux",
00235                                 CPL_TYPE_BOOL,
00236                                 "Apply flux conservation",
00237                                 "fors.fors_extract_slits",
00238                                 TRUE);
00239     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "flux");
00240     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00241     cpl_parameterlist_append(recipe->parameters, p);
00242 
00243     return 0;
00244 }
00245 
00246 
00255 static int fors_extract_slits_exec(cpl_plugin *plugin)
00256 {
00257     cpl_recipe *recipe;
00258     
00259     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00260         recipe = (cpl_recipe *)plugin;
00261     else 
00262         return -1;
00263 
00264     return fors_extract_slits(recipe->parameters, recipe->frames);
00265 }
00266 
00267 
00276 static int fors_extract_slits_destroy(cpl_plugin *plugin)
00277 {
00278     cpl_recipe *recipe;
00279     
00280     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00281         recipe = (cpl_recipe *)plugin;
00282     else 
00283         return -1;
00284 
00285     cpl_parameterlist_delete(recipe->parameters); 
00286 
00287     return 0;
00288 }
00289 
00290 
00300 static int fors_extract_slits(cpl_parameterlist *parlist, 
00301                                cpl_frameset *frameset)
00302 {
00303 
00304     const char *recipe = "fors_extract_slits";
00305 
00306 
00307     /*
00308      * Input parameters
00309      */
00310 
00311     double      dispersion;
00312     double      startwavelength;
00313     double      endwavelength;
00314     int         flux;
00315 
00316     /*
00317      * CPL objects
00318      */
00319 
00320     cpl_image        *spectra     = NULL;
00321     cpl_image        *spatial     = NULL;
00322     cpl_table        *grism_table = NULL;
00323     cpl_table        *slits       = NULL;
00324     cpl_table        *polytraces  = NULL;
00325     cpl_table        *maskslits   = NULL;
00326     cpl_propertylist *header      = NULL;
00327 
00328     /*
00329      * Auxiliary variables
00330      */
00331 
00332     char        version[80];
00333     const char *input_tag;
00334     const char *output_tag;
00335     const char *slit_location_tag;
00336     const char *curv_coeff_tag;
00337     int         nframes;
00338     int         rebin;
00339     int         treat_as_lss;
00340     double      reference;
00341     double      mxpos;
00342     int         mxu, mos, lss;
00343     int         slit_l, slit_d;
00344     int         lamp_mxu;
00345     int         lamp_mos;
00346     int         lamp_lss;
00347     int         scib_mxu;
00348     int         scib_mos;
00349     int         scib_lss;
00350     int         scif_mxu;
00351     int         scif_mos;
00352     int         scif_lss;
00353     int         stab_mxu;
00354     int         stab_mos;
00355     int         stab_lss;
00356     int         staf_mxu;
00357     int         staf_mos;
00358     int         staf_lss;
00359     int         sciu_mxu;
00360     int         sciu_mos;
00361     int         sciu_lss;
00362     int         stau_mxu;
00363     int         stau_mos;
00364     int         stau_lss;
00365     int         scis_mxu;
00366     int         scis_mos;
00367     int         scis_lss;
00368     int         stas_mxu;
00369     int         stas_mos;
00370     int         stas_lss;
00371     int         nslits_out_det = 0;
00372 
00373     char       *instrume = NULL;
00374 
00375 
00376     cpl_msg_set_indentation(2);
00377 
00378 
00379     /*
00380      * Get configuration parameters
00381      */
00382 
00383     cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00384     cpl_msg_indent_more();
00385     
00386     if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00387         fors_extract_slits_exit("Too many in input: GRISM_TABLE"); 
00388 
00389     grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00390 
00391     dispersion = dfs_get_parameter_double(parlist,
00392                     "fors.fors_extract_slits.dispersion", grism_table);
00393 
00394     if (dispersion <= 0.0)
00395         fors_extract_slits_exit("Invalid spectral dispersion value");
00396 
00397     startwavelength = dfs_get_parameter_double(parlist,
00398                     "fors.fors_extract_slits.startwavelength", grism_table);
00399     if (startwavelength > 1.0)
00400         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00401             fors_extract_slits_exit("Invalid wavelength");
00402 
00403     endwavelength = dfs_get_parameter_double(parlist,
00404                     "fors.fors_extract_slits.endwavelength", grism_table);
00405     if (endwavelength > 1.0) {
00406         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00407             fors_extract_slits_exit("Invalid wavelength");
00408         if (startwavelength < 1.0)
00409             fors_extract_slits_exit("Invalid wavelength interval");
00410     }
00411 
00412     if (startwavelength > 1.0)
00413         if (endwavelength - startwavelength <= 0.0)
00414             fors_extract_slits_exit("Invalid wavelength interval");
00415 
00416     flux = dfs_get_parameter_bool(parlist, 
00417                                   "fors.fors_extract_slits.flux", NULL);
00418 
00419     cpl_table_delete(grism_table); grism_table = NULL;
00420 
00421     if (cpl_error_get_code())
00422         fors_extract_slits_exit("Failure reading the configuration parameters");
00423 
00424 
00425     cpl_msg_indent_less();
00426     cpl_msg_info(recipe, "Check input set-of-frames:");
00427     cpl_msg_indent_more();
00428 
00429     mxu  = lamp_mxu = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MXU");
00430     mos  = lamp_mos = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MOS");
00431     lss  = lamp_lss = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_LSS");
00432     mxu += scib_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU");
00433     mos += scib_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS");
00434     lss += scib_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_LSS");
00435     mxu += scif_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU");
00436     mos += scif_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS");
00437     lss += scif_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_LSS");
00438     mxu += stab_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU");
00439     mos += stab_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS");
00440     lss += stab_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_LSS");
00441     mxu += staf_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU");
00442     mos += staf_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS");
00443     lss += staf_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_LSS");
00444     mxu += sciu_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MXU");
00445     mos += sciu_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MOS");
00446     lss += sciu_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_LSS");
00447     mxu += stau_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MXU");
00448     mos += stau_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MOS");
00449     lss += stau_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_LSS");
00450     mxu += scis_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MXU");
00451     mos += scis_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MOS");
00452     lss += scis_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_LSS");
00453     mxu += stas_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MXU");
00454     mos += stas_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MOS");
00455     lss += stas_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_LSS");
00456 
00457     nframes = mos + mxu + lss;
00458 
00459     if (nframes == 0) {
00460         fors_extract_slits_exit("Missing input spectral frame");
00461     }
00462     if (nframes > 1) {
00463         cpl_msg_error(recipe, 
00464                       "Too many input spectral frames (%d > 1)", nframes);
00465         fors_extract_slits_exit(NULL);
00466     }
00467 
00468     if (lss)
00469         fors_extract_slits_exit("Use this recipe just with MOS/MXU data.");
00470 
00471     if (mxu) {
00472         slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU");
00473         slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MXU");
00474     }
00475     else {
00476         slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS");
00477         slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MOS");
00478     }
00479 
00480     nframes = slit_l + slit_d;
00481 
00482     if (nframes == 0) {
00483         fors_extract_slits_exit("Missing input slit location table");
00484     }
00485     if (nframes > 1) {
00486         cpl_msg_error(recipe,
00487                       "Too many input slit location tables (%d > 1)", nframes);
00488         fors_extract_slits_exit(NULL);
00489     }
00490 
00491     if (slit_l) {
00492         if (mxu)
00493             slit_location_tag = "SLIT_LOCATION_MXU";
00494         else
00495             slit_location_tag = "SLIT_LOCATION_MOS";
00496     }
00497     else {
00498         if (mxu)
00499             slit_location_tag = "SLIT_LOCATION_DETECT_MXU";
00500         else
00501             slit_location_tag = "SLIT_LOCATION_DETECT_MOS";
00502     }
00503 
00504     if (mxu)
00505         curv_coeff_tag = "CURV_COEFF_MXU";
00506     else
00507         curv_coeff_tag = "CURV_COEFF_MOS";
00508 
00509     if (lamp_mxu) {
00510         input_tag = "LAMP_UNBIAS_MXU";
00511         output_tag = "RECTIFIED_LAMP_MXU";
00512     }
00513     else if (lamp_mos) {
00514         input_tag = "LAMP_UNBIAS_MOS";
00515         output_tag = "RECTIFIED_LAMP_MOS";
00516     }
00517     else if (scib_mxu) {
00518         input_tag = "SCIENCE_UNBIAS_MXU";
00519         output_tag = "RECTIFIED_ALL_SCI_MXU";
00520     }
00521     else if (scib_mos) {
00522         input_tag = "SCIENCE_UNBIAS_MOS";
00523         output_tag = "RECTIFIED_ALL_SCI_MOS";
00524     }
00525     else if (scif_mxu) {
00526         input_tag = "SCIENCE_UNFLAT_MXU";
00527         output_tag = "RECTIFIED_ALL_SCI_MXU";
00528     }
00529     else if (scif_mos) {
00530         input_tag = "SCIENCE_UNFLAT_MOS";
00531         output_tag = "RECTIFIED_ALL_SCI_MOS";
00532     }
00533     else if (stab_mxu) {
00534         input_tag = "STANDARD_UNBIAS_MXU";
00535         output_tag = "RECTIFIED_ALL_STD_MXU";
00536     }
00537     else if (stab_mos) {
00538         input_tag = "STANDARD_UNBIAS_MOS";
00539         output_tag = "RECTIFIED_ALL_STD_MOS";
00540     }
00541     else if (staf_mxu) {
00542         input_tag = "STANDARD_UNFLAT_MXU";
00543         output_tag = "RECTIFIED_ALL_STD_MXU";
00544     }
00545     else if (staf_mos) {
00546         input_tag = "STANDARD_UNFLAT_MOS";
00547         output_tag = "RECTIFIED_ALL_STD_MOS";
00548     }
00549     else if (sciu_mxu) {
00550         input_tag = "UNMAPPED_SCI_MXU";
00551         output_tag = "RECTIFIED_SCI_MXU";
00552     }
00553     else if (sciu_mos) {
00554         input_tag = "UNMAPPED_SCI_MOS";
00555         output_tag = "RECTIFIED_SCI_MOS";
00556     }
00557     else if (stau_mxu) {
00558         input_tag = "UNMAPPED_STD_MXU";
00559         output_tag = "RECTIFIED_STD_MXU";
00560     }
00561     else if (stau_mos) {
00562         input_tag = "UNMAPPED_STD_MOS";
00563         output_tag = "RECTIFIED_STD_MOS";
00564     }
00565     else if (scis_mxu) {
00566         input_tag = "UNMAPPED_SKY_SCI_MXU";
00567         output_tag = "RECTIFIED_SKY_SCI_MXU";
00568     }
00569     else if (scis_mos) {
00570         input_tag = "UNMAPPED_SKY_SCI_MOS";
00571         output_tag = "RECTIFIED_SKY_SCI_MOS";
00572     }
00573     else if (stas_mxu) {
00574         input_tag = "UNMAPPED_SKY_STD_MXU";
00575         output_tag = "RECTIFIED_SKY_STD_MXU";
00576     }
00577     else if (stas_mos) {
00578         input_tag = "UNMAPPED_SKY_STD_MOS";
00579         output_tag = "RECTIFIED_SKY_STD_MOS";
00580     }
00581 
00582     header = dfs_load_header(frameset, input_tag, 0);
00583 
00584     if (header == NULL)
00585         fors_extract_slits_exit("Cannot load master flat frame header");
00586 
00587     if (mos)
00588         maskslits = mos_load_slits_fors_mos(header, &nslits_out_det);
00589     else
00590         maskslits = mos_load_slits_fors_mxu(header);
00591 
00592     /*
00593      * Check if all slits have the same X offset: in such case, abort!
00594      */
00595 
00596     treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
00597 
00598     cpl_table_delete(maskslits); maskslits = NULL;
00599 
00600     if (treat_as_lss) {
00601         cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00602                       "The LSS data reduction strategy must be applied.", 
00603                       mxpos);
00604         fors_extract_slits_exit(NULL);
00605     }
00606 
00607     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00608         fors_extract_slits_exit("Input frames are not from the same grism");
00609 
00610     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00611         fors_extract_slits_exit("Input frames are not from the same filter");
00612 
00613     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00614         fors_extract_slits_exit("Input frames are not from the same chip");
00615 
00616 
00617     /*
00618      * Get the reference wavelength and the rebin factor along the
00619      * dispersion direction from the master flat frame
00620      */
00621 
00622     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00623     if (instrume == NULL)
00624         fors_extract_slits_exit("Missing keyword INSTRUME in master "
00625                                  "flat header");
00626 
00627     if (instrume[4] == '1')
00628         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00629     if (instrume[4] == '2')
00630         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00631 
00632     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00633 
00634     if (cpl_error_get_code() != CPL_ERROR_NONE)
00635         fors_extract_slits_exit("Missing keyword ESO INS GRIS1 WLEN "
00636                                  "in master flat frame header");
00637 
00638     if (reference < 3000.0)   /* Perhaps in nanometers... */
00639         reference *= 10;
00640 
00641     if (reference < 3000.0 || reference > 13000.0) {
00642         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00643                       "keyword ESO INS GRIS1 WLEN in master flat header",
00644                       reference);
00645         fors_extract_slits_exit(NULL);
00646     }
00647 
00648     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00649 
00650     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00651 
00652     if (cpl_error_get_code() != CPL_ERROR_NONE)
00653         fors_extract_slits_exit("Missing keyword ESO DET WIN1 BINX "
00654                                  "in master flat header");
00655 
00656     if (rebin != 1) {
00657         dispersion *= rebin;
00658         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00659                         "working dispersion used is %f A/pixel", rebin,
00660                         dispersion);
00661     }
00662 
00663     cpl_msg_indent_less();
00664     cpl_msg_info(recipe, "Load input frames...");
00665     cpl_msg_indent_more();
00666 
00667     spectra = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0);
00668     if (spectra == NULL)
00669         fors_extract_slits_exit("Cannot load input spectral frame");
00670 
00671     slits = dfs_load_table(frameset, slit_location_tag, 1);
00672     if (slits == NULL)
00673         fors_extract_slits_exit("Cannot load slits location table");
00674 
00675     polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00676     if (slits == NULL)
00677         fors_extract_slits_exit("Cannot load spectral curvature table");
00678 
00679     spatial = mos_spatial_calibration(spectra, slits, polytraces, reference,
00680                                       startwavelength, endwavelength,
00681                                       dispersion, flux, NULL);
00682 
00683     cpl_image_delete(spectra); spectra = NULL;
00684     cpl_table_delete(polytraces); polytraces = NULL;
00685     cpl_table_delete(slits); slits = NULL;
00686 
00687     cpl_propertylist_delete(header); header = NULL;
00688     header = cpl_propertylist_new();
00689 
00690     cpl_propertylist_update_double(header, "CRPIX2", 1.0);
00691     cpl_propertylist_update_double(header, "CRVAL2", 1.0);
00692     /* cpl_propertylist_update_double(header, "CDELT2", 1.0); */
00693     cpl_propertylist_update_double(header, "CD1_1", 1.0);
00694     cpl_propertylist_update_double(header, "CD1_2", 0.0);
00695     cpl_propertylist_update_double(header, "CD2_1", 0.0);
00696     cpl_propertylist_update_double(header, "CD2_2", 1.0);
00697     cpl_propertylist_update_string(header, "CTYPE1", "LINEAR");
00698     cpl_propertylist_update_string(header, "CTYPE2", "PIXEL");
00699 
00700     if (dfs_save_image(frameset, spatial, output_tag,
00701                        header, parlist, recipe, version))
00702         fors_extract_slits_exit(NULL);
00703 
00704     cpl_image_delete(spatial); spatial = NULL;
00705     cpl_propertylist_delete(header); header = NULL;
00706 
00707     return 0;
00708 }

Generated on 12 Feb 2016 for FORS Pipeline Reference Manual by  doxygen 1.6.1