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 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037
00038 #include "xsh_irplib_mkmaster.h"
00039 #include "xsh_pfits.h"
00040 #include "xsh_msg.h"
00041
00045
00046
00048
00055
00056
00057
00069
00070 static cpl_vector *
00071 irplib_imagelist_get_clean_mean_levels(const cpl_imagelist* iml,
00072 const double kappa,
00073 const int nclip,
00074 const double tolerance)
00075 {
00076
00077 const cpl_image* img=NULL;
00078 int size=0;
00079 int i=0;
00080 cpl_vector* levels=NULL;
00081 double* pval=NULL;
00082 double mean=0;
00083 double stdev=0;
00084
00085
00086 cpl_error_ensure(iml != NULL, CPL_ERROR_NULL_INPUT, return(levels),
00087 "Null input image list");
00088 cpl_error_ensure(kappa >= 0, CPL_ERROR_ILLEGAL_INPUT, return(levels),
00089 "Must be kappa>0");
00090
00091 size=cpl_imagelist_get_size(iml);
00092 levels=cpl_vector_new(size);
00093 pval=cpl_vector_get_data(levels);
00094
00095 for(i=0;i<size;i++) {
00096 img=cpl_imagelist_get_const(iml,i);
00097 xsh_ksigma_clip(img,1,1, cpl_image_get_size_x(img),
00098 cpl_image_get_size_y(img),
00099 nclip,kappa,tolerance,&mean,&stdev);
00100 cpl_msg_info(cpl_func,"Ima %d mean level: %g",i+1,mean);
00101 pval[i]=mean;
00102 }
00103
00104
00105 return levels;
00106 }
00107
00108
00116
00117 static cpl_error_code
00118 irplib_imagelist_subtract_values(cpl_imagelist** iml, cpl_vector* values)
00119 {
00120
00121 cpl_image* img=NULL;
00122 int size=0;
00123 int i=0;
00124 double* pval=NULL;
00125
00126 size=cpl_imagelist_get_size(*iml);
00127 pval=cpl_vector_get_data(values);
00128
00129 for(i=0;i<size;i++) {
00130 img=cpl_imagelist_get(*iml,i);
00131 cpl_image_subtract_scalar(img,pval[i]);
00132 cpl_imagelist_set(*iml,img,i);
00133 }
00134
00135 return cpl_error_get_code();
00136 }
00137
00138
00151
00152 static double
00153 irplib_vector_ksigma(cpl_vector *values,
00154 const double klow, const double khigh, int kiter)
00155 {
00156 cpl_vector *accepted;
00157 double mean = 0.0;
00158 double sigma = 0.0;
00159 double *data = cpl_vector_get_data(values);
00160 int n = cpl_vector_get_size(values);
00161 int ngood = n;
00162 int count = 0;
00163 int i;
00164
00165
00166
00167
00168
00169
00170 mean = cpl_vector_get_median(values);
00171
00172 for (i = 0; i < n; i++) {
00173 sigma += (mean - data[i]) * (mean - data[i]);
00174 }
00175 sigma = sqrt(sigma / (n - 1));
00176
00177 while (kiter) {
00178 count = 0;
00179 for (i = 0; i < ngood; i++) {
00180 if (data[i]-mean < khigh*sigma && mean-data[i] < klow*sigma) {
00181 data[count] = data[i];
00182 ++count;
00183 }
00184 }
00185
00186 if (count == 0)
00187 break;
00188
00189
00190
00191
00192
00193
00194
00195 accepted = cpl_vector_wrap(count, data);
00196 mean = cpl_vector_get_mean(accepted);
00197 if(count>1) {
00198 sigma = cpl_vector_get_stdev(accepted);
00199 }
00200 cpl_vector_unwrap(accepted);
00201
00202 if (count == ngood) {
00203 break;
00204 }
00205 ngood = count;
00206 --kiter;
00207 }
00208
00209 return mean;
00210 }
00211
00212
00231 static cpl_image *
00232 irplib_imagelist_ksigma_stack(const cpl_imagelist *imlist,
00233 double klow, double khigh, int kiter)
00234 {
00235 int ni, nx, ny, npix;
00236 cpl_image *out_ima=NULL;
00237 cpl_imagelist *loc_iml=NULL;
00238 float *pout_ima=NULL;
00239 cpl_image *image=NULL;
00240 const float **data=NULL;
00241 double *med=NULL;
00242 cpl_vector *time_line=NULL;
00243
00244 double *ptime_line=NULL;
00245 int i, j;
00246 double mean_of_medians=0;
00247
00248 cpl_error_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, return(out_ima),
00249 "Null input image list");
00250
00251 ni = cpl_imagelist_get_size(imlist);
00252 loc_iml = cpl_imagelist_duplicate(imlist);
00253 image = cpl_imagelist_get(loc_iml, 0);
00254 nx = cpl_image_get_size_x(image);
00255 ny = cpl_image_get_size_y(image);
00256 npix = nx * ny;
00257
00258 out_ima = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00259 pout_ima = cpl_image_get_data_float(out_ima);
00260
00261 time_line = cpl_vector_new(ni);
00262
00263 ptime_line = cpl_vector_get_data(time_line);
00264
00265 data = cpl_calloc(sizeof(float *), ni);
00266 med = cpl_calloc(sizeof(double), ni);
00267
00268 for (i = 0; i < ni; i++) {
00269 image = cpl_imagelist_get(loc_iml, i);
00270 med[i]=cpl_image_get_median(image);
00271 cpl_image_subtract_scalar(image,med[i]);
00272 data[i] = cpl_image_get_data_float(image);
00273 mean_of_medians+=med[i];
00274
00275 }
00276 mean_of_medians/=ni;
00277
00278 for (i = 0; i < npix; i++) {
00279 for (j = 0; j < ni; j++) {
00280 ptime_line[j] = data[j][i];
00281 }
00282 pout_ima[i] = irplib_vector_ksigma(time_line, klow, khigh, kiter);
00283 }
00284
00285 cpl_image_add_scalar(out_ima,mean_of_medians);
00286
00287
00288 cpl_free(data);
00289 cpl_free(med);
00290 cpl_vector_delete(time_line);
00291 cpl_imagelist_delete(loc_iml);
00292
00293 return out_ima;
00294
00295 }
00296
00297
00298
00299
00300
00312
00313 cpl_image*
00314 xsh_irplib_mkmaster_mean(cpl_imagelist* images,const double kappa, const int nclip,
00315 const double tolerance,const double klow,const double khigh,const int niter)
00316 {
00317
00318 cpl_image* master=NULL;
00319 cpl_vector* levels=NULL;
00320 double mean=0;
00321 cpl_imagelist* iml=NULL;
00322
00323 cpl_msg_info(cpl_func,"method mean");
00324 iml=cpl_imagelist_duplicate(images);
00325 levels=irplib_imagelist_get_clean_mean_levels(iml,kappa,nclip,tolerance);
00326 mean=cpl_vector_get_mean(levels);
00327 cpl_msg_info(cpl_func,"Master mean level: %g",mean);
00328
00329 irplib_imagelist_subtract_values(&iml,levels);
00330
00331 master = irplib_imagelist_ksigma_stack(iml,klow,khigh,niter);
00332 cpl_image_add_scalar(master,mean);
00333
00334 cpl_vector_delete(levels);
00335 cpl_imagelist_delete(iml);
00336
00337 return master;
00338
00339 }
00340
00341
00342
00343
00355
00356 cpl_image*
00357 xsh_irplib_mkmaster_median(cpl_imagelist* images,const double kappa, const int nclip,
00358 const double tolerance)
00359 {
00360
00361 cpl_image* master=NULL;
00362 cpl_vector* levels=NULL;
00363 double mean=0;
00364 cpl_imagelist* iml=NULL;
00365
00366 cpl_msg_info(cpl_func,"method median");
00367 iml=cpl_imagelist_duplicate(images);
00368 levels=irplib_imagelist_get_clean_mean_levels(iml,kappa,nclip,tolerance);
00369
00370 mean=cpl_vector_get_mean(levels);
00371 cpl_msg_info(cpl_func,"Master mean level: %g",mean);
00372 irplib_imagelist_subtract_values(&iml,levels);
00373
00374 master = cpl_imagelist_collapse_median_create(iml);
00375
00376 cpl_image_add_scalar(master,mean);
00377
00378 cpl_vector_delete(levels);
00379 cpl_imagelist_delete(iml);
00380
00381 return master;
00382
00383 }
00384
00385 cpl_imagelist*
00386 xsh_irplib_mkmaster_dark_fill_imagelist(const cpl_imagelist* raw_images,
00387 cpl_propertylist** raw_headers, const cpl_image* master_bias,
00388 double* mean_exptime) {
00389
00390
00391
00392 cpl_imagelist* preproc_images = NULL;
00393 int i = 0;
00394 cpl_image* current_dark = NULL;
00395 double min_exptime = 0;
00396 double max_exptime = 0;
00397
00398 preproc_images = cpl_imagelist_new();
00399 for (i = 0; i < cpl_imagelist_get_size(raw_images); i++) {
00400 double exposure_time = 0.0;
00401 const cpl_propertylist *current_header;
00402
00403 current_dark = cpl_image_duplicate(cpl_imagelist_get_const(raw_images, i));
00404 current_header = raw_headers[i];
00405
00406
00407 if (master_bias != NULL) {
00408
00409 cpl_image_subtract(current_dark, master_bias);
00410 } else {
00411
00412 }
00413
00414 exposure_time = xsh_pfits_get_exptime(current_header);
00415
00416 if (i == 0 || exposure_time < min_exptime) {
00417 min_exptime = exposure_time;
00418 }
00419 if (i == 0 || exposure_time > max_exptime) {
00420 max_exptime = exposure_time;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 cpl_imagelist_set(preproc_images, current_dark, i);
00432
00433
00434
00435 current_dark = NULL;
00436 }
00437
00438
00439
00440 cpl_msg_info(cpl_func,
00441 "Exposure times range from %e s to %e s (%e %% variation)", min_exptime,
00442 max_exptime, 100 * (max_exptime - min_exptime) / min_exptime);
00443
00444 if ((max_exptime - min_exptime) / min_exptime > .001) {
00445 cpl_msg_warning(cpl_func, "Exposure times differ by %e %%",
00446 100 * (max_exptime - min_exptime) / min_exptime);
00447 }
00448
00449
00450 *mean_exptime=0.5 * (max_exptime + min_exptime);
00451 return preproc_images;
00452 }
00453