fors_align_sky_lss.c

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

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