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: 2007/06/06 08:17:33 $
00023  * $Revision: 1.11 $
00024  * $Name: uves-3_3_1 $
00025  * $Log: uves_reduce_utils.c,v $
00026  * Revision 1.11  2007/06/06 08:17:33  amodigli
00027  * replace tab with 4 spaces
00028  *
00029  * Revision 1.10  2007/04/24 12:50:29  jmlarsen
00030  * Replaced cpl_propertylist -> uves_propertylist which is much faster
00031  *
00032  * Revision 1.9  2007/04/10 07:09:37  jmlarsen
00033  * Changed interface of uves_spline_hermite()
00034  *
00035  * Revision 1.8  2006/11/06 15:19:41  jmlarsen
00036  * Removed unused include directives
00037  *
00038  * Revision 1.7  2006/08/17 13:56:53  jmlarsen
00039  * Reduced max line length
00040  *
00041  * Revision 1.6  2006/05/12 15:10:07  jmlarsen
00042  * Shortened lines
00043  *
00044  * Revision 1.5  2006/04/10 12:38:13  jmlarsen
00045  * Bugfix: don't read uninitialized memory (caused atmospheric extinction step 
00046  * to be randomly disabled)
00047  *
00048  * Revision 1.4  2006/04/06 08:49:23  jmlarsen
00049  * Propagate errors when normalizing spectrum
00050  *
00051  * Revision 1.3  2005/12/19 16:17:56  jmlarsen
00052  * Replaced bool -> int
00053  *
00054  * Revision 1.2  2005/12/16 14:22:23  jmlarsen
00055  * Removed midas test data; Added sof files
00056  *
00057  * Revision 1.1  2005/11/11 13:18:54  jmlarsen
00058  * Reorganized code, renamed source files
00059  *
00060  */
00061 
00062 #ifdef HAVE_CONFIG_H
00063 #  include <config.h>
00064 #endif
00065 
00066 /*----------------------------------------------------------------------------*/
00070 /*----------------------------------------------------------------------------*/
00073 /*-----------------------------------------------------------------------------
00074                                 Includes
00075  -----------------------------------------------------------------------------*/
00076 
00077 #include <uves_reduce_utils.h>
00078 
00079 #include <uves_pfits.h>
00080 #include <uves_utils.h>
00081 #include <uves_utils_wrappers.h>
00082 #include <uves_error.h>
00083 #include <uves_msg.h>
00084 
00085 #include <cpl.h>
00086 
00087 /*-----------------------------------------------------------------------------
00088                             Functions prototypes
00089  -----------------------------------------------------------------------------*/
00090 
00091 /*-----------------------------------------------------------------------------
00092                             Implementation
00093  -----------------------------------------------------------------------------*/
00094 
00095 /*----------------------------------------------------------------------------*/
00117 /*----------------------------------------------------------------------------*/
00118 cpl_image *
00119 uves_normalize_spectrum(const cpl_image *spectrum, const cpl_image *spectrum_error,
00120             const uves_propertylist *spectrum_header,
00121             const uves_propertylist *raw_header,
00122             int n_traces,
00123             enum uves_chip chip,
00124             const cpl_table *atm_extinction,
00125             bool correct_binning,
00126             cpl_image **scaled_error)
00127 {
00128     cpl_image *scaled = NULL;
00129     double exptime, gain;
00130     int binx;
00131     int norders, ny, nx;
00132     
00133     assure_nomsg( spectrum != NULL, CPL_ERROR_NULL_INPUT);
00134     assure_nomsg( scaled_error == NULL || spectrum_error != NULL, CPL_ERROR_NULL_INPUT);
00135     assure_nomsg( spectrum_header != NULL, CPL_ERROR_NULL_INPUT);
00136 
00137     nx = cpl_image_get_size_x(spectrum);
00138     ny = cpl_image_get_size_y(spectrum);
00139 
00140     if (spectrum_error != NULL)
00141     {
00142         assure( nx == cpl_image_get_size_x(spectrum_error) &&
00143             ny == cpl_image_get_size_y(spectrum_error), CPL_ERROR_INCOMPATIBLE_INPUT,
00144             "Error spectrum geometry differs from spectrum: %dx%d vs. %dx%d",
00145             cpl_image_get_size_x(spectrum_error),
00146             cpl_image_get_size_y(spectrum_error),
00147             nx, ny);
00148     }
00149     
00150     assure( ny % n_traces == 0, CPL_ERROR_INCOMPATIBLE_INPUT,
00151         "Spectrum image height (%d) is not a multiple of "
00152         "the number of traces (%d). Confused, bailing out",
00153         ny, n_traces);
00154     
00155     norders = ny / n_traces;
00156 
00157     /*
00158      * Correct for exposure time, gain, bin 
00159      */
00160     check( exptime = uves_pfits_get_exptime(raw_header),
00161        "Could not read exposure time");
00162     
00163     check( gain = uves_pfits_get_gain(raw_header, chip),
00164        "Could not read gain factor");
00165     
00166     if (correct_binning)
00167     {
00168         /* x-binning of rotated image is y-binning of raw image */
00169         check( binx  = uves_pfits_get_biny(raw_header),
00170            "Could not read binning");
00171     }
00172     else
00173     {
00174         uves_msg("Spectrum will not be normalized to unit binning");
00175         binx = 1;
00176     }
00177     
00178     assure( exptime > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive exposure time: %f s", exptime);
00179     assure( gain    > 0, CPL_ERROR_ILLEGAL_INPUT, "Non-positive gain: %f", gain);
00180     assure( binx    > 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal binning: %d", binx);
00181     
00182     uves_msg("Correcting for exposure time = %f s, gain = %f, binx = %d", exptime, gain, binx);
00183     
00184     check( scaled        = cpl_image_divide_scalar_create(spectrum, exptime * gain * binx),
00185        "Error correcting spectrum for gain, exposure time, binning");
00186     
00187     if (scaled_error != NULL)
00188     {
00189         check( *scaled_error = cpl_image_divide_scalar_create(spectrum_error, 
00190                                   exptime * gain * binx),
00191            "Error correcting rebinned spectrum for gain, exposure time, binning");
00192     }
00193     
00194     /* 
00195      * Correct for atmospheric extinction 
00196      */
00197     {
00198     double airmass;
00199     double dlambda, lambda_start;
00200     int order;
00201 
00202     {
00203         double airmass_start, airmass_end;
00204         
00205         check( airmass_start = uves_pfits_get_airmass_start(raw_header),
00206            "Error reading airmass start");
00207         
00208         check( airmass_end = uves_pfits_get_airmass_end(raw_header),
00209            "Error reading airmass end");
00210         
00211         /* Use arithmetic mean of airmass start/end */
00212         airmass = (airmass_start + airmass_end) / 2;
00213     
00214     }
00215 
00216     uves_msg("Correcting for extinction through airmass %f", airmass);
00217         
00218     check( dlambda = uves_pfits_get_cdelt1(spectrum_header),
00219            "Error reading bin width from header");
00220     
00221     for (order = 1; order <= norders; order++)
00222         {
00223         int trace;
00224 
00225         /* If spectrum was already merged, then read crval1,
00226          * otherwise read wstart for each order
00227          */
00228         
00229         if (norders == 1)
00230             {
00231             check( lambda_start = uves_pfits_get_crval1(spectrum_header),
00232                    "Error reading start wavelength from header");    
00233             }
00234         else
00235             {
00236             check( lambda_start = uves_pfits_get_wstart(spectrum_header, order),
00237                    "Error reading start wavelength from header");    
00238             }
00239 
00240         for (trace = 1; trace <= n_traces; trace++)
00241             {
00242             int spectrum_row = (order - 1)*n_traces + trace;
00243             int x;
00244             
00245             for (x = 1; x <= nx; x++)
00246                 {
00247                 int pis_rejected1;
00248                 int pis_rejected2;
00249                 double flux;
00250                 double dflux = 0;
00251                 double extinction;
00252                 double lambda;
00253 
00254                 lambda = lambda_start + (x-1) * dlambda;
00255                 
00256                 flux  = cpl_image_get(scaled, x, spectrum_row, &pis_rejected1);
00257                 if (scaled_error != NULL)
00258                     {
00259                     dflux = cpl_image_get(*scaled_error, x, 
00260                                   spectrum_row, &pis_rejected2);
00261                     }
00262 
00263                 if (!pis_rejected1 && (scaled_error == NULL || !pis_rejected2))
00264                     {
00265                                         int istart = 0;
00266 
00267                     /* Read extinction (units: magnitude per airmass) */
00268                     check( extinction = 
00269                            uves_spline_hermite_table(
00270                            lambda, atm_extinction,
00271                            "LAMBDA", "LA_SILLA", &istart),
00272                            "Error interpolating extinction coefficient");
00273                     
00274                     /* Correct for extinction using
00275                      * the magnitude/flux relation
00276                      * m = -2.5 log_10 F
00277                      *  => 
00278                      * F = 10^(-m*0.4)
00279                      *
00280                      * m_top-of-atmosphere = m - ext.coeff*airmass
00281                      * F_top-of-atmosphere = F * 10^(0.4 * ext.coeff*airmass)
00282                      */
00283 
00284                     cpl_image_set(
00285                         scaled, x, spectrum_row,
00286                         flux * pow(10, 0.4 * extinction * airmass));
00287                     if (scaled_error != NULL)
00288                         {
00289                         cpl_image_set(
00290                             *scaled_error, x, spectrum_row,
00291                             dflux * pow(10, 0.4 * extinction * airmass));
00292                         }
00293                     }
00294                 else
00295                     {
00296                     cpl_image_reject(scaled, x, spectrum_row);
00297                     if (scaled_error != NULL)
00298                         {
00299                         cpl_image_reject(*scaled_error, x, spectrum_row);
00300                         }
00301                     }
00302                 } /* for each x */
00303 
00304             } /* for each (possibly only 1) trace */
00305 
00306         } /* for each (possibly only 1) order */
00307     }
00308     
00309   cleanup:
00310     if (cpl_error_get_code() != CPL_ERROR_NONE)
00311     {
00312         uves_free_image(&scaled);
00313         if (scaled_error != NULL)
00314         {
00315             uves_free_image(scaled_error);
00316         }
00317     }
00318     
00319     return scaled;
00320 }
00321 

Generated on Tue Jun 19 14:39:17 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6