30#include "cr2res_calib.h"
31#include "cr2res_bpm.h"
32#include "cr2res_pfits.h"
34#include "cr2res_detlin.h"
35#include "cr2res_utils.h"
43 const hdrl_image * flat, cpl_size degree);
72 const hdrl_imagelist * in,
75 int subtract_nolight_rows,
76 int subtract_interorder_column,
78 const cpl_frame * flat,
79 const cpl_frame * dark,
80 const cpl_frame * bpm,
81 const cpl_frame * detlin,
82 const cpl_vector * dits,
83 const cpl_vector * ndits)
85 hdrl_imagelist * out ;
91 if (in == NULL)
return NULL ;
102 const hdrl_image *cur_ima;
103 hdrl_image *cur_ima_calib;
106 if (dits != NULL) dit = cpl_vector_get(dits, i) ;
107 if (ndits != NULL) ndit = (int)cpl_vector_get(ndits, i) ;
110 cpl_msg_info(__func__,
111 "Apply calibrations for image #%"CPL_SIZE_FORMAT, i+1) ;
112 cpl_msg_indent_more() ;
114 subtract_nolight_rows, subtract_interorder_column,
115 cosmics_corr, flat, dark, bpm,
116 detlin, dit, ndit)) == NULL) {
117 cpl_msg_error(__func__,
"Failed to Calibrate the Data") ;
119 cpl_msg_indent_less() ;
125 cpl_msg_indent_less() ;
149 const hdrl_image * in,
152 int subtract_nolight_rows,
153 int subtract_interorder_column,
155 const cpl_frame * flat,
156 const cpl_frame * dark,
157 const cpl_frame * bpm,
158 const cpl_frame * detlin,
164 hdrl_imagelist * calib_list ;
167 if (in == NULL)
return NULL ;
168 if (chip < 1 || chip > CR2RES_NB_DETECTORS)
return NULL ;
175 cpl_msg_info(__func__,
"Correct the bad pixels") ;
177 cpl_frame_get_filename(bpm), chip, clean_bad) != 0) {
178 cpl_msg_error(__func__,
"Cannot clean the bad pixels");
185 if (detlin != NULL) {
186 cpl_msg_info(__func__,
"Correct for the Non-Linearity") ;
188 cpl_frame_get_filename(detlin), chip)) == NULL) {
189 cpl_msg_error(__func__,
"Cannot load the detlin") ;
197 cpl_msg_error(__func__,
"Cannot correct for the Non-Linearity") ;
203 cpl_msg_info(__func__,
"Add shot-noise") ;
205 cpl_msg_error(__func__,
"Cannot add shot-noise") ;
214 cpl_propertylist *plist;
216 cpl_msg_info(__func__,
"Correct for the dark") ;
221 cpl_msg_error(__func__,
"Cannot load the dark") ;
225 if (detlin != NULL) {
226 cpl_msg_indent_more() ;
227 cpl_msg_info(__func__,
"Correct DARK for Non-Linearity") ;
232 cpl_msg_error(__func__,
"Cannot correct DARK for Non-Linearity");
233 cpl_msg_indent_less() ;
236 cpl_msg_indent_less() ;
240 plist = cpl_propertylist_load(cpl_frame_get_filename(dark), 0);
242 cpl_propertylist_delete(plist) ;
244 hdrl_value hdrl_dit_corr = {dit/dark_dit, 0.0};
249 cpl_msg_error(__func__,
"Cannot apply the dark") ;
256 if (detlin != NULL) {
261 if (subtract_nolight_rows) {
264 cpl_msg_info(__func__,
"Subtract median of bottom rows");
266 img_tmp = cpl_image_collapse_median_create(
268 CR2RES_DETECTOR_SIZE-CR2RES_NB_BPM_VIGN_BOTTOM);
269 calib =
hdrl_image_new(CR2RES_DETECTOR_SIZE,CR2RES_DETECTOR_SIZE);
270 for (i=1; i<=CR2RES_DETECTOR_SIZE; i++) {
275 cpl_image_delete(img_tmp);
279 if (subtract_interorder_column) {
281 cpl_msg_info(__func__,
282 "Skip subtracting fit to inter-order pixels (no flat-field)");
284 cpl_msg_info(__func__,
"Subtract fit to inter-order pixels");
286 cpl_frame_get_filename(flat), chip)) == NULL) {
287 cpl_msg_error(__func__,
"Cannot load the flat field") ;
292 cpl_msg_error(__func__,
"Could not subtract inter-order fit");
300 cpl_msg_info(__func__,
"Correct for the flat field") ;
303 cpl_frame_get_filename(flat), chip)) == NULL) {
304 cpl_msg_error(__func__,
"Cannot load the flat field") ;
311 cpl_msg_error(__func__,
"Cannot apply the flat field") ;
322 cpl_msg_info(__func__,
"Apply the cosmics corrections") ;
325 cpl_msg_warning(__func__,
"invalid cospar");
328 cpl_mask_delete(cosmask);
349 cpl_msg_error(__func__,
"Broken input image");
353 cpl_msg_error(__func__,
"Error input null not supported");
356 if (chip == 1) gain_sqrt = sqrt(CR2RES_GAIN_CHIP1);
357 else if (chip == 2) gain_sqrt = sqrt(CR2RES_GAIN_CHIP2);
358 else if (chip == 3) gain_sqrt = sqrt(CR2RES_GAIN_CHIP3);
360 cpl_msg_error(__func__,
"Unknown detector");
364 cpl_msg_debug(__func__,
"chip:%d, sqrtgain:%g, ndit:%d",
365 chip, gain_sqrt, ndit);
367 if ( (tmp_im=cpl_image_abs_create(adu)) == NULL){
368 cpl_msg_error(__func__,
"Abs failed");
371 if ( (cpl_image_power(tmp_im, 0.5)) != CPL_ERROR_NONE){
372 cpl_msg_error(__func__,
"Sqrt failed");
375 cpl_image_divide_scalar(tmp_im, gain_sqrt);
376 cpl_image_divide_scalar(tmp_im, sqrt((
float)ndit));
380 double min_dit = 1.427;
381 double lim_dit = 50.0;
390 cpl_image_add_scalar(tmp_im, min_rn/(sqrt(ndit)*pow(gain_sqrt, 2)));
391 }
else if(dit >= lim_dit) {
392 cpl_image_add_scalar(tmp_im, lim_rn/(sqrt(ndit)*pow(gain_sqrt, 2)));
394 double read_noise = min_rn + (lim_rn-min_rn)*(dit-min_dit)/(lim_dit-min_dit);
395 cpl_image_add_scalar(tmp_im, read_noise/(sqrt(ndit)*pow(gain_sqrt, 2)));
400 cpl_image_accept_all(tmp_im) ;
402 cpl_image_add(error, tmp_im);
403 cpl_image_delete(tmp_im);
421 const hdrl_image * flat, cpl_size degree)
425 const cpl_image * flat_img;
426 cpl_polynomial * poly;
428 cpl_size ncolumns, nrow;
432 double value, median, mad;
435 if (in == NULL || flat == NULL)
return -1;
442 ncolumns = cpl_image_get_size_x(img);
443 nrow = cpl_image_get_size_y(img);
446 for (i = CR2RES_NB_BPM_EDGEPIX + 1; i < ncolumns - CR2RES_NB_BPM_EDGEPIX;
452 px = cpl_matrix_new(1, nrow);
453 py = cpl_vector_new(nrow);
455 for ( j = CR2RES_NB_BPM_VIGN_BOTTOM + 5; j < nrow -20 ; j++)
459 if (cpl_image_is_rejected(flat_img, i, j)
460 && !cpl_image_is_rejected(img, i, j) &&
461 isnan(cpl_image_get(img, i, j, &badpix)) == 0){
462 cpl_matrix_set(px, 0, npixel, j);
463 cpl_vector_set(py, npixel, cpl_image_get(img, i, j, &badpix));
467 cpl_msg_debug(__func__,
"Column %lld has %lld pixels for background",
471 cpl_matrix_delete(px);
472 cpl_vector_delete(py);
475 cpl_matrix_set_size(px, 1, npixel);
476 cpl_vector_set_size(py, npixel);
480 for (j=0;j<npixel;j++){
482 if ((cpl_vector_get(py,j) > median*2) || (cpl_vector_get(py,j) < 0.0) )
483 cpl_vector_set(py,j,median);
486 tmp = cpl_vector_filter_lowpass_create(py,CPL_LOWPASS_LINEAR,100);
487 cpl_vector_delete(py);
489 if (cpl_msg_get_level() == CPL_MSG_DEBUG){
490 tmp = cpl_vector_wrap(npixel, cpl_matrix_get_data(px));
491 cpl_vector_save(tmp,
"debug_background.fits",
492 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
493 cpl_vector_save(py,
"debug_background.fits",
494 CPL_TYPE_DOUBLE, NULL, CPL_IO_EXTEND);
495 cpl_vector_unwrap(tmp);
499 poly = cpl_polynomial_new(1);
500 if (cpl_polynomial_fit(poly, px, NULL, py, NULL, CPL_FALSE, NULL,
504 cpl_msg_warning(__func__,
505 "Could not fit the background of column %"CPL_SIZE_FORMAT, i);
507 cpl_matrix_delete(px);
508 cpl_vector_delete(py);
509 cpl_polynomial_delete(poly);
514 for ( j = 1; j < nrow + 1; j++)
516 value = cpl_image_get(img, i, j, &badpix);
518 if (badpix)
continue;
519 value -= cpl_polynomial_eval_1d(poly, j, NULL);
520 cpl_image_set(img, i, j, value);
524 cpl_matrix_delete(px);
525 cpl_vector_delete(py);
526 cpl_polynomial_delete(poly);
530 cpl_msg_warning(__func__,
531 "%d columns could not be background-subtracted from inter-order gaps",
int cr2res_bpm_set_and_correct_image(cpl_image *in, const char *bpm, int chip, int correct)
Set the BPM and optionally apply the correction to an image.
hdrl_image * cr2res_calib_image(const hdrl_image *in, int chip, int clean_bad, int subtract_nolight_rows, int subtract_interorder_column, int cosmics_corr, const cpl_frame *flat, const cpl_frame *dark, const cpl_frame *bpm, const cpl_frame *detlin, double dit, int ndit)
The images calibration routine for a given chip.
int cr2res_add_shotnoise(hdrl_image *in, double dit, int ndit, int chip)
Add shot-noise to errors in HDRL-image.
hdrl_imagelist * cr2res_calib_imagelist(const hdrl_imagelist *in, int chip, int clean_bad, int subtract_nolight_rows, int subtract_interorder_column, int cosmics_corr, const cpl_frame *flat, const cpl_frame *dark, const cpl_frame *bpm, const cpl_frame *detlin, const cpl_vector *dits, const cpl_vector *ndits)
The images calibration routine for a given chip on a list.
int cr2res_calib_subtract_interorder_column(hdrl_image *in, const hdrl_image *flat, cpl_size degree)
Remove background column by column.
int cr2res_detlin_correct(hdrl_image *in, const hdrl_imagelist *detlin)
Apply the detector linearity correction.
hdrl_imagelist * cr2res_io_load_DETLIN_COEFFS(const char *filename, int detector)
Load the detlin coefficients.
hdrl_image * cr2res_io_load_MASTER_DARK(const char *filename, int detector)
Load an image from a MASTER_DARK.
hdrl_image * cr2res_io_load_MASTER_FLAT(const char *filename, int detector)
Load an hdrl image from a MASTER_FLAT.
double cr2res_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
double cr2res_vector_get_mad(cpl_vector *invec, double *mad)
Get MAD from a vector.
cpl_error_code hdrl_image_sub_image(hdrl_image *self, const hdrl_image *other)
Subtract two images, store the result in the first image.
cpl_error_code hdrl_image_div_image(hdrl_image *self, const hdrl_image *other)
Divide two images, store the result in the first image.
cpl_error_code hdrl_image_mul_scalar(hdrl_image *self, hdrl_value value)
Elementwise multiplication of an image with a scalar.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
cpl_mask * hdrl_image_get_mask(hdrl_image *himg)
get cpl bad pixel mask from image
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
cpl_error_code hdrl_image_insert(hdrl_image *self, const cpl_image *image, const cpl_image *error, cpl_size xpos, cpl_size ypos)
Copy cpl images into an hdrl image.
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
cpl_mask * hdrl_lacosmic_edgedetect(const hdrl_image *ima_in, const hdrl_parameter *params)
Detect bad-pixels / cosmic-rays on a single image.
cpl_error_code hdrl_lacosmic_parameter_verify(const hdrl_parameter *param)
Verify basic correctness of the LaCosmic parameters.
hdrl_parameter * hdrl_lacosmic_parameter_create(double sigma_lim, double f_lim, int max_iter)
Creates LaCosmic parameters object.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter