fors_align_sky.c

00001 /* $Id: fors_align_sky.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_align_sky_create(cpl_plugin *);
00038 static int fors_align_sky_exec(cpl_plugin *);
00039 static int fors_align_sky_destroy(cpl_plugin *);
00040 static int fors_align_sky(cpl_parameterlist *, cpl_frameset *);
00041 
00042 static char fors_align_sky_description[] =
00043 "This recipe is used to align the wavelength solution based on the arc\n"
00044 "lamp exposure on a set of sky lines observed on a scientific exposure.\n"
00045 "The input rectified frames are produced by the recipe fors_extract_slits.\n"
00046 "An input catalog of sky lines can be specified, otherwise an internal one\n"
00047 "is used.\n"
00048 "\n"
00049 "This recipe should be applied to multi-slit MOS/MXU data: for LSS or\n"
00050 "long-slit like data (MOS/MXU with all slits at the same offset) use recipe\n"
00051 "fors_align_sky_lss instead. Please refer to the FORS Pipeline User's Manual\n"
00052 "for more details.\n"
00053 "\n"
00054 "In the table below the MXU acronym can be alternatively read as MOS, and\n"
00055 "SCI as STD.\n\n"
00056 "Input files:\n\n"
00057 "  DO category:               Type:       Explanation:         Required:\n"
00058 "  RECTIFIED_ALL_SCI_MXU\n"
00059 "  or RECTIFIED_SKY_SCI_MXU   Calib       Frame with sky lines    Y\n"
00060 "  SPATIAL_MAP_MXU            Calib       Spatial coordinate map  Y\n"
00061 "  CURV_COEFF_MXU             Calib       Spectral curvature      Y\n"
00062 "  SLIT_LOCATION_MXU          Calib       Slit location on CCD    Y\n"
00063 "  DISP_COEFF_MXU             Calib       Dispersion solution     Y\n"
00064 "  MASTER_SKYLINECAT          Calib       Catalog of sky lines    .\n"
00065 "  GRISM_TABLE                Calib       Grism table             .\n\n"
00066 "Output files:\n\n"
00067 "  DO category:               Data type:  Explanation:\n"
00068 "  SKY_SHIFTS_SLIT_SCI_MXU    FITS table  Observed sky lines offsets\n"
00069 "  WAVELENGTH_MAP_SCI_MXU     FITS image  Wavelength mapped on CCD\n"
00070 "  DISP_COEFF_SCI_MXU         FITS image  Upgraded dispersion solution\n\n";
00071 
00072 #define fors_align_sky_exit(message)          \
00073 {                                             \
00074 if (message) cpl_msg_error(recipe, message);  \
00075 cpl_image_delete(wavemap);                    \
00076 cpl_image_delete(coordinate);                 \
00077 cpl_image_delete(rainbow);                    \
00078 cpl_image_delete(smapped);                    \
00079 cpl_table_delete(grism_table);                \
00080 cpl_table_delete(maskslits);                  \
00081 cpl_table_delete(wavelengths);                \
00082 cpl_table_delete(offsets);                    \
00083 cpl_table_delete(slits);                      \
00084 cpl_table_delete(polytraces);                 \
00085 cpl_table_delete(idscoeff);                   \
00086 cpl_vector_delete(lines);                     \
00087 cpl_propertylist_delete(header);              \
00088 cpl_msg_indent_less();                        \
00089 return -1;                                    \
00090 }
00091 
00092 #define fors_align_sky_exit_memcheck(message)   \
00093 {                                               \
00094 if (message) cpl_msg_info(recipe, message);     \
00095 printf("free wavemap (%p)\n", wavemap);         \
00096 cpl_image_delete(wavemap);                      \
00097 printf("free coordinate (%p)\n", coordinate);   \
00098 cpl_image_delete(coordinate);                   \
00099 printf("free rainbow (%p)\n", rainbow);         \
00100 cpl_image_delete(rainbow);                      \
00101 printf("free smapped (%p)\n", smapped);         \
00102 cpl_image_delete(smapped);                      \
00103 printf("free grism_table (%p)\n", grism_table); \
00104 cpl_table_delete(grism_table);                  \
00105 printf("free maskslits (%p)\n", maskslits);     \
00106 cpl_table_delete(maskslits);                    \
00107 printf("free wavelengths (%p)\n", wavelengths); \
00108 cpl_table_delete(wavelengths);                  \
00109 printf("free offsets (%p)\n", offsets);         \
00110 cpl_table_delete(offsets);                      \
00111 printf("free idscoeff (%p)\n", idscoeff);       \
00112 cpl_table_delete(idscoeff);                     \
00113 printf("free slits (%p)\n", slits);             \
00114 cpl_table_delete(slits);                        \
00115 printf("free polytraces (%p)\n", polytraces);   \
00116 cpl_table_delete(polytraces);                   \
00117 printf("free lines (%p)\n", lines);             \
00118 cpl_vector_delete(lines);                       \
00119 printf("free header (%p)\n", header);           \
00120 cpl_propertylist_delete(header);                \
00121 cpl_msg_indent_less();                          \
00122 return 0;                                       \
00123 }
00124 
00125 
00137 int cpl_plugin_get_info(cpl_pluginlist *list)
00138 {
00139     cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00140     cpl_plugin *plugin = &recipe->interface;
00141 
00142     cpl_plugin_init(plugin,
00143                     CPL_PLUGIN_API,
00144                     FORS_BINARY_VERSION,
00145                     CPL_PLUGIN_TYPE_RECIPE,
00146                     "fors_align_sky",
00147                     "Upgrade wavelength solution using sky lines",
00148                     fors_align_sky_description,
00149                     "Carlo Izzo",
00150                     PACKAGE_BUGREPORT,
00151     "This file is currently part of the FORS Instrument Pipeline\n"
00152     "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00153     "This program is free software; you can redistribute it and/or modify\n"
00154     "it under the terms of the GNU General Public License as published by\n"
00155     "the Free Software Foundation; either version 2 of the License, or\n"
00156     "(at your option) any later version.\n\n"
00157     "This program is distributed in the hope that it will be useful,\n"
00158     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00159     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00160     "GNU General Public License for more details.\n\n"
00161     "You should have received a copy of the GNU General Public License\n"
00162     "along with this program; if not, write to the Free Software Foundation,\n"
00163     "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
00164                     fors_align_sky_create,
00165                     fors_align_sky_exec,
00166                     fors_align_sky_destroy);
00167 
00168     cpl_pluginlist_append(list, plugin);
00169     
00170     return 0;
00171 }
00172 
00173 
00184 static int fors_align_sky_create(cpl_plugin *plugin)
00185 {
00186     cpl_recipe    *recipe;
00187     cpl_parameter *p;
00188 
00189     /* 
00190      * Check that the plugin is part of a valid recipe 
00191      */
00192 
00193     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00194         recipe = (cpl_recipe *)plugin;
00195     else 
00196         return -1;
00197 
00198     /* 
00199      * Create the (empty) parameters list in the cpl_recipe object 
00200      */
00201 
00202     recipe->parameters = cpl_parameterlist_new(); 
00203 
00204     /*
00205      * Dispersion
00206      */
00207 
00208     p = cpl_parameter_new_value("fors.fors_align_sky.dispersion",
00209                                 CPL_TYPE_DOUBLE,
00210                                 "Expected spectral dispersion (Angstrom/pixel)",
00211                                 "fors.fors_align_sky",
00212                                 0.0);
00213     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion");
00214     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00215     cpl_parameterlist_append(recipe->parameters, p);
00216 
00217     /*
00218      * Start wavelength for spectral extraction
00219      */
00220 
00221     p = cpl_parameter_new_value("fors.fors_align_sky.startwavelength",
00222                                 CPL_TYPE_DOUBLE,
00223                                 "Start wavelength in spectral extraction",
00224                                 "fors.fors_align_sky",
00225                                 0.0);
00226     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength");
00227     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00228     cpl_parameterlist_append(recipe->parameters, p);
00229 
00230     /*
00231      * End wavelength for spectral extraction
00232      */
00233 
00234     p = cpl_parameter_new_value("fors.fors_align_sky.endwavelength",
00235                                 CPL_TYPE_DOUBLE,
00236                                 "End wavelength in spectral extraction",
00237                                 "fors.fors_align_sky",
00238                                 0.0);
00239     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength");
00240     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00241     cpl_parameterlist_append(recipe->parameters, p);
00242 
00243     /*
00244      * Sky lines alignment
00245      */
00246 
00247     p = cpl_parameter_new_value("fors.fors_align_sky.skyalign",
00248                                 CPL_TYPE_INT,
00249                                 "Polynomial order for sky lines alignment",
00250                                 "fors.fors_align_sky",
00251                                 0);
00252     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "skyalign");
00253     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00254     cpl_parameterlist_append(recipe->parameters, p);
00255 
00256     /*
00257      * Line catalog table column containing the sky reference wavelengths
00258      */
00259     
00260     p = cpl_parameter_new_value("fors.fors_align_sky.wcolumn",
00261                                 CPL_TYPE_STRING,
00262                                 "Name of sky line catalog table column "
00263                                 "with wavelengths",
00264                                 "fors.fors_align_sky",
00265                                 "WLEN");
00266     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wcolumn");
00267     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00268     cpl_parameterlist_append(recipe->parameters, p);
00269 
00270     return 0;
00271 }
00272 
00273 
00282 static int fors_align_sky_exec(cpl_plugin *plugin)
00283 {
00284     cpl_recipe *recipe;
00285     
00286     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00287         recipe = (cpl_recipe *)plugin;
00288     else 
00289         return -1;
00290 
00291     return fors_align_sky(recipe->parameters, recipe->frames);
00292 }
00293 
00294 
00303 static int fors_align_sky_destroy(cpl_plugin *plugin)
00304 {
00305     cpl_recipe *recipe;
00306     
00307     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
00308         recipe = (cpl_recipe *)plugin;
00309     else 
00310         return -1;
00311 
00312     cpl_parameterlist_delete(recipe->parameters); 
00313 
00314     return 0;
00315 }
00316 
00317 
00327 static int fors_align_sky(cpl_parameterlist *parlist, 
00328                                cpl_frameset *frameset)
00329 {
00330 
00331     const char *recipe = "fors_align_sky";
00332 
00333 
00334     /*
00335      * Input parameters
00336      */
00337 
00338     double      dispersion;
00339     double      startwavelength;
00340     double      endwavelength;
00341     int         skyalign;
00342     const char *wcolumn;
00343 
00344     /*
00345      * CPL objects
00346      */
00347 
00348     cpl_image        *rainbow     = NULL;
00349     cpl_image        *wavemap     = NULL;
00350     cpl_image        *smapped     = NULL;
00351     cpl_image        *coordinate  = NULL;
00352     cpl_table        *grism_table = NULL;
00353     cpl_table        *wavelengths = NULL;
00354     cpl_table        *slits       = NULL;
00355     cpl_table        *idscoeff    = NULL;
00356     cpl_table        *polytraces  = NULL;
00357     cpl_table        *maskslits   = NULL;
00358     cpl_table        *offsets     = NULL;
00359     cpl_vector       *lines       = NULL;
00360     cpl_propertylist *header      = NULL;
00361 
00362     /*
00363      * Auxiliary variables
00364      */
00365 
00366     char        version[80];
00367     const char *slit_location_tag;
00368     const char *curv_coeff_tag;
00369     const char *rectified_tag;
00370     const char *wavemap_tag;
00371     const char *shifts_tag;
00372     const char *disp_ali_tag;
00373     const char *disp_coeff_tag;
00374     const char *spatial_map_tag;
00375     int         nframes;
00376     int         rebin;
00377     int         nslits;
00378     int         nlines;
00379     int         nx;
00380     int         highres;
00381     int         treat_as_lss;
00382     int         i;
00383     double      reference;
00384     double     *xpos;
00385     double      mxpos;
00386     double     *line;
00387     int         mxu, mos;
00388     int         rec_scia;
00389     int         rec_stda;
00390     int         rec_scis;
00391     int         rec_stds;
00392 
00393     char       *instrume = NULL;
00394 
00395 
00396     cpl_msg_set_indentation(2);
00397 
00398     if (dfs_files_dont_exist(frameset))
00399         fors_align_sky_exit(NULL);
00400 
00401 
00402     /*
00403      * Get configuration parameters
00404      */
00405 
00406     cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00407     cpl_msg_indent_more();
00408     
00409     if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00410         fors_align_sky_exit("Too many in input: GRISM_TABLE"); 
00411 
00412     grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00413 
00414     dispersion = dfs_get_parameter_double(parlist,
00415                     "fors.fors_align_sky.dispersion", grism_table);
00416 
00417     if (dispersion <= 0.0)
00418         fors_align_sky_exit("Invalid spectral dispersion value");
00419 
00420     startwavelength = dfs_get_parameter_double(parlist,
00421                     "fors.fors_align_sky.startwavelength", grism_table);
00422     if (startwavelength > 1.0)
00423         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00424             fors_align_sky_exit("Invalid wavelength");
00425 
00426     endwavelength = dfs_get_parameter_double(parlist,
00427                     "fors.fors_align_sky.endwavelength", grism_table);
00428     if (endwavelength > 1.0) {
00429         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00430             fors_align_sky_exit("Invalid wavelength");
00431         if (startwavelength < 1.0)
00432             fors_align_sky_exit("Invalid wavelength interval");
00433     }
00434 
00435     if (startwavelength > 1.0)
00436         if (endwavelength - startwavelength <= 0.0)
00437             fors_align_sky_exit("Invalid wavelength interval");
00438 
00439     skyalign = dfs_get_parameter_int(parlist,
00440                     "fors.fors_align_sky.skyalign", NULL);
00441 
00442     if (skyalign < 0)
00443         fors_align_sky_exit("Invalid polynomial degree");
00444     if (skyalign > 2)
00445         fors_align_sky_exit("Max polynomial degree for sky alignment is 2");
00446 
00447     wcolumn = dfs_get_parameter_string(parlist,
00448                     "fors.fors_align_sky.wcolumn", NULL);
00449 
00450     cpl_table_delete(grism_table); grism_table = NULL;
00451 
00452     if (cpl_error_get_code())
00453         fors_align_sky_exit("Failure reading the configuration parameters");
00454 
00455 
00456     cpl_msg_indent_less();
00457     cpl_msg_info(recipe, "Check input set-of-frames:");
00458     cpl_msg_indent_more();
00459 
00460     mxu  = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MXU");
00461     mos  = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MOS");
00462 
00463     nframes = mos + mxu;
00464 
00465     if (nframes == 0) {
00466         fors_align_sky_exit("Missing input spatial map");
00467     }
00468     if (nframes > 1) {
00469         cpl_msg_error(recipe, 
00470                       "Too many input spatial maps (%d > 1)", nframes);
00471         fors_align_sky_exit(NULL);
00472     }
00473 
00474     if (mxu) {
00475         rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MXU");
00476         rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MXU");
00477         rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MXU");
00478         rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MXU");
00479     }
00480     else {
00481         rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MOS");
00482         rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MOS");
00483         rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MOS");
00484         rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MOS");
00485     }
00486 
00487     nframes = rec_scia + rec_stda + rec_scis + rec_stds;
00488 
00489     if (nframes == 0) {
00490         fors_align_sky_exit("Missing input rectified scientific spectra");
00491     }
00492     if (nframes > 1) {
00493         cpl_msg_error(recipe,
00494                       "Too many input rectified scientific spectra (%d > 1)", 
00495                       nframes);
00496         fors_align_sky_exit(NULL);
00497     }
00498 
00499     if (cpl_frameset_count_tags(frameset, "MASTER_SKYLINECAT") > 1)
00500         fors_align_sky_exit("Too many in input: MASTER_SKYLINECAT");
00501 
00502     if (rec_scia) {
00503         if (mxu) {
00504             rectified_tag = "RECTIFIED_ALL_SCI_MXU";
00505             wavemap_tag   = "WAVELENGTH_MAP_SCI_MXU";
00506             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MXU";
00507             disp_ali_tag  = "DISP_COEFF_SCI_MXU";
00508         }
00509         else {
00510             rectified_tag = "RECTIFIED_ALL_SCI_MOS";
00511             wavemap_tag   = "WAVELENGTH_MAP_SCI_MOS";
00512             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MOS";
00513             disp_ali_tag  = "DISP_COEFF_SCI_MOS";
00514         }
00515     }
00516     else if (rec_stda) {
00517         if (mxu) {
00518             rectified_tag = "RECTIFIED_ALL_STD_MXU";
00519             wavemap_tag   = "WAVELENGTH_MAP_STD_MXU";
00520             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MXU";
00521             disp_ali_tag  = "DISP_COEFF_STD_MXU";
00522         }
00523         else {
00524             rectified_tag = "RECTIFIED_ALL_STD_MOS";
00525             wavemap_tag   = "WAVELENGTH_MAP_STD_MOS";
00526             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MOS";
00527             disp_ali_tag  = "DISP_COEFF_STD_MOS";
00528         }
00529     }
00530     else if (rec_scis) {
00531         if (mxu) {
00532             rectified_tag = "RECTIFIED_SKY_SCI_MXU";
00533             wavemap_tag   = "WAVELENGTH_MAP_SCI_MXU";
00534             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MXU";
00535             disp_ali_tag  = "DISP_COEFF_SCI_MXU";
00536         }
00537         else {
00538             rectified_tag = "RECTIFIED_SKY_SCI_MOS";
00539             wavemap_tag   = "WAVELENGTH_MAP_SCI_MOS";
00540             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MOS";
00541             disp_ali_tag  = "DISP_COEFF_SCI_MOS";
00542         }
00543     }
00544     else if (rec_stds) {
00545         if (mxu) {
00546             rectified_tag = "RECTIFIED_SKY_STD_MXU";
00547             wavemap_tag   = "WAVELENGTH_MAP_STD_MXU";
00548             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MXU";
00549             disp_ali_tag  = "DISP_COEFF_STD_MXU";
00550         }
00551         else {
00552             rectified_tag = "RECTIFIED_SKY_STD_MOS";
00553             wavemap_tag   = "WAVELENGTH_MAP_STD_MOS";
00554             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MOS";
00555             disp_ali_tag  = "DISP_COEFF_STD_MOS";
00556         }
00557     }
00558 
00559 
00560     if (mxu) {
00561         disp_coeff_tag    = "DISP_COEFF_MXU";
00562         curv_coeff_tag    = "CURV_COEFF_MXU";
00563         slit_location_tag = "SLIT_LOCATION_MXU";
00564         spatial_map_tag   = "SPATIAL_MAP_MXU";
00565     }
00566     else {
00567         disp_coeff_tag    = "DISP_COEFF_MOS";
00568         curv_coeff_tag    = "CURV_COEFF_MOS";
00569         slit_location_tag = "SLIT_LOCATION_MOS";
00570         spatial_map_tag   = "SPATIAL_MAP_MOS";
00571     }
00572 
00573     nframes = cpl_frameset_count_tags(frameset, disp_coeff_tag);
00574 
00575     if (nframes == 0) {
00576         cpl_msg_error(recipe, "Missing input %s\n", disp_coeff_tag);
00577         fors_align_sky_exit(NULL);
00578     }
00579     if (nframes > 1) {
00580         cpl_msg_error(recipe, 
00581                       "Too many input %s (%d > 1)", disp_coeff_tag, nframes);
00582         fors_align_sky_exit(NULL);
00583     }
00584 
00585     nframes = cpl_frameset_count_tags(frameset, curv_coeff_tag);
00586 
00587     if (nframes == 0) {
00588         cpl_msg_error(recipe, "Missing input %s\n", curv_coeff_tag);
00589         fors_align_sky_exit(NULL);
00590     }
00591     if (nframes > 1) {
00592         cpl_msg_error(recipe,
00593                       "Too many input %s (%d > 1)", curv_coeff_tag, nframes);
00594         fors_align_sky_exit(NULL);
00595     }
00596 
00597     nframes = cpl_frameset_count_tags(frameset, spatial_map_tag);
00598 
00599     if (nframes == 0) {
00600         cpl_msg_error(recipe, "Missing input %s\n", spatial_map_tag);
00601         fors_align_sky_exit(NULL);
00602     }
00603     if (nframes > 1) {
00604         cpl_msg_error(recipe,
00605                       "Too many input %s (%d > 1)", spatial_map_tag, nframes);
00606         fors_align_sky_exit(NULL);
00607     }
00608     
00609 
00610     header = dfs_load_header(frameset, spatial_map_tag, 0);
00611 
00612     if (header == NULL)
00613         fors_align_sky_exit("Cannot load spatial map header");
00614 
00615     if (mos)
00616         maskslits = mos_load_slits_fors_mos(header);
00617     else
00618         maskslits = mos_load_slits_fors_mxu(header);
00619 
00620     /*
00621      * Check if all slits have the same X offset: in such case, abort!
00622      */
00623 
00624     mxpos = cpl_table_get_column_median(maskslits, "xtop");
00625     xpos = cpl_table_get_data_double(maskslits, "xtop");
00626     nslits = cpl_table_get_nrow(maskslits);
00627 
00628     treat_as_lss = 1;
00629     for (i = 0; i < nslits; i++) {
00630         if (fabs(mxpos-xpos[i]) > 0.01) {
00631             treat_as_lss = 0;
00632             break;
00633         }
00634     }
00635 
00636     cpl_table_delete(maskslits); maskslits = NULL;
00637 
00638     if (treat_as_lss) {
00639         cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00640                       "The LSS data reduction strategy must be applied. "
00641                       "Please use recipe fors_align_sky_lss.", mxpos);
00642         fors_align_sky_exit(NULL);
00643     }
00644 
00645     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00646         fors_align_sky_exit("Input frames are not from the same grism");
00647 
00648     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00649         fors_align_sky_exit("Input frames are not from the same filter");
00650 
00651     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00652         fors_align_sky_exit("Input frames are not from the same chip");
00653 
00654 
00655     /*
00656      * Get the reference wavelength and the rebin factor along the
00657      * dispersion direction from the reference frame
00658      */
00659 
00660     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00661     if (instrume == NULL)
00662         fors_align_sky_exit("Missing keyword INSTRUME in reference frame "
00663                             "header");
00664 
00665     if (instrume[4] == '1')
00666         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00667     if (instrume[4] == '2')
00668         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00669 
00670     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00671 
00672     if (cpl_error_get_code() != CPL_ERROR_NONE)
00673         fors_align_sky_exit("Missing keyword ESO INS GRIS1 WLEN "
00674                             "in reference frame header");
00675 
00676     if (reference < 3000.0)   /* Perhaps in nanometers... */
00677         reference *= 10;
00678 
00679     if (reference < 3000.0 || reference > 13000.0) {
00680         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00681                       "keyword ESO INS GRIS1 WLEN in reference frame header",
00682                       reference);
00683         fors_align_sky_exit(NULL);
00684     }
00685 
00686     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00687 
00688     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00689 
00690     if (cpl_error_get_code() != CPL_ERROR_NONE)
00691         fors_align_sky_exit("Missing keyword ESO DET WIN1 BINX "
00692                             "in reference frame header");
00693 
00694     if (rebin != 1) {
00695         dispersion *= rebin;
00696         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00697                         "working dispersion used is %f A/pixel", rebin,
00698                         dispersion);
00699     }
00700 
00701     cpl_msg_indent_less();
00702     cpl_msg_info(recipe, "Load input frames...");
00703     cpl_msg_indent_more();
00704 
00705     coordinate = dfs_load_image(frameset, spatial_map_tag, 
00706                                 CPL_TYPE_FLOAT, 0, 0);
00707     if (coordinate == NULL)
00708         fors_align_sky_exit("Cannot load input reference frame");
00709 
00710     slits = dfs_load_table(frameset, slit_location_tag, 1);
00711     if (slits == NULL)
00712         fors_align_sky_exit("Cannot load slits location table");
00713 
00714     polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00715     if (polytraces == NULL)
00716         fors_align_sky_exit("Cannot load spectral curvature table");
00717 
00718     idscoeff = dfs_load_table(frameset, disp_coeff_tag, 1);
00719     if (idscoeff == NULL)
00720         fors_align_sky_exit("Cannot load dispersion solution");
00721 
00722     smapped = dfs_load_image(frameset, rectified_tag, CPL_TYPE_FLOAT, 0, 0);
00723     if (smapped == NULL)
00724         fors_align_sky_exit("Cannot load input rectified frame");
00725 
00726     wavelengths = dfs_load_table(frameset, "MASTER_SKYLINECAT", 1);
00727 
00728     if (wavelengths) {
00729 
00730         /*
00731          * Cast the wavelengths into a (double precision) CPL vector
00732          */
00733 
00734         nlines = cpl_table_get_nrow(wavelengths);
00735 
00736         if (nlines == 0)
00737             fors_align_sky_exit("Empty input sky line catalog");
00738 
00739         if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
00740             cpl_msg_error(recipe, "Missing column %s in input line "
00741                           "catalog table", wcolumn);
00742             fors_align_sky_exit(NULL);
00743         }
00744 
00745         line = cpl_malloc(nlines * sizeof(double));
00746 
00747         for (i = 0; i < nlines; i++)
00748             line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
00749 
00750         cpl_table_delete(wavelengths); wavelengths = NULL;
00751 
00752         lines = cpl_vector_wrap(nlines, line);
00753     }
00754     else {
00755         cpl_msg_info(recipe, "No sky line catalog found in input - fine!");
00756     }
00757 
00758     if (skyalign) {
00759         cpl_msg_info(recipe, "Align wavelength solution to reference "
00760         "skylines applying %d order residual fit...", skyalign);
00761     }
00762     else {
00763         cpl_msg_info(recipe, "Align wavelength solution to reference "
00764         "skylines applying median offset...");
00765     }
00766 
00767     if (dispersion > 1.0)
00768         highres = 0;
00769     else
00770         highres = 1;
00771 
00772     nx = cpl_image_get_size_x(coordinate);
00773 
00774     rainbow = mos_map_idscoeff(idscoeff, nx, reference, startwavelength,
00775                                endwavelength);
00776 
00777     offsets = mos_wavelength_align(smapped, slits, reference,
00778                                    startwavelength, endwavelength,
00779                                    idscoeff, lines, highres, skyalign,
00780                                    rainbow, 4);
00781 
00782     cpl_vector_delete(lines); lines = NULL;
00783     cpl_image_delete(smapped); smapped = NULL;
00784 
00785     if (offsets) {
00786         if (dfs_save_table(frameset, offsets, shifts_tag, NULL,
00787                            parlist, recipe, version))
00788             fors_align_sky_exit(NULL);
00789 
00790         cpl_table_delete(offsets); offsets = NULL;
00791     }
00792     else
00793         fors_align_sky_exit("Alignment of the wavelength solution "
00794                         "to reference sky lines could not be done!");
00795 
00796     if (dfs_save_table(frameset, idscoeff, disp_ali_tag, NULL,
00797                        parlist, recipe, version))
00798         fors_align_sky_exit(NULL);
00799 
00800     cpl_table_delete(idscoeff); idscoeff = NULL;
00801 
00802     wavemap = mos_map_wavelengths(coordinate, rainbow, slits,
00803                                   polytraces, reference,
00804                                   startwavelength, endwavelength,
00805                                   dispersion);
00806 
00807     cpl_image_delete(rainbow); rainbow = NULL;
00808     cpl_image_delete(coordinate); coordinate = NULL;
00809     cpl_table_delete(polytraces); polytraces = NULL;
00810     cpl_table_delete(slits); slits = NULL;
00811 
00812     if (dfs_save_image(frameset, wavemap, wavemap_tag,
00813                        header, parlist, recipe, version))
00814         fors_align_sky_exit(NULL);
00815 
00816     cpl_image_delete(wavemap); wavemap = NULL;
00817     cpl_propertylist_delete(header); header = NULL;
00818 
00819     return 0;
00820 }

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