fors_align_sky.c

00001 /* $Id: fors_align_sky.c,v 1.8 2013-08-14 16:07:47 cgarcia 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: cgarcia $
00023  * $Date: 2013-08-14 16:07:47 $
00024  * $Revision: 1.8 $
00025  * $Name: not supported by cvs2svn $
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 ((const char *)message != NULL) 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 ((const char *)message != NULL) 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         nlines;
00378     int         nx;
00379     int         highres;
00380     int         treat_as_lss;
00381     int         i;
00382     double      reference;
00383     double      mxpos;
00384     double     *line;
00385     int         mxu, mos;
00386     int         rec_scia;
00387     int         rec_stda;
00388     int         rec_scis;
00389     int         rec_stds;
00390     int         nslits_out_det = 0;
00391 
00392 
00393     char       *instrume = NULL;
00394 
00395 
00396     cpl_msg_set_indentation(2);
00397 
00398 
00399     /*
00400      * Get configuration parameters
00401      */
00402 
00403     cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
00404     cpl_msg_indent_more();
00405     
00406     if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1)
00407         fors_align_sky_exit("Too many in input: GRISM_TABLE"); 
00408 
00409     grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1);
00410 
00411     dispersion = dfs_get_parameter_double(parlist,
00412                     "fors.fors_align_sky.dispersion", grism_table);
00413 
00414     if (dispersion <= 0.0)
00415         fors_align_sky_exit("Invalid spectral dispersion value");
00416 
00417     startwavelength = dfs_get_parameter_double(parlist,
00418                     "fors.fors_align_sky.startwavelength", grism_table);
00419     if (startwavelength > 1.0)
00420         if (startwavelength < 3000.0 || startwavelength > 13000.0)
00421             fors_align_sky_exit("Invalid wavelength");
00422 
00423     endwavelength = dfs_get_parameter_double(parlist,
00424                     "fors.fors_align_sky.endwavelength", grism_table);
00425     if (endwavelength > 1.0) {
00426         if (endwavelength < 3000.0 || endwavelength > 13000.0)
00427             fors_align_sky_exit("Invalid wavelength");
00428         if (startwavelength < 1.0)
00429             fors_align_sky_exit("Invalid wavelength interval");
00430     }
00431 
00432     if (startwavelength > 1.0)
00433         if (endwavelength - startwavelength <= 0.0)
00434             fors_align_sky_exit("Invalid wavelength interval");
00435 
00436     skyalign = dfs_get_parameter_int(parlist,
00437                     "fors.fors_align_sky.skyalign", NULL);
00438 
00439     if (skyalign < 0)
00440         fors_align_sky_exit("Invalid polynomial degree");
00441     if (skyalign > 2)
00442         fors_align_sky_exit("Max polynomial degree for sky alignment is 2");
00443 
00444     wcolumn = dfs_get_parameter_string(parlist,
00445                     "fors.fors_align_sky.wcolumn", NULL);
00446 
00447     cpl_table_delete(grism_table); grism_table = NULL;
00448 
00449     if (cpl_error_get_code())
00450         fors_align_sky_exit("Failure reading the configuration parameters");
00451 
00452 
00453     cpl_msg_indent_less();
00454     cpl_msg_info(recipe, "Check input set-of-frames:");
00455     cpl_msg_indent_more();
00456 
00457     mxu  = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MXU");
00458     mos  = cpl_frameset_count_tags(frameset, "SPATIAL_MAP_MOS");
00459 
00460     nframes = mos + mxu;
00461 
00462     if (nframes == 0) {
00463         fors_align_sky_exit("Missing input spatial map");
00464     }
00465     if (nframes > 1) {
00466         cpl_msg_error(recipe, 
00467                       "Too many input spatial maps (%d > 1)", nframes);
00468         fors_align_sky_exit(NULL);
00469     }
00470 
00471     if (mxu) {
00472         rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MXU");
00473         rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MXU");
00474         rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MXU");
00475         rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MXU");
00476     }
00477     else {
00478         rec_scia = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_SCI_MOS");
00479         rec_stda = cpl_frameset_count_tags(frameset, "RECTIFIED_ALL_STD_MOS");
00480         rec_scis = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_SCI_MOS");
00481         rec_stds = cpl_frameset_count_tags(frameset, "RECTIFIED_SKY_STD_MOS");
00482     }
00483 
00484     nframes = rec_scia + rec_stda + rec_scis + rec_stds;
00485 
00486     if (nframes == 0) {
00487         fors_align_sky_exit("Missing input rectified scientific spectra");
00488     }
00489     if (nframes > 1) {
00490         cpl_msg_error(recipe,
00491                       "Too many input rectified scientific spectra (%d > 1)", 
00492                       nframes);
00493         fors_align_sky_exit(NULL);
00494     }
00495 
00496     if (cpl_frameset_count_tags(frameset, "MASTER_SKYLINECAT") > 1)
00497         fors_align_sky_exit("Too many in input: MASTER_SKYLINECAT");
00498 
00499     if (rec_scia) {
00500         if (mxu) {
00501             rectified_tag = "RECTIFIED_ALL_SCI_MXU";
00502             wavemap_tag   = "WAVELENGTH_MAP_SCI_MXU";
00503             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MXU";
00504             disp_ali_tag  = "DISP_COEFF_SCI_MXU";
00505         }
00506         else {
00507             rectified_tag = "RECTIFIED_ALL_SCI_MOS";
00508             wavemap_tag   = "WAVELENGTH_MAP_SCI_MOS";
00509             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MOS";
00510             disp_ali_tag  = "DISP_COEFF_SCI_MOS";
00511         }
00512     }
00513     else if (rec_stda) {
00514         if (mxu) {
00515             rectified_tag = "RECTIFIED_ALL_STD_MXU";
00516             wavemap_tag   = "WAVELENGTH_MAP_STD_MXU";
00517             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MXU";
00518             disp_ali_tag  = "DISP_COEFF_STD_MXU";
00519         }
00520         else {
00521             rectified_tag = "RECTIFIED_ALL_STD_MOS";
00522             wavemap_tag   = "WAVELENGTH_MAP_STD_MOS";
00523             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MOS";
00524             disp_ali_tag  = "DISP_COEFF_STD_MOS";
00525         }
00526     }
00527     else if (rec_scis) {
00528         if (mxu) {
00529             rectified_tag = "RECTIFIED_SKY_SCI_MXU";
00530             wavemap_tag   = "WAVELENGTH_MAP_SCI_MXU";
00531             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MXU";
00532             disp_ali_tag  = "DISP_COEFF_SCI_MXU";
00533         }
00534         else {
00535             rectified_tag = "RECTIFIED_SKY_SCI_MOS";
00536             wavemap_tag   = "WAVELENGTH_MAP_SCI_MOS";
00537             shifts_tag    = "SKY_SHIFTS_SLIT_SCI_MOS";
00538             disp_ali_tag  = "DISP_COEFF_SCI_MOS";
00539         }
00540     }
00541     else if (rec_stds) {
00542         if (mxu) {
00543             rectified_tag = "RECTIFIED_SKY_STD_MXU";
00544             wavemap_tag   = "WAVELENGTH_MAP_STD_MXU";
00545             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MXU";
00546             disp_ali_tag  = "DISP_COEFF_STD_MXU";
00547         }
00548         else {
00549             rectified_tag = "RECTIFIED_SKY_STD_MOS";
00550             wavemap_tag   = "WAVELENGTH_MAP_STD_MOS";
00551             shifts_tag    = "SKY_SHIFTS_SLIT_STD_MOS";
00552             disp_ali_tag  = "DISP_COEFF_STD_MOS";
00553         }
00554     }
00555 
00556 
00557     if (mxu) {
00558         disp_coeff_tag    = "DISP_COEFF_MXU";
00559         curv_coeff_tag    = "CURV_COEFF_MXU";
00560         slit_location_tag = "SLIT_LOCATION_MXU";
00561         spatial_map_tag   = "SPATIAL_MAP_MXU";
00562     }
00563     else {
00564         disp_coeff_tag    = "DISP_COEFF_MOS";
00565         curv_coeff_tag    = "CURV_COEFF_MOS";
00566         slit_location_tag = "SLIT_LOCATION_MOS";
00567         spatial_map_tag   = "SPATIAL_MAP_MOS";
00568     }
00569 
00570     nframes = cpl_frameset_count_tags(frameset, disp_coeff_tag);
00571 
00572     if (nframes == 0) {
00573         cpl_msg_error(recipe, "Missing input %s\n", disp_coeff_tag);
00574         fors_align_sky_exit(NULL);
00575     }
00576     if (nframes > 1) {
00577         cpl_msg_error(recipe, 
00578                       "Too many input %s (%d > 1)", disp_coeff_tag, nframes);
00579         fors_align_sky_exit(NULL);
00580     }
00581 
00582     nframes = cpl_frameset_count_tags(frameset, curv_coeff_tag);
00583 
00584     if (nframes == 0) {
00585         cpl_msg_error(recipe, "Missing input %s\n", curv_coeff_tag);
00586         fors_align_sky_exit(NULL);
00587     }
00588     if (nframes > 1) {
00589         cpl_msg_error(recipe,
00590                       "Too many input %s (%d > 1)", curv_coeff_tag, nframes);
00591         fors_align_sky_exit(NULL);
00592     }
00593 
00594     nframes = cpl_frameset_count_tags(frameset, spatial_map_tag);
00595 
00596     if (nframes == 0) {
00597         cpl_msg_error(recipe, "Missing input %s\n", spatial_map_tag);
00598         fors_align_sky_exit(NULL);
00599     }
00600     if (nframes > 1) {
00601         cpl_msg_error(recipe,
00602                       "Too many input %s (%d > 1)", spatial_map_tag, nframes);
00603         fors_align_sky_exit(NULL);
00604     }
00605     
00606 
00607     header = dfs_load_header(frameset, spatial_map_tag, 0);
00608 
00609     if (header == NULL)
00610         fors_align_sky_exit("Cannot load spatial map header");
00611 
00612     if (mos)
00613         maskslits = mos_load_slits_fors_mos(header, &nslits_out_det);
00614     else
00615         maskslits = mos_load_slits_fors_mxu(header);
00616 
00617     /*
00618      * Check if all slits have the same X offset: in such case, abort!
00619      */
00620 
00621     treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
00622 
00623     cpl_table_delete(maskslits); maskslits = NULL;
00624 
00625     if (treat_as_lss) {
00626         cpl_msg_error(recipe, "All slits have the same offset: %.2f mm\n"
00627                       "The LSS data reduction strategy must be applied. "
00628                       "Please use recipe fors_align_sky_lss.", mxpos);
00629         fors_align_sky_exit(NULL);
00630     }
00631 
00632     if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00633         cpl_msg_warning(cpl_func,"Input frames are not from the same grism");
00634 
00635     if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00636         cpl_msg_warning(cpl_func,"Input frames are not from the same filter");
00637 
00638     if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00639         cpl_msg_warning(cpl_func,"Input frames are not from the same chip");
00640 
00641 
00642     /*
00643      * Get the reference wavelength and the rebin factor along the
00644      * dispersion direction from the reference frame
00645      */
00646 
00647     instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00648     if (instrume == NULL)
00649         fors_align_sky_exit("Missing keyword INSTRUME in reference frame "
00650                             "header");
00651 
00652     if (instrume[4] == '1')
00653         snprintf(version, 80, "%s/%s", "fors1", VERSION);
00654     if (instrume[4] == '2')
00655         snprintf(version, 80, "%s/%s", "fors2", VERSION);
00656 
00657     reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN");
00658 
00659     if (cpl_error_get_code() != CPL_ERROR_NONE)
00660         fors_align_sky_exit("Missing keyword ESO INS GRIS1 WLEN "
00661                             "in reference frame header");
00662 
00663     if (reference < 3000.0)   /* Perhaps in nanometers... */
00664         reference *= 10;
00665 
00666     if (reference < 3000.0 || reference > 13000.0) {
00667         cpl_msg_error(recipe, "Invalid central wavelength %.2f read from "
00668                       "keyword ESO INS GRIS1 WLEN in reference frame header",
00669                       reference);
00670         fors_align_sky_exit(NULL);
00671     }
00672 
00673     cpl_msg_info(recipe, "The central wavelength is: %.2f", reference);
00674 
00675     rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX");
00676 
00677     if (cpl_error_get_code() != CPL_ERROR_NONE)
00678         fors_align_sky_exit("Missing keyword ESO DET WIN1 BINX "
00679                             "in reference frame header");
00680 
00681     if (rebin != 1) {
00682         dispersion *= rebin;
00683         cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the "
00684                         "working dispersion used is %f A/pixel", rebin,
00685                         dispersion);
00686     }
00687 
00688     cpl_msg_indent_less();
00689     cpl_msg_info(recipe, "Load input frames...");
00690     cpl_msg_indent_more();
00691 
00692     coordinate = dfs_load_image(frameset, spatial_map_tag, 
00693                                 CPL_TYPE_FLOAT, 0, 0);
00694     if (coordinate == NULL)
00695         fors_align_sky_exit("Cannot load input reference frame");
00696 
00697     slits = dfs_load_table(frameset, slit_location_tag, 1);
00698     if (slits == NULL)
00699         fors_align_sky_exit("Cannot load slits location table");
00700 
00701     polytraces = dfs_load_table(frameset, curv_coeff_tag, 1);
00702     if (polytraces == NULL)
00703         fors_align_sky_exit("Cannot load spectral curvature table");
00704 
00705     idscoeff = dfs_load_table(frameset, disp_coeff_tag, 1);
00706     if (idscoeff == NULL)
00707         fors_align_sky_exit("Cannot load dispersion solution");
00708 
00709     smapped = dfs_load_image(frameset, rectified_tag, CPL_TYPE_FLOAT, 0, 0);
00710     if (smapped == NULL)
00711         fors_align_sky_exit("Cannot load input rectified frame");
00712 
00713     wavelengths = dfs_load_table(frameset, "MASTER_SKYLINECAT", 1);
00714 
00715     if (wavelengths) {
00716 
00717         /*
00718          * Cast the wavelengths into a (double precision) CPL vector
00719          */
00720 
00721         nlines = cpl_table_get_nrow(wavelengths);
00722 
00723         if (nlines == 0)
00724             fors_align_sky_exit("Empty input sky line catalog");
00725 
00726         if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
00727             cpl_msg_error(recipe, "Missing column %s in input line "
00728                           "catalog table", wcolumn);
00729             fors_align_sky_exit(NULL);
00730         }
00731 
00732         line = cpl_malloc(nlines * sizeof(double));
00733 
00734         for (i = 0; i < nlines; i++)
00735             line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
00736 
00737         cpl_table_delete(wavelengths); wavelengths = NULL;
00738 
00739         lines = cpl_vector_wrap(nlines, line);
00740     }
00741     else {
00742         cpl_msg_info(recipe, "No sky line catalog found in input - fine!");
00743     }
00744 
00745     if (skyalign) {
00746         cpl_msg_info(recipe, "Align wavelength solution to reference "
00747         "skylines applying %d order residual fit...", skyalign);
00748     }
00749     else {
00750         cpl_msg_info(recipe, "Align wavelength solution to reference "
00751         "skylines applying median offset...");
00752     }
00753 
00754     if (dispersion > 1.0)
00755         highres = 0;
00756     else
00757         highres = 1;
00758 
00759     nx = cpl_image_get_size_x(coordinate);
00760 
00761     rainbow = mos_map_idscoeff(idscoeff, nx, reference, startwavelength,
00762                                endwavelength);
00763 
00764     offsets = mos_wavelength_align(smapped, slits, reference,
00765                                    startwavelength, endwavelength,
00766                                    idscoeff, lines, highres, skyalign,
00767                                    rainbow, 4);
00768 
00769     cpl_vector_delete(lines); lines = NULL;
00770     cpl_image_delete(smapped); smapped = NULL;
00771 
00772     if (offsets) {
00773         if (dfs_save_table(frameset, offsets, shifts_tag, NULL,
00774                            parlist, recipe, version))
00775             fors_align_sky_exit(NULL);
00776 
00777         cpl_table_delete(offsets); offsets = NULL;
00778     }
00779     else
00780         fors_align_sky_exit("Alignment of the wavelength solution "
00781                         "to reference sky lines could not be done!");
00782 
00783     if (dfs_save_table(frameset, idscoeff, disp_ali_tag, NULL,
00784                        parlist, recipe, version))
00785         fors_align_sky_exit(NULL);
00786 
00787     cpl_table_delete(idscoeff); idscoeff = NULL;
00788 
00789     wavemap = mos_map_wavelengths(coordinate, rainbow, slits,
00790                                   polytraces, reference,
00791                                   startwavelength, endwavelength,
00792                                   dispersion);
00793 
00794     cpl_image_delete(rainbow); rainbow = NULL;
00795     cpl_image_delete(coordinate); coordinate = NULL;
00796     cpl_table_delete(polytraces); polytraces = NULL;
00797     cpl_table_delete(slits); slits = NULL;
00798 
00799     if (dfs_save_image(frameset, wavemap, wavemap_tag,
00800                        header, parlist, recipe, version))
00801         fors_align_sky_exit(NULL);
00802 
00803     cpl_image_delete(wavemap); wavemap = NULL;
00804     cpl_propertylist_delete(header); header = NULL;
00805 
00806     return 0;
00807 }

Generated on 12 Feb 2016 for FORS Pipeline Reference Manual by  doxygen 1.6.1