39#include "eris_nix_detector.h"
41#include "eris_nix_casu_utils.h"
42#include "eris_nix_dfs.h"
58void engl_lin_correct_(
double *,
64 const int) CPL_ATTR_NONNULL;
67double engl_lin_find_(
const double,
72 double *) CPL_ATTR_NONNULL;
101eris_nix_samples * end_calculate_samples(
const cpl_image * start_intensity,
102 const cpl_image * ramp_intensity,
105 const cpl_image * f) {
107 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
109 cpl_ensure(start_intensity, CPL_ERROR_NULL_INPUT, NULL);
110 cpl_ensure(ramp_intensity, CPL_ERROR_NULL_INPUT, NULL);
111 cpl_ensure(f, CPL_ERROR_NULL_INPUT, NULL);
112 cpl_ensure(nr > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
113 cpl_ensure(dit > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
115 eris_nix_samples * result = cpl_calloc(1,
sizeof(eris_nix_samples));
117 result->samples = cpl_calloc(nr,
sizeof(cpl_image *));
118 const double dt = dit / (float) (nr - 1);
122 result->samples[0] = cpl_image_multiply_scalar_create(f, -1.0);
123 cpl_image_add_scalar(result->samples[0], 1.0);
124 cpl_image_multiply(result->samples[0], start_intensity);
125 cpl_image_multiply_scalar(result->samples[0], dt);
130 for (cpl_size i = 2; i <= nr; i++) {
131 result->samples[i-1] = cpl_image_duplicate(ramp_intensity);
132 cpl_image_multiply_scalar(result->samples[i-1], (
double) (i-1) * dt);
134 cpl_image_add(result->samples[i-1], result->samples[0]);
139 if (cpl_error_get_code() != CPL_ERROR_NONE) {
140 end_samples_delete(result);
157void end_samples_delete(eris_nix_samples * samples) {
160 for (cpl_size i = 0; i < samples->nr; i++) {
161 cpl_image_delete(samples->samples[i]);
163 cpl_free(samples->samples);
209cpl_error_code end_linearize_image(cpl_image * data,
210 const gain_linearity * gain_lin,
214 const cpl_size x_probe,
215 const cpl_size y_probe) {
217 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
220 double time1, time2, time3;
221 time1 = omp_get_wtime();
223 clock_t time1, time2, time3;
227 cpl_ensure_code(data, CPL_ERROR_NULL_INPUT);
228 cpl_ensure_code(gain_lin, CPL_ERROR_NULL_INPUT);
230 cpl_ensure_code(rot == 0, CPL_ERROR_UNSUPPORTED_MODE);
234 const cpl_size fit_order = cpl_imagelist_get_size(gain_lin->
236 const cpl_binary * fit_bpm = cpl_mask_get_data_const(gain_lin->bpm);
238 enu_check(cpl_error_get_code()==CPL_ERROR_NONE && fit_order > 1,
239 CPL_ERROR_INCOMPATIBLE_INPUT,
240 "linearization data in unexpected format");
244 cpl_size coeff_nx = cpl_image_get_size_x(cpl_imagelist_get_const(
245 gain_lin->lin_coeffs, 0));
246 cpl_size coeff_ny = cpl_image_get_size_y(cpl_imagelist_get_const(
247 gain_lin->lin_coeffs, 0));
248 const cpl_size nx = cpl_image_get_size_x(data);
249 const cpl_size ny = cpl_image_get_size_y(data);
252 enu_check(cpl_image_get_type(data)==CPL_TYPE_DOUBLE,
253 CPL_ERROR_INCOMPATIBLE_INPUT,
"image data is not double");
257 double * pdata = cpl_image_get_data_double(data);
258 cpl_binary * pbpm = cpl_mask_get_data(cpl_image_get_bpm(data));
259 const cpl_boolean do_info_msg = cpl_msg_get_level() <= CPL_MSG_INFO &&
260 (x_probe >= 0) && (y_probe >= 0);
262 enu_check(nx + strx - 1 <= coeff_nx, CPL_ERROR_UNSPECIFIED,
263 "Illegal X-windowing");
264 enu_check(ny + stry - 1 <= coeff_ny, CPL_ERROR_UNSPECIFIED,
265 "Illegal Y-windowing");
270 time2 = omp_get_wtime();
275 if (strx == 1 && stry == 1 && coeff_nx == nx) {
280 for (cpl_size ipos= 0 ; ipos < nx * ny ; ipos++) {
283 const int debug = do_info_msg &&
284 (ipos % nx == x_probe) && (ipos / nx == y_probe);
287 engl_lin_correct_(pdata + ipos, fit_order, gain_lin
288 ->ordered_lin_coeffs + ipos * fit_order,
290 gain_lin->saturation_limit,
298 cpl_msg_info(cpl_func,
"Windowing: %d %d %d %d", (
int)strx, (
int)stry,
299 (
int)coeff_nx, (
int)coeff_ny);
304 for (cpl_size iy=0 ; iy < ny ; iy++) {
305 for (cpl_size ix=0 ; ix < nx ; ix++) {
308 const cpl_size ipos = ix + iy * nx;
313 const cpl_size coeff_x = ix + strx - 1;
314 const cpl_size coeff_y = iy + stry - 1;
315 const cpl_size coeff_pos = coeff_x + coeff_y * coeff_nx;
316 const int debug = do_info_msg && (ix == x_probe) && (iy == y_probe);
320 engl_lin_correct_(pdata + ipos, fit_order, gain_lin
321 ->ordered_lin_coeffs + coeff_pos * fit_order,
323 gain_lin->saturation_limit,
334 time3 = omp_get_wtime();
340 cpl_msg_info(cpl_func,
"end_linearize_image OPM setup %5.2e lin %5.2e",
341 time2-time1, time3-time2);
343 cpl_msg_info(cpl_func,
"end_linearize_image setup %5.2e lin %5.2e",
344 (
double)(time2-time1) / CLOCKS_PER_SEC,
345 (
double)(time3-time2) / CLOCKS_PER_SEC);
350 return cpl_error_get_code();
372cpl_image * end_uptheramp_reduce(eris_nix_samples * samples,
375 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
377 cpl_ensure(samples, CPL_ERROR_NULL_INPUT, NULL);
378 cpl_ensure(samples->nr > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
379 cpl_ensure(dit > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
383 cpl_image * result = cpl_image_new(
384 cpl_image_get_size_x(samples->samples[0]),
385 cpl_image_get_size_y(samples->samples[0]),
386 cpl_image_get_type(samples->samples[0]));
390 const cpl_size nr = samples->nr;
391 for (cpl_size i = 1; i <= nr && cpl_error_get_code()==CPL_ERROR_NONE;
394 cpl_image * temp = cpl_image_multiply_scalar_create(
395 samples->samples[i-1],
396 (
double)i - ((
double)nr + 1.0) / 2.0);
397 cpl_image_add(result, temp);
398 cpl_image_delete(temp);
400 const double alpha = (double) (nr * (nr + 1)) * dit / 12.0;
401 cpl_image_divide_scalar(result, alpha);
405 if (cpl_error_get_code() != CPL_ERROR_NONE) {
406 cpl_image_delete(result);
444end_linearize_and_variance_detmon(
const gain_linearity * gain_lin,
445 const master_dark * mdark,
446 const hdrl_image * himage,
447 const cpl_propertylist * plist,
448 const cpl_size x_probe,
449 const cpl_size y_probe) {
451 hdrl_image * self = NULL;
452 cpl_image * linear_data;
453 cpl_image * variance;
455 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
457 cpl_ensure(gain_lin, CPL_ERROR_NULL_INPUT, NULL);
458 cpl_ensure(mdark, CPL_ERROR_NULL_INPUT, NULL);
467 cpl_size nx_chip = 0;
468 cpl_size ny_chip = 0;
469 cpl_boolean windowed = 0;
479 enu_check_error_code(
"failed to read detector window information");
481 int probing = CPL_FALSE;
482 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
487 enu_check_error_code(
"failed to read detector mode information");
488 cpl_msg_info(cpl_func,
"curname=%s rot=%d strx=%d stry=%d nx=%d ny=%d",
489 det_mode, (
int)rot, (
int)strx, (
int)stry, (
int)nx, (
int)ny );
496 if (!strcmp(det_mode,
"Double_RdRstRd")) {
506 const int ndit = cpl_propertylist_get_int(plist,
510 const double g = gain_lin->gain.data;
511 const double sigma_read = cpl_propertylist_get_double(
513 "ESO QC READ NOISE");
519 end_linearize_image(linear_data, gain_lin, rot, strx, stry,
524 double probe_v = cpl_image_get(linear_data, x_probe, y_probe,
526 cpl_msg_info(cpl_func,
"linear_data %4.2e %d", probe_v,
533 cpl_image_divide_scalar(linear_data, dit);
542 cpl_image_copy(variance, linear_data, 1, 1);
550 cpl_image_threshold(variance, 0.0, DBL_MAX, 0.0, DBL_MAX);
551 const double dt = 0.05;
552 cpl_image_multiply_scalar(variance,
553 (1.0 - dt * (nr * nr - 1) /
557 cpl_msg_info(cpl_func,
"photnoise factor %5.3e %d %5.3e %5.3e "
558 "%d %5.3e", dt, nr, dit, g, ndit,
559 (1.0 - dt * (nr * nr - 1) / (3.0 * dit * nr)) /
566 cpl_msg_info(cpl_func,
"readnoise comp %5.3e %5.3e %d %d"
567 "%5.3e% 5.3e", sigma_read, g, nr, ndit, dit,
568 2.0 * sigma_read * sigma_read /
569 (g * g * nr * ndit * dit * dit));
571 cpl_image_add_scalar(variance,
572 2.0 * sigma_read * sigma_read /
573 (g * g * nr * ndit * dit * dit));
577 cpl_image_fill_rejected(variance, 0.0);
579 }
else if (!strcmp(det_mode,
"SLOW_UP_THE_RAMP") ||
580 !strcmp(det_mode,
"SLOW_GR_UTR")) {
582 cpl_msg_info(cpl_func,
"slow gr utr %s", cpl_error_get_message());
592 const int ndit = cpl_propertylist_get_int(plist,
594 const int nr = cpl_propertylist_get_int(plist,
595 "ESO DET NDSAMPLES");
596 const double g = gain_lin->gain.data;
597 const double sigma_read = cpl_propertylist_get_double(
599 "ESO QC READ NOISE");
607 end_linearize_image(linear_data, gain_lin, rot, strx, stry,
613 cpl_image_divide_scalar(linear_data, dit);
622 cpl_image_copy(variance, linear_data, 1, 1);
623 cpl_image_multiply_scalar(variance, 1.2 * (nr*nr + 1) /
624 ((nr + 1) * nr * g * dit));
628 cpl_image_add_scalar(variance,
629 12.0 * sigma_read * sigma_read *
631 ((nr + 1) * nr * g * g * dit * dit));
636 cpl_image_divide_scalar(variance, (
double) ndit);
638 cpl_image_power(variance, 0.5);
643 cpl_image_reject_from_mask(linear_data, cpl_image_get_bpm(variance));
645 }
else if (!strcmp(det_mode,
"FAST_UNCORR")) {
650 end_linearize_image(linear_data, gain_lin, rot, strx, stry,
654 double val = cpl_image_get(linear_data, x_probe, y_probe,
656 cpl_msg_info(cpl_func,
"..eris_nix_detector probe (%d %d) "
657 "linearized_data v=%5.3e", (
int)x_probe,
665 const double ndit = (double) cpl_propertylist_get_int(plist,
667 const double g = gain_lin->gain.data;
668 const double sigma_read = cpl_propertylist_get_double(
670 "ESO QC READ NOISE");
675 cpl_image_divide_scalar(linear_data, dit);
701 cpl_image_copy(variance, linear_data, 1, 1);
702 cpl_image_threshold(variance, 0.0, 1e32, 0.0, 1e32);
703 cpl_image_multiply_scalar(variance, 1.0 / (g * ndit * dit));
707 cpl_image_add_scalar(variance,
708 sigma_read * sigma_read /
709 (g * g * ndit * dit * dit));
711 cpl_image_power(variance, 0.5);
714 double val = cpl_image_get(variance, x_probe, y_probe,
716 cpl_msg_info(cpl_func,
"..eris_nix_detector probe %d %d "
717 "variance %5.3e", (
int)x_probe, (
int)y_probe, val);
718 cpl_msg_info(cpl_func,
"..probe information sigma=%5.3e "
719 "g=%5.3e ndit=%d dit=%5.3e", sigma_read, g,
726 cpl_image_reject_from_mask(linear_data, cpl_image_get_bpm(variance));
729 cpl_msg_warning(cpl_func,
"linearization not done - unsupported "
730 "detector mode: %s", det_mode);
765cpl_error_code end_linearize_and_variance(
const gain_linearity * gain_lin,
766 const master_dark * mdark,
767 located_imagelist * limlist,
768 const cpl_size x_probe,
769 const cpl_size y_probe) {
771 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
773 cpl_msg_info(cpl_func,
"%p %p %p", (
const void*)gain_lin,
774 (
const void*)mdark, (
const void*)limlist);
775 cpl_ensure_code(gain_lin, CPL_ERROR_NULL_INPUT);
776 cpl_ensure_code(mdark, CPL_ERROR_NULL_INPUT);
777 cpl_ensure_code(limlist, CPL_ERROR_NULL_INPUT);
778 cpl_msg_info(cpl_func,
"after %p %p %p", (
const void*)gain_lin,
779 (
const void*)mdark, (
const void*)limlist);
781 if (limlist->size <= 0)
return CPL_ERROR_NONE;
792 cpl_image * f = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
793 cpl_image_fill_window(f, 1, 1, nx, ny, 1.0);
795 int probing = CPL_FALSE;
796 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
802 for (cpl_size i = 0; i < limlist->size; i++) {
804 cpl_msg_info(cpl_func,
"image %d", (
int) i);
806 const char * det_mode = cpl_propertylist_get_string(
807 (limlist->limages[i])->plist,
808 "ESO DET READ CURNAME");
809 const int rot = cpl_propertylist_get_int(
810 (limlist->limages[i])->plist,
811 "ESO DET SEQ1 WIN ROT");
812 const cpl_size strx = cpl_propertylist_get_int(
813 (limlist->limages[i])->plist,
814 "ESO DET SEQ1 WIN STRX");
815 const cpl_size stry = cpl_propertylist_get_int(
816 (limlist->limages[i])->plist,
817 "ESO DET SEQ1 WIN STRY");
818 enu_check_error_code(
"failed to read detector mode information");
819 cpl_msg_info(cpl_func,
"curname=%s rot=%d strx=%d stry=%d nx=%d ny=%d",
820 det_mode, (
int)rot, (
int)strx, (
int)stry, (
int)nx, (
int)ny );
822 if (!strcmp(det_mode,
"SLOW_LR_CDS")) {
831 double dit =
enu_get_dit(limlist->limages[i]->plist);
832 const int ndit = cpl_propertylist_get_int(
833 (limlist->limages[i])->plist,
"ESO DET NDIT");
834 const int nr = cpl_propertylist_get_int(
835 (limlist->limages[i])->plist,
"ESO DET NDSAMPLES");
836 const double g = gain_lin->gain.data;
837 const double sigma_read = cpl_propertylist_get_double(
838 mdark->plist,
"ESO QC READ NOISE");
841 (limlist->limages[i])->himage));
845 cpl_image_divide_scalar(data, dit);
851 double probe_v = cpl_image_get(data, x_probe, y_probe,
853 cpl_msg_info(cpl_func,
"data %4.2e %d", probe_v, ignore);
856 cpl_image * linear_data = end_vacca_linearize_cds(data,
857 gain_lin, dit, nr, f,
858 rot, strx, stry, x_probe, y_probe);
861 double probe_v = cpl_image_get(linear_data, x_probe, y_probe,
863 cpl_msg_info(cpl_func,
"linear_data %4.2e %d", probe_v,
874 cpl_image * variance = cpl_image_duplicate(linear_data);
882 cpl_image_threshold(variance, 0.0, DBL_MAX, 0.0, DBL_MAX);
883 const double dt = 0.05;
884 cpl_image_multiply_scalar(variance,
885 (1.0 - dt * (nr * nr - 1) /
889 cpl_msg_info(cpl_func,
"photnoise factor %5.3e %d %5.3e %5.3e "
890 "%d %5.3e", dt, nr, dit, g, ndit,
891 (1.0 - dt * (nr * nr - 1) / (3.0 * dit * nr)) /
898 cpl_msg_info(cpl_func,
"readnoise comp %5.3e %5.3e %d %d"
899 "%5.3e% 5.3e", sigma_read, g, nr, ndit, dit,
900 2.0 * sigma_read * sigma_read /
901 (g * g * nr * ndit * dit * dit));
903 cpl_image_add_scalar(variance,
904 2.0 * sigma_read * sigma_read /
905 (g * g * nr * ndit * dit * dit));
909 cpl_image_fill_rejected(variance, 0.0);
913 cpl_image_power(variance, 0.5);
919 cpl_image_delete(data);
920 cpl_image_delete(linear_data);
921 cpl_image_delete(variance);
923 }
else if (!strcmp(det_mode,
"SLOW_UP_THE_RAMP") ||
924 !strcmp(det_mode,
"SLOW_GR_UTR")) {
926 cpl_msg_info(cpl_func,
"slow gr utr %s", cpl_error_get_message());
935 double dit =
enu_get_dit(limlist->limages[i]->plist);
936 const int ndit = cpl_propertylist_get_int(
937 (limlist->limages[i])->plist,
"ESO DET NDIT");
938 const int nr = cpl_propertylist_get_int(
939 (limlist->limages[i])->plist,
"ESO DET NDSAMPLES");
940 const double g = gain_lin->gain.data;
941 const double sigma_read = cpl_propertylist_get_double(
942 mdark->plist,
"ESO QC READ NOISE");
947 (limlist->limages[i])->himage));
948 cpl_image_divide_scalar(data, dit);
959 cpl_image * linear_data = end_vacca_linearize_ramp(data,
960 gain_lin, dit, nr, f,
961 rot, strx, stry, x_probe, y_probe);
970 cpl_image * variance = cpl_image_duplicate(linear_data);
971 cpl_image_multiply_scalar(variance, 1.2 * (nr*nr + 1) /
972 ((nr + 1) * nr * g * dit));
976 cpl_image_add_scalar(variance,
977 12.0 * sigma_read * sigma_read *
979 ((nr + 1) * nr * g * g * dit * dit));
984 cpl_image_divide_scalar(variance, (
double) ndit);
988 cpl_image_power(variance, 0.5);
993 cpl_mask * vbpm = cpl_mask_duplicate(cpl_image_get_bpm(variance));
994 cpl_mask * ignore = cpl_image_set_bpm(linear_data, vbpm);
995 cpl_mask_delete(ignore); ignore = NULL;
1002 cpl_image_delete(data);
1003 cpl_image_delete(linear_data);
1004 cpl_image_delete(variance);
1007 cpl_msg_warning(cpl_func,
"linearization not done - unsupported "
1008 "detector mode: %s", det_mode);
1015 cpl_image_delete(f);
1017 return cpl_error_get_code();
1052cpl_image * end_vacca_linearize_cds(cpl_image * intensity,
1053 const gain_linearity * gain_lin,
1056 const cpl_image * f,
1063 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
1065 cpl_ensure(intensity, CPL_ERROR_NULL_INPUT, NULL);
1066 cpl_ensure(gain_lin, CPL_ERROR_NULL_INPUT, NULL);
1067 cpl_ensure(nr > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1069 cpl_image * change = NULL;
1070 cpl_image * result = NULL;
1072 cpl_size nx = cpl_image_get_size_x(intensity);
1073 cpl_size ny = cpl_image_get_size_y(intensity);
1075 int probing = CPL_FALSE;
1076 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
1082 cpl_image ** iteration = cpl_calloc(LINEARIZE_MAXITER,
1083 sizeof(cpl_image *));
1085 iteration[0] = cpl_image_duplicate(intensity);
1090 const double dt = 0.05;
1092 while (niter+1 < LINEARIZE_MAXITER &&
1093 cpl_error_get_code() == CPL_ERROR_NONE) {
1098 cpl_image * pedestal = cpl_image_multiply_scalar_create(f, -1.0);
1099 cpl_image_add_scalar(pedestal, (
double) (nr + 1) / 2);
1100 cpl_image_multiply(pedestal, iteration[niter]);
1101 cpl_image_multiply_scalar(pedestal, dt);
1102 cpl_image * signal = cpl_image_multiply_scalar_create(iteration[0],
1104 cpl_image_add(signal, pedestal);
1108 double probe_val = cpl_image_get(iteration[niter], x_probe,
1111 double probe_p = cpl_image_get(pedestal, x_probe, y_probe,
1113 double probe_s = cpl_image_get(signal, x_probe, y_probe,
1115 cpl_msg_info(cpl_func,
"linearizing: (pix %d,%d) niter=%d "
1116 "I=%4.2e pedestal=%4.2e signal=%4.2e",
1117 (
int)x_probe, (
int)y_probe, (
int)niter,
1118 probe_val, probe_p, probe_s);
1120 cpl_msg_info(cpl_func,
"linearizing: (pix %d,%d) niter=%d "
1121 "bad pixel", (
int)x_probe, (
int)y_probe,
1128 end_linearize_image(pedestal, gain_lin, rot, strx, stry,
1130 end_linearize_image(signal, gain_lin, rot, strx, stry,
1136 iteration[niter] = cpl_image_subtract_create(signal, pedestal);
1137 cpl_image_divide_scalar(iteration[niter], dit);
1138 cpl_image_delete(pedestal);
1139 cpl_image_delete(signal);
1142 result = cpl_image_duplicate(iteration[niter]);
1148 change = cpl_image_divide_create(iteration[niter],
1149 iteration[niter-1]);
1150 cpl_mask_threshold_image(cpl_image_get_bpm(result), change, 0.99,
1151 1.01, CPL_BINARY_0);
1155 cpl_image_fill_rejected(result, 0.0);
1160 for (cpl_size i = 0; i < LINEARIZE_MAXITER; i++) {
1161 cpl_image_delete(iteration[i]);
1163 cpl_free(iteration);
1164 cpl_image_delete(change);
1168 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1169 cpl_image_delete(result);
1207cpl_image * end_vacca_linearize_ramp(cpl_image * intensity,
1208 const gain_linearity * gain_lin,
1211 const cpl_image * f,
1213 const cpl_size strx,
1214 const cpl_size stry,
1215 const cpl_size x_probe,
1216 const cpl_size y_probe) {
1218 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
1221 double time1, time2, time3, time4, time11, time12, time13, time14;
1222 time1 = omp_get_wtime();
1224 clock_t time1, time2, time3, time4, time11, time12, time13, time14;
1228 cpl_ensure(intensity, CPL_ERROR_NULL_INPUT, NULL);
1229 cpl_ensure(gain_lin, CPL_ERROR_NULL_INPUT, NULL);
1230 cpl_ensure(nr > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1232 cpl_image * result = NULL;
1233 cpl_image * change = NULL;
1235 cpl_size nx = cpl_image_get_size_x(intensity);
1236 cpl_size ny = cpl_image_get_size_y(intensity);
1237 int probing = CPL_FALSE;
1238 cpl_msg_info(cpl_func,
"%d %d %d %d", (
int)x_probe, (
int)y_probe, (
int)nx, (
int)ny);
1239 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
1241 cpl_msg_info(cpl_func,
"messaging on");
1248 cpl_image ** iteration = cpl_calloc(LINEARIZE_MAXITER,
1249 sizeof(cpl_image *));
1251 iteration[0] = cpl_image_duplicate(intensity);
1253 s = cpl_image_get(intensity, x_probe, y_probe, &reject);
1254 cpl_msg_info(cpl_func,
"initial %s %5.2f", cpl_error_get_message(), s);
1258 time2 = omp_get_wtime();
1263 while (niter+1 < LINEARIZE_MAXITER &&
1264 cpl_error_get_code() == CPL_ERROR_NONE) {
1269 time11 = omp_get_wtime();
1273 eris_nix_samples * samples = end_calculate_samples(iteration[niter],
1278 cpl_msg_info(cpl_func,
"samples before linearization: is, reject, s");
1279 for (cpl_size is=0; is<samples->nr; is++) {
1280 s = cpl_image_get(samples->samples[is], x_probe, y_probe, &reject);
1281 cpl_msg_info(cpl_func,
"%d %d %5.2f", (
int)is, reject, s);
1288 time12 = omp_get_wtime();
1292 for (cpl_size i = 0; i < nr; i++) {
1293 end_linearize_image(samples->samples[i], gain_lin, rot,
1294 strx, stry, x_probe, y_probe);
1298 cpl_msg_info(cpl_func,
"samples after: is, reject, s");
1299 for (cpl_size is=0; is<samples->nr; is++) {
1300 s = cpl_image_get(samples->samples[is], x_probe, y_probe, &reject);
1301 cpl_msg_info(cpl_func,
"%d %d %5.2f", (
int)is, reject, s);
1308 time13 = omp_get_wtime();
1313 iteration[niter] = end_uptheramp_reduce(samples, dit);
1316 s = cpl_image_get(iteration[niter], x_probe, y_probe, &reject);
1317 cpl_msg_info(cpl_func,
"iteration %s %d %9.4e", cpl_error_get_message(),
1323 time14 = omp_get_wtime();
1324 cpl_msg_info(cpl_func,
"%d ramp samp %5.2e lin %5.2e calc %5.2e",
1331 cpl_msg_info(cpl_func,
"%d ramp samp %5.2e lin %5.2e calc %5.2e",
1333 (
double)(time12-time11) / CLOCKS_PER_SEC,
1334 (
double)(time13-time12) / CLOCKS_PER_SEC,
1335 (
double)(time14-time13) / CLOCKS_PER_SEC);
1337 end_samples_delete(samples);
1341 time3 = omp_get_wtime();
1346 result = cpl_image_duplicate(iteration[niter]);
1349 s = cpl_image_get(result, x_probe, y_probe, &reject);
1350 cpl_msg_info(cpl_func,
"result %s %5.2f", cpl_error_get_message(), s);
1358 change = cpl_image_divide_create(iteration[niter],
1359 iteration[niter-1]);
1360 cpl_mask_threshold_image(cpl_image_get_bpm(result), change, 0.99,
1361 1.01, CPL_BINARY_0);
1366 for (cpl_size i = 0; i < LINEARIZE_MAXITER; i++) {
1367 cpl_image_delete(iteration[i]);
1369 cpl_free(iteration);
1370 cpl_image_delete(change);
1374 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1375 cpl_image_delete(result);
1380 time4 = omp_get_wtime();
1381 cpl_msg_info(cpl_func,
"ramp setup %5.2e lin %5.2e tidy %5.2e",
1387 cpl_msg_info(cpl_func,
"ramp setup %5.2e lin %5.2e tidy %5.2e",
1388 (
double)(time2-time1) / CLOCKS_PER_SEC,
1389 (
double)(time3-time2) / CLOCKS_PER_SEC,
1390 (
double)(time4-time3) / CLOCKS_PER_SEC);
1414double engl_lin_correct(
const double obs,
1415 const cpl_size fit_order,
1416 const double* coeffs,
1417 const cpl_binary fit_quality,
1418 const double saturation,
1419 cpl_binary * rejected,
1420 cpl_binary * saturated,
1423 double result = obs;
1424 if (cpl_error_get_code())
return 0.0;
1426 cpl_msg_info(cpl_func,
"Saturation ptr: %p", (
const void*)saturated);
1428 engl_lin_correct_(&result,
1457void engl_lin_correct_(
double * pobs,
1458 const cpl_size fit_order,
1459 const double* coeffs,
1460 const cpl_binary fit_quality,
1461 const double saturation,
1462 cpl_binary * rejected,
1465 if (fit_quality == CPL_BINARY_1) {
1467 if (debug) cpl_msg_info(cpl_func,
"....debug bad quality");
1468 *rejected = CPL_BINARY_1;
1470 }
else if (coeffs[1] <= 0.0) {
1474 if (debug) cpl_msg_info(cpl_func,
"....debug bad slope");
1475 *rejected = CPL_BINARY_1;
1477 }
else if (*pobs > 0.0) {
1485 const double useobs = *pobs > saturation ? saturation : *pobs;
1488 const double t = engl_lin_find_(*pobs, 0.9 * useobs / coeffs[1],
1489 1.5 * useobs / coeffs[1],
1490 fit_order, coeffs, &curve);
1492 const double correction = (coeffs[1] * t) / curve;
1494 *pobs *= correction;
1495 *rejected = t > 0.0 ? CPL_BINARY_0 : CPL_BINARY_1;
1498 if (useobs == saturation)
1499 cpl_msg_info(cpl_func,
"....debug saturated");
1501 for (
int j = fit_order-1; j>-1; j--) {
1502 cpl_msg_info(cpl_func,
"....debug curve coeffs %d %5.3e",
1505 cpl_msg_info(cpl_func,
"....debug t %4.2f", t);
1506 cpl_msg_info(cpl_func,
"....debug correction %6.4e %4.2e "
1507 "%4.2e", correction, *pobs, curve);
1514 cpl_msg_info(cpl_func,
"....debug negative");
1533double engl_lin_find(
const double obs,
1536 const cpl_size fit_order,
1537 const double* coeffs) {
1540 return cpl_error_get_code() ? -1.0 :
1541 engl_lin_find_(obs, low_t, high_t, fit_order, coeffs, &dummy);
1563double engl_lin_find_(
const double obs,
1566 const cpl_size fit_order,
1567 const double* coeffs,
1570 double result = 0.0;
1573 double low_curve = 0.0;
1574 double high_curve = 0.0;
1582 if (low_curve == 0.0) {
1583 int j = fit_order-2;
1584 low_curve = coeffs[fit_order-1];
1585 for (; j >= 3; j--) {
1586 low_curve = low_curve * low_t + coeffs[j];
1590 low_curve = low_curve * low_t + coeffs[2];
1593 low_curve = low_curve * low_t + coeffs[1];
1599 if (high_curve == 0.0) {
1600 int j = fit_order-2;
1601 high_curve = coeffs[fit_order-1];
1602 for (; j >= 3; j--) {
1603 high_curve = high_curve * high_t + coeffs[j];
1607 high_curve = high_curve * high_t + coeffs[2];
1610 high_curve = high_curve * high_t + coeffs[1];
1613 high_curve *= high_t;
1616 double mid_t = (low_t + high_t) / 2.0;
1617 double mid_curve = coeffs[fit_order-1];
1618 int j = fit_order-2;
1619 for (; j >= 3; j--) {
1620 mid_curve = mid_curve * mid_t + coeffs[j];
1624 mid_curve = mid_curve * mid_t + coeffs[2];
1627 mid_curve = mid_curve * mid_t + coeffs[1];
1635 if (fabs(obs - mid_curve) < MAX_LIN_DIFFERENCE) {
1636 *pcurve = mid_curve;
1639 }
else if ((obs > low_curve) && (obs < mid_curve)) {
1642 }
else if ((obs > mid_curve) && (obs < high_curve)) {
1652 }
while (iter++ < MAX_LIN_DEPTH);
1656 if (iter >= MAX_LIN_DEPTH) {
1657 cpl_msg_info(cpl_func,
"max depth %4.2e %4.2e %4.2e %d %4.2e %4.2e "
1658 "%4.2e", obs, low_t, high_t,
1659 (
int)fit_order, coeffs[0], coeffs[1],coeffs[3]);
cpl_error_code enu_get_window_info(cpl_size *nx, cpl_size *ny, int *rot, cpl_size *strx, cpl_size *stry, cpl_size *nx_chip, cpl_size *ny_chip, cpl_boolean *windowed, const cpl_propertylist *plist)
Get the detector 'window' information.
const char * enu_get_det_mode(const cpl_propertylist *plist)
Get the detector mode of an integration.
double enu_get_dit(const cpl_propertylist *plist)
Get the DIT of an integration.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_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
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
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image