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 const cpl_image* img=NULL;
00077 int size=0;
00078 int i=0;
00079 cpl_vector* levels=NULL;
00080 double* pval=NULL;
00081 double mean=0;
00082 double stdev=0;
00083
00084
00085 cpl_error_ensure(iml != NULL, CPL_ERROR_NULL_INPUT, return(levels),
00086 "Null input image list");
00087 cpl_error_ensure(kappa >= 0, CPL_ERROR_ILLEGAL_INPUT, return(levels),
00088 "Must be kappa>0");
00089
00090 size=cpl_imagelist_get_size(iml);
00091 levels=cpl_vector_new(size);
00092 pval=cpl_vector_get_data(levels);
00093
00094 for(i=0;i<size;i++) {
00095 img=cpl_imagelist_get_const(iml,i);
00096 irplib_ksigma_clip(img,1,1,
00097 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 double *pout_ima=NULL;
00239 cpl_image *image=NULL;
00240 const double **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_DOUBLE);
00259 pout_ima = cpl_image_get_data_double(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(double *), 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_double(image);
00273 mean_of_medians+=med[i];
00274 }
00275 mean_of_medians/=ni;
00276
00277 for (i = 0; i < npix; i++) {
00278 for (j = 0; j < ni; j++) {
00279 ptime_line[j] = data[j][i];
00280 }
00281 pout_ima[i] = irplib_vector_ksigma(time_line, klow, khigh, kiter);
00282 }
00283
00284 cpl_image_add_scalar(out_ima,mean_of_medians);
00285
00286
00287 cpl_free(data);
00288 cpl_free(med);
00289 cpl_vector_delete(time_line);
00290 cpl_imagelist_delete(loc_iml);
00291
00292 return out_ima;
00293
00294 }
00295
00296
00297
00298
00299
00311
00312 cpl_image*
00313 irplib_mkmaster_mean(cpl_imagelist* images,const double kappa, const int nclip, const double tolerance,const double klow,const double khigh,const int niter)
00314 {
00315
00316 cpl_image* master=NULL;
00317 cpl_vector* levels=NULL;
00318 double mean=0;
00319 cpl_imagelist* iml=NULL;
00320
00321 cpl_msg_info(cpl_func,"method mean");
00322 iml=cpl_imagelist_duplicate(images);
00323 levels=irplib_imagelist_get_clean_mean_levels(iml,kappa,nclip,tolerance);
00324 mean=cpl_vector_get_mean(levels);
00325 cpl_msg_info(cpl_func,"Master mean level: %g",mean);
00326
00327 irplib_imagelist_subtract_values(&iml,levels);
00328
00329 master = irplib_imagelist_ksigma_stack(iml,klow,khigh,niter);
00330 cpl_image_add_scalar(master,mean);
00331
00332 cpl_vector_delete(levels);
00333 cpl_imagelist_delete(iml);
00334 return master;
00335
00336 }
00337
00338
00350
00351 cpl_image*
00352 irplib_mkmaster_median(cpl_imagelist* images,const double kappa, const int nclip, const double tolerance)
00353 {
00354
00355 cpl_image* master=NULL;
00356 cpl_vector* levels=NULL;
00357 double mean=0;
00358 cpl_imagelist* iml=NULL;
00359
00360 cpl_msg_info(cpl_func,"method median");
00361 iml=cpl_imagelist_duplicate(images);
00362 levels=irplib_imagelist_get_clean_mean_levels(iml,kappa,nclip,tolerance);
00363
00364 mean=cpl_vector_get_mean(levels);
00365 cpl_msg_info(cpl_func,"Master mean level: %g",mean);
00366 irplib_imagelist_subtract_values(&iml,levels);
00367
00368 master = cpl_imagelist_collapse_median_create(iml);
00369
00370 cpl_image_add_scalar(master,mean);
00371
00372 cpl_vector_delete(levels);
00373 cpl_imagelist_delete(iml);
00374
00375 return master;
00376
00377 }
00378
00379
00380 static cpl_error_code
00381 irplib_mkmaster_dark_qc(const cpl_imagelist* raw_images,
00382 cpl_imagelist* preproc_images,
00383 const cpl_parameterlist* parameters,
00384 const int pr_num_x, const int pr_num_y,
00385 const int pr_box_sx, const int pr_box_sy, const char* recipe_id,
00386 cpl_table* qclog) {
00387
00388 cpl_ensure_code(qclog !=NULL, CPL_ERROR_NULL_INPUT);
00389 cpl_ensure_code(recipe_id !=NULL, CPL_ERROR_NULL_INPUT);
00390 cpl_ensure_code(parameters !=NULL, CPL_ERROR_NULL_INPUT);
00391
00392 int i = 0;
00393 cpl_image* current_dark = 0;
00394 if (pr_num_x != 0 && pr_num_y != 0 && pr_box_sx != 0 && pr_box_sy != 0) {
00395 for (i = 0; i < cpl_imagelist_get_size(raw_images); i++) {
00396 current_dark = cpl_image_duplicate(
00397 cpl_imagelist_get_const(preproc_images, i));
00398 cpl_msg_info(cpl_func, "Calculating QC parameters on raw dark frame %d",
00399 i);
00400
00401
00402
00403
00404 }
00405 }
00406 return cpl_error_get_code();
00407 }
00408
00409
00419
00420 static double
00421 irplib_head_get_exptime(const cpl_propertylist * plist) {
00422 double result = 0;
00423
00424 result=cpl_propertylist_get_double(plist, "EXPTIME");
00425 cpl_ensure_code(result >= 0, CPL_ERROR_ILLEGAL_OUTPUT);
00426
00427 return result;
00428 }
00429
00430
00438
00439 static cpl_error_code
00440 irplib_head_set_exptime(cpl_propertylist *plist, double exptime)
00441 {
00442 cpl_propertylist_update_double(plist, "EXPTIME", exptime);
00443 cpl_propertylist_set_comment(plist, "EXPTIME", "Total integration time");
00444
00445 return cpl_error_get_code();
00446 }
00447
00448 static cpl_imagelist*
00449 irplib_mkmaster_dark_fill_imagelist(const cpl_imagelist* raw_images,
00450 cpl_propertylist** raw_headers, const cpl_image* master_bias,
00451 double* mean_exptime) {
00452
00453
00454
00455 cpl_imagelist* preproc_images = NULL;
00456 int i = 0;
00457 cpl_image* current_dark = NULL;
00458 double min_exptime = 0;
00459 double max_exptime = 0;
00460
00461 preproc_images = cpl_imagelist_new();
00462 for (i = 0; i < cpl_imagelist_get_size(raw_images); i++) {
00463 double exposure_time = 0.0;
00464 const cpl_propertylist *current_header;
00465
00466 current_dark = cpl_image_duplicate(cpl_imagelist_get_const(raw_images, i));
00467 current_header = raw_headers[i];
00468
00469
00470 if (master_bias != NULL) {
00471 cpl_msg_info(cpl_func, "Subtracting master bias");
00472 cpl_image_subtract(current_dark, master_bias);
00473 } else {
00474 cpl_msg_info(cpl_func, "Skipping bias subtraction");
00475 }
00476
00477 exposure_time = irplib_head_get_exptime(current_header);
00478
00479
00480 if (i == 0 || exposure_time < min_exptime) {
00481 min_exptime = exposure_time;
00482 }
00483 if (i == 0 || exposure_time > max_exptime) {
00484 max_exptime = exposure_time;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 cpl_imagelist_set(preproc_images, current_dark, i);
00496
00497
00498
00499 current_dark = NULL;
00500 }
00501
00502
00503
00504 cpl_msg_info(cpl_func,
00505 "Exposure times range from %e s to %e s (%e %% variation)", min_exptime,
00506 max_exptime, 100 * (max_exptime - min_exptime) / min_exptime);
00507
00508 if ((max_exptime - min_exptime) / min_exptime > .001) {
00509 cpl_msg_warning(cpl_func, "Exposure times differ by %e %%",
00510 100 * (max_exptime - min_exptime) / min_exptime);
00511 }
00512
00513
00514 *mean_exptime=0.5 * (max_exptime + min_exptime);
00515 return preproc_images;
00516 }
00517
00518
00519 cpl_image *
00520 irplib_mdark_process_chip(const cpl_imagelist *raw_images,
00521 cpl_propertylist **raw_headers, const cpl_image *master_bias,
00522 cpl_propertylist *mdark_header, const cpl_parameterlist *parameters,
00523 const char* recipe_id, cpl_table* qclog, const int do_qc,
00524 const char* STACK_METHOD, const double STACK_KLOW, const double STACK_KHIGH,
00525 const int STACK_NITER,
00526 const int pr_num_x, const int pr_num_y,
00527 const int pr_box_sx, const int pr_box_sy) {
00528 cpl_image *master_dark = NULL;
00529 cpl_image *current_dark = NULL;
00530 cpl_imagelist *preproc_images = NULL;
00531 double mean_exptime = 0;
00532
00533
00534
00535 preproc_images = irplib_mkmaster_dark_fill_imagelist(raw_images, raw_headers,
00536 master_bias, &mean_exptime);
00537 if (do_qc) {
00538
00539 irplib_mkmaster_dark_qc(raw_images, preproc_images, parameters, pr_num_x,
00540 pr_num_y, pr_box_sx, pr_box_sy, recipe_id, qclog);
00541
00542 }
00543
00544 if (strcmp(STACK_METHOD, "MEDIAN") == 0) {
00545 cpl_msg_info(cpl_func, "Calculating stack median");
00546 master_dark = cpl_imagelist_collapse_median_create(preproc_images);
00547 } else {
00548 cpl_msg_info(cpl_func, "Calculating stack mean");
00549 master_dark = irplib_imagelist_ksigma_stack(preproc_images, STACK_KLOW,
00550 STACK_KHIGH, STACK_NITER);
00551
00552 }
00553 irplib_head_set_exptime(mdark_header, mean_exptime );
00554
00555 cpl_image_delete(current_dark);
00556 cpl_imagelist_delete(preproc_images);
00557 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00558 cpl_image_delete(master_dark);
00559 }
00560
00561 return master_dark;
00562 }
00563