28#include "hdrl_overscan.h"
29#include "hdrl_overscan_defs.h"
30#include "hdrl_sigclip.h"
31#include "hdrl_utils.h"
32#include "hdrl_collapse.h"
42static hdrl_overscan_compute_result * hdrl_overscan_compute_result_create(
44static cpl_error_code hdrl_overscan_compute_result_verify(
45 const hdrl_overscan_compute_result *);
46static hdrl_overscan_correct_result * hdrl_overscan_correct_result_create(
48static cpl_error_code hdrl_overscan_compute_chi_square(
const cpl_image *,
49 const cpl_image *,
const double,
double *,
double *);
50static cpl_error_code hdrl_overscan_reduce_image_to_scalar(
51 hdrl_collapse_imagelist_to_vector_t *, cpl_image *, cpl_image *,
52 double *,
double *, cpl_size *,
void **) ;
53static void hdrl_overscan_parameter_destroy(
void * param);
119 hdrl_direction correction_direction;
122 hdrl_parameter * collapse;
123 hdrl_parameter * rect_region;
124} hdrl_overscan_parameter;
127static hdrl_parameter_typeobj hdrl_overscan_parameter_type = {
128 HDRL_PARAMETER_OVERSCAN,
129 (hdrl_alloc *)&cpl_malloc,
130 (hdrl_free *)&cpl_free,
131 (hdrl_free *)&hdrl_overscan_parameter_destroy,
132 sizeof(hdrl_overscan_parameter),
151 hdrl_direction correction_direction,
154 hdrl_parameter * collapse,
155 hdrl_parameter * rect_region)
157 hdrl_overscan_parameter * p = (hdrl_overscan_parameter *)
158 hdrl_parameter_new(&hdrl_overscan_parameter_type);
159 p->correction_direction = correction_direction ;
160 p->ccd_ron = ccd_ron ;
161 p->box_hsize = box_hsize ;
162 p->collapse = collapse ;
163 p->rect_region = rect_region ;
164 return (hdrl_parameter *)p;
177 const hdrl_parameter * param,
181 const hdrl_overscan_parameter * param_loc =
182 (
const hdrl_overscan_parameter *)param ;
184 cpl_error_ensure(param != NULL, CPL_ERROR_NULL_INPUT,
185 return CPL_ERROR_NULL_INPUT,
"NULL Input Parameters");
187 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
188 "Expected Overscan parameter") ;
190 cpl_error_ensure(param_loc->ccd_ron >= 0, CPL_ERROR_ILLEGAL_INPUT,
191 return CPL_ERROR_ILLEGAL_INPUT,
192 "CCD read out noise (%g) must be >= 0", param_loc->ccd_ron);
193 cpl_error_ensure(param_loc->box_hsize >= 0 ||
194 param_loc->box_hsize == HDRL_OVERSCAN_FULL_BOX,
195 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
196 "half box size (%d) must be >= 0 or -1",
197 param_loc->box_hsize);
198 cpl_error_ensure(param_loc->correction_direction == HDRL_X_AXIS ||
199 param_loc->correction_direction == HDRL_Y_AXIS,
200 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
201 "correction_direction must be HDRL_X_AXIS or HDRL_Y_AXIS");
205 hdrl_collapse_sigclip_parameter_verify(param_loc->collapse)
206 == CPL_ERROR_NONE, CPL_ERROR_ILLEGAL_INPUT,
207 return CPL_ERROR_ILLEGAL_INPUT,
208 "Illegal Collapse Sigclip parameters");
212 hdrl_collapse_minmax_parameter_verify(param_loc->collapse)
213 == CPL_ERROR_NONE, CPL_ERROR_ILLEGAL_INPUT,
214 return CPL_ERROR_ILLEGAL_INPUT,
215 "Illegal Collapse Minmax parameters");
219 hdrl_collapse_mode_parameter_verify(param_loc->collapse)
220 == CPL_ERROR_NONE, CPL_ERROR_ILLEGAL_INPUT,
221 return CPL_ERROR_ILLEGAL_INPUT,
222 "Illegal Collapse Mode parameters");
226 == CPL_ERROR_NONE, CPL_ERROR_ILLEGAL_INPUT,
227 return CPL_ERROR_ILLEGAL_INPUT,
228 "Illegal Rect Region parameters");
236 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
237 "Only supported methods are MEAN, WEIGHTED_MEAN, MEDIAN, SIGCLIP,"
245 region_llx>=1 && region_urx <= nx,
246 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
247 "Region (%d) exceeds source (%d) size in the X dir.",
248 (
int)region_urx, (
int)nx);
254 region_lly>=1 && region_ury <= ny,
255 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
256 "Region (%d) exceeds source (%d) size in the Y dir.",
257 (
int)region_ury, (
int)ny);
259 return CPL_ERROR_NONE;
271 return hdrl_parameter_check_type(self, &hdrl_overscan_parameter_type);
282 const hdrl_parameter * p)
284 cpl_ensure(p, CPL_ERROR_NULL_INPUT, HDRL_UNDEFINED_AXIS);
285 return ((
const hdrl_overscan_parameter *)p)->correction_direction;
295 const hdrl_parameter * p)
297 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.0) ;
298 return ((
const hdrl_overscan_parameter *)p)->ccd_ron ;
308 const hdrl_parameter * p)
310 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.0) ;
311 return ((
const hdrl_overscan_parameter *)p)->box_hsize ;
321 const hdrl_parameter * p)
323 cpl_ensure(p, CPL_ERROR_NULL_INPUT, NULL) ;
324 return ((
const hdrl_overscan_parameter *)p)->collapse;
334 const hdrl_parameter * p)
336 cpl_ensure(p, CPL_ERROR_NULL_INPUT, NULL) ;
337 return ((
const hdrl_overscan_parameter *)p)->rect_region;
368 const char *base_context,
370 const char *corr_dir_def,
373 hdrl_parameter *rect_region_def,
374 const char *method_def,
375 hdrl_parameter *sigclip_def,
376 hdrl_parameter *minmax_def,
377 hdrl_parameter *mode_def)
379 cpl_ensure(prefix && base_context && rect_region_def && sigclip_def
380 && minmax_def && mode_def, CPL_ERROR_NULL_INPUT, NULL);
386 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
389 cpl_parameterlist * parlist = cpl_parameterlist_new();
390 cpl_parameter * par ;
396 par = cpl_parameter_new_enum(name, CPL_TYPE_STRING,
"Correction Direction",
397 context, corr_dir_def, 2,
"alongX",
"alongY");
400 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, name);
401 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
403 cpl_parameterlist_append(parlist, par);
406 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"box-hsize", base_context,
407 "Half size of running box in pixel, -1 for full overscan region",
408 CPL_TYPE_INT, box_hsize_def) ;
411 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"ccd-ron", base_context,
412 "Readout noise in ADU", CPL_TYPE_DOUBLE, ccd_ron_def) ;
417 base_context, prefix,
"calc-", rect_region_def);
418 for (cpl_parameter * p = cpl_parameterlist_get_first(os_comp_reg) ;
419 p != NULL; p = cpl_parameterlist_get_next(os_comp_reg))
420 cpl_parameterlist_append(parlist,cpl_parameter_duplicate(p));
421 cpl_parameterlist_delete(os_comp_reg);
427 base_context, name, method_def, sigclip_def, minmax_def, mode_def) ;
429 for (cpl_parameter * p = cpl_parameterlist_get_first(pcollapse) ;
430 p != NULL; p = cpl_parameterlist_get_next(pcollapse))
431 cpl_parameterlist_append(parlist,cpl_parameter_duplicate(p));
432 cpl_parameterlist_delete(pcollapse);
436 if (cpl_error_get_code()) {
437 cpl_parameterlist_delete(parlist);
474 const cpl_parameterlist * parlist,
477 cpl_ensure(prefix && parlist, CPL_ERROR_NULL_INPUT, NULL);
478 hdrl_direction corr_dir_param = HDRL_UNDEFINED_AXIS ;
480 double ccd_ron = 0. ;
481 hdrl_parameter * os_collapse_params = NULL;
482 hdrl_parameter * os_region_params = NULL;
487 const cpl_parameter *par = cpl_parameterlist_find_const(parlist, name);
488 const char *correction_direction = cpl_parameter_get_string(par);
489 if (correction_direction == NULL) {
490 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
491 "Parameter %s not found", name);
495 if(!strcmp(correction_direction,
"alongX")) {
496 corr_dir_param = HDRL_X_AXIS;
497 }
else if(!strcmp(correction_direction,
"alongY")) {
498 corr_dir_param = HDRL_Y_AXIS;
504 par=cpl_parameterlist_find_const(parlist, name);
505 box_hsize = cpl_parameter_get_int(par);
510 par=cpl_parameterlist_find_const(parlist, name);
511 ccd_ron = cpl_parameter_get_double(par);
514 if (cpl_error_get_code()) {
515 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
516 "Error while parsing parameterlist "
517 "with prefix %s", prefix);
530 if (cpl_error_get_code()) {
537 box_hsize, os_collapse_params,
556get_reduction(
const hdrl_parameter * cpse,
557 const cpl_image * overscan_sub_ima,
558 hdrl_collapse_imagelist_to_vector_t ** reduce)
561 *reduce = hdrl_collapse_imagelist_to_vector_mean();
563 *reduce = hdrl_collapse_imagelist_to_vector_weighted_mean();
565 *reduce = hdrl_collapse_imagelist_to_vector_median();
568 sqrt(log(CX_MAX(hdrl_get_image_good_npix(overscan_sub_ima), 1)));
573 if (kappa_low <= 0) kappa_low = kappa;
574 if (kappa_high <= 0) kappa_high = kappa;
575 *reduce = hdrl_collapse_imagelist_to_vector_sigclip(kappa_low,
580 if (nlow <= 0) nlow = 0;
581 if (nhigh <= 0) nhigh = 0;
582 *reduce = hdrl_collapse_imagelist_to_vector_minmax(nlow, nhigh);
590 *reduce = hdrl_collapse_imagelist_to_vector_mode(histo_min, histo_max,
595 return cpl_error_get_code();
687 const cpl_image * source,
688 const hdrl_parameter * params)
690 cpl_image * correction_img = NULL;
691 cpl_image * correction_err_img = NULL;
692 cpl_image * contribution_img = NULL;
693 cpl_image * chi2_img = NULL;
694 cpl_image * red_chi2_img = NULL;
695 cpl_image * reject_low = NULL;
696 cpl_image * reject_high = NULL;
701 cpl_image * overscan_ima = NULL;
706 cpl_error_ensure(source != NULL, CPL_ERROR_NULL_INPUT,
707 return NULL,
"NULL input image");
708 cpl_error_ensure(params != NULL, CPL_ERROR_NULL_INPUT,
709 return NULL,
"NULL input parameters");
711 int d1 =
sizeof(hdrl_sigclip_vector_output);
712 int d2 =
sizeof(hdrl_minmax_vector_output );
713 cpl_error_ensure(d1 == d2, CPL_ERROR_INVALID_TYPE,
return NULL,
714 "Invalid check type between hdrl_sigclip_vector_output and hdrl_minmax_vector_output");
718 cpl_image_get_size_x(source),
719 cpl_image_get_size_y(source)) != CPL_ERROR_NONE)
723 const hdrl_overscan_parameter * p_loc =
724 (
const hdrl_overscan_parameter *)params ;
725 const hdrl_parameter * cpse = p_loc->collapse ;
726 const hdrl_parameter * rr = p_loc->rect_region ;
729 overscan_ima = cpl_image_extract(source,
736 if(p_loc->correction_direction == HDRL_Y_AXIS) {
738 cpl_image_turn(overscan_ima, -1);
744 urx = cpl_image_get_size_x(overscan_ima);
745 ury = cpl_image_get_size_y(overscan_ima);
748 correction_img = cpl_image_new(1, ury, HDRL_TYPE_DATA);
749 correction_err_img = cpl_image_new(1, ury, HDRL_TYPE_ERROR);
750 contribution_img = cpl_image_new(1, ury, CPL_TYPE_INT);
751 chi2_img = cpl_image_new(1, ury, CPL_TYPE_DOUBLE);
752 red_chi2_img = cpl_image_new(1, ury, CPL_TYPE_DOUBLE);
756 reject_low = cpl_image_new(1, ury, CPL_TYPE_DOUBLE);
757 reject_high = cpl_image_new(1, ury, CPL_TYPE_DOUBLE);
762HDRL_OMP(omp parallel
for)
763 for (
long ipixel = 1;
764 ipixel <= (p_loc->box_hsize == HDRL_OVERSCAN_FULL_BOX ? 1 : ury);
766 cpl_size contribution;
767 double corr, error, chi2, red_chi2;
768 const int box_hsize = p_loc->box_hsize;
769 const double ccd_ron = p_loc->ccd_ron;
772 cpl_image * overscan_sub_ima, * ccd_ron_ima;
774 hdrl_collapse_imagelist_to_vector_t * reduce = NULL;
775 void * collapse_eout = NULL;
778 if (box_hsize == HDRL_OVERSCAN_FULL_BOX) {
783 else if (ipixel + box_hsize > ury) {
785 upperlimit = CX_MIN(ipixel + box_hsize, ury);
786 lowerlimit = 2 * ipixel - upperlimit;
790 lowerlimit = CX_MAX(ipixel - box_hsize, 1);
791 upperlimit = 2 * ipixel - lowerlimit;
795 overscan_sub_ima = cpl_image_extract(overscan_ima, llx, lowerlimit,
799 ccd_ron_ima = cpl_image_duplicate(overscan_sub_ima);
800 cpl_image_multiply_scalar(ccd_ron_ima, 0.0);
801 cpl_image_add_scalar(ccd_ron_ima, ccd_ron);
803 get_reduction(cpse, overscan_sub_ima, &reduce);
806 hdrl_overscan_reduce_image_to_scalar(reduce, overscan_sub_ima,
807 ccd_ron_ima, &corr, &error, &contribution, &collapse_eout);
813 hdrl_sigclip_vector_output * eout = collapse_eout;
815 double low = cpl_vector_get(eout->reject_low, 0);
816 double high = cpl_vector_get(eout->reject_high, 0);
818 cpl_image_set(reject_low, 1, ipixel, low);
819 cpl_image_set(reject_high, 1, ipixel, high);
821 cpl_vector_delete(eout->reject_low);
822 cpl_vector_delete(eout->reject_high);
825 hdrl_collapse_imagelist_to_vector_unwrap_eout(reduce, collapse_eout);
828 if (contribution == 0) {
831 }
else if (p_loc->box_hsize == HDRL_OVERSCAN_FULL_BOX) {
832 hdrl_overscan_compute_chi_square(overscan_sub_ima,
833 ccd_ron_ima, corr, &chi2, &red_chi2);
837 cpl_size nx = cpl_image_get_size_x(overscan_sub_ima);
838 cpl_size ny = cpl_image_get_size_y(overscan_sub_ima);
840 cpl_image * overscan_sub_ima_slice =
841 cpl_image_extract(overscan_sub_ima, 1, (cpl_size)((ny+1)/2),
842 nx, (cpl_size)((ny+1)/2));
843 cpl_image * ccd_ron_ima_slice =
844 cpl_image_extract(ccd_ron_ima, 1, (cpl_size)((ny+1)/2), nx,
845 (cpl_size)((ny+1)/2));
847 hdrl_overscan_compute_chi_square(overscan_sub_ima_slice,
848 ccd_ron_ima_slice, corr, &chi2, &red_chi2);
850 cpl_image_delete(overscan_sub_ima_slice);
851 cpl_image_delete(ccd_ron_ima_slice);
855 cpl_image_set(correction_img, 1, ipixel, corr);
856 cpl_image_set(correction_err_img, 1, ipixel, error);
857 cpl_image_set(contribution_img, 1, ipixel, contribution);
858 cpl_image_set(chi2_img, 1, ipixel, chi2);
859 cpl_image_set(red_chi2_img, 1, ipixel, red_chi2);
861 cpl_image_delete(overscan_sub_ima);
862 cpl_image_delete(ccd_ron_ima);
864 hdrl_collapse_imagelist_to_vector_delete(reduce);
868 if (p_loc->box_hsize == HDRL_OVERSCAN_FULL_BOX) {
870 const double ccd_ron = p_loc->ccd_ron;
871 const double correction_value =
872 cpl_image_get(correction_img, 1, 1, &rej);
873 const double correction_err_value =
874 cpl_image_get(correction_err_img, 1, 1, &rej);
875 const cpl_size contribution_value =
876 cpl_image_get(contribution_img, 1, 1, &rej);
877 cpl_size loopmax = cpl_image_get_size_y(correction_img);
878HDRL_OMP(omp parallel
for private(rej))
879 for (cpl_size i = 1; i <= loopmax; i++) {
880 double chi2, red_chi2;
881 cpl_image * overscan_sub_ima, * ccd_ron_ima;
885 cpl_image_set(correction_img, 1, i + 1, correction_value);
886 cpl_image_set(correction_err_img, 1, i + 1,
887 correction_err_value);
888 cpl_image_set(contribution_img, 1, i + 1,contribution_value);
891 cpl_image_set(reject_low, 1, i + 1,
892 cpl_image_get(reject_low, 1, 1, &rej));
893 cpl_image_set(reject_high, 1, i + 1,
894 cpl_image_get(reject_high, 1, 1, &rej));
900 overscan_sub_ima = cpl_image_extract(overscan_ima, llx, i, urx, i);
903 ccd_ron_ima = cpl_image_duplicate(overscan_sub_ima);
904 cpl_image_multiply_scalar(ccd_ron_ima, 0.0);
905 cpl_image_add_scalar(ccd_ron_ima, ccd_ron);
907 hdrl_overscan_compute_chi_square(overscan_sub_ima,
908 ccd_ron_ima, correction_value,
911 cpl_image_set(chi2_img, 1, i, chi2);
912 cpl_image_set(red_chi2_img, 1, i, red_chi2);
913 cpl_image_delete(overscan_sub_ima);
914 cpl_image_delete(ccd_ron_ima);
918 cpl_image_delete(overscan_ima);
920 cpl_image_reject_value(correction_img, CPL_VALUE_NAN);
921 cpl_image_reject_value(correction_err_img, CPL_VALUE_NAN);
922 cpl_image_reject_value(chi2_img, CPL_VALUE_NAN);
923 cpl_image_reject_value(red_chi2_img, CPL_VALUE_NAN);
926 cpl_image_reject_value(reject_low, CPL_VALUE_NAN);
927 cpl_image_reject_value(reject_high, CPL_VALUE_NAN);
931 if(p_loc->correction_direction == HDRL_Y_AXIS) {
932 cpl_image_turn(correction_img, +1);
933 cpl_image_turn(correction_err_img, +1);
934 cpl_image_turn(contribution_img, +1);
935 cpl_image_turn(chi2_img, +1);
936 cpl_image_turn(red_chi2_img, +1);
939 cpl_image_turn(reject_low, +1);
940 cpl_image_turn(reject_high, +1);
946 hdrl_overscan_compute_result * result =
947 hdrl_overscan_compute_result_create();
950 cpl_image_delete(correction_img);
951 cpl_image_delete(correction_err_img);
952 result->correction_direction = p_loc->correction_direction;
953 result->correction = res;
954 result->contribution = contribution_img;
955 result->chi2 = chi2_img;
956 result->red_chi2 = red_chi2_img;
957 result->sigclip_reject_low = reject_low;
958 result->sigclip_reject_high = reject_high;
971 const hdrl_overscan_compute_result * res)
973 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
974 return res->correction;
985 hdrl_overscan_compute_result * res)
987 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
988 hdrl_image * r = res->correction;
989 res->correction = NULL;
1001 const hdrl_overscan_compute_result * res)
1003 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1004 return res->contribution;
1015 hdrl_overscan_compute_result * res)
1017 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1018 cpl_image * r = res->contribution;
1019 res->contribution = NULL;
1031 const hdrl_overscan_compute_result * res)
1033 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1045 hdrl_overscan_compute_result * res)
1047 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1048 cpl_image * r = res->chi2;
1061 const hdrl_overscan_compute_result * res)
1063 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1064 return res->red_chi2;
1075 hdrl_overscan_compute_result * res)
1077 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1078 cpl_image * r = res->red_chi2;
1079 res->red_chi2 = NULL;
1091 const hdrl_overscan_compute_result * res)
1093 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1094 if (!res->sigclip_reject_low) {
1095 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1096 "rejection parameters are only "
1097 "available if collapse mode of overscan is set "
1098 "to sigclip or minmax");
1100 return res->sigclip_reject_low;
1111 hdrl_overscan_compute_result * res)
1113 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1114 cpl_image * r = res->sigclip_reject_low;
1115 if (!res->sigclip_reject_low) {
1116 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1117 "rejection parameters are only "
1118 "available if collapse mode of overscan is set "
1119 "to sigclip or minmax");
1121 res->sigclip_reject_low = NULL;
1133 const hdrl_overscan_compute_result * res)
1135 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1136 if (!res->sigclip_reject_high) {
1137 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1138 "rejection parameters are only "
1139 "available if collapse mode of overscan is set "
1140 "to sigclip or minmax");
1142 return res->sigclip_reject_high;
1153 hdrl_overscan_compute_result * res)
1155 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1156 cpl_image * r = res->sigclip_reject_high;
1157 res->sigclip_reject_high = NULL;
1170 const hdrl_overscan_compute_result * res)
1183 hdrl_overscan_compute_result * res)
1196 const hdrl_overscan_compute_result * res)
1209 hdrl_overscan_compute_result * res)
1223 hdrl_overscan_compute_result * result)
1225 if (result == NULL)
return;
1227 cpl_image_delete(result->contribution);
1228 cpl_image_delete(result->chi2);
1229 cpl_image_delete(result->red_chi2);
1230 cpl_image_delete(result->sigclip_reject_low);
1231 cpl_image_delete(result->sigclip_reject_high);
1287 const hdrl_image * source,
1288 const hdrl_parameter * region,
1289 const hdrl_overscan_compute_result * os_computation)
1291 cpl_size llx = 0, lly = 0, urx = 0, ury = 0;
1293 cpl_image * source_loc = NULL;
1294 cpl_image * source_error_loc = NULL;
1295 long xsize_overscan = 0;
1296 long ysize_overscan = 0;
1298 cpl_mask * orig_mask = NULL;
1299 hdrl_image * hoverscan;
1301 hdrl_bitmask_t reject_code = 1;
1304 cpl_error_ensure(source != NULL, CPL_ERROR_NULL_INPUT,
1305 return NULL,
"NULL input source image");
1306 cpl_error_ensure(os_computation != NULL, CPL_ERROR_NULL_INPUT,
1307 return NULL,
"NULL overscan computation result");
1309 cpl_error_ensure(hdrl_int_is_power_of_two(reject_code),
1310 CPL_ERROR_ILLEGAL_INPUT,
return NULL,
1311 "reject_code must be a power of two");
1313 if (hdrl_overscan_compute_result_verify(os_computation) != CPL_ERROR_NONE)
1316 hoverscan = os_computation->correction;
1319 if (region != NULL) {
1338 nx = cpl_image_get_size_x(source_loc);
1344 if (os_computation->correction_direction == HDRL_X_AXIS &&
1345 ury-lly+1 != ysize_overscan) {
1346 cpl_image_delete(source_loc);
1347 cpl_image_delete(source_error_loc);
1348 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1349 "Correction region Y size does not match overscan Y size");
1352 if (os_computation->correction_direction == HDRL_Y_AXIS &&
1353 urx-llx+1 != xsize_overscan) {
1354 cpl_image_delete(source_loc);
1355 cpl_image_delete(source_error_loc);
1356 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
1357 "Correction region X size does not match overscan X size");
1361 if (xsize_overscan != 1 && ysize_overscan != 1) {
1362 cpl_image_delete(source_loc);
1363 cpl_image_delete(source_error_loc);
1364 cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
1369 orig_mask = hdrl_copy_image_mask(source_loc);
1372 hdrl_data_t * psource_loc = cpl_image_get_data(source_loc);
1373 hdrl_error_t * psource_err_loc = cpl_image_get_data(source_error_loc);
1376 const cpl_binary * rej = bpm ? cpl_mask_get_data_const(bpm) : NULL;
1377 const hdrl_data_t * pos_val = hdrl_get_image_data_const(
1379 const hdrl_error_t * pos_e = hdrl_get_image_error_const(
1382 cpl_image_get_bpm(source_loc);
1386HDRL_OMP(omp parallel
for)
1387 for (
long j = lly - 1; j < ury; j++) {
1388 for (
long i = llx - 1; i < urx; i++) {
1390 os_computation->correction_direction == HDRL_X_AXIS ?
1392 double ima_e = psource_err_loc[j * nx + i];
1394 if (rej && rej[idx]) {
1396 cpl_image_reject(source_loc, i + 1, j + 1);
1397 psource_loc[j * nx + i] = 0;
1398 psource_err_loc[j * nx + i] = 0;
1400 psource_loc[j * nx + i] -= pos_val[idx];
1401 psource_err_loc[j * nx + i] =
1402 sqrt(pos_e[idx] * pos_e[idx] + ima_e * ima_e);
1409 hdrl_overscan_correct_result * res;
1410 cpl_mask * new_mask = hdrl_copy_image_mask(source_loc);
1411 cpl_image * badmask = cpl_image_new(cpl_image_get_size_x(source_loc),
1412 cpl_image_get_size_y(source_loc),
1415 cpl_mask_xor(new_mask, orig_mask);
1417 cpl_image_reject_from_mask(badmask, new_mask);
1418 cpl_image_fill_rejected(badmask, reject_code);
1420 cpl_mask_delete(new_mask);
1421 cpl_mask_delete(orig_mask);
1424 res = hdrl_overscan_correct_result_create();
1425 res->corrected = hdrl_image_wrap(source_loc, source_error_loc, NULL,
1427 res->badmask = badmask;
1439 hdrl_overscan_correct_result * result)
1441 if (result == NULL)
return;
1443 cpl_image_delete(result->badmask);
1456 const hdrl_overscan_correct_result * res)
1458 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1459 return res->corrected;
1470 hdrl_overscan_correct_result * res)
1472 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1473 hdrl_image * r = res->corrected;
1474 res->corrected = NULL;
1486 const hdrl_overscan_correct_result * res)
1488 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1489 return res->badmask;
1500 hdrl_overscan_correct_result * res)
1502 cpl_ensure(res, CPL_ERROR_NULL_INPUT, NULL);
1503 cpl_image * r = res->badmask;
1504 res->badmask = NULL;
1516static void hdrl_overscan_parameter_destroy(
void * param)
1518 hdrl_overscan_parameter * p = (hdrl_overscan_parameter *)param ;
1533static hdrl_overscan_compute_result * hdrl_overscan_compute_result_create(
1536 hdrl_overscan_compute_result * self =
1537 cpl_malloc(
sizeof(hdrl_overscan_compute_result));
1539 self->correction_direction = HDRL_UNDEFINED_AXIS;
1540 self->correction = NULL;
1541 self->contribution = NULL;
1543 self->red_chi2 = NULL;
1544 self->sigclip_reject_low = NULL;
1545 self->sigclip_reject_high = NULL;
1557static cpl_error_code hdrl_overscan_compute_result_verify(
1558 const hdrl_overscan_compute_result * result)
1560 cpl_error_ensure(result != NULL, CPL_ERROR_NULL_INPUT,
1561 return CPL_ERROR_NULL_INPUT,
1562 "NULL input overscan result structure");
1563 cpl_error_ensure(result->correction_direction == HDRL_X_AXIS ||
1564 result->correction_direction == HDRL_Y_AXIS,
1565 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1566 "The specified collapse direction is unknown");
1568 if (result->correction_direction == HDRL_X_AXIS) {
1570 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1571 "The Correction image X size should be 1");
1572 cpl_error_ensure(cpl_image_get_size_x(result->contribution) == 1,
1573 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1574 "The Contribution image X size should be 1");
1575 cpl_error_ensure(cpl_image_get_size_x(result->chi2) == 1,
1576 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1577 "The Chi Square image X size should be 1");
1578 cpl_error_ensure(cpl_image_get_size_x(result->red_chi2) == 1,
1579 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1580 "The reduced Chi Square image X size should be 1");
1581 if (result->sigclip_reject_low != NULL) {
1582 cpl_error_ensure(cpl_image_get_size_x(result->sigclip_reject_low)
1584 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1585 "The SIGCLIP low rejection image X size should be 1");
1588 if (result->sigclip_reject_high != NULL) {
1589 cpl_error_ensure(cpl_image_get_size_x(result->sigclip_reject_high)
1591 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1592 "The SIGCLIP high rejection image X size should be 1");
1595 else if (result->correction_direction == HDRL_Y_AXIS) {
1597 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1598 "The Correction image Y size should be 1");
1599 cpl_error_ensure(cpl_image_get_size_y(result->contribution) == 1,
1600 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1601 "The Contribution image Y size should be 1");
1602 cpl_error_ensure(cpl_image_get_size_y(result->chi2) == 1,
1603 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1604 "The Chi Square image Y size should be 1");
1605 cpl_error_ensure(cpl_image_get_size_y(result->red_chi2) == 1,
1606 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1607 "The reduced Chi Square image Y size should be 1");
1608 if (result->sigclip_reject_low != NULL) {
1609 cpl_error_ensure(cpl_image_get_size_y(result->sigclip_reject_low)
1611 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1612 "The SIGCLIP low rejection image Y size should be 1");
1615 if (result->sigclip_reject_high != NULL) {
1616 cpl_error_ensure(cpl_image_get_size_y(result->sigclip_reject_high)
1618 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
1619 "The SIGCLIP high rejection image Y size should be 1");
1622 else return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
1623 "correction_direction must be HDRL_X_AXIS or HDRL_Y_AXIS");
1624 return CPL_ERROR_NONE;
1635static hdrl_overscan_correct_result * hdrl_overscan_correct_result_create(
1638 hdrl_overscan_correct_result * self = cpl_malloc(
sizeof(*self));
1639 self->corrected = NULL;
1640 self->badmask = NULL;
1655static cpl_error_code hdrl_overscan_compute_chi_square(
1656 const cpl_image * data,
1657 const cpl_image * error,
1658 const double expect,
1663 cpl_size nrej, nerej;
1664 cpl_image * e = NULL;
1668 nrej = cpl_image_count_rejected(data);
1669 npix = cpl_image_get_size_x(data) * cpl_image_get_size_y(data);
1674 return CPL_ERROR_NONE;
1677 e = cpl_image_duplicate(error);
1678 nepix = cpl_image_get_size_x(e) * cpl_image_get_size_y(e);
1682 cpl_image_accept_all(e);
1683 cpl_image_reject_value(e, CPL_VALUE_ZERO);
1684 nerej = cpl_image_count_rejected(e);
1686 if (nerej == nepix) {
1687 cpl_image_delete(e);
1690 return CPL_ERROR_NONE;
1693 else if (nerej != 0) {
1694 cpl_image_delete(e);
1695 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
1696 "Error image can't contain zeros");
1699 return CPL_ERROR_ILLEGAL_INPUT;
1702 s = cpl_image_duplicate(data);
1705 cpl_image_subtract_scalar(s, expect);
1706 cpl_image_divide(s, e);
1707 *chi2 = cpl_image_get_sqflux(s);
1708 *red_chi2 = *chi2 / npix;
1709 cpl_image_delete(s);
1710 cpl_image_delete(e);
1711 return CPL_ERROR_NONE;
1730static cpl_error_code hdrl_overscan_reduce_image_to_scalar(
1731 hdrl_collapse_imagelist_to_vector_t * red,
1733 cpl_image * data_error,
1736 cpl_size * contribution,
1739 cpl_imagelist * ld = cpl_imagelist_new();
1740 cpl_imagelist * le = cpl_imagelist_new();
1741 cpl_vector * od = NULL, * oe = NULL;
1742 cpl_array * oc = NULL;
1743 cpl_error_code fail;
1744 cpl_imagelist_set(ld, data, 0);
1745 cpl_imagelist_set(le, data_error, 0);
1748 fail = hdrl_collapse_imagelist_to_vector_call(red, ld, le, &od, &oe, &oc,
1750 cpl_imagelist_unwrap(ld);
1751 cpl_imagelist_unwrap(le);
1753 if (fail == CPL_ERROR_NONE) {
1754 *result = cpl_vector_get(od, 0);
1755 *error = cpl_vector_get(oe, 0);
1756 *contribution = cpl_array_get_int(oc, 0, NULL);
1764 cpl_vector_delete(od);
1765 cpl_vector_delete(oe);
1766 cpl_array_delete(oc);
double hdrl_collapse_mode_parameter_get_bin_size(const hdrl_parameter *p)
get size of the histogram bins
double hdrl_collapse_mode_parameter_get_histo_min(const hdrl_parameter *p)
get min value
cpl_boolean hdrl_collapse_parameter_is_weighted_mean(const hdrl_parameter *self)
check if parameter is a weighted mean parameter
double hdrl_collapse_sigclip_parameter_get_kappa_low(const hdrl_parameter *p)
get low kappa
cpl_boolean hdrl_collapse_parameter_is_mean(const hdrl_parameter *self)
check if parameter is a mean parameter
cpl_boolean hdrl_collapse_parameter_is_median(const hdrl_parameter *self)
check if parameter is a median parameter
double hdrl_collapse_mode_parameter_get_histo_max(const hdrl_parameter *p)
get high value
int hdrl_collapse_sigclip_parameter_get_niter(const hdrl_parameter *p)
get maximum number of clipping iterations
cpl_size hdrl_collapse_mode_parameter_get_error_niter(const hdrl_parameter *p)
get the error type of the mode
cpl_boolean hdrl_collapse_parameter_is_minmax(const hdrl_parameter *self)
check if parameter is a minmax mean parameter
cpl_boolean hdrl_collapse_parameter_is_mode(const hdrl_parameter *self)
check if parameter is a mode parameter
cpl_boolean hdrl_collapse_parameter_is_sigclip(const hdrl_parameter *self)
check if parameter is a sigclip mean parameter
double hdrl_collapse_sigclip_parameter_get_kappa_high(const hdrl_parameter *p)
get high kappa
double hdrl_collapse_minmax_parameter_get_nlow(const hdrl_parameter *p)
get low value
cpl_parameterlist * hdrl_collapse_parameter_create_parlist(const char *base_context, const char *prefix, const char *method_def, hdrl_parameter *sigclip_def, hdrl_parameter *minmax_def, hdrl_parameter *mode_def)
Create parameters for the collapse.
hdrl_mode_type hdrl_collapse_mode_parameter_get_method(const hdrl_parameter *p)
get the mode determination method
hdrl_parameter * hdrl_collapse_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
parse parameterlist for imagelist reduction method
double hdrl_collapse_minmax_parameter_get_nhigh(const hdrl_parameter *p)
get high value
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
const cpl_mask * hdrl_image_get_mask_const(const hdrl_image *himg)
get cpl bad pixel mask from image
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
const cpl_image * hdrl_image_get_error_const(const hdrl_image *himg)
get error as cpl image
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
void hdrl_overscan_compute_result_delete(hdrl_overscan_compute_result *result)
Deletes the Overscan Computation Result Structure.
cpl_image * hdrl_overscan_correct_result_get_badmask(const hdrl_overscan_correct_result *res)
Access the bad pixels mask in the Overscan Correction result object.
cpl_image * hdrl_overscan_compute_result_unset_red_chi2(hdrl_overscan_compute_result *res)
Unset the reduced CHI2 in the Overscan Computation result object.
cpl_image * hdrl_overscan_correct_result_unset_badmask(hdrl_overscan_correct_result *res)
Unset the bad pixels mask in the Overscan Correction result object.
cpl_image * hdrl_overscan_compute_result_get_minmax_reject_high(const hdrl_overscan_compute_result *res)
Access the high threshold in the Overscan Computation result object.
cpl_boolean hdrl_overscan_parameter_check(const hdrl_parameter *self)
Check that the parameter is an Overscan parameter.
hdrl_image * hdrl_overscan_correct_result_unset_corrected(hdrl_overscan_correct_result *res)
Unset the corrected image in the Overscan Correction result object.
cpl_image * hdrl_overscan_compute_result_get_red_chi2(const hdrl_overscan_compute_result *res)
Access the reduced CHI2 in the Overscan Computation result object.
cpl_image * hdrl_overscan_compute_result_get_sigclip_reject_low(const hdrl_overscan_compute_result *res)
Access the low threshold in the Overscan Computation result object.
cpl_image * hdrl_overscan_compute_result_get_chi2(const hdrl_overscan_compute_result *res)
Access the CHI2 in the Overscan Computation result object.
hdrl_overscan_compute_result * hdrl_overscan_compute(const cpl_image *source, const hdrl_parameter *params)
Overscan correction computation.
cpl_image * hdrl_overscan_compute_result_unset_chi2(hdrl_overscan_compute_result *res)
Unset the CHI2 in the Overscan Computation result object.
cpl_image * hdrl_overscan_compute_result_unset_minmax_reject_high(hdrl_overscan_compute_result *res)
Unset the high threshold in the Overscan Computation result object.
cpl_image * hdrl_overscan_compute_result_unset_contribution(hdrl_overscan_compute_result *res)
Unset the contribution in the Overscan Computation result object.
cpl_image * hdrl_overscan_compute_result_get_minmax_reject_low(const hdrl_overscan_compute_result *res)
Access the low threshold in the Overscan Computation result object.
hdrl_image * hdrl_overscan_compute_result_unset_correction(hdrl_overscan_compute_result *res)
Unset the correction in the Overscan Computation result object.
hdrl_image * hdrl_overscan_correct_result_get_corrected(const hdrl_overscan_correct_result *res)
Access the corrected image in the Overscan Correction result object.
hdrl_parameter * hdrl_overscan_parameter_get_rect_region(const hdrl_parameter *p)
Access the Overscan Region parameters in the Overscan Parameter.
hdrl_parameter * hdrl_overscan_parameter_get_collapse(const hdrl_parameter *p)
Access the collapse method parameters in the Overscan Parameter.
hdrl_parameter * hdrl_overscan_parameter_create(hdrl_direction correction_direction, double ccd_ron, int box_hsize, hdrl_parameter *collapse, hdrl_parameter *rect_region)
Creates Overscan Parameters object.
hdrl_image * hdrl_overscan_compute_result_get_correction(const hdrl_overscan_compute_result *res)
Access the correction in the Overscan Computation result object.
double hdrl_overscan_parameter_get_ccd_ron(const hdrl_parameter *p)
Access the CCD read out noise in the Overscan Parameter.
hdrl_direction hdrl_overscan_parameter_get_correction_direction(const hdrl_parameter *p)
Access the Correction Direction in the Overscan Parameter.
hdrl_overscan_correct_result * hdrl_overscan_correct(const hdrl_image *source, const hdrl_parameter *region, const hdrl_overscan_compute_result *os_computation)
Overscan correction.
hdrl_parameter * hdrl_overscan_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameterlist to create input parameters for the Overscan method.
cpl_image * hdrl_overscan_compute_result_get_contribution(const hdrl_overscan_compute_result *res)
Access the contribution in the Overscan Computation result object.
int hdrl_overscan_parameter_get_box_hsize(const hdrl_parameter *p)
Access the Box Half Size in the Overscan Parameter.
cpl_image * hdrl_overscan_compute_result_unset_minmax_reject_low(hdrl_overscan_compute_result *res)
Unset the low threshold in the Overscan Computation result object.
cpl_image * hdrl_overscan_compute_result_get_sigclip_reject_high(const hdrl_overscan_compute_result *res)
Access the high threshold in the Overscan Computation result object.
void hdrl_overscan_correct_result_delete(hdrl_overscan_correct_result *result)
Delete the Overscan Correction Result Structure.
cpl_image * hdrl_overscan_compute_result_unset_sigclip_reject_low(hdrl_overscan_compute_result *res)
Unset the low threshold in the Overscan Computation result object.
cpl_image * hdrl_overscan_compute_result_unset_sigclip_reject_high(hdrl_overscan_compute_result *res)
Unset the high threshold in the Overscan Computation result object.
cpl_parameterlist * hdrl_overscan_parameter_create_parlist(const char *base_context, const char *prefix, const char *corr_dir_def, int box_hsize_def, double ccd_ron_def, hdrl_parameter *rect_region_def, const char *method_def, hdrl_parameter *sigclip_def, hdrl_parameter *minmax_def, hdrl_parameter *mode_def)
Create parameter list for the Overscan computation.
cpl_error_code hdrl_overscan_parameter_verify(const hdrl_parameter *param, cpl_size nx, cpl_size ny)
Verify basic correctness of the Overscan parameters.
void hdrl_parameter_destroy(hdrl_parameter *obj)
deep delete of a parameter
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
cpl_error_code hdrl_rect_region_parameter_verify(const hdrl_parameter *param, const cpl_size max_x, const cpl_size max_y)
Verify basic correctness of the parameters.
cpl_parameterlist * hdrl_rect_region_parameter_create_parlist(const char *base_context, const char *prefix, const char *name_prefix, const hdrl_parameter *defaults)
Create parameter list for hdrl_rect_region.
cpl_size hdrl_rect_region_get_llx(const hdrl_parameter *p)
get lower left x coordinate of rectangual region
cpl_size hdrl_rect_region_get_urx(const hdrl_parameter *p)
get upper right x coordinate of rectangular region
cpl_size hdrl_rect_region_get_lly(const hdrl_parameter *p)
get lower left y coordinate of rectangual region
char * hdrl_join_string(const char *sep_, int n,...)
join strings together
cpl_size hdrl_rect_region_get_ury(const hdrl_parameter *p)
get upper right y coordinate of rectangual region
hdrl_parameter * hdrl_rect_region_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *base_context, const char *name_prefix)
parse parameterlist for rectangle parameters
cpl_boolean hdrl_rect_region_parameter_check(const hdrl_parameter *self)
Check that the parameter is hdrl_rect_region parameter.