fors_trace_flat.c

00001 /* $Id: fors_trace_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_trace_flat_create(cpl_plugin *);
00038 static int fors_trace_flat_exec(cpl_plugin *);
00039 static int fors_trace_flat_destroy(cpl_plugin *);
00040 static int fors_trace_flat(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_trace_flat_description[] =
00043 "This recipe is used to trace the edges of MOS/MXU flat field slit spectra\n"
00044 "and determine the spectral curvature solution. The input master flat field\n"
00045 "image, product of the recipe fors_flat, is expected to be oriented with\n"
00046 "horizontal dispersion direction and red wavelengths on the right side.\n"
00047 "The input slits location table should be the product of the recipe\n"
00048 "fors_detect_spectra.\n"
00049 "\n"
00050 "The input master flat image is shifted one pixel down and is subtracted\n"
00051 "from the original image. The result is a vertical gradient map. Next,\n"
00052 "the negative values are forced positive, to obtain an absolute gradient\n"
00053 "map. The map is passed with a horizontal median filter, and after that\n"
00054 "the gradient peaks are traced starting from the slits positions listed\n"
00055 "in the input slits location table. The number of pixels to the left and\n"
00056 "to the right of the reference pixel is trivially derived from the specified\n"
00057 "spectral range and spectral dispersion.\n"
00058 "\n"
00059 "The output spectral curvature table contains the coefficients of the\n"
00060 "polynomial fitting of the found traces, while the output trace table\n"
00061 "contains the traced spectral edges positions in CCD (Y) coordinates for\n"
00062 "each spectrum, and their comparison with their modeling. A spatial map\n"
00063 "is also created, where to each CCD pixel is assigned the value of the\n"
00064 "spatial coordinate along the slit (in pixel). For more details please\n"
00065 "refer to the FORS Pipeline User's Manual.\n"
00066 "\n"
00067 "Note that specifying an input GRISM_TABLE will set some of the recipe\n"
00068 "configuration parameters to default values valid for a particular grism.\n"
00069 "Again, see the pipeline manual for more details.\n"
00070 "\n"
00071 "In the table below the MXU acronym can be alternatively read as MOS.\n\n"
00072 "Input files:\n\n"
00073 "  DO category:               Type:       Explanation:         Required:\n"
00074 "  MASTER_SCREEN_FLAT_MXU     Calib       Master flat frame       Y\n"
00075 "  SLIT_LOCATION_DETECT_MXU   Calib       Slits location          Y\n"
00076 "  GRISM_TABLE                Calib       Grism table             .\n\n"
00077 "Output files:\n\n"
00078 "  DO category:               Data type:  Explanation:\n"
00079 "  CURV_TRACES_MXU            FITS table  Flat field tracings\n"
00080 "  CURV_COEFF_MXU             FITS table  Spectral curvature table\n"
00081 "  SPATIAL_MAP_MXU            FITS image  Map of spatial coordinate\n\n";
00082 
00083 #define fors_trace_flat_exit(message)         \
00084 {                                             \
00085 if (message) cpl_msg_error(recipe, message);  \
00086 cpl_image_delete(master_flat);                \
00087 cpl_image_delete(spatial);                    \
00088 cpl_image_delete(coordinate);                 \
00089 cpl_table_delete(grism_table);                \
00090 cpl_table_delete(maskslits);                  \
00091 cpl_table_delete(slits);                      \
00092 cpl_table_delete(traces);                     \
00093 cpl_table_delete(polytraces);                 \
00094 cpl_propertylist_delete(header);              \
00095 cpl_msg_indent_less();                        \
00096 return -1;                                    \
00097 }
00098 
00099 #define fors_trace_flat_exit_memcheck(message)  \
00100 {                                               \
00101 if (message) cpl_msg_info(recipe, message);     \
00102 printf("free master_flat (%p)\n", master_flat); \
00103 cpl_image_delete(master_flat);                  \
00104 printf("free spatial (%p)\n", spatial);         \
00105 cpl_image_delete(spatial);                      \
00106 printf("free coordinate (%p)\n", coordinate);   \
00107 cpl_image_delete(coordinate);                   \
00108 printf("free grism_table (%p)\n", grism_table); \
00109 cpl_table_delete(grism_table);                  \
00110 printf("free maskslits (%p)\n", maskslits);     \
00111 cpl_table_delete(maskslits);                    \
00112 printf("free slits (%p)\n", slits);             \
00113 cpl_table_delete(slits);                        \
00114 printf("free traces (%p)\n", traces);           \
00115 cpl_table_delete(traces);                       \
00116 printf("free polytraces (%p)\n", polytraces);   \
00117 cpl_table_delete(polytraces);                   \
00118 printf("free header (%p)\n", header);           \
00119 cpl_propertylist_delete(header);                \
00120 cpl_msg_indent_less();                          \
00121 return 0;                                       \
00122 }
00123 
00124 
00136 int cpl_plugin_get_info(cpl_pluginlist *list)
00137 {
00138     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00139     cpl_plugin *plugin = &recipe->interface;
00140 
00141     cpl_plugin_init(plugin,
00142                     CPL_PLUGIN_API,
00143                     FORS_BINARY_VERSION,
00144                     CPL_PLUGIN_TYPE_RECIPE,
00145                     "fors_trace_flat",
00146                     "Determine spectral curvature model",
00147                     fors_trace_flat_description,
00148                     "Carlo Izzo",
00149                     PACKAGE_BUGREPORT,
00150     "This file is currently part of the FORS Instrument Pipeline\n"
00151     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00152     "This program is free software; you can redistribute it and/or modify\n"
00153     "it under the terms of the GNU General Public License as published by\n"
00154     "the Free Software Foundation; either version 2 of the License, or\n"
00155     "(at your option) any later version.\n\n"
00156     "This program is distributed in the hope that it will be useful,\n"
00157     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00158     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00159     "GNU General Public License for more details.\n\n"
00160     "You should have received a copy of the GNU General Public License\n"
00161     "along with this program; if not, write to the Free Software Foundation,\n"
00162     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00163                     fors_trace_flat_create,
00164                     fors_trace_flat_exec,
00165                     fors_trace_flat_destroy);
00166 
00167     cpl_pluginlist_append(list, plugin);
00168     
00169     return 0;
00170 }
00171 
00172 
00183 static int fors_trace_flat_create(cpl_plugin *plugin)
00184 {
00185     cpl_recipe    *recipe;
00186     cpl_parameter *p;
00187 
00188     /* 
00189      * Check that the plugin is part of a valid recipe 
00190      */
00191 
00192     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00193         recipe = (cpl_recipe *)plugin;
00194     else 
00195         return -1;
00196 
00197     /* 
00198      * Create the (empty) parameters list in the cpl_recipe object 
00199      */
00200 
00201     recipe->parameters = cpl_parameterlist_new(); 
00202 
00203     /*
00204      * Dispersion
00205      */
00206 
00207     p = cpl_parameter_new_value("fors.fors_trace_flat.dispersion",
00208                                 CPL_TYPE_DOUBLE,
00209                                 "Expected spectral dispersion (Angstrom/pixel)",
00210                                 "fors.fors_trace_flat",
00211                                 0.0);
00212     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
00213     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00214     cpl_parameterlist_append(recipe->parameters, p);
00215 
00216     /*
00217      * Start wavelength for spectral extraction
00218      */
00219 
00220     p = cpl_parameter_new_value("fors.fors_trace_flat.startwavelength",
00221                                 CPL_TYPE_DOUBLE,
00222                                 "Start wavelength in spectral extraction",
00223                                 "fors.fors_trace_flat",
00224                                 0.0);
00225     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
00226     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00227     cpl_parameterlist_append(recipe->parameters, p);
00228 
00229     /*
00230      * End wavelength for spectral extraction
00231      */
00232 
00233     p = cpl_parameter_new_value("fors.fors_trace_flat.endwavelength",
00234                                 CPL_TYPE_DOUBLE,
00235                                 "End wavelength in spectral extraction",
00236                                 "fors.fors_trace_flat",
00237                                 0.0);
00238     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
00239     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00240     cpl_parameterlist_append(recipe->parameters, p);
00241 
00242     /*
00243      * Degree of spectral curvature polynomial
00244      */
00245 
00246     p = cpl_parameter_new_value("fors.fors_trace_flat.cdegree",
00247                                 CPL_TYPE_INT,
00248                                 "Degree of spectral curvature polynomial",
00249                                 "fors.fors_trace_flat",
00250                                 0);
00251     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cdegree");
00252     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00253     cpl_parameterlist_append(recipe->parameters, p);
00254 
00255     /*
00256      * Curvature solution interpolation (for MOS-like data)
00257      */
00258 
00259     p = cpl_parameter_new_value("fors.fors_trace_flat.cmode",
00260                                 CPL_TYPE_INT,
00261                                 "Interpolation mode of curvature solution "
00262                                 "applicable to MOS-like data (0 = no "
00263                                 "interpolation, 1 = fill gaps, 2 = global "
00264                                 "model)",
00265                                 "fors.fors_trace_flat",
00266                                 1);
00267     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "cmode");
00268     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00269     cpl_parameterlist_append(recipe->parameters, p);
00270 
00271     return 0;
00272 }
00273 
00274 
00283 static int fors_trace_flat_exec(cpl_plugin *plugin)
00284 {
00285     cpl_recipe *recipe;
00286     
00287     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00288         recipe = (cpl_recipe *)plugin;
00289     else 
00290         return -1;
00291 
00292     return fors_trace_flat(recipe->parameters, recipe->frames);
00293 }
00294 
00295 
00304 static int fors_trace_flat_destroy(cpl_plugin *plugin)
00305 {
00306     cpl_recipe *recipe;
00307     
00308     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00309         recipe = (cpl_recipe *)plugin;
00310     else 
00311         return -1;
00312 
00313     cpl_parameterlist_delete(recipe->parameters); 
00314 
00315     return 0;
00316 }
00317 
00318 
00328 static int fors_trace_flat(cpl_parameterlist *parlist, 
00329                                cpl_frameset *frameset)
00330 {
00331 
00332     const char *recipe = "fors_trace_flat";
00333 
00334 
00335     /*
00336      * Input parameters
00337      */
00338 
00339     double      dispersion;
00340     double      startwavelength;
00341     double      endwavelength;
00342     int         cdegree;
00343     int         cmode;
00344 
00345     /*
00346      * CPL objects
00347      */
00348 
00349     cpl_image        *master_flat = NULL;
00350     cpl_image        *coordinate  = NULL;
00351     cpl_image        *spatial     = NULL;
00352     cpl_table        *grism_table = NULL;
00353     cpl_table        *maskslits   = NULL;
00354     cpl_table        *slits       = NULL;
00355     cpl_table        *traces      = NULL;
00356     cpl_table        *polytraces  = NULL;
00357     cpl_propertylist *header      = NULL;
00358 
00359     /*
00360      * Auxiliary variables
00361      */
00362 
00363     char        version[80];
00364     const char *master_flat_tag;
00365     const char *spatial_map_tag;
00366     const char *slit_detect_tag;
00367     const char *slit_location_tag;
00368     const char *curv_traces_tag;
00369     const char *curv_coeff_tag;
00370     int         flat_mxu;
00371     int         flat_mos;
00372     int         flat_lss;
00373     int         mxu, mos;
00374     int         nflat;
00375     int         nslits;
00376     int         rebin;
00377     int         nx, ny;
00378     int         treat_as_lss;
00379     int         i;
00380     double      reference;
00381     double     *xpos;
00382     double      mxpos;
00383 
00384     char       *instrume = NULL;
00385 
00386 
00387     cpl_msg_set_indentation(2);
00388 
00389     if (dfs_files_dont_exist(frameset))
00390         fors_trace_flat_exit(NULL);
00391 
00392 
00393     /*
00394      * Get configuration parameters
00395      */
00396 
00397     cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00398     cpl_msg_indent_more();
00399     
00400     if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00401         fors_trace_flat_exit("Too many in input: GRISM_TABLE"); 
00402 
00403     grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00404 
00405     dispersion = dfs_get_parameter_double(parlist,
00406                     "fors.fors_trace_flat.dispersion", grism_table);
00407 
00408     if (dispersion <= 0.0)
00409         fors_trace_flat_exit("Invalid spectral dispersion value");
00410 
00411     startwavelength = dfs_get_parameter_double(parlist,
00412                     "fors.fors_trace_flat.startwavelength", grism_table);
00413     if (startwavelength > 1.0)
00414         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00415             fors_trace_flat_exit("Invalid wavelength");
00416 
00417     endwavelength = dfs_get_parameter_double(parlist,
00418                     "fors.fors_trace_flat.endwavelength", grism_table);
00419     if (endwavelength > 1.0) {
00420         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00421             fors_trace_flat_exit("Invalid wavelength");
00422         if (startwavelength < 1.0)
00423             fors_trace_flat_exit("Invalid wavelength interval");
00424     }
00425 
00426     if (startwavelength > 1.0)
00427         if (endwavelength - startwavelength <= 0.0)
00428             fors_trace_flat_exit("Invalid wavelength interval");
00429 
00430     cdegree = dfs_get_parameter_int(parlist,
00431                     "fors.fors_trace_flat.cdegree", grism_table);
00432 
00433     if (cdegree < 1)
00434         fors_trace_flat_exit("Invalid polynomial degree");
00435 
00436     if (cdegree > 5)
00437         fors_trace_flat_exit("Max allowed polynomial degree is 5");
00438 
00439     cmode = dfs_get_parameter_int(parlist, "fors.fors_trace_flat.cmode", NULL);
00440 
00441     if (cmode < 0 || cmode > 2)
00442         fors_trace_flat_exit("Invalid curvature solution interpolation mode");
00443 
00444     cpl_table_delete(grism_table); grism_table = NULL;
00445 
00446     if (cpl_error_get_code())
00447         fors_trace_flat_exit("Failure reading the configuration parameters");
00448 
00449 
00450     cpl_msg_indent_less();
00451     cpl_msg_info(recipe, "Check input set-of-frames:");
00452     cpl_msg_indent_more();
00453 
00454     nflat  = flat_mxu = cpl_frameset_count_tags(frameset, 
00455                                                 "MASTER_SCREEN_FLAT_MXU");
00456     nflat += flat_mos = cpl_frameset_count_tags(frameset, 
00457                                                 "MASTER_SCREEN_FLAT_MOS");
00458     nflat += flat_lss = cpl_frameset_count_tags(frameset, 
00459                                                 "MASTER_SCREEN_FLAT_LSS");
00460 
00461     if (nflat == 0) {
00462         fors_trace_flat_exit("Missing input master flat field frame");
00463     }
00464     if (nflat > 1) {
00465         cpl_msg_error(recipe, "Too many input flat frames (%d > 1)", nflat);
00466         fors_trace_flat_exit(NULL);
00467     }
00468 
00469     mxu = mos = 0;
00470 
00471     if (flat_mxu) {
00472         mxu = 1;
00473         master_flat_tag   = "MASTER_SCREEN_FLAT_MXU";
00474         slit_detect_tag   = "SLIT_LOCATION_DETECT_MXU";
00475         slit_location_tag = "SLIT_LOCATION_MXU";
00476         curv_traces_tag   = "CURV_TRACES_MXU";
00477         curv_coeff_tag    = "CURV_COEFF_MXU";
00478         spatial_map_tag   = "SPATIAL_MAP_MXU";
00479     }
00480     else if (flat_mos) {
00481         mos = 1;
00482         master_flat_tag   = "MASTER_SCREEN_FLAT_MOS";
00483         slit_detect_tag   = "SLIT_LOCATION_DETECT_MOS";
00484         slit_location_tag = "SLIT_LOCATION_MOS";
00485         curv_traces_tag   = "CURV_TRACES_MOS";
00486         curv_coeff_tag    = "CURV_COEFF_MOS";
00487         spatial_map_tag   = "SPATIAL_MAP_MOS";
00488     }
00489     else if (flat_lss) {
00490         fors_trace_flat_exit("LSS spectra are not traceable: use this recipe "
00491                              "just for MOS/MXU data.");
00492     }
00493 
00494     if (cpl_frameset_count_tags(frameset, slit_detect_tag) == 0) {
00495         cpl_msg_error(recipe, "Missing required input: %s", slit_detect_tag);
00496         fors_trace_flat_exit(NULL);
00497     }
00498 
00499     if (cpl_frameset_count_tags(frameset, slit_detect_tag) > 1) {
00500         cpl_msg_error(recipe, "Too many in input: %s", slit_detect_tag);
00501         fors_trace_flat_exit(NULL);
00502     }
00503 
00504     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00505         fors_trace_flat_exit("Input frames are not from the same grism");
00506 
00507     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00508         fors_trace_flat_exit("Input frames are not from the same filter");
00509 
00510     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00511         fors_trace_flat_exit("Input frames are not from the same chip");
00512 
00513 
00514     /*
00515      * Get the reference wavelength and the rebin factor along the
00516      * dispersion direction from the master flat frame
00517      */
00518 
00519     header = dfs_load_header(frameset, master_flat_tag, 0);
00520 
00521     if (header == NULL)
00522         fors_trace_flat_exit("Cannot load master flat frame header");
00523 
00524     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00525     if (instrume == NULL)
00526         fors_trace_flat_exit("Missing keyword INSTRUME in master flat header");
00527 
00528     if (instrume[4] == '1')
00529         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00530     if (instrume[4] == '2')
00531         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00532 
00533     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00534 
00535     if (cpl_error_get_code() != CPL_ERROR_NONE)
00536         fors_trace_flat_exit("Missing keyword ESO INS GRIS1 WLEN "
00537                                  "in master flat frame header");
00538 
00539     if (reference < 3000.0)   /* Perhaps in nanometers... */
00540         reference *= 10;
00541 
00542     if (reference < 3000.0 || reference > 13000.0) {
00543         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00544                       "keyword ESO INS GRIS1 WLEN in master flat header",
00545                       reference);
00546         fors_trace_flat_exit(NULL);
00547     }
00548 
00549     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00550 
00551     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00552 
00553     if (cpl_error_get_code() != CPL_ERROR_NONE)
00554         fors_trace_flat_exit("Missing keyword ESO DET WIN1 BINX "
00555                                  "in master flat header");
00556 
00557     if (rebin != 1) {
00558         dispersion *= rebin;
00559         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00560                         "working dispersion used is %f A/pixel", rebin,
00561                         dispersion);
00562     }
00563 
00564 
00565     /*
00566      * Check if all slits have the same X offset: in such case, abort!
00567      */
00568 
00569     if (mos)
00570         maskslits = mos_load_slits_fors_mos(header);
00571     else
00572         maskslits = mos_load_slits_fors_mxu(header);
00573 
00574     mxpos = cpl_table_get_column_median(maskslits, "xtop");
00575     xpos = cpl_table_get_data_double(maskslits, "xtop");
00576     nslits = cpl_table_get_nrow(maskslits);
00577 
00578     treat_as_lss = 1;
00579     for (i = 0; i < nslits; i++) {
00580         if (fabs(mxpos-xpos[i]) > 0.01) {
00581             treat_as_lss = 0;
00582             break;
00583         }
00584     }
00585 
00586     if (treat_as_lss) {
00587         cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00588                       "Spectra are not traceable: the LSS data reduction\n"
00589                       "strategy must be applied.", mxpos);
00590         fors_trace_flat_exit(NULL);
00591     }
00592 
00593     cpl_table_delete(maskslits); maskslits = NULL;
00594 
00595 
00596     cpl_msg_indent_less();
00597     cpl_msg_info(recipe, "Load input frames...");
00598     cpl_msg_indent_more();
00599 
00600     master_flat = dfs_load_image(frameset, master_flat_tag, 
00601                                  CPL_TYPE_FLOAT, 0, 0);
00602     if (master_flat == NULL)
00603         fors_trace_flat_exit("Cannot load master flat field frame");
00604 
00605     slits = dfs_load_table(frameset, slit_detect_tag, 1);
00606     if (slits == NULL)
00607         fors_trace_flat_exit("Cannot load slits location table");
00608 
00609 
00610     cpl_msg_indent_less();
00611     cpl_msg_info(recipe, "Determining spectral curvature...");
00612     cpl_msg_indent_more();
00613 
00614     cpl_msg_info(recipe, "Tracing master flat field spectra edges...");
00615     traces = mos_trace_flat(master_flat, slits, reference,
00616                             startwavelength, endwavelength, dispersion);
00617 
00618     if (!traces)
00619         fors_trace_flat_exit("Tracing failure");
00620 
00621     cpl_msg_info(recipe, "Fitting flat field spectra edges...");
00622     polytraces = mos_poly_trace(slits, traces, cdegree);
00623 
00624     if (!polytraces)
00625         fors_trace_flat_exit("Trace fitting failure");
00626 
00627     if (cmode) {
00628         cpl_msg_info(recipe, "Computing global spectral curvature model...");
00629         mos_global_trace(slits, polytraces, cmode);
00630     }
00631 
00632     if (dfs_save_table(frameset, traces, curv_traces_tag, NULL, parlist,
00633                        recipe, version))
00634         fors_trace_flat_exit(NULL);
00635 
00636     cpl_table_delete(traces); traces = NULL;
00637 
00638     nx = cpl_image_get_size_x(master_flat);
00639     ny = cpl_image_get_size_y(master_flat);
00640     coordinate = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00641 
00642     spatial = mos_spatial_calibration(master_flat, slits, polytraces, 
00643                                       reference,
00644                                       startwavelength, endwavelength,
00645                                       dispersion, 0, coordinate);
00646 
00647     cpl_image_delete(master_flat); master_flat = NULL;
00648     cpl_image_delete(spatial); spatial = NULL;
00649 
00650     if (dfs_save_image(frameset, coordinate, spatial_map_tag, header,
00651                        parlist, recipe, version))
00652         fors_trace_flat_exit(NULL);
00653 
00654     cpl_image_delete(coordinate); coordinate = NULL;
00655     cpl_propertylist_delete(header); header = NULL;
00656 
00657     if (dfs_save_table(frameset, slits, slit_location_tag, NULL,
00658                        parlist, recipe, version))
00659         fors_trace_flat_exit(NULL);
00660 
00661     cpl_table_delete(slits); slits = NULL;
00662 
00663     if (dfs_save_table(frameset, polytraces, curv_coeff_tag, NULL,
00664                        parlist, recipe, version))
00665         fors_trace_flat_exit(NULL);
00666 
00667     cpl_table_delete(polytraces); polytraces = NULL;
00668 
00669     return 0;
00670 }

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