fors_flatfield.c

00001 /* $Id: fors_flatfield.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_flatfield_create(cpl_plugin *);
00038 static int fors_flatfield_exec(cpl_plugin *);
00039 static int fors_flatfield_destroy(cpl_plugin *);
00040 static int fors_flatfield(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_flatfield_description[] =
00043 "This recipe is used to divide the input frame by the normalised flat\n"
00044 "field frame produced by recipe fors_normalise_flat. The input frame must\n"
00045 "be already bias subtracted (e.g., by recipe fors_remove_bias).\n"
00046 "In the table below the MXU acronym can be alternatively read as MOS and\n"
00047 "LSS.\n\n"
00048 "Input files:\n\n"
00049 "  DO category:               Type:       Explanation:         Required:\n"
00050 "  SCIENCE_UNBIAS_MXU\n"
00051 "  or STANDARD_UNBIAS_MXU     Raw         Bias subtracted frame   Y\n"
00052 "  MASTER_NORM_FLAT_MXU       Calib       Normalised flat frame   Y\n\n"
00053 "Output files:\n\n"
00054 "  DO category:               Data type:  Explanation:\n"
00055 "  SCIENCE_UNFLAT_MXU\n"
00056 "  or STANDARD_UNFLAT_MXU     FITS image  Flat field corrected frame\n\n";
00057 
00058 #define fors_flatfield_exit(message)          \
00059 {                                             \
00060 if (message) cpl_msg_error(recipe, message);  \
00061 cpl_image_delete(raw_image);                  \
00062 cpl_image_delete(norm_flat);                  \
00063 cpl_propertylist_delete(header);              \
00064 cpl_msg_indent_less();                        \
00065 return -1;                                    \
00066 }
00067 
00068 #define fors_flatfield_exit_memcheck(message) \
00069 {                                               \
00070 if (message) cpl_msg_info(recipe, message);     \
00071 printf("free raw_image (%p)\n", raw_image);     \
00072 cpl_image_delete(raw_image);                    \
00073 printf("free norm_flat (%p)\n", norm_flat);     \
00074 cpl_image_delete(norm_flat);                    \
00075 printf("free header (%p)\n", header);           \
00076 cpl_propertylist_delete(header);                \
00077 cpl_msg_indent_less();                          \
00078 return 0;                                       \
00079 }
00080 
00081 
00093 int cpl_plugin_get_info(cpl_pluginlist *list)
00094 {
00095     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00096     cpl_plugin *plugin = &recipe->interface;
00097 
00098     cpl_plugin_init(plugin,
00099                     CPL_PLUGIN_API,
00100                     FORS_BINARY_VERSION,
00101                     CPL_PLUGIN_TYPE_RECIPE,
00102                     "fors_flatfield",
00103                     "Flat field correction of input frame",
00104                     fors_flatfield_description,
00105                     "Carlo Izzo",
00106                     PACKAGE_BUGREPORT,
00107     "This file is currently part of the FORS Instrument Pipeline\n"
00108     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00109     "This program is free software; you can redistribute it and/or modify\n"
00110     "it under the terms of the GNU General Public License as published by\n"
00111     "the Free Software Foundation; either version 2 of the License, or\n"
00112     "(at your option) any later version.\n\n"
00113     "This program is distributed in the hope that it will be useful,\n"
00114     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00115     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00116     "GNU General Public License for more details.\n\n"
00117     "You should have received a copy of the GNU General Public License\n"
00118     "along with this program; if not, write to the Free Software Foundation,\n"
00119     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00120                     fors_flatfield_create,
00121                     fors_flatfield_exec,
00122                     fors_flatfield_destroy);
00123 
00124     cpl_pluginlist_append(list, plugin);
00125     
00126     return 0;
00127 }
00128 
00129 
00140 static int fors_flatfield_create(cpl_plugin *plugin)
00141 {
00142     cpl_recipe    *recipe;
00143 /* Uncomment in case parameters are defined
00144     cpl_parameter *p;
00145 */
00146 
00147     /* 
00148      * Check that the plugin is part of a valid recipe 
00149      */
00150 
00151     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00152         recipe = (cpl_recipe *)plugin;
00153     else 
00154         return -1;
00155 
00156     /* 
00157      * Create the (empty) parameters list in the cpl_recipe object 
00158      */
00159 
00160     recipe->parameters = cpl_parameterlist_new(); 
00161 
00162     return 0;
00163 }
00164 
00165 
00174 static int fors_flatfield_exec(cpl_plugin *plugin)
00175 {
00176     cpl_recipe *recipe;
00177     
00178     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00179         recipe = (cpl_recipe *)plugin;
00180     else 
00181         return -1;
00182 
00183     return fors_flatfield(recipe->parameters, recipe->frames);
00184 }
00185 
00186 
00195 static int fors_flatfield_destroy(cpl_plugin *plugin)
00196 {
00197     cpl_recipe *recipe;
00198     
00199     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00200         recipe = (cpl_recipe *)plugin;
00201     else 
00202         return -1;
00203 
00204     cpl_parameterlist_delete(recipe->parameters); 
00205 
00206     return 0;
00207 }
00208 
00209 
00219 static int fors_flatfield(cpl_parameterlist *parlist, cpl_frameset *frameset)
00220 {
00221 
00222     const char *recipe = "fors_flatfield";
00223 
00224 
00225     /*
00226      * CPL objects
00227      */
00228 
00229     cpl_image        *raw_image   = NULL;
00230     cpl_image        *norm_flat   = NULL;
00231     cpl_propertylist *header      = NULL;
00232 
00233     /*
00234      * Auxiliary variables
00235      */
00236 
00237     char        version[80];
00238     const char *norm_flat_tag;
00239     const char *raw_image_tag;
00240     const char *pro_image_tag;
00241     char       *instrume = NULL;
00242     int         science_mxu;
00243     int         science_mos;
00244     int         science_lss;
00245     int         standard_mxu;
00246     int         standard_mos;
00247     int         standard_lss;
00248     int         nflat, nframe;
00249 
00250 
00251     cpl_msg_set_indentation(2);
00252 
00253     if (dfs_files_dont_exist(frameset))
00254         fors_flatfield_exit(NULL);
00255 
00256 
00257     cpl_msg_info(recipe, "Check input set-of-frames:");
00258     cpl_msg_indent_more();
00259 
00260     nframe  = science_mxu  = cpl_frameset_count_tags(frameset, 
00261                                                      "SCIENCE_UNBIAS_MXU");
00262     nframe += science_mos  = cpl_frameset_count_tags(frameset, 
00263                                                      "SCIENCE_UNBIAS_MOS");
00264     nframe += science_lss  = cpl_frameset_count_tags(frameset, 
00265                                                      "SCIENCE_UNBIAS_LSS");
00266     nframe += standard_mxu = cpl_frameset_count_tags(frameset, 
00267                                                      "STANDARD_UNBIAS_MXU");
00268     nframe += standard_mos = cpl_frameset_count_tags(frameset, 
00269                                                      "STANDARD_UNBIAS_MOS");
00270     nframe += standard_lss = cpl_frameset_count_tags(frameset, 
00271                                                      "STANDARD_UNBIAS_LSS");
00272 
00273     if (nframe == 0) {
00274         fors_flatfield_exit("Missing required input scientific frame");
00275     }
00276     if (nframe > 1) {
00277         cpl_msg_error(recipe, "Too many input scientific frames (%d > 1)", 
00278                       nframe);
00279         fors_flatfield_exit(NULL);
00280     }
00281 
00282     if (science_mxu) {
00283         norm_flat_tag = "MASTER_NORM_FLAT_MXU";
00284         pro_image_tag = "SCIENCE_UNFLAT_MXU";
00285         raw_image_tag = "SCIENCE_UNBIAS_MXU";
00286     }
00287     else if (science_mos) {
00288         norm_flat_tag = "MASTER_NORM_FLAT_MOS";
00289         pro_image_tag = "SCIENCE_UNFLAT_MOS";
00290         raw_image_tag = "SCIENCE_UNBIAS_MOS";
00291     }
00292     else if (science_lss) {
00293         norm_flat_tag = "MASTER_NORM_FLAT_LSS";
00294         pro_image_tag = "SCIENCE_UNFLAT_LSS";
00295         raw_image_tag = "SCIENCE_UNBIAS_LSS";
00296     }
00297     else if (standard_mxu) {
00298         norm_flat_tag = "MASTER_NORM_FLAT_MXU";
00299         pro_image_tag = "STANDARD_UNFLAT_MXU";
00300         raw_image_tag = "STANDARD_UNBIAS_MXU";
00301     }
00302     else if (standard_mos) {
00303         norm_flat_tag = "MASTER_NORM_FLAT_MOS";
00304         pro_image_tag = "STANDARD_UNFLAT_MOS";
00305         raw_image_tag = "STANDARD_UNBIAS_MOS";
00306     }
00307     else if (standard_lss) {
00308         norm_flat_tag = "MASTER_NORM_FLAT_LSS";
00309         pro_image_tag = "STANDARD_UNFLAT_LSS";
00310         raw_image_tag = "STANDARD_UNBIAS_LSS";
00311     }
00312 
00313     nflat = cpl_frameset_count_tags(frameset, norm_flat_tag);
00314     if (nflat == 0) {
00315         cpl_msg_error(recipe, "Missing required input: %s", norm_flat_tag);
00316         fors_flatfield_exit(NULL);
00317     }
00318     if (nflat > 1) {
00319         cpl_msg_error(recipe, "Too many in input (%d > 1): %s",
00320                       nflat, norm_flat_tag);
00321         fors_flatfield_exit(NULL);
00322     }
00323 
00324     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00325         fors_flatfield_exit("Input frames are not from the same grism");
00326 
00327     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00328         fors_flatfield_exit("Input frames are not from the same filter");
00329 
00330     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 
00331         fors_flatfield_exit("Input frames are not from the same chip");
00332 
00333     header = dfs_load_header(frameset, raw_image_tag, 0);
00334 
00335     if (header == NULL) {
00336         cpl_msg_error(recipe, "Cannot load header of %s frame", raw_image_tag);
00337         fors_flatfield_exit(NULL);
00338     }
00339 
00340     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00341     if (instrume == NULL) {
00342         cpl_msg_error(recipe, "Missing keyword INSTRUME in %s header", 
00343                       raw_image_tag);
00344         fors_flatfield_exit(NULL);
00345     }
00346 
00347     if (instrume[4] == '1')
00348         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00349     if (instrume[4] == '2')
00350         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00351 
00352     cpl_msg_indent_less();
00353     cpl_msg_info(recipe, "Load input frames:");
00354     cpl_msg_indent_more();
00355 
00356     norm_flat = dfs_load_image(frameset, norm_flat_tag, CPL_TYPE_FLOAT, 0, 1);
00357     if (norm_flat == NULL)
00358         fors_flatfield_exit("Cannot load normalised flat field");
00359 
00360     raw_image = dfs_load_image(frameset, raw_image_tag, CPL_TYPE_FLOAT, 0, 0);
00361     if (raw_image == NULL) {
00362         cpl_msg_error(recipe, "Cannot load %s frame", raw_image_tag);
00363         fors_flatfield_exit(NULL);
00364     }
00365 
00366     cpl_msg_indent_less();
00367     cpl_msg_info(recipe, "Divide input %s by flat field...", raw_image_tag);
00368     cpl_msg_indent_more();
00369 
00370     if (cpl_image_divide(raw_image, norm_flat) != CPL_ERROR_NONE) {
00371         cpl_msg_error(recipe, "Failure of flat field correction: %s",
00372                       cpl_error_get_message());
00373         fors_flatfield_exit(NULL);
00374     }
00375     cpl_image_delete(norm_flat); norm_flat = NULL;
00376 
00377     cpl_msg_indent_less();
00378 
00379     if (dfs_save_image(frameset, raw_image, pro_image_tag,
00380                        header, parlist, recipe, version))
00381         fors_flatfield_exit(NULL);
00382 
00383     cpl_propertylist_delete(header); header = NULL;
00384     cpl_image_delete(raw_image); raw_image = NULL;
00385 
00386     return 0;
00387 }

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