fors_align_sky_lss.c

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

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