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 #ifdef HAVE_CONFIG_H
00126 # include <config.h>
00127 #endif
00128
00129
00136
00139
00140
00141
00142 #include <string.h>
00143 #include <uves_flatfield.h>
00144 #include <uves_utils.h>
00145 #include <uves_utils_wrappers.h>
00146 #include <uves_error.h>
00147
00148 #include <cpl.h>
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00180
00181 cpl_error_code
00182 uves_flatfielding(cpl_image *image, cpl_image *noise,
00183 const cpl_image *master_flat, const cpl_image *mflat_noise)
00184 {
00185 double *image_data = NULL;
00186 cpl_mask *image_mask = NULL;
00187 cpl_binary *image_bad = NULL;
00188
00189 double *noise_data = NULL;
00190 cpl_mask *noise_mask = NULL;
00191 cpl_binary *noise_bad = NULL;
00192
00193 const double *mf_data = NULL;
00194 const cpl_mask *mf_mask = NULL;
00195 const cpl_binary *mf_bad = NULL;
00196
00197 const double *mfnoise_data = NULL;
00198 const cpl_mask *mfnoise_mask = NULL;
00199 cpl_mask *mfnoise_mask_own = NULL;
00200 cpl_mask *mf_mask_own = NULL;
00201 const cpl_binary *mfnoise_bad = NULL;
00202
00203
00204 double ff_mean;
00205 int nx, ny;
00206 int x, y;
00207
00208 passure( image != NULL, " ");
00209 passure( master_flat != NULL, " ");
00210 passure( noise == NULL || mflat_noise != NULL, " ");
00211
00212 passure( cpl_image_get_type(image) == CPL_TYPE_DOUBLE,
00213 "Image must be double");
00214 passure( noise == NULL || cpl_image_get_type(noise) == CPL_TYPE_DOUBLE,
00215 "Image must be double");
00216 passure( cpl_image_get_type(master_flat) == CPL_TYPE_DOUBLE,
00217 "Image must be double");
00218 passure( mflat_noise == NULL || cpl_image_get_type(mflat_noise) == CPL_TYPE_DOUBLE,
00219 "Image must be double");
00220
00221 nx = cpl_image_get_size_x(image);
00222 ny = cpl_image_get_size_y(image);
00223
00224 assure( nx == cpl_image_get_size_x(master_flat),
00225 CPL_ERROR_INCOMPATIBLE_INPUT,
00226 "Input image and master flat field image have different widths: "
00227 "%d and %d (pixels)",
00228 nx, cpl_image_get_size_x(master_flat));
00229
00230 assure( ny == cpl_image_get_size_y(master_flat),
00231 CPL_ERROR_INCOMPATIBLE_INPUT,
00232 "Input image and master flat field image have different heights: "
00233 "%d and %d (pixels)",
00234 ny, cpl_image_get_size_y(master_flat));
00235
00236
00237 check_nomsg(image_data = cpl_image_get_data(image));
00238 check_nomsg(image_mask = cpl_image_get_bpm(image));
00239 check_nomsg(image_bad = cpl_mask_get_data(image_mask));
00240
00241 check_nomsg(mf_data = cpl_image_get_data_const(master_flat));
00242 check_nomsg(mf_mask = cpl_image_get_bpm_const(master_flat));
00243 if(mf_mask==NULL) {
00244 mf_mask_own = cpl_mask_new(nx,ny);
00245 mf_mask = mf_mask_own ;
00246 }
00247 check_nomsg(mf_bad = cpl_mask_get_data_const(mf_mask));
00248
00249 if (noise != NULL)
00250 {
00251 check_nomsg(noise_data = cpl_image_get_data(noise));
00252 check_nomsg(noise_mask = cpl_image_get_bpm(noise));
00253 check_nomsg(noise_bad = cpl_mask_get_data(noise_mask));
00254
00255 check_nomsg(mfnoise_data = cpl_image_get_data_const(mflat_noise));
00256 check_nomsg(mfnoise_mask = cpl_image_get_bpm_const(mflat_noise));
00257 if(mfnoise_mask==NULL) {
00258 mfnoise_mask_own = cpl_mask_new(nx,ny);
00259 mfnoise_mask = mfnoise_mask_own ;
00260 }
00261 check_nomsg(mfnoise_bad = cpl_mask_get_data_const(mfnoise_mask));
00262 }
00263
00264 if (false)
00265 {
00266
00267
00268
00269
00270
00271
00272
00273
00274 check( ff_mean = cpl_image_get_mean(master_flat),
00275 "Could not read average flux of master flat image");
00276 }
00277 else
00278 {
00279
00280
00281
00282
00283 check( ff_mean = cpl_image_get_flux(master_flat) / (nx * ny),
00284 "Could not read average flux of master flat image");
00285 }
00286
00287 assure( ff_mean != 0 && !irplib_isnan(ff_mean) &&
00288 !irplib_isinf(ff_mean), CPL_ERROR_ILLEGAL_INPUT,
00289 "Flat-field mean value is %g! Please provide a better flat-field",
00290 ff_mean );
00291
00292
00293 for (y = 0; y < ny; y++)
00294 {
00295 for (x = 0; x < nx; x++)
00296 {
00297 double mf, mf_noise = 0;
00298 double flux, flux_noise = 0, flux_corrected = 0;
00299 double noise_corrected = 0;
00300 cpl_binary pis_rejected;
00301 bool is_bad = false;
00302
00303 mf = mf_data[x + y*nx];
00304 pis_rejected = mf_bad [x + y*nx];
00305 is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00306
00307
00308
00309 if (noise != NULL)
00310 {
00311 flux_noise = noise_data[x + y*nx];
00312 pis_rejected = noise_bad [x + y*nx];
00313 is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00314
00315
00316
00317
00318 mf_noise = mfnoise_data[x + y*nx];
00319 pis_rejected = mfnoise_bad [x + y*nx];
00320 is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00321
00322
00323
00324 }
00325
00326 flux = image_data[x + y*nx];
00327 pis_rejected = image_bad [x + y*nx];
00328 is_bad = is_bad || (pis_rejected == CPL_BINARY_1);
00329
00330
00331
00332
00333
00334
00335 if (mf > 0)
00336 {
00337 flux_corrected = (flux / mf) * ff_mean;
00338 }
00339 else
00340 {
00341
00342
00343
00344 is_bad = true;
00345 }
00346
00347 if (noise != NULL)
00348 {
00349 noise_corrected = uves_error_fraction(
00350 flux, mf, flux_noise, mf_noise)
00351 * ff_mean;
00352 }
00353
00354 if (is_bad)
00355 {
00356 image_bad[x + nx*y] = CPL_BINARY_1;
00357
00358 if (noise != NULL)
00359 {
00360 noise_bad[x + nx*y] = CPL_BINARY_1;
00361
00362 }
00363 }
00364 else
00365 {
00366 image_data[x + nx*y] = flux_corrected;
00367
00368 if (noise != NULL)
00369 {
00370 noise_data[x + nx*y] = noise_corrected;
00371
00372 }
00373 }
00374 }
00375 }
00376
00377 cleanup:
00378 if(mf_mask_own) uves_free_mask(&mf_mask_own);
00379 if(mfnoise_mask_own) uves_free_mask(&mfnoise_mask_own);
00380 return cpl_error_get_code();
00381 }
00382
00383
00393
00394 flatfielding_method
00395 uves_get_flatfield_method(const cpl_parameterlist *parameters,
00396 const char *context, const char *subcontext)
00397 {
00398 const char *ff = "";
00399 flatfielding_method result = 0;
00400
00401 check( uves_get_parameter(parameters, context, subcontext, "ffmethod", CPL_TYPE_STRING, &ff),
00402 "Could not read parameter");
00403
00404 if (strcmp(ff, "pixel" ) == 0) result = FF_PIXEL;
00405 else if (strcmp(ff, "extract") == 0) result = FF_EXTRACT;
00406 else if (strcmp(ff, "no" ) == 0) result = FF_NO;
00407 else
00408 {
00409 assure(false, CPL_ERROR_ILLEGAL_INPUT, "No such flat-fielding method: '%s'", ff);
00410 }
00411
00412 cleanup:
00413 return result;
00414 }
00415