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 #include <string.h>
00038 #include "irplib_mkmaster.h"
00039
00040
00044
00045
00047
00054
00055
00056
00068
00069 static cpl_vector *
00070 irplib_imagelist_get_clean_mean_levels(const cpl_imagelist* iml,
00071 const double kappa,
00072 const int nclip,
00073 const double tolerance)
00074 {
00075
00076 int size=0;
00077 int i=0;
00078 cpl_vector* levels=NULL;
00079 double* pval=NULL;
00080 double mean=0;
00081 double stdev=0;
00082
00083
00084 cpl_error_ensure(iml != NULL, CPL_ERROR_NULL_INPUT, return(levels),
00085 "Null input image list");
00086 cpl_error_ensure(kappa >= 0, CPL_ERROR_ILLEGAL_INPUT, return(levels),
00087 "Must be kappa>0");
00088
00089 size=cpl_imagelist_get_size(iml);
00090 levels=cpl_vector_new(size);
00091 pval=cpl_vector_get_data(levels);
00092
00093 for(i=0;i<size;i++) {
00094 const cpl_image* img=cpl_imagelist_get_const(iml,i);
00095 irplib_ksigma_clip(img,1,1,
00096 cpl_image_get_size_x(img),
00097 cpl_image_get_size_y(img),
00098 nclip,kappa,tolerance,&mean,&stdev);
00099 cpl_msg_info(cpl_func,"Ima %d mean level: %g",i+1,mean);
00100 pval[i]=mean;
00101 }
00102
00103
00104 return levels;
00105 }
00106
00107
00115
00116 static cpl_error_code
00117 irplib_imagelist_subtract_values(cpl_imagelist** iml, cpl_vector* values)
00118 {
00119
00120 int size=0;
00121 int i=0;
00122 double* pval=NULL;
00123
00124 size=cpl_imagelist_get_size(*iml);
00125 pval=cpl_vector_get_data(values);
00126
00127 for(i=0;i<size;i++) {
00128 cpl_image* img=cpl_imagelist_get(*iml,i);
00129 cpl_image_subtract_scalar(img,pval[i]);
00130 cpl_imagelist_set(*iml,img,i);
00131 }
00132
00133 return cpl_error_get_code();
00134 }
00135
00136
00149
00150 static double
00151 irplib_vector_ksigma(cpl_vector *values,
00152 const double klow, const double khigh, int kiter)
00153 {
00154 double mean ;
00155 double sigma = 0.0;
00156 double *data = cpl_vector_get_data(values);
00157 int n = cpl_vector_get_size(values);
00158 int ngood = n;
00159 int i;
00160
00161
00162
00163
00164
00165
00166 mean = cpl_vector_get_median(values);
00167
00168 for (i = 0; i < n; i++) {
00169 sigma += (mean - data[i]) * (mean - data[i]);
00170 }
00171 sigma = sqrt(sigma / (n - 1));
00172
00173 while (kiter) {
00174 cpl_vector *accepted;
00175 int count = 0;
00176 for (i = 0; i < ngood; i++) {
00177 if (data[i]-mean < khigh*sigma && mean-data[i] < klow*sigma) {
00178 data[count] = data[i];
00179 ++count;
00180 }
00181 }
00182
00183 if (count == 0)
00184 break;
00185
00186
00187
00188
00189
00190
00191
00192 accepted = cpl_vector_wrap(count, data);
00193 mean = cpl_vector_get_mean(accepted);
00194 if(count>1) {
00195 sigma = cpl_vector_get_stdev(accepted);
00196 }
00197 cpl_vector_unwrap(accepted);
00198
00199 if (count == ngood) {
00200 break;
00201 }
00202 ngood = count;
00203 --kiter;
00204 }
00205
00206 return mean;
00207 }
00208
00209
00228 static cpl_image *
00229 irplib_imagelist_ksigma_stack(const cpl_imagelist *imlist,
00230 double klow, double khigh, int kiter)
00231 {
00232 int ni, nx, ny, npix;
00233 cpl_image *out_ima=NULL;
00234 cpl_imagelist *loc_iml=NULL;
00235 double *pout_ima=NULL;
00236 cpl_image *image=NULL;
00237 const double **data=NULL;
00238 double *med=NULL;
00239 cpl_vector *time_line=NULL;
00240
00241 double *ptime_line=NULL;
00242 int i, j;
00243 double mean_of_medians=0;
00244
00245 cpl_error_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, return(out_ima),
00246 "Null input image list");
00247
00248 ni = cpl_imagelist_get_size(imlist);
00249 loc_iml = cpl_imagelist_duplicate(imlist);
00250 image = cpl_imagelist_get(loc_iml, 0);
00251 nx = cpl_image_get_size_x(image);
00252 ny = cpl_image_get_size_y(image);
00253 npix = nx * ny;
00254
00255 out_ima = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
00256 pout_ima = cpl_image_get_data_double(out_ima);
00257
00258 time_line = cpl_vector_new(ni);
00259
00260 ptime_line = cpl_vector_get_data(time_line);
00261
00262 data = cpl_calloc(sizeof(double *), ni);
00263 med = cpl_calloc(sizeof(double), ni);
00264
00265 for (i = 0; i < ni; i++) {
00266 image = cpl_imagelist_get(loc_iml, i);
00267 med[i]=cpl_image_get_median(image);
00268 cpl_image_subtract_scalar(image,med[i]);
00269 data[i] = cpl_image_get_data_double(image);
00270 mean_of_medians+=med[i];
00271 }
00272 mean_of_medians/=ni;
00273
00274 for (i = 0; i < npix; i++) {
00275 for (j = 0; j < ni; j++) {
00276 ptime_line[j] = data[j][i];
00277 }
00278 pout_ima[i] = irplib_vector_ksigma(time_line, klow, khigh, kiter);
00279 }
00280
00281 cpl_image_add_scalar(out_ima,mean_of_medians);
00282
00283
00284 cpl_free(data);
00285 cpl_free(med);
00286 cpl_vector_delete(time_line);
00287 cpl_imagelist_delete(loc_iml);
00288
00289 return out_ima;
00290
00291 }
00292
00293
00294
00295
00296
00308
00309 cpl_image*
00310 irplib_mkmaster_mean(cpl_imagelist* images,const double kappa, const int nclip, const double tolerance,const double klow,const double khigh,const int niter)
00311 {
00312
00313 cpl_image* master=NULL;
00314 cpl_vector* levels=NULL;
00315 double mean=0;
00316 cpl_imagelist* iml=NULL;
00317
00318 cpl_msg_info(cpl_func,"method mean");
00319 iml=cpl_imagelist_duplicate(images);
00320 levels=irplib_imagelist_get_clean_mean_levels(iml,kappa,nclip,tolerance);
00321 mean=cpl_vector_get_mean(levels);
00322 cpl_msg_info(cpl_func,"Master mean level: %g",mean);
00323
00324 irplib_imagelist_subtract_values(&iml,levels);
00325
00326 master = irplib_imagelist_ksigma_stack(iml,klow,khigh,niter);
00327 cpl_image_add_scalar(master,mean);
00328
00329 cpl_vector_delete(levels);
00330 cpl_imagelist_delete(iml);
00331 return master;
00332
00333 }
00334
00335
00347
00348 cpl_image*
00349 irplib_mkmaster_median(cpl_imagelist* images,const double kappa, const int nclip, const double tolerance)
00350 {
00351
00352 cpl_image* master=NULL;
00353 cpl_vector* levels=NULL;
00354 double mean=0;
00355 cpl_imagelist* iml=NULL;
00356
00357 cpl_msg_info(cpl_func,"method median");
00358 iml=cpl_imagelist_duplicate(images);
00359 levels=irplib_imagelist_get_clean_mean_levels(iml,kappa,nclip,tolerance);
00360
00361 mean=cpl_vector_get_mean(levels);
00362 cpl_msg_info(cpl_func,"Master mean level: %g",mean);
00363 irplib_imagelist_subtract_values(&iml,levels);
00364
00365 master = cpl_imagelist_collapse_median_create(iml);
00366
00367 cpl_image_add_scalar(master,mean);
00368
00369 cpl_vector_delete(levels);
00370 cpl_imagelist_delete(iml);
00371
00372 return master;
00373
00374 }
00375
00376
00377 static cpl_error_code
00378 irplib_mkmaster_dark_qc(const cpl_imagelist* raw_images,
00379 cpl_imagelist* preproc_images,
00380 const cpl_parameterlist* parameters,
00381 const int pr_num_x, const int pr_num_y,
00382 const int pr_box_sx, const int pr_box_sy, const char* recipe_id,
00383 cpl_table* qclog) {
00384
00385 cpl_ensure_code(qclog !=NULL, CPL_ERROR_NULL_INPUT);
00386 cpl_ensure_code(recipe_id !=NULL, CPL_ERROR_NULL_INPUT);
00387 cpl_ensure_code(parameters !=NULL, CPL_ERROR_NULL_INPUT);
00388
00389 if (pr_num_x != 0 && pr_num_y != 0 && pr_box_sx != 0 && pr_box_sy != 0) {
00390 int i;
00391 for (i = 0; i < cpl_imagelist_get_size(raw_images); i++) {
00392 cpl_image* current_dark = cpl_image_duplicate(
00393 cpl_imagelist_get_const(preproc_images, i));
00394 cpl_msg_info(cpl_func, "Calculating QC parameters on raw dark frame %d",
00395 i);
00396
00397
00398
00399
00400
00401 cpl_image_delete(current_dark);
00402 }
00403 }
00404 return cpl_error_get_code();
00405 }
00406
00407
00417
00418 static double
00419 irplib_head_get_exptime(const cpl_propertylist * plist) {
00420 double result = 0;
00421
00422 result=cpl_propertylist_get_double(plist, "EXPTIME");
00423 cpl_ensure_code(result >= 0, CPL_ERROR_ILLEGAL_OUTPUT);
00424
00425 return result;
00426 }
00427
00428
00436
00437 static cpl_error_code
00438 irplib_head_set_exptime(cpl_propertylist *plist, double exptime)
00439 {
00440 cpl_propertylist_update_double(plist, "EXPTIME", exptime);
00441 cpl_propertylist_set_comment(plist, "EXPTIME", "Total integration time");
00442
00443 return cpl_error_get_code();
00444 }
00445
00446 static cpl_imagelist*
00447 irplib_mkmaster_dark_fill_imagelist(const cpl_imagelist* raw_images,
00448 cpl_propertylist** raw_headers, const cpl_image* master_bias,
00449 double* mean_exptime) {
00450
00451
00452
00453 cpl_imagelist* preproc_images = NULL;
00454 int i = 0;
00455 double min_exptime = 0;
00456 double max_exptime = 0;
00457
00458 preproc_images = cpl_imagelist_new();
00459 for (i = 0; i < cpl_imagelist_get_size(raw_images); i++) {
00460 double exposure_time = 0.0;
00461 cpl_image* current_dark = NULL;
00462 const cpl_propertylist *current_header;
00463
00464 current_dark = cpl_image_duplicate(cpl_imagelist_get_const(raw_images, i));
00465 current_header = raw_headers[i];
00466
00467
00468 if (master_bias != NULL) {
00469 cpl_msg_info(cpl_func, "Subtracting master bias");
00470 cpl_image_subtract(current_dark, master_bias);
00471 } else {
00472 cpl_msg_info(cpl_func, "Skipping bias subtraction");
00473 }
00474
00475 exposure_time = irplib_head_get_exptime(current_header);
00476
00477
00478 if (i == 0 || exposure_time < min_exptime) {
00479 min_exptime = exposure_time;
00480 }
00481 if (i == 0 || exposure_time > max_exptime) {
00482 max_exptime = exposure_time;
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 cpl_imagelist_set(preproc_images, current_dark, i);
00494
00495
00496
00497 current_dark = NULL;
00498 }
00499
00500
00501
00502 cpl_msg_info(cpl_func,
00503 "Exposure times range from %e s to %e s (%e %% variation)", min_exptime,
00504 max_exptime, 100 * (max_exptime - min_exptime) / min_exptime);
00505
00506 if ((max_exptime - min_exptime) / min_exptime > .001) {
00507 cpl_msg_warning(cpl_func, "Exposure times differ by %e %%",
00508 100 * (max_exptime - min_exptime) / min_exptime);
00509 }
00510
00511
00512 *mean_exptime=0.5 * (max_exptime + min_exptime);
00513 return preproc_images;
00514 }
00515
00516
00517 cpl_image *
00518 irplib_mdark_process_chip(const cpl_imagelist *raw_images,
00519 cpl_propertylist **raw_headers, const cpl_image *master_bias,
00520 cpl_propertylist *mdark_header, const cpl_parameterlist *parameters,
00521 const char* recipe_id, cpl_table* qclog, const int do_qc,
00522 const char* STACK_METHOD, const double STACK_KLOW, const double STACK_KHIGH,
00523 const int STACK_NITER,
00524 const int pr_num_x, const int pr_num_y,
00525 const int pr_box_sx, const int pr_box_sy) {
00526 cpl_image *master_dark = NULL;
00527 cpl_image *current_dark = NULL;
00528 cpl_imagelist *preproc_images = NULL;
00529 double mean_exptime = 0;
00530
00531
00532
00533 preproc_images = irplib_mkmaster_dark_fill_imagelist(raw_images, raw_headers,
00534 master_bias, &mean_exptime);
00535 if (do_qc) {
00536
00537 irplib_mkmaster_dark_qc(raw_images, preproc_images, parameters, pr_num_x,
00538 pr_num_y, pr_box_sx, pr_box_sy, recipe_id, qclog);
00539
00540 }
00541
00542 if (strcmp(STACK_METHOD, "MEDIAN") == 0) {
00543 cpl_msg_info(cpl_func, "Calculating stack median");
00544 master_dark = cpl_imagelist_collapse_median_create(preproc_images);
00545 } else {
00546 cpl_msg_info(cpl_func, "Calculating stack mean");
00547 master_dark = irplib_imagelist_ksigma_stack(preproc_images, STACK_KLOW,
00548 STACK_KHIGH, STACK_NITER);
00549
00550 }
00551 irplib_head_set_exptime(mdark_header, mean_exptime );
00552
00553 cpl_image_delete(current_dark);
00554 cpl_imagelist_delete(preproc_images);
00555 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00556 cpl_image_delete(master_dark);
00557 }
00558
00559 return master_dark;
00560 }
00561