38#include "irplib_mkmaster.h"
70irplib_imagelist_get_clean_mean_levels(
const cpl_imagelist *iml,
73 const double tolerance)
77 cpl_vector *levels = NULL;
83 cpl_error_ensure(iml != NULL, CPL_ERROR_NULL_INPUT,
return (levels),
84 "Null input image list");
85 cpl_error_ensure(kappa >= 0, CPL_ERROR_ILLEGAL_INPUT,
return (levels),
88 size = cpl_imagelist_get_size(iml);
89 levels = cpl_vector_new(size);
90 pval = cpl_vector_get_data(levels);
92 for (i = 0; i < size; i++) {
93 const cpl_image *img = cpl_imagelist_get_const(iml, i);
94 irplib_ksigma_clip(img, 1, 1, cpl_image_get_size_x(img),
95 cpl_image_get_size_y(img), nclip, kappa, tolerance,
97 cpl_msg_info(cpl_func,
"Ima %d mean level: %g", i + 1, mean);
115irplib_imagelist_subtract_values(cpl_imagelist **iml, cpl_vector *values)
121 size = cpl_imagelist_get_size(*iml);
122 pval = cpl_vector_get_data(values);
124 for (i = 0; i < size; i++) {
125 cpl_image *img = cpl_imagelist_get(*iml, i);
126 cpl_image_subtract_scalar(img, pval[i]);
127 cpl_imagelist_set(*iml, img, i);
130 return cpl_error_get_code();
148irplib_vector_ksigma(cpl_vector *values,
155 double *data = cpl_vector_get_data(values);
156 int n = cpl_vector_get_size(values);
165 mean = cpl_vector_get_median(values);
167 for (i = 0; i < n; i++) {
168 sigma += (mean - data[i]) * (mean - data[i]);
170 sigma = sqrt(sigma / (n - 1));
173 cpl_vector *accepted;
175 for (i = 0; i < ngood; i++) {
176 if (data[i] - mean < khigh * sigma &&
177 mean - data[i] < klow * sigma) {
178 data[count] = data[i];
192 accepted = cpl_vector_wrap(count, data);
193 mean = cpl_vector_get_mean(accepted);
195 sigma = cpl_vector_get_stdev(accepted);
197 cpl_vector_unwrap(accepted);
199 if (count == ngood) {
229irplib_imagelist_ksigma_stack(
const cpl_imagelist *imlist,
234 cpl_size ni, nx, ny, npix;
235 cpl_image *out_ima = NULL;
236 cpl_imagelist *loc_iml = NULL;
237 double *pout_ima = NULL;
238 cpl_image *image = NULL;
239 const double **data = NULL;
241 cpl_vector *time_line = NULL;
243 double *ptime_line = NULL;
245 double mean_of_medians = 0;
247 cpl_error_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT,
return (out_ima),
248 "Null input image list");
250 ni = cpl_imagelist_get_size(imlist);
251 loc_iml = cpl_imagelist_duplicate(imlist);
252 image = cpl_imagelist_get(loc_iml, 0);
253 nx = cpl_image_get_size_x(image);
254 ny = cpl_image_get_size_y(image);
257 out_ima = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
258 pout_ima = cpl_image_get_data_double(out_ima);
260 time_line = cpl_vector_new(ni);
262 ptime_line = cpl_vector_get_data(time_line);
264 cpl_error_ensure(ni < (cpl_size)(SIZE_MAX /
sizeof(
double *)),
265 CPL_ERROR_INCOMPATIBLE_INPUT,
return (NULL),
266 "Image to big for allocation");
267 data = cpl_calloc((
size_t)ni,
sizeof(
double *));
268 med = cpl_calloc((
size_t)ni,
sizeof(
double));
270 for (i = 0; i < ni; i++) {
271 image = cpl_imagelist_get(loc_iml, i);
272 med[i] = cpl_image_get_median(image);
273 cpl_image_subtract_scalar(image, med[i]);
274 data[i] = cpl_image_get_data_double(image);
275 mean_of_medians += med[i];
277 mean_of_medians /= ni;
279 for (i = 0; i < npix; i++) {
280 for (j = 0; j < ni; j++) {
281 ptime_line[j] = data[j][i];
283 pout_ima[i] = irplib_vector_ksigma(time_line, klow, khigh, kiter);
286 cpl_image_add_scalar(out_ima, mean_of_medians);
291 cpl_vector_delete(time_line);
292 cpl_imagelist_delete(loc_iml);
315 const double tolerance,
320 cpl_image *master = NULL;
321 cpl_vector *levels = NULL;
323 cpl_imagelist *iml = NULL;
325 cpl_msg_info(cpl_func,
"method mean");
326 iml = cpl_imagelist_duplicate(images);
328 irplib_imagelist_get_clean_mean_levels(iml, kappa, nclip, tolerance);
329 mean = cpl_vector_get_mean(levels);
330 cpl_msg_info(cpl_func,
"Master mean level: %g", mean);
332 irplib_imagelist_subtract_values(&iml, levels);
334 master = irplib_imagelist_ksigma_stack(iml, klow, khigh, niter);
335 cpl_image_add_scalar(master, mean);
337 cpl_vector_delete(levels);
338 cpl_imagelist_delete(iml);
359 const double tolerance)
361 cpl_image *master = NULL;
362 cpl_vector *levels = NULL;
364 cpl_imagelist *iml = NULL;
366 cpl_msg_info(cpl_func,
"method median");
367 iml = cpl_imagelist_duplicate(images);
369 irplib_imagelist_get_clean_mean_levels(iml, kappa, nclip, tolerance);
371 mean = cpl_vector_get_mean(levels);
372 cpl_msg_info(cpl_func,
"Master mean level: %g", mean);
373 irplib_imagelist_subtract_values(&iml, levels);
375 master = cpl_imagelist_collapse_median_create(iml);
377 cpl_image_add_scalar(master, mean);
379 cpl_vector_delete(levels);
380 cpl_imagelist_delete(iml);
387irplib_mkmaster_dark_qc(
const cpl_imagelist *raw_images,
388 cpl_imagelist *preproc_images,
389 const cpl_parameterlist *parameters,
394 const char *recipe_id,
397 cpl_ensure_code(qclog != NULL, CPL_ERROR_NULL_INPUT);
398 cpl_ensure_code(recipe_id != NULL, CPL_ERROR_NULL_INPUT);
399 cpl_ensure_code(parameters != NULL, CPL_ERROR_NULL_INPUT);
401 if (pr_num_x != 0 && pr_num_y != 0 && pr_box_sx != 0 && pr_box_sy != 0) {
403 for (i = 0; i < cpl_imagelist_get_size(raw_images); i++) {
404 cpl_image *current_dark =
405 cpl_image_duplicate(cpl_imagelist_get_const(preproc_images, i));
406 cpl_msg_info(cpl_func,
407 "Calculating QC parameters on raw dark frame %d", i);
413 cpl_image_delete(current_dark);
416 return cpl_error_get_code();
431irplib_head_get_exptime(
const cpl_propertylist *plist)
435 result = cpl_propertylist_get_double(plist,
"EXPTIME");
436 cpl_ensure_code(result >= 0, CPL_ERROR_ILLEGAL_OUTPUT);
451irplib_head_set_exptime(cpl_propertylist *plist,
double exptime)
453 cpl_propertylist_update_double(plist,
"EXPTIME", exptime);
454 cpl_propertylist_set_comment(plist,
"EXPTIME",
"Total integration time");
456 return cpl_error_get_code();
459static cpl_imagelist *
460irplib_mkmaster_dark_fill_imagelist(
const cpl_imagelist *raw_images,
461 cpl_propertylist **raw_headers,
462 const cpl_image *master_bias,
463 double *mean_exptime)
468 cpl_imagelist *preproc_images = NULL;
470 double min_exptime = 0;
471 double max_exptime = 0;
473 preproc_images = cpl_imagelist_new();
474 for (i = 0; i < cpl_imagelist_get_size(raw_images); i++) {
475 double exposure_time = 0.0;
476 cpl_image *current_dark = NULL;
477 const cpl_propertylist *current_header;
480 cpl_image_duplicate(cpl_imagelist_get_const(raw_images, i));
481 current_header = raw_headers[i];
484 if (master_bias != NULL) {
485 cpl_msg_info(cpl_func,
"Subtracting master bias");
486 cpl_image_subtract(current_dark, master_bias);
489 cpl_msg_info(cpl_func,
"Skipping bias subtraction");
492 exposure_time = irplib_head_get_exptime(current_header);
495 if (i == 0 || exposure_time < min_exptime) {
496 min_exptime = exposure_time;
498 if (i == 0 || exposure_time > max_exptime) {
499 max_exptime = exposure_time;
510 cpl_imagelist_set(preproc_images, current_dark, i);
519 cpl_msg_info(cpl_func,
520 "Exposure times range from %e s to %e s (%e %% variation)",
521 min_exptime, max_exptime,
522 100 * (max_exptime - min_exptime) / min_exptime);
524 if ((max_exptime - min_exptime) / min_exptime > .001) {
525 cpl_msg_warning(cpl_func,
"Exposure times differ by %e %%",
526 100 * (max_exptime - min_exptime) / min_exptime);
530 *mean_exptime = 0.5 * (max_exptime + min_exptime);
531 return preproc_images;
536irplib_mdark_process_chip(
const cpl_imagelist *raw_images,
537 cpl_propertylist **raw_headers,
538 const cpl_image *master_bias,
539 cpl_propertylist *mdark_header,
540 const cpl_parameterlist *parameters,
541 const char *recipe_id,
544 const char *STACK_METHOD,
545 const double STACK_KLOW,
546 const double STACK_KHIGH,
547 const int STACK_NITER,
553 cpl_image *master_dark = NULL;
554 cpl_image *current_dark = NULL;
555 cpl_imagelist *preproc_images = NULL;
556 double mean_exptime = 0;
561 irplib_mkmaster_dark_fill_imagelist(raw_images, raw_headers,
562 master_bias, &mean_exptime);
565 irplib_mkmaster_dark_qc(raw_images, preproc_images, parameters,
566 pr_num_x, pr_num_y, pr_box_sx, pr_box_sy,
570 if (strcmp(STACK_METHOD,
"MEDIAN") == 0) {
571 cpl_msg_info(cpl_func,
"Calculating stack median");
572 master_dark = cpl_imagelist_collapse_median_create(preproc_images);
575 cpl_msg_info(cpl_func,
"Calculating stack mean");
576 master_dark = irplib_imagelist_ksigma_stack(preproc_images, STACK_KLOW,
577 STACK_KHIGH, STACK_NITER);
579 irplib_head_set_exptime(mdark_header, mean_exptime);
581 cpl_image_delete(current_dark);
582 cpl_imagelist_delete(preproc_images);
583 if (cpl_error_get_code() != CPL_ERROR_NONE) {
584 cpl_image_delete(master_dark);
cpl_image * irplib_mkmaster_mean(cpl_imagelist *images, const double kappa, const int nclip, const double tolerance, const double klow, const double khigh, const int niter)
Computes master frame by clean stack mean of the input imagelist.
cpl_image * irplib_mkmaster_median(cpl_imagelist *images, const double kappa, const int nclip, const double tolerance)
Computes master frame by clean stack median of the input imagelist.