uves_flatfield.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: jmlarsen $
00022  * $Date: 2007/08/21 13:08:26 $
00023  * $Revision: 1.27 $
00024  * $Name: uves-3_9_0 $
00025  * $Log: uves_flatfield.c,v $
00026  * Revision 1.27  2007/08/21 13:08:26  jmlarsen
00027  * Removed irplib_access module, largely deprecated by CPL-4
00028  *
00029  * Revision 1.26  2007/06/06 08:17:33  amodigli
00030  * replace tab with 4 spaces
00031  *
00032  * Revision 1.25  2007/05/24 13:07:46  jmlarsen
00033  * Fail if the provided flat-field has unreasonable (zero, nan or inf) mean value
00034  *
00035  * Revision 1.24  2007/05/22 11:36:37  jmlarsen
00036  * Removed MIDAS flag for good
00037  *
00038  * Revision 1.23  2006/11/15 15:02:14  jmlarsen
00039  * Implemented const safe workarounds for CPL functions
00040  *
00041  * Revision 1.21  2006/11/15 14:04:08  jmlarsen
00042  * Removed non-const version of parameterlist_get_first/last/next which is already
00043  * in CPL, added const-safe wrapper, unwrapper and deallocator functions
00044  *
00045  * Revision 1.20  2006/11/13 14:23:55  jmlarsen
00046  * Removed workarounds for CPL const bugs
00047  *
00048  * Revision 1.19  2006/11/06 15:19:41  jmlarsen
00049  * Removed unused include directives
00050  *
00051  * Revision 1.18  2006/08/17 13:56:53  jmlarsen
00052  * Reduced max line length
00053  *
00054  * Revision 1.17  2006/08/17 09:16:40  jmlarsen
00055  * Removed CPL2 code
00056  *
00057  * Revision 1.16  2006/08/10 10:49:57  jmlarsen
00058  * Removed workaround for cpl_image_get_bpm
00059  *
00060  * Revision 1.15  2006/06/16 08:23:31  jmlarsen
00061  * Changed 0 -> false
00062  *
00063  * Revision 1.14  2006/04/24 09:20:12  jmlarsen
00064  * Always use the MIDAS normalization
00065  *
00066  * Revision 1.13  2006/03/24 14:16:43  jmlarsen
00067  * Changed order of for loops for efficiency
00068  *
00069  * Revision 1.12  2006/03/03 13:54:11  jmlarsen
00070  * Changed syntax of check macro
00071  *
00072  * Revision 1.11  2006/02/21 14:26:54  jmlarsen
00073  * Minor changes
00074  *
00075  * Revision 1.10  2006/02/03 07:46:30  jmlarsen
00076  * Moved recipe implementations to ./uves directory
00077  *
00078  * Revision 1.9  2006/01/31 08:24:16  jmlarsen
00079  * Wrapper for cpl_image_get_bpm
00080  *
00081  * Revision 1.8  2006/01/25 16:13:20  jmlarsen
00082  * Changed interface of gauss.fitting routine
00083  *
00084  * Revision 1.7  2005/12/19 16:17:56  jmlarsen
00085  * Replaced bool -> int
00086  *
00087  * Revision 1.6  2005/12/16 14:22:23  jmlarsen
00088  * Removed midas test data; Added sof files
00089  *
00090  * Revision 1.5  2005/12/02 10:41:49  jmlarsen
00091  * Minor update
00092  *
00093  * Revision 1.4  2005/11/28 08:18:12  jmlarsen
00094  * Replaced cpl_mask_get_bpm -> cpl_image_get_bpm
00095  *
00096  * Revision 1.3  2005/11/25 09:27:00  jmlarsen
00097  * Switched off time component
00098  *
00099  * Revision 1.2  2005/11/24 11:54:46  jmlarsen
00100  * Added support for CPL 3 interface
00101  *
00102  * Revision 1.1  2005/11/11 13:18:54  jmlarsen
00103  * Reorganized code, renamed source files
00104  *
00105  */
00106 
00107 #ifdef HAVE_CONFIG_H
00108 #  include <config.h>
00109 #endif
00110 
00111 /*----------------------------------------------------------------------------*/
00118 /*----------------------------------------------------------------------------*/
00121 /*-----------------------------------------------------------------------------
00122                                 Includes
00123  -----------------------------------------------------------------------------*/
00124 
00125 #include <uves_flatfield.h>
00126 #include <uves_utils.h>
00127 #include <uves_utils_wrappers.h>
00128 #include <uves_error.h>
00129 
00130 #include <cpl.h>
00131 
00132 /*-----------------------------------------------------------------------------
00133                             Functions prototypes
00134  -----------------------------------------------------------------------------*/
00135 
00136 /*-----------------------------------------------------------------------------
00137                             Implementation
00138  -----------------------------------------------------------------------------*/
00139 
00140 
00141 /*----------------------------------------------------------------------------*/
00162 /*----------------------------------------------------------------------------*/
00163 cpl_error_code
00164 uves_flatfielding(cpl_image *image, cpl_image *noise, 
00165           const cpl_image *master_flat, const cpl_image *mflat_noise)
00166 {
00167     double     *image_data   = NULL;      /* We have to get direct pointers because of the slow */
00168     cpl_mask   *image_mask   = NULL;      /*  bad pix handling in cpl_image_get()  CPLv2-3      */
00169     cpl_binary *image_bad    = NULL;  
00170 
00171     double     *noise_data   = NULL;   
00172     cpl_mask   *noise_mask   = NULL;   
00173     cpl_binary *noise_bad    = NULL;
00174 
00175     const double     *mf_data      = NULL;   
00176     const cpl_mask   *mf_mask      = NULL;   
00177     const cpl_binary *mf_bad       = NULL;  
00178 
00179     const double     *mfnoise_data = NULL;   
00180     const cpl_mask   *mfnoise_mask = NULL;   
00181     const cpl_binary *mfnoise_bad  = NULL;  
00182 
00183 
00184     double ff_mean;
00185     int nx, ny;
00186     int x, y;
00187     
00188     passure( image != NULL, " ");
00189     passure( master_flat != NULL, " ");
00190     passure( noise == NULL || mflat_noise != NULL, " ");
00191 
00192     passure( cpl_image_get_type(image) == CPL_TYPE_DOUBLE, 
00193          "Image must be double");
00194     passure( noise == NULL || cpl_image_get_type(noise) == CPL_TYPE_DOUBLE, 
00195          "Image must be double");
00196     passure( cpl_image_get_type(master_flat) == CPL_TYPE_DOUBLE, 
00197          "Image must be double");
00198     passure( mflat_noise == NULL || cpl_image_get_type(mflat_noise) == CPL_TYPE_DOUBLE,
00199          "Image must be double");
00200 
00201     nx = cpl_image_get_size_x(image);
00202     ny = cpl_image_get_size_y(image);
00203     
00204     assure( nx == cpl_image_get_size_x(master_flat),
00205         CPL_ERROR_INCOMPATIBLE_INPUT,
00206         "Input image and master flat field image have different widths: "
00207         "%d and %d (pixels)",
00208         nx, cpl_image_get_size_x(master_flat));
00209     
00210     assure( ny == cpl_image_get_size_y(master_flat),
00211         CPL_ERROR_INCOMPATIBLE_INPUT,
00212         "Input image and master flat field image have different heights: "
00213         "%d and %d (pixels)",
00214         ny, cpl_image_get_size_y(master_flat));
00215 
00216     /* Get all pointers */
00217     image_data = cpl_image_get_data(image);
00218     image_mask = cpl_image_get_bpm(image);
00219     image_bad  = cpl_mask_get_data(image_mask);
00220 
00221     mf_data = cpl_image_get_data_const(master_flat);
00222     mf_mask = cpl_image_get_bpm_const(master_flat);
00223     mf_bad  = cpl_mask_get_data_const(mf_mask);
00224 
00225     if (noise != NULL)
00226     {
00227         noise_data = cpl_image_get_data(noise);
00228             noise_mask = cpl_image_get_bpm(noise);
00229         noise_bad  = cpl_mask_get_data(noise_mask);
00230 
00231         mfnoise_data = cpl_image_get_data_const(mflat_noise);
00232         mfnoise_mask = cpl_image_get_bpm_const(mflat_noise);
00233         mfnoise_bad  = cpl_mask_get_data_const(mfnoise_mask);
00234     }
00235 
00236     if (false)
00237     {
00238         /* This would actually be the proper thing to do (take bad
00239            pixels into account), but for backwards compatibility
00240            with MIDAS, pretend bad pixels have value zero.
00241            This is done in order to get the same normalization and
00242            be able to use response curves produces by the MIDAS pipeline.
00243 
00244            (The difference in normalization is usually ~10% or so)
00245         */
00246         check( ff_mean = cpl_image_get_mean(master_flat),
00247            "Could not read average flux of master flat image");
00248     }
00249     else
00250     {
00251         /* To get same normalization as MIDAS (which doesn't take bad pixels
00252          * into account), calculate 'ff_mean' while assuming that bad pixels
00253          * have value zero.
00254          */
00255         check( ff_mean = cpl_image_get_flux(master_flat) / (nx * ny),
00256            "Could not read average flux of master flat image");
00257     }
00258     
00259     assure( ff_mean != 0 && !irplib_isnan(ff_mean) &&
00260             !irplib_isinf(ff_mean), CPL_ERROR_ILLEGAL_INPUT,
00261             "Flat-field mean value is %g! Please provide a better flat-field",
00262             ff_mean );
00263     
00264     /* Divide by normalized master flat */
00265     for (y = 0; y < ny; y++)
00266     {
00267         for (x = 0; x < nx; x++)
00268         {
00269             double mf, mf_noise = 0;
00270             double flux, flux_noise = 0, flux_corrected = 0;
00271             double noise_corrected = 0;
00272             cpl_binary pis_rejected;
00273             bool is_bad = false;
00274             
00275             mf           = mf_data[x + y*nx];
00276             pis_rejected = mf_bad [x + y*nx];
00277             is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00278             /* Slow: mf = cpl_image_get(master_flat, x, y, &pis_rejected);
00279                is_bad = is_bad || pis_rejected; */
00280 
00281             if (noise != NULL)
00282             {
00283                 flux_noise   = noise_data[x + y*nx];
00284                 pis_rejected = noise_bad [x + y*nx];
00285                 is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00286                 /* Slow: flux_noise = 
00287                    cpl_image_get(image_noise, x, y, &pis_rejected); 
00288                    is_bad = is_bad || pis_rejected; */
00289                 
00290                 mf_noise     = mfnoise_data[x + y*nx];
00291                 pis_rejected = mfnoise_bad [x + y*nx];
00292                 is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00293                 /* Slow: mf_noise = 
00294                    cpl_image_get(mflat_noise, x, y, &pis_rejected); 
00295                    is_bad = is_bad || pis_rejected; */
00296             }
00297             
00298             flux         = image_data[x + y*nx];
00299             pis_rejected = image_bad [x + y*nx];
00300             is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00301             /* Slow: flux = cpl_image_get(image, x, y, &pis_rejected); 
00302                is_bad = is_bad || pis_rejected; */
00303             
00304 
00305 
00306 
00307             if (mf > 0)
00308             {
00309                 flux_corrected = (flux / mf) * ff_mean;
00310             }
00311             else
00312             {
00313                 /* Some mf frames (produced by MIDAS) have have
00314                    negative flux values because of improper
00315                    background subtraction */
00316                 is_bad = true;
00317             }
00318 
00319             if (noise != NULL)
00320             {
00321                 noise_corrected = uves_error_fraction(
00322                 flux, mf, flux_noise, mf_noise)
00323                 * ff_mean;
00324             }
00325             
00326             if (is_bad) 
00327             {
00328                 image_bad[x + nx*y] = CPL_BINARY_1;
00329                 /* Slow: cpl_image_reject(image, x, y);*/
00330                 if (noise != NULL)
00331                 {
00332                     noise_bad[x + nx*y] = CPL_BINARY_1;
00333                     /* Slow: cpl_image_reject(noise, x, y);*/
00334                 }
00335             }
00336             else
00337             {
00338                 image_data[x + nx*y] = flux_corrected;
00339                 /* Slow: cpl_image_set(image, x, y, flux_corrected); */
00340                 if (noise != NULL)
00341                 {
00342                     noise_data[x + nx*y] = noise_corrected;
00343                     /* Slow: cpl_image_set(noise, x, y, noise_corrected); */
00344                 }
00345             }
00346         }
00347     }
00348     
00349   cleanup:
00350     return cpl_error_get_code();
00351 }
00352 
00353 /*----------------------------------------------------------------------------*/
00363 /*----------------------------------------------------------------------------*/
00364 flatfielding_method
00365 uves_get_flatfield_method(const cpl_parameterlist *parameters, 
00366               const char *context, const char *subcontext)
00367 {
00368     const char *ff = "";
00369     flatfielding_method result = 0;
00370 
00371     check( uves_get_parameter(parameters, context, subcontext, "ffmethod", CPL_TYPE_STRING, &ff),
00372        "Could not read parameter");
00373     
00374     if      (strcmp(ff, "pixel"  ) == 0) result = FF_PIXEL;
00375     else if (strcmp(ff, "extract") == 0) result = FF_EXTRACT;
00376     else if (strcmp(ff, "no"     ) == 0) result = FF_NO;
00377     else
00378     {
00379         assure(false, CPL_ERROR_ILLEGAL_INPUT, "No such flat-fielding method: '%s'", ff);
00380     }
00381     
00382   cleanup:
00383     return result;
00384 }
00385 

Generated on Fri Apr 18 14:11:42 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1