uves_reduce_utils.c

00001 /*                                                                              *
00002  *   This file is part of the ESO UVES Pipeline                                 *
00003  *   Copyright (C) 2004,2005 European Southern Observatory                      *
00004  *                                                                              *
00005  *   This library is free software; you can redistribute it and/or modify       *
00006  *   it under the terms of the GNU General Public License as published by       *
00007  *   the Free Software Foundation; either version 2 of the License, or          *
00008  *   (at your option) any later version.                                        *
00009  *                                                                              *
00010  *   This program is distributed in the hope that it will be useful,            *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00013  *   GNU General Public License for more details.                               *
00014  *                                                                              *
00015  *   You should have received a copy of the GNU General Public License          *
00016  *   along with this program; if not, write to the Free Software                *
00017  *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA       *
00018  *                                                                              */
00019 
00020 /*
00021  * $Author: amodigli $
00022  * $Date: 2012/03/02 16:49:48 $
00023  * $Revision: 1.15 $
00024  * $Name: uves-5_0_0 $
00025  * $Log: uves_reduce_utils.c,v $
00026  * Revision 1.15  2012/03/02 16:49:48  amodigli
00027  * fixed warning related to upgrade to CPL6
00028  *
00029  * Revision 1.14  2011/12/08 14:05:48  amodigli
00030  * Fix warnings with CPL6
00031  *
00032  * Revision 1.13  2010/09/24 09:32:07  amodigli
00033  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
00034  *
00035  * Revision 1.11  2007/06/06 08:17:33  amodigli
00036  * replace tab with 4 spaces
00037  *
00038  * Revision 1.10  2007/04/24 12:50:29  jmlarsen
00039  * Replaced cpl_propertylist -> uves_propertylist which is much faster
00040  *
00041  * Revision 1.9  2007/04/10 07:09:37  jmlarsen
00042  * Changed interface of uves_spline_hermite()
00043  *
00044  * Revision 1.8  2006/11/06 15:19:41  jmlarsen
00045  * Removed unused include directives
00046  *
00047  * Revision 1.7  2006/08/17 13:56:53  jmlarsen
00048  * Reduced max line length
00049  *
00050  * Revision 1.6  2006/05/12 15:10:07  jmlarsen
00051  * Shortened lines
00052  *
00053  * Revision 1.5  2006/04/10 12:38:13  jmlarsen
00054  * Bugfix: don't read uninitialized memory (caused atmospheric extinction step 
00055  * to be randomly disabled)
00056  *
00057  * Revision 1.4  2006/04/06 08:49:23  jmlarsen
00058  * Propagate errors when normalizing spectrum
00059  *
00060  * Revision 1.3  2005/12/19 16:17:56  jmlarsen
00061  * Replaced bool -> int
00062  *
00063  * Revision 1.2  2005/12/16 14:22:23  jmlarsen
00064  * Removed midas test data; Added sof files
00065  *
00066  * Revision 1.1  2005/11/11 13:18:54  jmlarsen
00067  * Reorganized code, renamed source files
00068  *
00069  */
00070 
00071 #ifdef HAVE_CONFIG_H
00072 #  include <config.h>
00073 #endif
00074 
00075 /*----------------------------------------------------------------------------*/
00079 /*----------------------------------------------------------------------------*/
00082 /*-----------------------------------------------------------------------------
00083                                 Includes
00084  -----------------------------------------------------------------------------*/
00085 
00086 #include <uves_reduce_utils.h>
00087 
00088 #include <uves_pfits.h>
00089 #include <uves_utils.h>
00090 #include <uves_utils_wrappers.h>
00091 #include <uves_error.h>
00092 #include <uves_msg.h>
00093 
00094 #include <cpl.h>
00095 
00096 /*-----------------------------------------------------------------------------
00097                             Functions prototypes
00098  -----------------------------------------------------------------------------*/
00099 
00100 /*-----------------------------------------------------------------------------
00101                             Implementation
00102  -----------------------------------------------------------------------------*/
00103 
00104 /*----------------------------------------------------------------------------*/
00126 /*----------------------------------------------------------------------------*/
00127 cpl_image *
00128 uves_normalize_spectrum(const cpl_image *spectrum, const cpl_image *spectrum_error,
00129             const uves_propertylist *spectrum_header,
00130             const uves_propertylist *raw_header,
00131             int n_traces,
00132             enum uves_chip chip,
00133             const cpl_table *atm_extinction,
00134             bool correct_binning,
00135             cpl_image **scaled_error)
00136 {
00137     cpl_image *scaled = NULL;
00138     double exptime, gain;
00139     int binx;
00140     int norders, ny, nx;
00141     
00142     assure_nomsg( spectrum != NULL, CPL_ERROR_NULL_INPUT);
00143     assure_nomsg( scaled_error == NULL || spectrum_error != NULL, CPL_ERROR_NULL_INPUT);
00144     assure_nomsg( spectrum_header != NULL, CPL_ERROR_NULL_INPUT);
00145 
00146     nx = cpl_image_get_size_x(spectrum);
00147     ny = cpl_image_get_size_y(spectrum);
00148 
00149     if (spectrum_error != NULL)
00150     {
00151         assure( nx == cpl_image_get_size_x(spectrum_error) &&
00152             ny == cpl_image_get_size_y(spectrum_error), CPL_ERROR_INCOMPATIBLE_INPUT,
00153             "Error spectrum geometry differs from spectrum: %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT " vs. %d x %d",
00154             cpl_image_get_size_x(spectrum_error),
00155             cpl_image_get_size_y(spectrum_error),
00156             nx, ny);
00157     }
00158     
00159     assure( ny % n_traces == 0, CPL_ERROR_INCOMPATIBLE_INPUT,
00160         "Spectrum image height (%d) is not a multiple of "
00161         "the number of traces (%d). Confused, bailing out",
00162         ny, n_traces);
00163     
00164     norders = ny / n_traces;
00165 
00166     /*
00167      * Correct for exposure time, gain, bin 
00168      */
00169     check( exptime = uves_pfits_get_exptime(raw_header),
00170        "Could not read exposure time");
00171     
00172     check( gain = uves_pfits_get_gain(raw_header, chip),
00173        "Could not read gain factor");
00174     
00175     if (correct_binning)
00176     {
00177         /* x-binning of rotated image is y-binning of raw image */
00178         check( binx  = uves_pfits_get_biny(raw_header),
00179            "Could not read binning");
00180     }
00181     else
00182     {
00183         uves_msg("Spectrum will not be normalized to unit binning");
00184         binx = 1;
00185     }
00186     
00187     assure( exptime > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive exposure time: %f s", exptime);
00188     assure( gain    > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive gain: %f", gain);
00189     assure( binx    > 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal binning: %d", binx);
00190     
00191     uves_msg("Correcting for exposure time = %f s, gain = %f, binx = %d", exptime, gain, binx);
00192     
00193     check( scaled        = cpl_image_divide_scalar_create(spectrum, exptime * gain * binx),
00194        "Error correcting spectrum for gain, exposure time, binning");
00195     
00196     if (scaled_error != NULL)
00197     {
00198         check( *scaled_error = cpl_image_divide_scalar_create(spectrum_error, 
00199                                   exptime * gain * binx),
00200            "Error correcting rebinned spectrum for gain, exposure time, binning");
00201     }
00202     
00203     /* 
00204      * Correct for atmospheric extinction 
00205      */
00206     {
00207     double airmass;
00208     double dlambda, lambda_start;
00209     int order;
00210 
00211     {
00212         double airmass_start, airmass_end;
00213         
00214         check( airmass_start = uves_pfits_get_airmass_start(raw_header),
00215            "Error reading airmass start");
00216         
00217         check( airmass_end = uves_pfits_get_airmass_end(raw_header),
00218            "Error reading airmass end");
00219         
00220         /* Use arithmetic mean of airmass start/end */
00221         airmass = (airmass_start + airmass_end) / 2;
00222     
00223     }
00224 
00225     uves_msg("Correcting for extinction through airmass %f", airmass);
00226         
00227     check( dlambda = uves_pfits_get_cdelt1(spectrum_header),
00228            "Error reading bin width from header");
00229     
00230     for (order = 1; order <= norders; order++)
00231         {
00232         int trace;
00233 
00234         /* If spectrum was already merged, then read crval1,
00235          * otherwise read wstart for each order
00236          */
00237         
00238         if (norders == 1)
00239             {
00240             check( lambda_start = uves_pfits_get_crval1(spectrum_header),
00241                    "Error reading start wavelength from header");    
00242             }
00243         else
00244             {
00245             check( lambda_start = uves_pfits_get_wstart(spectrum_header, order),
00246                    "Error reading start wavelength from header");    
00247             }
00248 
00249         for (trace = 1; trace <= n_traces; trace++)
00250             {
00251             int spectrum_row = (order - 1)*n_traces + trace;
00252             int x;
00253             
00254             for (x = 1; x <= nx; x++)
00255                 {
00256                 int pis_rejected1;
00257                 int pis_rejected2;
00258                 double flux;
00259                 double dflux = 0;
00260                 double extinction;
00261                 double lambda;
00262 
00263                 lambda = lambda_start + (x-1) * dlambda;
00264                 
00265                 flux  = cpl_image_get(scaled, x, spectrum_row, &pis_rejected1);
00266                 if (scaled_error != NULL)
00267                     {
00268                     dflux = cpl_image_get(*scaled_error, x, 
00269                                   spectrum_row, &pis_rejected2);
00270                     }
00271 
00272                 if (!pis_rejected1 && (scaled_error == NULL || !pis_rejected2))
00273                     {
00274                                         int istart = 0;
00275 
00276                     /* Read extinction (units: magnitude per airmass) */
00277                     check( extinction = 
00278                            uves_spline_hermite_table(
00279                            lambda, atm_extinction,
00280                            "LAMBDA", "LA_SILLA", &istart),
00281                            "Error interpolating extinction coefficient");
00282                     
00283                     /* Correct for extinction using
00284                      * the magnitude/flux relation
00285                      * m = -2.5 log_10 F
00286                      *  => 
00287                      * F = 10^(-m*0.4)
00288                      *
00289                      * m_top-of-atmosphere = m - ext.coeff*airmass
00290                      * F_top-of-atmosphere = F * 10^(0.4 * ext.coeff*airmass)
00291                      */
00292 
00293                     cpl_image_set(
00294                         scaled, x, spectrum_row,
00295                         flux * pow(10, 0.4 * extinction * airmass));
00296                     if (scaled_error != NULL)
00297                         {
00298                         cpl_image_set(
00299                             *scaled_error, x, spectrum_row,
00300                             dflux * pow(10, 0.4 * extinction * airmass));
00301                         }
00302                     }
00303                 else
00304                     {
00305                     cpl_image_reject(scaled, x, spectrum_row);
00306                     if (scaled_error != NULL)
00307                         {
00308                         cpl_image_reject(*scaled_error, x, spectrum_row);
00309                         }
00310                     }
00311                 } /* for each x */
00312 
00313             } /* for each (possibly only 1) trace */
00314 
00315         } /* for each (possibly only 1) order */
00316     }
00317     
00318   cleanup:
00319     if (cpl_error_get_code() != CPL_ERROR_NONE)
00320     {
00321         uves_free_image(&scaled);
00322         if (scaled_error != NULL)
00323         {
00324             uves_free_image(scaled_error);
00325         }
00326     }
00327     
00328     return scaled;
00329 }
00330 

Generated on 9 Mar 2012 for UVES Pipeline Reference Manual by  doxygen 1.6.1