fors_extract_slits.c

00001 /* $Id: fors_extract_slits.c,v 1.5 2010/09/14 07:38:16 cizzo 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: cizzo $
00023  * $Date: 2010/09/14 07:38:16 $
00024  * $Revision: 1.5 $
00025  * $Name: fors-4_8_6 $
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 (message) 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 (message) 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         nslits;
00340     int         treat_as_lss;
00341     int         i;
00342     double      reference;
00343     double     *xpos;
00344     double      mxpos;
00345     int         mxu, mos, lss;
00346     int         slit_l, slit_d;
00347     int         lamp_mxu;
00348     int         lamp_mos;
00349     int         lamp_lss;
00350     int         scib_mxu;
00351     int         scib_mos;
00352     int         scib_lss;
00353     int         scif_mxu;
00354     int         scif_mos;
00355     int         scif_lss;
00356     int         stab_mxu;
00357     int         stab_mos;
00358     int         stab_lss;
00359     int         staf_mxu;
00360     int         staf_mos;
00361     int         staf_lss;
00362     int         sciu_mxu;
00363     int         sciu_mos;
00364     int         sciu_lss;
00365     int         stau_mxu;
00366     int         stau_mos;
00367     int         stau_lss;
00368     int         scis_mxu;
00369     int         scis_mos;
00370     int         scis_lss;
00371     int         stas_mxu;
00372     int         stas_mos;
00373     int         stas_lss;
00374 
00375     char       *instrume = NULL;
00376 
00377 
00378     cpl_msg_set_indentation(2);
00379 
00380     if (dfs_files_dont_exist(frameset))
00381         fors_extract_slits_exit(NULL);
00382 
00383 
00384     /*
00385      * Get configuration parameters
00386      */
00387 
00388     cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00389     cpl_msg_indent_more();
00390     
00391     if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00392         fors_extract_slits_exit("Too many in input: GRISM_TABLE"); 
00393 
00394     grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00395 
00396     dispersion = dfs_get_parameter_double(parlist,
00397                     "fors.fors_extract_slits.dispersion", grism_table);
00398 
00399     if (dispersion <= 0.0)
00400         fors_extract_slits_exit("Invalid spectral dispersion value");
00401 
00402     startwavelength = dfs_get_parameter_double(parlist,
00403                     "fors.fors_extract_slits.startwavelength", grism_table);
00404     if (startwavelength > 1.0)
00405         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00406             fors_extract_slits_exit("Invalid wavelength");
00407 
00408     endwavelength = dfs_get_parameter_double(parlist,
00409                     "fors.fors_extract_slits.endwavelength", grism_table);
00410     if (endwavelength > 1.0) {
00411         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00412             fors_extract_slits_exit("Invalid wavelength");
00413         if (startwavelength < 1.0)
00414             fors_extract_slits_exit("Invalid wavelength interval");
00415     }
00416 
00417     if (startwavelength > 1.0)
00418         if (endwavelength - startwavelength <= 0.0)
00419             fors_extract_slits_exit("Invalid wavelength interval");
00420 
00421     flux = dfs_get_parameter_bool(parlist, 
00422                                   "fors.fors_extract_slits.flux", NULL);
00423 
00424     cpl_table_delete(grism_table); grism_table = NULL;
00425 
00426     if (cpl_error_get_code())
00427         fors_extract_slits_exit("Failure reading the configuration parameters");
00428 
00429 
00430     cpl_msg_indent_less();
00431     cpl_msg_info(recipe, "Check input set-of-frames:");
00432     cpl_msg_indent_more();
00433 
00434     mxu  = lamp_mxu = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MXU");
00435     mos  = lamp_mos = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_MOS");
00436     lss  = lamp_lss = cpl_frameset_count_tags(frameset, "LAMP_UNBIAS_LSS");
00437     mxu += scib_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU");
00438     mos += scib_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS");
00439     lss += scib_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_LSS");
00440     mxu += scif_mxu = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU");
00441     mos += scif_mos = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS");
00442     lss += scif_lss = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_LSS");
00443     mxu += stab_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU");
00444     mos += stab_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS");
00445     lss += stab_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_LSS");
00446     mxu += staf_mxu = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU");
00447     mos += staf_mos = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS");
00448     lss += staf_lss = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_LSS");
00449     mxu += sciu_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MXU");
00450     mos += sciu_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_MOS");
00451     lss += sciu_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SCI_LSS");
00452     mxu += stau_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MXU");
00453     mos += stau_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_MOS");
00454     lss += stau_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_STD_LSS");
00455     mxu += scis_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MXU");
00456     mos += scis_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_MOS");
00457     lss += scis_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_SCI_LSS");
00458     mxu += stas_mxu = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MXU");
00459     mos += stas_mos = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_MOS");
00460     lss += stas_lss = cpl_frameset_count_tags(frameset, "UNMAPPED_SKY_STD_LSS");
00461 
00462     nframes = mos + mxu + lss;
00463 
00464     if (nframes == 0) {
00465         fors_extract_slits_exit("Missing input spectral frame");
00466     }
00467     if (nframes > 1) {
00468         cpl_msg_error(recipe, 
00469                       "Too many input spectral frames (%d > 1)", nframes);
00470         fors_extract_slits_exit(NULL);
00471     }
00472 
00473     if (lss)
00474         fors_extract_slits_exit("Use this recipe just with MOS/MXU data.");
00475 
00476     if (mxu) {
00477         slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU");
00478         slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MXU");
00479     }
00480     else {
00481         slit_l = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS");
00482         slit_d = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_DETECT_MOS");
00483     }
00484 
00485     nframes = slit_l + slit_d;
00486 
00487     if (nframes == 0) {
00488         fors_extract_slits_exit("Missing input slit location table");
00489     }
00490     if (nframes > 1) {
00491         cpl_msg_error(recipe,
00492                       "Too many input slit location tables (%d > 1)", nframes);
00493         fors_extract_slits_exit(NULL);
00494     }
00495 
00496     if (slit_l) {
00497         if (mxu)
00498             slit_location_tag = "SLIT_LOCATION_MXU";
00499         else
00500             slit_location_tag = "SLIT_LOCATION_MOS";
00501     }
00502     else {
00503         if (mxu)
00504             slit_location_tag = "SLIT_LOCATION_DETECT_MXU";
00505         else
00506             slit_location_tag = "SLIT_LOCATION_DETECT_MOS";
00507     }
00508 
00509     if (mxu)
00510         curv_coeff_tag = "CURV_COEFF_MXU";
00511     else
00512         curv_coeff_tag = "CURV_COEFF_MOS";
00513 
00514     if (lamp_mxu) {
00515         input_tag = "LAMP_UNBIAS_MXU";
00516         output_tag = "RECTIFIED_LAMP_MXU";
00517     }
00518     else if (lamp_mos) {
00519         input_tag = "LAMP_UNBIAS_MOS";
00520         output_tag = "RECTIFIED_LAMP_MOS";
00521     }
00522     else if (scib_mxu) {
00523         input_tag = "SCIENCE_UNBIAS_MXU";
00524         output_tag = "RECTIFIED_ALL_SCI_MXU";
00525     }
00526     else if (scib_mos) {
00527         input_tag = "SCIENCE_UNBIAS_MOS";
00528         output_tag = "RECTIFIED_ALL_SCI_MOS";
00529     }
00530     else if (scif_mxu) {
00531         input_tag = "SCIENCE_UNFLAT_MXU";
00532         output_tag = "RECTIFIED_ALL_SCI_MXU";
00533     }
00534     else if (scif_mos) {
00535         input_tag = "SCIENCE_UNFLAT_MOS";
00536         output_tag = "RECTIFIED_ALL_SCI_MOS";
00537     }
00538     else if (stab_mxu) {
00539         input_tag = "STANDARD_UNBIAS_MXU";
00540         output_tag = "RECTIFIED_ALL_STD_MXU";
00541     }
00542     else if (stab_mos) {
00543         input_tag = "STANDARD_UNBIAS_MOS";
00544         output_tag = "RECTIFIED_ALL_STD_MOS";
00545     }
00546     else if (staf_mxu) {
00547         input_tag = "STANDARD_UNFLAT_MXU";
00548         output_tag = "RECTIFIED_ALL_STD_MXU";
00549     }
00550     else if (staf_mos) {
00551         input_tag = "STANDARD_UNFLAT_MOS";
00552         output_tag = "RECTIFIED_ALL_STD_MOS";
00553     }
00554     else if (sciu_mxu) {
00555         input_tag = "UNMAPPED_SCI_MXU";
00556         output_tag = "RECTIFIED_SCI_MXU";
00557     }
00558     else if (sciu_mos) {
00559         input_tag = "UNMAPPED_SCI_MOS";
00560         output_tag = "RECTIFIED_SCI_MOS";
00561     }
00562     else if (stau_mxu) {
00563         input_tag = "UNMAPPED_STD_MXU";
00564         output_tag = "RECTIFIED_STD_MXU";
00565     }
00566     else if (stau_mos) {
00567         input_tag = "UNMAPPED_STD_MOS";
00568         output_tag = "RECTIFIED_STD_MOS";
00569     }
00570     else if (scis_mxu) {
00571         input_tag = "UNMAPPED_SKY_SCI_MXU";
00572         output_tag = "RECTIFIED_SKY_SCI_MXU";
00573     }
00574     else if (scis_mos) {
00575         input_tag = "UNMAPPED_SKY_SCI_MOS";
00576         output_tag = "RECTIFIED_SKY_SCI_MOS";
00577     }
00578     else if (stas_mxu) {
00579         input_tag = "UNMAPPED_SKY_STD_MXU";
00580         output_tag = "RECTIFIED_SKY_STD_MXU";
00581     }
00582     else if (stas_mos) {
00583         input_tag = "UNMAPPED_SKY_STD_MOS";
00584         output_tag = "RECTIFIED_SKY_STD_MOS";
00585     }
00586 
00587     header = dfs_load_header(frameset, input_tag, 0);
00588 
00589     if (header == NULL)
00590         fors_extract_slits_exit("Cannot load master flat frame header");
00591 
00592     if (mos)
00593         maskslits = mos_load_slits_fors_mos(header);
00594     else
00595         maskslits = mos_load_slits_fors_mxu(header);
00596 
00597     /*
00598      * Check if all slits have the same X offset: in such case, abort!
00599      */
00600 
00601     mxpos = cpl_table_get_column_median(maskslits, "xtop");
00602     xpos = cpl_table_get_data_double(maskslits, "xtop");
00603     nslits = cpl_table_get_nrow(maskslits);
00604 
00605     treat_as_lss = 1;
00606     for (i = 0; i < nslits; i++) {
00607         if (fabs(mxpos-xpos[i]) > 0.01) {
00608             treat_as_lss = 0;
00609             break;
00610         }
00611     }
00612 
00613     cpl_table_delete(maskslits); maskslits = NULL;
00614 
00615     if (treat_as_lss) {
00616         cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00617                       "The LSS data reduction strategy must be applied.", 
00618                       mxpos);
00619         fors_extract_slits_exit(NULL);
00620     }
00621 
00622     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00623         fors_extract_slits_exit("Input frames are not from the same grism");
00624 
00625     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00626         fors_extract_slits_exit("Input frames are not from the same filter");
00627 
00628     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00629         fors_extract_slits_exit("Input frames are not from the same chip");
00630 
00631 
00632     /*
00633      * Get the reference wavelength and the rebin factor along the
00634      * dispersion direction from the master flat frame
00635      */
00636 
00637     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00638     if (instrume == NULL)
00639         fors_extract_slits_exit("Missing keyword INSTRUME in master "
00640                                  "flat header");
00641 
00642     if (instrume[4] == '1')
00643         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00644     if (instrume[4] == '2')
00645         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00646 
00647     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00648 
00649     if (cpl_error_get_code() != CPL_ERROR_NONE)
00650         fors_extract_slits_exit("Missing keyword ESO INS GRIS1 WLEN "
00651                                  "in master flat frame header");
00652 
00653     if (reference < 3000.0)   /* Perhaps in nanometers... */
00654         reference *= 10;
00655 
00656     if (reference < 3000.0 || reference > 13000.0) {
00657         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00658                       "keyword ESO INS GRIS1 WLEN in master flat header",
00659                       reference);
00660         fors_extract_slits_exit(NULL);
00661     }
00662 
00663     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00664 
00665     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00666 
00667     if (cpl_error_get_code() != CPL_ERROR_NONE)
00668         fors_extract_slits_exit("Missing keyword ESO DET WIN1 BINX "
00669                                  "in master flat header");
00670 
00671     if (rebin != 1) {
00672         dispersion *= rebin;
00673         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00674                         "working dispersion used is %f A/pixel", rebin,
00675                         dispersion);
00676     }
00677 
00678     cpl_msg_indent_less();
00679     cpl_msg_info(recipe, "Load input frames...");
00680     cpl_msg_indent_more();
00681 
00682     spectra = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0);
00683     if (spectra == NULL)
00684         fors_extract_slits_exit("Cannot load input spectral frame");
00685 
00686     slits = dfs_load_table(frameset, slit_location_tag, 1);
00687     if (slits == NULL)
00688         fors_extract_slits_exit("Cannot load slits location table");
00689 
00690     polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00691     if (slits == NULL)
00692         fors_extract_slits_exit("Cannot load spectral curvature table");
00693 
00694     spatial = mos_spatial_calibration(spectra, slits, polytraces, reference,
00695                                       startwavelength, endwavelength,
00696                                       dispersion, flux, NULL);
00697 
00698     cpl_image_delete(spectra); spectra = NULL;
00699     cpl_table_delete(polytraces); polytraces = NULL;
00700     cpl_table_delete(slits); slits = NULL;
00701 
00702     cpl_propertylist_delete(header); header = NULL;
00703     header = cpl_propertylist_new();
00704 
00705     cpl_propertylist_update_double(header, "CRPIX2", 1.0);
00706     cpl_propertylist_update_double(header, "CRVAL2", 1.0);
00707     /* cpl_propertylist_update_double(header, "CDELT2", 1.0); */
00708     cpl_propertylist_update_double(header, "CD1_1", 1.0);
00709     cpl_propertylist_update_double(header, "CD1_2", 0.0);
00710     cpl_propertylist_update_double(header, "CD2_1", 0.0);
00711     cpl_propertylist_update_double(header, "CD2_2", 1.0);
00712     cpl_propertylist_update_string(header, "CTYPE1", "LINEAR");
00713     cpl_propertylist_update_string(header, "CTYPE2", "PIXEL");
00714 
00715     if (dfs_save_image(frameset, spatial, output_tag,
00716                        header, parlist, recipe, version))
00717         fors_extract_slits_exit(NULL);
00718 
00719     cpl_image_delete(spatial); spatial = NULL;
00720     cpl_propertylist_delete(header); header = NULL;
00721 
00722     return 0;
00723 }

Generated on Fri Mar 4 09:46:00 2011 for FORS Pipeline Reference Manual by  doxygen 1.4.7