00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 #ifdef HAVE_CONFIG_H
00132 # include <config.h>
00133 #endif
00134
00135
00142
00145
00146
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
00158
00159
00160
00161
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;
00192 cpl_mask *image_mask = NULL;
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
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
00273
00274
00275
00276
00277
00278
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
00286
00287
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
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
00313
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
00321
00322
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
00328
00329
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
00336
00337
00338
00339
00340
00341 if (mf > 0)
00342 {
00343 flux_corrected = (flux / mf) * ff_mean;
00344 }
00345 else
00346 {
00347
00348
00349
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
00364 if (noise != NULL)
00365 {
00366 noise_bad[x + nx*y] = CPL_BINARY_1;
00367
00368 }
00369 }
00370 else
00371 {
00372 image_data[x + nx*y] = flux_corrected;
00373
00374 if (noise != NULL)
00375 {
00376 noise_data[x + nx*y] = noise_corrected;
00377
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