fors_subtract_sky_lss.c

00001 /* $Id: fors_subtract_sky_lss.c,v 1.3 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.3 $
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_lss_create(cpl_plugin *);
00038 static int fors_subtract_sky_lss_exec(cpl_plugin *);
00039 static int fors_subtract_sky_lss_destroy(cpl_plugin *);
00040 static int fors_subtract_sky_lss(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_subtract_sky_lss_description[] =
00043 "This recipe is used to subtract the sky from wavelength calibrated\n"
00044 "scientific spectra produced by the recipe fors_resample. A simple median\n"
00045 "signal level is subtracted from each image column.\n"
00046 "In the table below the MXU acronym can be read alternatively as MOS\n"
00047 "and LSS, depending on the instrument mode of the input data. The acronym\n"
00048 "SCI may be read STD in case of standard stars observations.\n"
00049 "Note that only LSS or LSS-like MOS/MXU data are to be processed by this\n"
00050 "recipe.\n\n"
00051 "Input files:\n\n"
00052 "  DO category:               Type:       Explanation:         Required:\n"
00053 "  MAPPED_ALL_SCI_MXU         Raw         Scientific exposure     Y\n\n"
00054 "Output files:\n\n"
00055 "  DO category:               Data type:  Explanation:\n"
00056 "  MAPPED_SCI_MXU             FITS image  Rectified scientific spectra\n"
00057 "  MAPPED_SKY_SCI_MXU         FITS image  Rectified sky spectra\n\n";
00058 
00059 #define fors_subtract_sky_lss_exit(message)            \
00060 {                                             \
00061 if (message) cpl_msg_error(recipe, message);  \
00062 cpl_image_delete(skymap);                     \
00063 cpl_image_delete(sky);                        \
00064 cpl_image_delete(spectra);                    \
00065 cpl_propertylist_delete(header);              \
00066 cpl_msg_indent_less();                        \
00067 return -1;                                    \
00068 }
00069 
00070 
00071 #define fors_subtract_sky_lss_exit_memcheck(message)   \
00072 {                                             \
00073 if (message) cpl_msg_info(recipe, message);   \
00074 cpl_image_delete(skymap);                     \
00075 cpl_image_delete(sky);                        \
00076 cpl_image_delete(spectra);                    \
00077 cpl_propertylist_delete(header);              \
00078 cpl_msg_indent_less();                        \
00079 return 0;                                     \
00080 }
00081 
00082 
00094 int cpl_plugin_get_info(cpl_pluginlist *list)
00095 {
00096     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00097     cpl_plugin *plugin = &recipe->interface;
00098 
00099     cpl_plugin_init(plugin,
00100                     CPL_PLUGIN_API,
00101                     FORS_BINARY_VERSION,
00102                     CPL_PLUGIN_TYPE_RECIPE,
00103                     "fors_subtract_sky_lss",
00104                     "Subtract sky from calibrated long slit exposure",
00105                     fors_subtract_sky_lss_description,
00106                     "Carlo Izzo",
00107                     PACKAGE_BUGREPORT,
00108     "This file is currently part of the FORS Instrument Pipeline\n"
00109     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00110     "This program is free software; you can redistribute it and/or modify\n"
00111     "it under the terms of the GNU General Public License as published by\n"
00112     "the Free Software Foundation; either version 2 of the License, or\n"
00113     "(at your option) any later version.\n\n"
00114     "This program is distributed in the hope that it will be useful,\n"
00115     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00116     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00117     "GNU General Public License for more details.\n\n"
00118     "You should have received a copy of the GNU General Public License\n"
00119     "along with this program; if not, write to the Free Software Foundation,\n"
00120     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00121                     fors_subtract_sky_lss_create,
00122                     fors_subtract_sky_lss_exec,
00123                     fors_subtract_sky_lss_destroy);
00124 
00125     cpl_pluginlist_append(list, plugin);
00126     
00127     return 0;
00128 }
00129 
00130 
00141 static int fors_subtract_sky_lss_create(cpl_plugin *plugin)
00142 {
00143     cpl_recipe    *recipe;
00144 /* Uncomment in case parameters are defined
00145     cpl_parameter *p;
00146 */
00147 
00148     /* 
00149      * Check that the plugin is part of a valid recipe 
00150      */
00151 
00152     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00153         recipe = (cpl_recipe *)plugin;
00154     else 
00155         return -1;
00156 
00157     /* 
00158      * Create the parameters list in the cpl_recipe object 
00159      */
00160 
00161     recipe->parameters = cpl_parameterlist_new(); 
00162 
00163     return 0;
00164 }
00165 
00166 
00175 static int fors_subtract_sky_lss_exec(cpl_plugin *plugin)
00176 {
00177     cpl_recipe *recipe;
00178     
00179     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00180         recipe = (cpl_recipe *)plugin;
00181     else 
00182         return -1;
00183 
00184     return fors_subtract_sky_lss(recipe->parameters, recipe->frames);
00185 }
00186 
00187 
00196 static int fors_subtract_sky_lss_destroy(cpl_plugin *plugin)
00197 {
00198     cpl_recipe *recipe;
00199     
00200     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00201         recipe = (cpl_recipe *)plugin;
00202     else 
00203         return -1;
00204 
00205     cpl_parameterlist_delete(recipe->parameters); 
00206 
00207     return 0;
00208 }
00209 
00210 
00220 static int fors_subtract_sky_lss(cpl_parameterlist *parlist, 
00221                                  cpl_frameset *frameset)
00222 {
00223 
00224     const char *recipe = "fors_subtract_sky_lss";
00225 
00226 
00227     /*
00228      * Input parameters (none)
00229      */
00230 
00231     /*
00232      * CPL objects
00233      */
00234 
00235     cpl_image        *spectra   = NULL;
00236     cpl_image        *skymap    = NULL;
00237     cpl_image        *sky       = NULL;
00238     cpl_table        *maskslits = NULL;
00239 
00240     cpl_propertylist *header    = NULL;
00241 
00242     /*
00243      * Auxiliary variables
00244      */
00245 
00246     char        version[80];
00247     char       *instrume = NULL;
00248     const char *mapped_science_tag;
00249     const char *mapped_science_sky_tag;
00250     const char *mapped_sky_tag;
00251     int         mxu, mos, lss;
00252     int         treat_as_lss = 0;
00253     int         nslits;
00254     int         nscience;
00255     double     *xpos;
00256     double      mxpos;
00257     int         nx, ny;
00258     int         standard;
00259     float      *data;
00260     float      *sdata;
00261     int         i, j;
00262 
00263 
00264     snprintf(version, 80, "%s-%s", PACKAGE, PACKAGE_VERSION);
00265 
00266     cpl_msg_set_indentation(2);
00267 
00268     if (dfs_files_dont_exist(frameset))
00269         fors_subtract_sky_lss_exit(NULL);
00270 
00271 
00272     /* 
00273      * Get configuration parameters (none)
00274      */
00275 
00276     /* 
00277      * Check input set-of-frames
00278      */
00279 
00280     cpl_msg_indent_less();
00281     cpl_msg_info(recipe, "Check input set-of-frames:");
00282     cpl_msg_indent_more();
00283 
00284     mxu = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_MXU");
00285     mos = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_MOS");
00286     lss = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_LSS");
00287     standard = 0;
00288 
00289     if (mxu + mos + lss == 0) {
00290         mxu = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_MXU");
00291         mos = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_MOS");
00292         lss = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_LSS");
00293         standard = 1;
00294     }
00295 
00296     if (mxu + mos + lss == 0)
00297         fors_subtract_sky_lss_exit("Missing input scientific frame");
00298 
00299     nscience = mxu + mos + lss;
00300 
00301     if (nscience > 1)
00302         fors_subtract_sky_lss_exit("More than one scientific frame in input"); 
00303 
00304     if (mxu) {
00305         if (standard) {
00306             cpl_msg_info(recipe, "MXU data found");
00307             mapped_science_tag     = "MAPPED_STD_MXU";
00308             mapped_science_sky_tag = "MAPPED_ALL_STD_MXU";
00309             mapped_sky_tag         = "MAPPED_SKY_STD_MXU";
00310         }
00311         else {
00312             cpl_msg_info(recipe, "MXU data found");
00313             mapped_science_tag     = "MAPPED_SCI_MXU";
00314             mapped_science_sky_tag = "MAPPED_ALL_SCI_MXU";
00315             mapped_sky_tag         = "MAPPED_SKY_SCI_MXU";
00316         }
00317     }
00318 
00319     if (lss) {
00320         if (standard) {
00321             cpl_msg_info(recipe, "LSS data found");
00322             mapped_science_tag      = "MAPPED_STD_LSS";
00323             mapped_science_sky_tag  = "MAPPED_ALL_STD_LSS";
00324             mapped_sky_tag          = "MAPPED_SKY_STD_LSS";
00325         }
00326         else {
00327             cpl_msg_info(recipe, "LSS data found");
00328             mapped_science_tag      = "MAPPED_SCI_LSS";
00329             mapped_science_sky_tag  = "MAPPED_ALL_SCI_LSS";
00330             mapped_sky_tag          = "MAPPED_SKY_SCI_LSS";
00331         }
00332     }
00333 
00334     if (mos) {
00335         if (standard) {
00336             cpl_msg_info(recipe, "MOS data found");
00337             mapped_science_tag      = "MAPPED_STD_MOS";
00338             mapped_science_sky_tag  = "MAPPED_ALL_STD_MOS";
00339             mapped_sky_tag          = "MAPPED_SKY_STD_MOS";
00340         }
00341         else {
00342             cpl_msg_info(recipe, "MOS data found");
00343             mapped_science_tag      = "MAPPED_SCI_MOS";
00344             mapped_science_sky_tag  = "MAPPED_ALL_SCI_MOS";
00345             mapped_sky_tag          = "MAPPED_SKY_SCI_MOS";
00346         }
00347     }
00348 
00349     /*
00350      * Loading input data
00351      */
00352 
00353     cpl_msg_info(recipe, "Load mapped scientific exposure...");
00354     cpl_msg_indent_more();
00355 
00356     spectra = dfs_load_image(frameset, mapped_science_sky_tag, 
00357                              CPL_TYPE_FLOAT, 0, 0);
00358 
00359     if (spectra == NULL)
00360         fors_subtract_sky_lss_exit("Cannot load input frame");
00361 
00362     header = dfs_load_header(frameset, mapped_science_sky_tag, 0);
00363 
00364     if (header == NULL)
00365         fors_subtract_sky_lss_exit("Cannot load input frame header");
00366 
00367     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00368     if (instrume == NULL)
00369         fors_subtract_sky_lss_exit("Missing keyword INSTRUME in scientific header");
00370     instrume = cpl_strdup(instrume);
00371 
00372     if (instrume[4] == '1')
00373         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00374     if (instrume[4] == '2')
00375         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00376 
00377     cpl_free(instrume); instrume = NULL;
00378 
00379     cpl_msg_indent_less();
00380 
00381     if (mos || mxu) {
00382         if (mos)
00383             maskslits = mos_load_slits_fors_mos(header);
00384         else
00385             maskslits = mos_load_slits_fors_mxu(header);
00386 
00387         /*
00388          * Check if all slits have the same X offset: in such case,
00389          * treat the observation as a long-slit one!
00390          */
00391 
00392         mxpos = cpl_table_get_column_median(maskslits, "xtop");
00393         xpos = cpl_table_get_data_double(maskslits, "xtop");
00394         nslits = cpl_table_get_nrow(maskslits);
00395      
00396         treat_as_lss = 1;
00397         for (i = 0; i < nslits; i++) { 
00398             if (fabs(mxpos-xpos[i]) > 0.01) {
00399                 treat_as_lss = 0;
00400                 break;
00401             }
00402         }
00403 
00404         cpl_table_delete(maskslits); maskslits = NULL;
00405 
00406         if (treat_as_lss)
00407             cpl_msg_info(recipe, "All MOS slits have the same offset: %.2f\n"
00408                          "The LSS data reduction strategy is applied.",
00409                          mxpos);
00410         else
00411             fors_subtract_sky_lss_exit("This recipe can only be used "
00412                                        "with LSS-like data");
00413     }
00414 
00415     nx = cpl_image_get_size_x(spectra);
00416     ny = cpl_image_get_size_y(spectra);
00417 
00418     skymap = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00419     sky    = cpl_image_collapse_median_create(spectra, 0, 0, 1);
00420 
00421     data   = cpl_image_get_data(skymap);
00422 
00423     for (i = 0; i < ny; i++) {
00424         sdata  = cpl_image_get_data(sky);
00425         for (j = 0; j < nx; j++) {
00426             *data++ = *sdata++;
00427         }
00428     }
00429 
00430     cpl_image_delete(sky); sky = NULL;
00431     cpl_image_subtract(spectra, skymap);
00432 
00433     if (dfs_save_image(frameset, skymap, mapped_sky_tag, header,
00434                        parlist, recipe, version))
00435         fors_subtract_sky_lss_exit(NULL);
00436 
00437     cpl_image_delete(skymap); skymap = NULL;
00438 
00439     if (dfs_save_image(frameset, spectra, mapped_science_tag, header,
00440                        parlist, recipe, version))
00441         fors_subtract_sky_lss_exit(NULL);
00442 
00443     cpl_image_delete(spectra); spectra = NULL;
00444 
00445     cpl_propertylist_delete(header); header = NULL;
00446 
00447     if (cpl_error_get_code()) {
00448         cpl_msg_error(cpl_error_get_where(), cpl_error_get_message());
00449         fors_subtract_sky_lss_exit(NULL);
00450     }
00451     else 
00452         return 0;
00453 }

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