fors_subtract_sky.c

00001 /* $Id: fors_subtract_sky.c,v 1.6 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.6 $
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_subtract_sky_create(cpl_plugin *);
00038 static int fors_subtract_sky_exec(cpl_plugin *);
00039 static int fors_subtract_sky_destroy(cpl_plugin *);
00040 static int fors_subtract_sky(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_subtract_sky_description[] =
00043 "This recipe is used to subtract the sky emission from unrebinned slit\n"
00044 "spectra. This is obtained by robust fitting (i.e., excluding the signal\n"
00045 "from possible point-like objects in slit) of the emission along the CCD\n"
00046 "columns within each spectrum). This method doesn't work if extended\n"
00047 "objects are in slit (it really destroys the object spectra), and is\n"
00048 "not applicable to LSS data. The input scientific frames are produced\n"
00049 "by the recipes fors_remove_bias and fors_flatfield.\n"
00050 "\n"
00051 "This recipe cannot be applied to LSS or long-slit like data (MOS/MXU with\n"
00052 "all slits at the same offset). No automatic recipe is available for this.\n"
00053 "Please refer to the FORS Pipeline User's Manual for more details.\n"
00054 "\n"
00055 "In the table below the MXU acronym can be alternatively read as MOS, and\n"
00056 "SCI as STD.\n\n"
00057 "Input files:\n\n"
00058 "  DO category:               Type:       Explanation:         Required:\n"
00059 "  SCIENCE_UNBIAS_MXU\n"
00060 "  or SCIENCE_UNFLAT_MXU\n"
00061 "  or STANDARD_UNBIAS_MXU\n"
00062 "  or STANDARD_UNFLAT_MXU     Calib       Frame with sky lines    Y\n"
00063 "  CURV_COEFF_MXU             Calib       Spectral curvature      Y\n"
00064 "  SLIT_LOCATION_MXU          Calib       Slit location on CCD    Y\n"
00065 "  GRISM_TABLE                Calib       Grism table             .\n\n"
00066 "Output files:\n\n"
00067 "  DO category:               Data type:  Explanation:\n"
00068 "  UNMAPPED_SCI_MXU\n"
00069 "  or UNMAPPED_STD_MXU        FITS image  Sky subtracted scientific frame\n"
00070 "  UNMAPPED_SKY_SCI_MXU\n"
00071 "  or UNMAPPED_SKY_STD_MXU    FITS image  Subtracted sky frame\n\n";
00072 
00073 #define fors_subtract_sky_exit(message)       \
00074 {                                             \
00075 if (message) cpl_msg_error(recipe, message);  \
00076 cpl_image_delete(spectra);                    \
00077 cpl_image_delete(skymap);                     \
00078 cpl_table_delete(grism_table);                \
00079 cpl_table_delete(maskslits);                  \
00080 cpl_table_delete(slits);                      \
00081 cpl_table_delete(polytraces);                 \
00082 cpl_propertylist_delete(header);              \
00083 cpl_msg_indent_less();                        \
00084 return -1;                                    \
00085 }
00086 
00087 #define fors_subtract_sky_exit_memcheck(message)   \
00088 {                                               \
00089 if (message) cpl_msg_info(recipe, message);     \
00090 printf("free spectra (%p)\n", spectra);         \
00091 cpl_image_delete(spectra);                      \
00092 printf("free skymap (%p)\n", skymap);           \
00093 cpl_image_delete(skymap);                       \
00094 printf("free grism_table (%p)\n", grism_table); \
00095 cpl_table_delete(grism_table);                  \
00096 printf("free maskslits (%p)\n", maskslits);     \
00097 cpl_table_delete(maskslits);                    \
00098 printf("free slits (%p)\n", slits);             \
00099 cpl_table_delete(slits);                        \
00100 printf("free polytraces (%p)\n", polytraces);   \
00101 cpl_table_delete(polytraces);                   \
00102 printf("free header (%p)\n", header);           \
00103 cpl_propertylist_delete(header);                \
00104 cpl_msg_indent_less();                          \
00105 return 0;                                       \
00106 }
00107 
00108 
00120 int cpl_plugin_get_info(cpl_pluginlist *list)
00121 {
00122     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00123     cpl_plugin *plugin = &recipe->interface;
00124 
00125     cpl_plugin_init(plugin,
00126                     CPL_PLUGIN_API,
00127                     FORS_BINARY_VERSION,
00128                     CPL_PLUGIN_TYPE_RECIPE,
00129                     "fors_subtract_sky",
00130                     "Subtract sky from scientific spectra",
00131                     fors_subtract_sky_description,
00132                     "Carlo Izzo",
00133                     PACKAGE_BUGREPORT,
00134     "This file is currently part of the FORS Instrument Pipeline\n"
00135     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00136     "This program is free software; you can redistribute it and/or modify\n"
00137     "it under the terms of the GNU General Public License as published by\n"
00138     "the Free Software Foundation; either version 2 of the License, or\n"
00139     "(at your option) any later version.\n\n"
00140     "This program is distributed in the hope that it will be useful,\n"
00141     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00142     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00143     "GNU General Public License for more details.\n\n"
00144     "You should have received a copy of the GNU General Public License\n"
00145     "along with this program; if not, write to the Free Software Foundation,\n"
00146     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00147                     fors_subtract_sky_create,
00148                     fors_subtract_sky_exec,
00149                     fors_subtract_sky_destroy);
00150 
00151     cpl_pluginlist_append(list, plugin);
00152     
00153     return 0;
00154 }
00155 
00156 
00167 static int fors_subtract_sky_create(cpl_plugin *plugin)
00168 {
00169     cpl_recipe    *recipe;
00170     cpl_parameter *p;
00171 
00172     /* 
00173      * Check that the plugin is part of a valid recipe 
00174      */
00175 
00176     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00177         recipe = (cpl_recipe *)plugin;
00178     else 
00179         return -1;
00180 
00181     /* 
00182      * Create the (empty) parameters list in the cpl_recipe object 
00183      */
00184 
00185     recipe->parameters = cpl_parameterlist_new(); 
00186 
00187     /*
00188      * Dispersion
00189      */
00190 
00191     p = cpl_parameter_new_value("fors.fors_subtract_sky.dispersion",
00192                                 CPL_TYPE_DOUBLE,
00193                                 "Expected spectral dispersion (Angstrom/pixel)",
00194                                 "fors.fors_subtract_sky",
00195                                 0.0);
00196     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
00197     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00198     cpl_parameterlist_append(recipe->parameters, p);
00199 
00200     /*
00201      * Start wavelength for spectral extraction
00202      */
00203 
00204     p = cpl_parameter_new_value("fors.fors_subtract_sky.startwavelength",
00205                                 CPL_TYPE_DOUBLE,
00206                                 "Start wavelength in spectral extraction",
00207                                 "fors.fors_subtract_sky",
00208                                 0.0);
00209     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
00210     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00211     cpl_parameterlist_append(recipe->parameters, p);
00212 
00213     /*
00214      * End wavelength for spectral extraction
00215      */
00216 
00217     p = cpl_parameter_new_value("fors.fors_subtract_sky.endwavelength",
00218                                 CPL_TYPE_DOUBLE,
00219                                 "End wavelength in spectral extraction",
00220                                 "fors.fors_subtract_sky",
00221                                 0.0);
00222     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
00223     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00224     cpl_parameterlist_append(recipe->parameters, p);
00225 
00226     /*
00227      * Cosmic rays removal
00228      */
00229 
00230     p = cpl_parameter_new_value("fors.fors_subtract_sky.cosmics",
00231                                 CPL_TYPE_BOOL,
00232                                 "Eliminate cosmic rays hits",
00233                                 "fors.fors_subtract_sky",
00234                                 FALSE);
00235     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cosmics");
00236     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00237     cpl_parameterlist_append(recipe->parameters, p);
00238 
00239     return 0;
00240 }
00241 
00242 
00251 static int fors_subtract_sky_exec(cpl_plugin *plugin)
00252 {
00253     cpl_recipe *recipe;
00254     
00255     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00256         recipe = (cpl_recipe *)plugin;
00257     else 
00258         return -1;
00259 
00260     return fors_subtract_sky(recipe->parameters, recipe->frames);
00261 }
00262 
00263 
00272 static int fors_subtract_sky_destroy(cpl_plugin *plugin)
00273 {
00274     cpl_recipe *recipe;
00275     
00276     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00277         recipe = (cpl_recipe *)plugin;
00278     else 
00279         return -1;
00280 
00281     cpl_parameterlist_delete(recipe->parameters); 
00282 
00283     return 0;
00284 }
00285 
00286 
00296 static int fors_subtract_sky(cpl_parameterlist *parlist, 
00297                                cpl_frameset *frameset)
00298 {
00299 
00300     const char *recipe = "fors_subtract_sky";
00301 
00302 
00303     /*
00304      * Input parameters
00305      */
00306 
00307     double      dispersion;
00308     double      startwavelength;
00309     double      endwavelength;
00310     int         cosmics;
00311 
00312     /*
00313      * CPL objects
00314      */
00315 
00316     cpl_image        *spectra     = NULL;
00317     cpl_image        *skymap      = NULL;
00318     cpl_table        *grism_table = NULL;
00319     cpl_table        *polytraces  = NULL;
00320     cpl_table        *slits       = NULL;
00321     cpl_table        *maskslits   = NULL;
00322     cpl_propertylist *header      = NULL;
00323 
00324     /*
00325      * Auxiliary variables
00326      */
00327 
00328     char        version[80];
00329     const char *slit_location_tag;
00330     const char *input_tag;
00331     const char *curv_coeff_tag;
00332     const char *unmapped_tag;
00333     const char *unmapped_sky_tag;
00334     int         nframes;
00335     int         rebin;
00336     int         nslits;
00337     int         treat_as_lss;
00338     int         i;
00339     double      reference;
00340     double      gain;
00341     double     *xpos;
00342     double      mxpos;
00343     int         mxu, mos, lss;
00344     int         rec_scib;
00345     int         rec_stdb;
00346     int         rec_scif;
00347     int         rec_stdf;
00348 
00349     char       *instrume = NULL;
00350 
00351 
00352     cpl_msg_set_indentation(2);
00353 
00354     if (dfs_files_dont_exist(frameset))
00355         fors_subtract_sky_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_subtract_sky_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_subtract_sky.dispersion", grism_table);
00372 
00373     if (dispersion <= 0.0)
00374         fors_subtract_sky_exit("Invalid spectral dispersion value");
00375 
00376     startwavelength = dfs_get_parameter_double(parlist,
00377                     "fors.fors_subtract_sky.startwavelength", grism_table);
00378     if (startwavelength > 1.0)
00379         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00380             fors_subtract_sky_exit("Invalid wavelength");
00381 
00382     endwavelength = dfs_get_parameter_double(parlist,
00383                     "fors.fors_subtract_sky.endwavelength", grism_table);
00384     if (endwavelength > 1.0) {
00385         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00386             fors_subtract_sky_exit("Invalid wavelength");
00387         if (startwavelength < 1.0)
00388             fors_subtract_sky_exit("Invalid wavelength interval");
00389     }
00390 
00391     if (startwavelength > 1.0)
00392         if (endwavelength - startwavelength <= 0.0)
00393             fors_subtract_sky_exit("Invalid wavelength interval");
00394 
00395     cosmics = dfs_get_parameter_bool(parlist, 
00396                                      "fors.fors_subtract_sky.cosmics", NULL);
00397 
00398     cpl_table_delete(grism_table); grism_table = NULL;
00399 
00400     if (cpl_error_get_code())
00401         fors_subtract_sky_exit("Failure reading the configuration parameters");
00402 
00403 
00404     cpl_msg_indent_less();
00405     cpl_msg_info(recipe, "Check input set-of-frames:");
00406     cpl_msg_indent_more();
00407 
00408     mxu  = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MXU");
00409     mos  = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_MOS");
00410     lss  = cpl_frameset_count_tags(frameset, "SLIT_LOCATION_LSS");
00411 
00412     if (lss)
00413         fors_subtract_sky_exit("Use this recipe just with MOS/MXU data.");
00414 
00415     nframes = mos + mxu;
00416 
00417     if (nframes == 0) {
00418         fors_subtract_sky_exit("Missing input slit location table");
00419     }
00420     if (nframes > 1) {
00421         cpl_msg_error(recipe, 
00422                       "Too many input slit location tables (%d > 1)", nframes);
00423         fors_subtract_sky_exit(NULL);
00424     }
00425 
00426     if (mxu)
00427         curv_coeff_tag = "CURV_COEFF_MXU";
00428     else
00429         curv_coeff_tag = "CURV_COEFF_MXU";
00430 
00431     
00432     nframes = cpl_frameset_count_tags(frameset, curv_coeff_tag);
00433 
00434     if (nframes == 0) {
00435         cpl_msg_error(recipe, "Missing input %s", curv_coeff_tag);
00436         fors_subtract_sky_exit(NULL);
00437     }
00438     if (nframes > 1) {
00439         cpl_msg_error(recipe, "Too many input %s (%d > 1)", curv_coeff_tag,
00440                       nframes);
00441         fors_subtract_sky_exit(NULL);
00442     }
00443 
00444     if (mxu) {
00445         rec_scib = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MXU");
00446         rec_stdb = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MXU");
00447         rec_scif = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MXU");
00448         rec_stdf = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MXU");
00449     }
00450     else {
00451         rec_scib = cpl_frameset_count_tags(frameset, "SCIENCE_UNBIAS_MOS");
00452         rec_stdb = cpl_frameset_count_tags(frameset, "STANDARD_UNBIAS_MOS");
00453         rec_scif = cpl_frameset_count_tags(frameset, "SCIENCE_UNFLAT_MOS");
00454         rec_stdf = cpl_frameset_count_tags(frameset, "STANDARD_UNFLAT_MOS");
00455     }
00456 
00457     nframes = rec_scib + rec_stdb + rec_scif + rec_stdf;
00458 
00459     if (nframes == 0) {
00460         fors_subtract_sky_exit("Missing input scientific spectra");
00461     }
00462     if (nframes > 1) {
00463         cpl_msg_error(recipe, "Too many input scientific spectra (%d > 1)", 
00464                       nframes);
00465         fors_subtract_sky_exit(NULL);
00466     }
00467 
00468     if (rec_scib) {
00469         if (mxu) {
00470             input_tag         = "SCIENCE_UNBIAS_MXU";
00471             slit_location_tag = "SLIT_LOCATION_MXU";
00472             unmapped_tag      = "UNMAPPED_SCI_MXU";
00473             unmapped_sky_tag  = "UNMAPPED_SKY_SCI_MXU";
00474         }
00475         else {
00476             input_tag         = "SCIENCE_UNBIAS_MOS";
00477             slit_location_tag = "SLIT_LOCATION_MOS";
00478             unmapped_tag      = "UNMAPPED_SCI_MOS";
00479             unmapped_sky_tag  = "UNMAPPED_SKY_SCI_MOS";
00480         }
00481     }
00482     else if (rec_stdb) {
00483         if (mxu) {
00484             input_tag         = "STANDARD_UNBIAS_MXU";
00485             slit_location_tag = "SLIT_LOCATION_MXU";
00486             unmapped_tag      = "UNMAPPED_STD_MXU";
00487             unmapped_sky_tag  = "UNMAPPED_SKY_STD_MXU";
00488         }
00489         else {
00490             input_tag         = "STANDARD_UNBIAS_MOS";
00491             slit_location_tag = "SLIT_LOCATION_MOS";
00492             unmapped_tag      = "UNMAPPED_STD_MOS";
00493             unmapped_sky_tag  = "UNMAPPED_SKY_STD_MOS";
00494         }
00495     }
00496     else if (rec_scif) {
00497         if (mxu) {
00498             input_tag         = "SCIENCE_UNFLAT_MXU";
00499             slit_location_tag = "SLIT_LOCATION_MXU";
00500             unmapped_tag      = "UNMAPPED_SCI_MXU";
00501             unmapped_sky_tag  = "UNMAPPED_SKY_SCI_MXU";
00502         }
00503         else {   
00504             input_tag         = "SCIENCE_UNFLAT_MOS";
00505             slit_location_tag = "SLIT_LOCATION_MOS";
00506             unmapped_tag      = "UNMAPPED_SCI_MOS";
00507             unmapped_sky_tag  = "UNMAPPED_SKY_SCI_MOS";
00508         }
00509     }
00510     else if (rec_stdf) {
00511         if (mxu) {
00512             input_tag         = "STANDARD_UNFLAT_MXU";
00513             slit_location_tag = "SLIT_LOCATION_MXU";
00514             unmapped_tag      = "UNMAPPED_STD_MXU";
00515             unmapped_sky_tag  = "UNMAPPED_SKY_STD_MXU";
00516         }
00517         else {   
00518             input_tag         = "STANDARD_UNFLAT_MOS";
00519             slit_location_tag = "SLIT_LOCATION_MOS";
00520             unmapped_tag      = "UNMAPPED_STD_MOS";
00521             unmapped_sky_tag  = "UNMAPPED_SKY_STD_MOS";
00522         }
00523     }
00524 
00525 
00526     header = dfs_load_header(frameset, input_tag, 0);
00527 
00528     if (header == NULL)
00529         fors_subtract_sky_exit("Cannot load scientific frame header");
00530 
00531     if (mos)
00532         maskslits = mos_load_slits_fors_mos(header);
00533     else
00534         maskslits = mos_load_slits_fors_mxu(header);
00535 
00536     /*
00537      * Check if all slits have the same X offset: if not, abort!
00538      */
00539 
00540     mxpos = cpl_table_get_column_median(maskslits, "xtop");
00541     xpos = cpl_table_get_data_double(maskslits, "xtop");
00542     nslits = cpl_table_get_nrow(maskslits);
00543 
00544     treat_as_lss = 1;
00545     for (i = 0; i < nslits; i++) {
00546         if (fabs(mxpos-xpos[i]) > 0.01) {
00547             treat_as_lss = 0;
00548             break;
00549         }
00550     }
00551 
00552     cpl_table_delete(maskslits); maskslits = NULL;
00553 
00554     if (treat_as_lss)
00555         fors_subtract_sky_exit("This recipe cannot process MOS/MXU "
00556                                "data with all slits at the same offset.");
00557 
00558 
00559     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00560         fors_subtract_sky_exit("Input frames are not from the same grism");
00561 
00562     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00563         fors_subtract_sky_exit("Input frames are not from the same filter");
00564 
00565     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00566         fors_subtract_sky_exit("Input frames are not from the same chip");
00567 
00568 
00569     /*
00570      * Get the reference wavelength and the rebin factor along the
00571      * dispersion direction from the reference frame
00572      */
00573 
00574     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00575     if (instrume == NULL)
00576         fors_subtract_sky_exit("Missing keyword INSTRUME in reference frame "
00577                             "header");
00578 
00579     if (instrume[4] == '1')
00580         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00581     if (instrume[4] == '2')
00582         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00583 
00584     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00585 
00586     if (cpl_error_get_code() != CPL_ERROR_NONE)
00587         fors_subtract_sky_exit("Missing keyword ESO INS GRIS1 WLEN "
00588                             "in reference frame header");
00589 
00590     if (reference < 3000.0)   /* Perhaps in nanometers... */
00591         reference *= 10;
00592 
00593     if (reference < 3000.0 || reference > 13000.0) {
00594         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00595                       "keyword ESO INS GRIS1 WLEN in reference frame header",
00596                       reference);
00597         fors_subtract_sky_exit(NULL);
00598     }
00599 
00600     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00601 
00602     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00603 
00604     if (cpl_error_get_code() != CPL_ERROR_NONE)
00605         fors_subtract_sky_exit("Missing keyword ESO DET WIN1 BINX "
00606                             "in reference frame header");
00607 
00608     if (rebin != 1) {
00609         dispersion *= rebin;
00610         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00611                         "working dispersion used is %f A/pixel", rebin,
00612                         dispersion);
00613     }
00614 
00615     if (cosmics) {
00616         gain = cpl_propertylist_get_double(header, "ESO DET OUT1 CONAD");
00617 
00618         if (cpl_error_get_code() != CPL_ERROR_NONE)
00619             fors_subtract_sky_exit("Missing keyword ESO DET OUT1 CONAD in "
00620                                    "scientific frame header");
00621 
00622         cpl_msg_info(recipe, "The gain factor is: %.2f e-/ADU", gain);
00623     }
00624 
00625 
00626     cpl_msg_indent_less();
00627     cpl_msg_info(recipe, "Load input frames...");
00628     cpl_msg_indent_more();
00629 
00630     spectra = dfs_load_image(frameset, input_tag, CPL_TYPE_FLOAT, 0, 0);
00631     if (spectra == NULL)
00632         fors_subtract_sky_exit("Cannot load input scientific frame");
00633 
00634     slits = dfs_load_table(frameset, slit_location_tag, 1);
00635     if (slits == NULL)
00636         fors_subtract_sky_exit("Cannot load slits location table");
00637 
00638     polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00639     if (polytraces == NULL)
00640         fors_subtract_sky_exit("Cannot load spectral curvature table");
00641 
00642     cpl_msg_indent_less();
00643     cpl_msg_info(recipe, "Local sky determination...");
00644     cpl_msg_indent_more();
00645     skymap = mos_subtract_sky(spectra, slits, polytraces, reference,
00646                               startwavelength, endwavelength, dispersion);
00647 
00648     cpl_table_delete(polytraces); polytraces = NULL;
00649     cpl_table_delete(slits); slits = NULL;
00650 
00651     if (cosmics) {
00652         cpl_msg_info(recipe, "Removing cosmic rays...");
00653         mos_clean_cosmics(spectra, gain, -1., -1.);
00654     }
00655 
00656     if (dfs_save_image(frameset, spectra, unmapped_tag,
00657                        header, parlist, recipe, version))
00658         fors_subtract_sky_exit(NULL);
00659 
00660     cpl_image_delete(spectra); spectra = NULL;
00661 
00662     if (dfs_save_image(frameset, skymap, unmapped_sky_tag,
00663                        header, parlist, recipe, version))
00664         fors_subtract_sky_exit(NULL);
00665 
00666     cpl_image_delete(skymap); skymap = NULL;
00667 
00668     cpl_propertylist_delete(header); header = NULL;
00669 
00670     return 0;
00671 }

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