fors_normalise_flat.c

00001 /* $Id: fors_normalise_flat.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_normalise_flat_create(cpl_plugin *);
00038 static int fors_normalise_flat_exec(cpl_plugin *);
00039 static int fors_normalise_flat_destroy(cpl_plugin *);
00040 static int fors_normalise_flat(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_normalise_flat_description[] =
00043 "This recipe is used to normalise a master flat field frame dividing it\n"
00044 "by its large scale illumination trend. This recipe can be applied both\n"
00045 "to generic multi-slit (MOS/MXU) and to long slit exposures (either LSS, or\n"
00046 "LSS-like MOS/MXU), even if different normalisation methods are applied in\n"
00047 "such different cases. The input master flat field image is the product\n"
00048 "of the recipe fors_flat. The input spectral curvature table, product of\n"
00049 "the recipe fors_detect_spectra, is only required in the case of multi-slit\n"
00050 "data.\n"
00051 "\n"
00052 "In the case of multi-slit data, the flat field spectra are spatially\n"
00053 "rectified, heavily smoothed, and then mapped back on the CCD. Then the\n"
00054 "master flat image is divided by its smoothed counterpart. The smoothing\n"
00055 "may be obtained either by applying a running median filter of specified\n"
00056 "sizes, or by polynomial fitting along the dispersion direction performed\n"
00057 "independently for each row of the spatially remapped spectra.\n"
00058 "\n"
00059 "In the case of long-slit data, the smoothing can still be obtained either\n"
00060 "by applying a running median filter or by polynomial fitting, but the\n"
00061 "polynomial fitting will be performed along the spatial direction, for\n"
00062 "each column of the spectrum.\n"
00063 "\n"
00064 "In the table below the MXU acronym can be alternatively read as MOS or\n"
00065 "LSS.\n\n"
00066 "Input files:\n\n"
00067 "  DO category:               Type:       Explanation:         Required:\n"
00068 "  MASTER_SCREEN_FLAT_MXU     Calib       Master flat frame       Y\n"
00069 "  CURV_COEFF_MXU             Calib       Spectral curvature      .\n"
00070 "  GRISM_TABLE                Calib       Grism table             .\n\n"
00071 "Output files:\n\n"
00072 "  DO category:               Data type:  Explanation:\n"
00073 "  MASTER_NORM_FLAT_MXU       FITS image  Normalised flat field\n\n";
00074 
00075 #define fors_normalise_flat_exit(message)     \
00076 {                                             \
00077 if (message) cpl_msg_error(recipe, message);  \
00078 cpl_image_delete(master_flat);                \
00079 cpl_image_delete(spatial);                    \
00080 cpl_image_delete(coordinate);                 \
00081 cpl_image_delete(smo_flat);                   \
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_normalise_flat_exit_memcheck(message)  \
00092 {                                               \
00093 if (message) cpl_msg_info(recipe, message);     \
00094 printf("free master_flat (%p)\n", master_flat); \
00095 cpl_image_delete(master_flat);                  \
00096 printf("free spatial (%p)\n", spatial);         \
00097 cpl_image_delete(spatial);                      \
00098 printf("free coordinate (%p)\n", coordinate);   \
00099 cpl_image_delete(coordinate);                   \
00100 printf("free smo_flat (%p)\n", smo_flat);       \
00101 cpl_image_delete(smo_flat);                     \
00102 printf("free grism_table (%p)\n", grism_table); \
00103 cpl_table_delete(grism_table);                  \
00104 printf("free maskslits (%p)\n", maskslits);     \
00105 cpl_table_delete(maskslits);                    \
00106 printf("free slits (%p)\n", slits);             \
00107 cpl_table_delete(slits);                        \
00108 printf("free polytraces (%p)\n", polytraces);   \
00109 cpl_table_delete(polytraces);                   \
00110 printf("free header (%p)\n", header);           \
00111 cpl_propertylist_delete(header);                \
00112 cpl_msg_indent_less();                          \
00113 return 0;                                       \
00114 }
00115 
00116 
00128 int cpl_plugin_get_info(cpl_pluginlist *list)
00129 {
00130     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00131     cpl_plugin *plugin = &recipe->interface;
00132 
00133     cpl_plugin_init(plugin,
00134                     CPL_PLUGIN_API,
00135                     FORS_BINARY_VERSION,
00136                     CPL_PLUGIN_TYPE_RECIPE,
00137                     "fors_normalise_flat",
00138                     "Normalise master flat spectrum",
00139                     fors_normalise_flat_description,
00140                     "Carlo Izzo",
00141                     PACKAGE_BUGREPORT,
00142     "This file is currently part of the FORS Instrument Pipeline\n"
00143     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00144     "This program is free software; you can redistribute it and/or modify\n"
00145     "it under the terms of the GNU General Public License as published by\n"
00146     "the Free Software Foundation; either version 2 of the License, or\n"
00147     "(at your option) any later version.\n\n"
00148     "This program is distributed in the hope that it will be useful,\n"
00149     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00150     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00151     "GNU General Public License for more details.\n\n"
00152     "You should have received a copy of the GNU General Public License\n"
00153     "along with this program; if not, write to the Free Software Foundation,\n"
00154     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00155                     fors_normalise_flat_create,
00156                     fors_normalise_flat_exec,
00157                     fors_normalise_flat_destroy);
00158 
00159     cpl_pluginlist_append(list, plugin);
00160     
00161     return 0;
00162 }
00163 
00164 
00175 static int fors_normalise_flat_create(cpl_plugin *plugin)
00176 {
00177     cpl_recipe    *recipe;
00178     cpl_parameter *p;
00179 
00180     /* 
00181      * Check that the plugin is part of a valid recipe 
00182      */
00183 
00184     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00185         recipe = (cpl_recipe *)plugin;
00186     else 
00187         return -1;
00188 
00189     /* 
00190      * Create the (empty) parameters list in the cpl_recipe object 
00191      */
00192 
00193     recipe->parameters = cpl_parameterlist_new(); 
00194 
00195     /*
00196      * Dispersion
00197      */
00198 
00199     p = cpl_parameter_new_value("fors.fors_normalise_flat.dispersion",
00200                                 CPL_TYPE_DOUBLE,
00201                                 "Expected spectral dispersion (Angstrom/pixel)",
00202                                 "fors.fors_normalise_flat",
00203                                 0.0);
00204     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
00205     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00206     cpl_parameterlist_append(recipe->parameters, p);
00207 
00208     /*
00209      * Start wavelength for spectral extraction
00210      */
00211 
00212     p = cpl_parameter_new_value("fors.fors_normalise_flat.startwavelength",
00213                                 CPL_TYPE_DOUBLE,
00214                                 "Start wavelength in spectral extraction",
00215                                 "fors.fors_normalise_flat",
00216                                 0.0);
00217     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
00218     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00219     cpl_parameterlist_append(recipe->parameters, p);
00220 
00221     /*
00222      * End wavelength for spectral extraction
00223      */
00224 
00225     p = cpl_parameter_new_value("fors.fors_normalise_flat.endwavelength",
00226                                 CPL_TYPE_DOUBLE,
00227                                 "End wavelength in spectral extraction",
00228                                 "fors.fors_normalise_flat",
00229                                 0.0);
00230     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
00231     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00232     cpl_parameterlist_append(recipe->parameters, p);
00233 
00234     /*
00235      * Degree of flat field fitting polynomial along spatial direction
00236      * (used for LSS data)
00237      */
00238 
00239     p = cpl_parameter_new_value("fors.fors_normalise_flat.sdegree",
00240                                 CPL_TYPE_INT,
00241                                 "Degree of flat field fitting polynomial "
00242                                 "along spatial direction (used for LSS "
00243                                 "data only)",
00244                                 "fors.fors_normalise_flat",
00245                                 4);
00246     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sdegree");
00247     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00248     cpl_parameterlist_append(recipe->parameters, p);
00249 
00250     /*
00251      * Degree of flat field fitting polynomial along dispersion direction
00252      * (used for MOS and MXU data)
00253      */
00254 
00255     p = cpl_parameter_new_value("fors.fors_normalise_flat.ddegree",
00256                                 CPL_TYPE_INT,
00257                                 "Degree of flat field fitting polynomial "
00258                                 "along dispersion direction (used for MOS "
00259                                 "and MXU data only)",
00260                                 "fors.fors_normalise_flat",
00261                                 -1);
00262     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ddegree");
00263     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00264     cpl_parameterlist_append(recipe->parameters, p);
00265 
00266     /*
00267      * Smooth box radius for flat field along dispersion direction
00268      */
00269 
00270     p = cpl_parameter_new_value("fors.fors_normalise_flat.dradius",
00271                                 CPL_TYPE_INT,
00272                                 "Smooth box radius for flat field along "
00273                                 "dispersion direction",
00274                                 "fors.fors_normalise_flat",
00275                                 10);
00276     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dradius");
00277     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00278     cpl_parameterlist_append(recipe->parameters, p);
00279 
00280     /*
00281      * Smooth box radius for flat field along spatial direction
00282      * (used for LSS data only)
00283      */
00284 
00285     p = cpl_parameter_new_value("fors.fors_normalise_flat.sradius",
00286                                 CPL_TYPE_INT,
00287                                 "Smooth box radius for flat field along "
00288                                 "spatial direction",
00289                                 "fors.fors_normalise_flat",
00290                                 10);
00291     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sradius");
00292     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00293     cpl_parameterlist_append(recipe->parameters, p);
00294 
00295     return 0;
00296 }
00297 
00298 
00307 static int fors_normalise_flat_exec(cpl_plugin *plugin)
00308 {
00309     cpl_recipe *recipe;
00310     
00311     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00312         recipe = (cpl_recipe *)plugin;
00313     else 
00314         return -1;
00315 
00316     return fors_normalise_flat(recipe->parameters, recipe->frames);
00317 }
00318 
00319 
00328 static int fors_normalise_flat_destroy(cpl_plugin *plugin)
00329 {
00330     cpl_recipe *recipe;
00331     
00332     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00333         recipe = (cpl_recipe *)plugin;
00334     else 
00335         return -1;
00336 
00337     cpl_parameterlist_delete(recipe->parameters); 
00338 
00339     return 0;
00340 }
00341 
00342 
00352 static int fors_normalise_flat(cpl_parameterlist *parlist, 
00353                                cpl_frameset *frameset)
00354 {
00355 
00356     const char *recipe = "fors_normalise_flat";
00357 
00358 
00359     /*
00360      * Input parameters
00361      */
00362 
00363     double      dispersion;
00364     double      startwavelength;
00365     double      endwavelength;
00366     int         sdegree;
00367     int         ddegree;
00368     int         sradius;
00369     int         dradius;
00370 
00371     /*
00372      * CPL objects
00373      */
00374 
00375     cpl_image        *master_flat = NULL;
00376     cpl_image        *smo_flat    = NULL;
00377     cpl_image        *coordinate  = NULL;
00378     cpl_image        *spatial     = NULL;
00379     cpl_table        *grism_table = NULL;
00380     cpl_table        *slits       = NULL;
00381     cpl_table        *polytraces  = NULL;
00382     cpl_table        *maskslits   = NULL;
00383     cpl_propertylist *header      = NULL;
00384 
00385     /*
00386      * Auxiliary variables
00387      */
00388 
00389     char        version[80];
00390     const char *master_flat_tag;
00391     const char *master_norm_flat_tag;
00392     const char *slit_location_tag;
00393     const char *curv_coeff_tag;
00394     int         mxu, mos, lss;
00395     int         nflat;
00396     int         rebin;
00397     int         nx, ny;
00398     int         nslits;
00399     int         treat_as_lss;
00400     int         i;
00401     double      reference;
00402     double     *xpos;
00403     double      mxpos;
00404 
00405     char       *instrume = NULL;
00406 
00407 
00408     cpl_msg_set_indentation(2);
00409 
00410     if (dfs_files_dont_exist(frameset))
00411         fors_normalise_flat_exit(NULL);
00412 
00413 
00414     /*
00415      * Get configuration parameters
00416      */
00417 
00418     cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00419     cpl_msg_indent_more();
00420     
00421     if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00422         fors_normalise_flat_exit("Too many in input: GRISM_TABLE"); 
00423 
00424     grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00425 
00426     dispersion = dfs_get_parameter_double(parlist,
00427                     "fors.fors_normalise_flat.dispersion", grism_table);
00428 
00429     if (dispersion <= 0.0)
00430         fors_normalise_flat_exit("Invalid spectral dispersion value");
00431 
00432     startwavelength = dfs_get_parameter_double(parlist,
00433                     "fors.fors_normalise_flat.startwavelength", grism_table);
00434     if (startwavelength > 1.0)
00435         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00436             fors_normalise_flat_exit("Invalid wavelength");
00437 
00438     endwavelength = dfs_get_parameter_double(parlist,
00439                     "fors.fors_normalise_flat.endwavelength", grism_table);
00440     if (endwavelength > 1.0) {
00441         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00442             fors_normalise_flat_exit("Invalid wavelength");
00443         if (startwavelength < 1.0)
00444             fors_normalise_flat_exit("Invalid wavelength interval");
00445     }
00446 
00447     if (startwavelength > 1.0)
00448         if (endwavelength - startwavelength <= 0.0)
00449             fors_normalise_flat_exit("Invalid wavelength interval");
00450 
00451     sdegree = dfs_get_parameter_int(parlist, 
00452                                     "fors.fors_normalise_flat.sdegree", NULL);
00453     ddegree = dfs_get_parameter_int(parlist, 
00454                                     "fors.fors_normalise_flat.ddegree", NULL);
00455     sradius = dfs_get_parameter_int(parlist, 
00456                                     "fors.fors_normalise_flat.sradius", NULL);
00457     dradius = dfs_get_parameter_int(parlist, 
00458                                     "fors.fors_normalise_flat.dradius", NULL);
00459 
00460     if (sradius < 1 || dradius < 1)
00461         fors_normalise_flat_exit("Invalid smoothing box radius");
00462 
00463     cpl_table_delete(grism_table); grism_table = NULL;
00464 
00465     if (cpl_error_get_code())
00466         fors_normalise_flat_exit("Failure reading the configuration "
00467                                  "parameters");
00468 
00469 
00470     cpl_msg_indent_less();
00471     cpl_msg_info(recipe, "Check input set-of-frames:");
00472     cpl_msg_indent_more();
00473 
00474     nflat  = mxu = cpl_frameset_count_tags(frameset, "MASTER_SCREEN_FLAT_MXU");
00475     nflat += mos = cpl_frameset_count_tags(frameset, "MASTER_SCREEN_FLAT_MOS");
00476     nflat += lss = cpl_frameset_count_tags(frameset, "MASTER_SCREEN_FLAT_LSS");
00477 
00478     if (nflat == 0) {
00479         fors_normalise_flat_exit("Missing input master flat field frame");
00480     }
00481     if (nflat > 1) {
00482         cpl_msg_error(recipe, "Too many input flat frames (%d > 1)", nflat);
00483         fors_normalise_flat_exit(NULL);
00484     }
00485 
00486     if (mxu) {
00487         master_flat_tag      = "MASTER_SCREEN_FLAT_MXU";
00488         master_norm_flat_tag = "MASTER_NORM_FLAT_MXU";
00489         slit_location_tag    = "SLIT_LOCATION_MXU";
00490         curv_coeff_tag       = "CURV_COEFF_MXU";
00491     }
00492     else if (mos) {
00493         master_flat_tag      = "MASTER_SCREEN_FLAT_MOS";
00494         master_norm_flat_tag = "MASTER_NORM_FLAT_MOS";
00495         slit_location_tag    = "SLIT_LOCATION_MOS";
00496         curv_coeff_tag       = "CURV_COEFF_MOS";
00497     }
00498     else if (lss) {
00499         master_flat_tag      = "MASTER_SCREEN_FLAT_LSS";
00500         master_norm_flat_tag = "MASTER_NORM_FLAT_LSS";
00501     }
00502 
00503     header = dfs_load_header(frameset, master_flat_tag, 0);
00504 
00505     if (mos || mxu) {
00506         if (mos)
00507             maskslits = mos_load_slits_fors_mos(header);
00508         else
00509             maskslits = mos_load_slits_fors_mxu(header);
00510 
00511         /*
00512          * Check if all slits have the same X offset: in such case,
00513          * treat the observation as a long-slit one!
00514          */
00515 
00516         mxpos = cpl_table_get_column_median(maskslits, "xtop");
00517         xpos = cpl_table_get_data_double(maskslits, "xtop");
00518         nslits = cpl_table_get_nrow(maskslits);
00519 
00520         treat_as_lss = 1;
00521         for (i = 0; i < nslits; i++) {
00522             if (fabs(mxpos-xpos[i]) > 0.01) {
00523                 treat_as_lss = 0;
00524                 break;
00525             }
00526         }
00527 
00528         cpl_table_delete(maskslits); maskslits = NULL;
00529 
00530         if (treat_as_lss)
00531             cpl_msg_warning(recipe, "All MOS slits have the same offset: %.2f\n"
00532                             "The LSS data reduction strategy is applied!",
00533                             mxpos);
00534     }
00535 
00536     if (!(lss || treat_as_lss)) {
00537         if (cpl_frameset_count_tags(frameset, curv_coeff_tag) == 0) {
00538             cpl_msg_error(recipe, "Missing input: %s", curv_coeff_tag);
00539             fors_normalise_flat_exit(NULL);
00540         }
00541 
00542         if (cpl_frameset_count_tags(frameset, curv_coeff_tag) > 1) {
00543             cpl_msg_error(recipe, "Too many in input: %s", curv_coeff_tag);
00544             fors_normalise_flat_exit(NULL);
00545         }
00546 
00547         if (cpl_frameset_count_tags(frameset, slit_location_tag) == 0) {
00548             cpl_msg_error(recipe, "Missing input: %s", slit_location_tag);
00549             fors_normalise_flat_exit(NULL);
00550         }
00551 
00552         if (cpl_frameset_count_tags(frameset, slit_location_tag) > 1) {
00553             cpl_msg_error(recipe, "Too many in input: %s", slit_location_tag);
00554             fors_normalise_flat_exit(NULL);
00555         }
00556     }
00557 
00558     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00559         fors_normalise_flat_exit("Input frames are not from the same grism");
00560 
00561     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00562         fors_normalise_flat_exit("Input frames are not from the same filter");
00563 
00564     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00565         fors_normalise_flat_exit("Input frames are not from the same chip");
00566 
00567 
00568     /*
00569      * Get the reference wavelength and the rebin factor along the
00570      * dispersion direction from the master flat frame
00571      */
00572 
00573     if (header == NULL)
00574         fors_normalise_flat_exit("Cannot load master flat frame header");
00575 
00576     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00577     if (instrume == NULL)
00578         fors_normalise_flat_exit("Missing keyword INSTRUME in master "
00579                                  "flat header");
00580 
00581     if (instrume[4] == '1')
00582         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00583     if (instrume[4] == '2')
00584         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00585 
00586     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00587 
00588     if (cpl_error_get_code() != CPL_ERROR_NONE)
00589         fors_normalise_flat_exit("Missing keyword ESO INS GRIS1 WLEN "
00590                                  "in master flat frame header");
00591 
00592     if (reference < 3000.0)   /* Perhaps in nanometers... */
00593         reference *= 10;
00594 
00595     if (reference < 3000.0 || reference > 13000.0) {
00596         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00597                       "keyword ESO INS GRIS1 WLEN in master flat header",
00598                       reference);
00599         fors_normalise_flat_exit(NULL);
00600     }
00601 
00602     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00603 
00604     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00605 
00606     if (cpl_error_get_code() != CPL_ERROR_NONE)
00607         fors_normalise_flat_exit("Missing keyword ESO DET WIN1 BINX "
00608                                  "in master flat header");
00609 
00610     if (rebin != 1) {
00611         dispersion *= rebin;
00612         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00613                         "working dispersion used is %f A/pixel", rebin,
00614                         dispersion);
00615     }
00616 
00617 
00618     cpl_msg_indent_less();
00619     cpl_msg_info(recipe, "Load input frames...");
00620     cpl_msg_indent_more();
00621 
00622     master_flat = dfs_load_image(frameset, master_flat_tag, 
00623                                  CPL_TYPE_FLOAT, 0, 0);
00624     if (master_flat == NULL)
00625         fors_normalise_flat_exit("Cannot load master flat field frame");
00626 
00627 
00628     cpl_msg_indent_less();
00629     cpl_msg_info(recipe, "Perform flat field normalisation...");
00630     cpl_msg_indent_more();
00631 
00632     if (lss || treat_as_lss) {
00633 
00634         /* FIXME:
00635          * The LSS data calibration is still dirty: it doesn't apply
00636          * any spatial rectification, and only in future an external
00637          * spectral curvature model would be provided in input. Here
00638          * and there temporary solutions are adpted, such as accepting
00639          * the preliminary wavelength calibration.
00640          */
00641 
00642         /*
00643          * Flat field normalisation is done directly on the master flat
00644          * field (without spatial rectification first). The spectral
00645          * curvature model may be provided in input, in future releases.
00646          */
00647 
00648         smo_flat = mos_normalise_longflat(master_flat, 
00649                                           sradius, dradius, sdegree);
00650 
00651         cpl_image_delete(smo_flat); smo_flat = NULL; /* It may be a product */
00652 
00653         if (dfs_save_image(frameset, master_flat, master_norm_flat_tag,
00654                            header, parlist, recipe, version))
00655             fors_normalise_flat_exit(NULL);
00656 
00657         cpl_propertylist_delete(header); header = NULL;
00658         cpl_image_delete(master_flat); master_flat = NULL;
00659 
00660         return 0;
00661     }
00662 
00663 
00664     /*
00665      * This is the generic MOS/MXU handling
00666      */
00667 
00668     slits = dfs_load_table(frameset, slit_location_tag, 1);
00669     if (slits == NULL)
00670         fors_normalise_flat_exit("Cannot load slits location table");
00671 
00672     polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00673     if (slits == NULL)
00674         fors_normalise_flat_exit("Cannot load spectral curvature table");
00675 
00676     nx = cpl_image_get_size_x(master_flat);
00677     ny = cpl_image_get_size_y(master_flat);
00678 
00679     coordinate = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00680     spatial = mos_spatial_calibration(master_flat, slits, polytraces, 
00681                                       reference,
00682                                       startwavelength, endwavelength,
00683                                       dispersion, 0, coordinate);
00684 
00685     cpl_image_delete(spatial); spatial = NULL;
00686 
00687     smo_flat = mos_normalise_flat(master_flat, coordinate, slits, polytraces,
00688                                   reference, startwavelength, endwavelength,
00689                                   dispersion, dradius, ddegree);
00690 
00691     cpl_image_delete(smo_flat); smo_flat = NULL;  /* It may be a product */
00692     cpl_image_delete(coordinate); coordinate = NULL;
00693     cpl_table_delete(polytraces); polytraces = NULL;
00694     cpl_table_delete(slits); slits = NULL;
00695 
00696     if (dfs_save_image(frameset, master_flat, master_norm_flat_tag,
00697                        header, parlist, recipe, version))
00698         fors_normalise_flat_exit(NULL);
00699 
00700     cpl_propertylist_delete(header); header = NULL;
00701     cpl_image_delete(master_flat); master_flat = NULL;
00702 
00703     return 0;
00704 }

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