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

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