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) {
278#pragma omp parallel for
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,
296 cpl_msg_info(cpl_func,
"Windowing: %d %d %d %d", (
int)strx, (
int)stry,
297 (
int)coeff_nx, (
int)coeff_ny);
300#pragma omp parallel for
302 for (cpl_size iy=0 ; iy < ny ; iy++) {
303 for (cpl_size ix=0 ; ix < nx ; ix++) {
306 const cpl_size ipos = ix + iy * nx;
311 const cpl_size coeff_x = ix + strx - 1;
312 const cpl_size coeff_y = iy + stry - 1;
313 const cpl_size coeff_pos = coeff_x + coeff_y * coeff_nx;
314 const int debug = do_info_msg && (ix == x_probe) && (iy == y_probe);
318 engl_lin_correct_(pdata + ipos, fit_order, gain_lin
319 ->ordered_lin_coeffs + coeff_pos * fit_order,
321 gain_lin->saturation_limit,
330 time3 = omp_get_wtime();
336 cpl_msg_info(cpl_func,
"end_linearize_image OPM setup %5.2e lin %5.2e",
337 time2-time1, time3-time2);
339 cpl_msg_info(cpl_func,
"end_linearize_image setup %5.2e lin %5.2e",
340 (
double)(time2-time1) / CLOCKS_PER_SEC,
341 (
double)(time3-time2) / CLOCKS_PER_SEC);
346 return cpl_error_get_code();
368cpl_image * end_uptheramp_reduce(eris_nix_samples * samples,
371 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
373 cpl_ensure(samples, CPL_ERROR_NULL_INPUT, NULL);
374 cpl_ensure(samples->nr > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
375 cpl_ensure(dit > 0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
379 cpl_image * result = cpl_image_new(
380 cpl_image_get_size_x(samples->samples[0]),
381 cpl_image_get_size_y(samples->samples[0]),
382 cpl_image_get_type(samples->samples[0]));
386 const cpl_size nr = samples->nr;
387 for (cpl_size i = 1; i <= nr && cpl_error_get_code()==CPL_ERROR_NONE;
390 cpl_image * temp = cpl_image_multiply_scalar_create(
391 samples->samples[i-1],
392 (
double)i - ((
double)nr + 1.0) / 2.0);
393 cpl_image_add(result, temp);
394 cpl_image_delete(temp);
396 const double alpha = (double) (nr * (nr + 1)) * dit / 12.0;
397 cpl_image_divide_scalar(result, alpha);
401 if (cpl_error_get_code() != CPL_ERROR_NONE) {
402 cpl_image_delete(result);
440end_linearize_and_variance_detmon(
const gain_linearity * gain_lin,
441 const master_dark * mdark,
442 const hdrl_image * himage,
443 const cpl_propertylist * plist,
444 const cpl_size x_probe,
445 const cpl_size y_probe) {
447 hdrl_image * self = NULL;
448 cpl_image * linear_data;
449 cpl_image * variance;
451 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
453 cpl_ensure(gain_lin, CPL_ERROR_NULL_INPUT, NULL);
454 cpl_ensure(mdark, CPL_ERROR_NULL_INPUT, NULL);
463 cpl_size nx_chip = 0;
464 cpl_size ny_chip = 0;
465 cpl_boolean windowed = 0;
475 enu_check_error_code(
"failed to read detector window information");
477 int probing = CPL_FALSE;
478 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
483 enu_check_error_code(
"failed to read detector mode information");
484 cpl_msg_info(cpl_func,
"curname=%s rot=%d strx=%d stry=%d nx=%d ny=%d",
485 det_mode, (
int)rot, (
int)strx, (
int)stry, (
int)nx, (
int)ny );
492 if (!strcmp(det_mode,
"Double_RdRstRd")) {
502 const int ndit = cpl_propertylist_get_int(plist,
506 const double g = gain_lin->gain.data;
507 const double sigma_read = cpl_propertylist_get_double(
509 "ESO QC READ NOISE");
515 end_linearize_image(linear_data, gain_lin, rot, strx, stry,
520 double probe_v = cpl_image_get(linear_data, x_probe, y_probe,
522 cpl_msg_info(cpl_func,
"linear_data %4.2e %d", probe_v,
529 cpl_image_divide_scalar(linear_data, dit);
538 cpl_image_copy(variance, linear_data, 1, 1);
546 cpl_image_threshold(variance, 0.0, DBL_MAX, 0.0, DBL_MAX);
547 const double dt = 0.05;
548 cpl_image_multiply_scalar(variance,
549 (1.0 - dt * (nr * nr - 1) /
553 cpl_msg_info(cpl_func,
"photnoise factor %5.3e %d %5.3e %5.3e "
554 "%d %5.3e", dt, nr, dit, g, ndit,
555 (1.0 - dt * (nr * nr - 1) / (3.0 * dit * nr)) /
562 cpl_msg_info(cpl_func,
"readnoise comp %5.3e %5.3e %d %d"
563 "%5.3e% 5.3e", sigma_read, g, nr, ndit, dit,
564 2.0 * sigma_read * sigma_read /
565 (g * g * nr * ndit * dit * dit));
567 cpl_image_add_scalar(variance,
568 2.0 * sigma_read * sigma_read /
569 (g * g * nr * ndit * dit * dit));
573 cpl_image_fill_rejected(variance, 0.0);
575 }
else if (!strcmp(det_mode,
"SLOW_UP_THE_RAMP") ||
576 !strcmp(det_mode,
"SLOW_GR_UTR")) {
578 cpl_msg_info(cpl_func,
"slow gr utr %s", cpl_error_get_message());
588 const int ndit = cpl_propertylist_get_int(plist,
590 const int nr = cpl_propertylist_get_int(plist,
591 "ESO DET NDSAMPLES");
592 const double g = gain_lin->gain.data;
593 const double sigma_read = cpl_propertylist_get_double(
595 "ESO QC READ NOISE");
603 end_linearize_image(linear_data, gain_lin, rot, strx, stry,
609 cpl_image_divide_scalar(linear_data, dit);
618 cpl_image_copy(variance, linear_data, 1, 1);
619 cpl_image_multiply_scalar(variance, 1.2 * (nr*nr + 1) /
620 ((nr + 1) * nr * g * dit));
624 cpl_image_add_scalar(variance,
625 12.0 * sigma_read * sigma_read *
627 ((nr + 1) * nr * g * g * dit * dit));
632 cpl_image_divide_scalar(variance, (
double) ndit);
634 cpl_image_power(variance, 0.5);
639 cpl_image_reject_from_mask(linear_data, cpl_image_get_bpm(variance));
641 }
else if (!strcmp(det_mode,
"FAST_UNCORR")) {
646 end_linearize_image(linear_data, gain_lin, rot, strx, stry,
650 double val = cpl_image_get(linear_data, x_probe, y_probe,
652 cpl_msg_info(cpl_func,
"..eris_nix_detector probe (%d %d) "
653 "linearized_data v=%5.3e", (
int)x_probe,
661 const double ndit = (double) cpl_propertylist_get_int(plist,
663 const double g = gain_lin->gain.data;
664 const double sigma_read = cpl_propertylist_get_double(
666 "ESO QC READ NOISE");
671 cpl_image_divide_scalar(linear_data, dit);
697 cpl_image_copy(variance, linear_data, 1, 1);
698 cpl_image_threshold(variance, 0.0, 1e32, 0.0, 1e32);
699 cpl_image_multiply_scalar(variance, 1.0 / (g * ndit * dit));
703 cpl_image_add_scalar(variance,
704 sigma_read * sigma_read /
705 (g * g * ndit * dit * dit));
707 cpl_image_power(variance, 0.5);
710 double val = cpl_image_get(variance, x_probe, y_probe,
712 cpl_msg_info(cpl_func,
"..eris_nix_detector probe %d %d "
713 "variance %5.3e", (
int)x_probe, (
int)y_probe, val);
714 cpl_msg_info(cpl_func,
"..probe information sigma=%5.3e "
715 "g=%5.3e ndit=%d dit=%5.3e", sigma_read, g,
722 cpl_image_reject_from_mask(linear_data, cpl_image_get_bpm(variance));
725 cpl_msg_warning(cpl_func,
"linearization not done - unsupported "
726 "detector mode: %s", det_mode);
761cpl_error_code end_linearize_and_variance(
const gain_linearity * gain_lin,
762 const master_dark * mdark,
763 located_imagelist * limlist,
764 const cpl_size x_probe,
765 const cpl_size y_probe) {
767 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
769 cpl_msg_info(cpl_func,
"%p %p %p", (
const void*)gain_lin,
770 (
const void*)mdark, (
const void*)limlist);
771 cpl_ensure_code(gain_lin, CPL_ERROR_NULL_INPUT);
772 cpl_ensure_code(mdark, CPL_ERROR_NULL_INPUT);
773 cpl_ensure_code(limlist, CPL_ERROR_NULL_INPUT);
774 cpl_msg_info(cpl_func,
"after %p %p %p", (
const void*)gain_lin,
775 (
const void*)mdark, (
const void*)limlist);
777 if (limlist->size <= 0)
return CPL_ERROR_NONE;
788 cpl_image * f = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
789 cpl_image_fill_window(f, 1, 1, nx, ny, 1.0);
791 int probing = CPL_FALSE;
792 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
798 for (cpl_size i = 0; i < limlist->size; i++) {
800 cpl_msg_info(cpl_func,
"image %d", (
int) i);
802 const char * det_mode = cpl_propertylist_get_string(
803 (limlist->limages[i])->plist,
804 "ESO DET READ CURNAME");
805 const int rot = cpl_propertylist_get_int(
806 (limlist->limages[i])->plist,
807 "ESO DET SEQ1 WIN ROT");
808 const cpl_size strx = cpl_propertylist_get_int(
809 (limlist->limages[i])->plist,
810 "ESO DET SEQ1 WIN STRX");
811 const cpl_size stry = cpl_propertylist_get_int(
812 (limlist->limages[i])->plist,
813 "ESO DET SEQ1 WIN STRY");
814 enu_check_error_code(
"failed to read detector mode information");
815 cpl_msg_info(cpl_func,
"curname=%s rot=%d strx=%d stry=%d nx=%d ny=%d",
816 det_mode, (
int)rot, (
int)strx, (
int)stry, (
int)nx, (
int)ny );
818 if (!strcmp(det_mode,
"SLOW_LR_CDS")) {
827 double dit =
enu_get_dit(limlist->limages[i]->plist);
828 const int ndit = cpl_propertylist_get_int(
829 (limlist->limages[i])->plist,
"ESO DET NDIT");
830 const int nr = cpl_propertylist_get_int(
831 (limlist->limages[i])->plist,
"ESO DET NDSAMPLES");
832 const double g = gain_lin->gain.data;
833 const double sigma_read = cpl_propertylist_get_double(
834 mdark->plist,
"ESO QC READ NOISE");
837 (limlist->limages[i])->himage));
841 cpl_image_divide_scalar(data, dit);
847 double probe_v = cpl_image_get(data, x_probe, y_probe,
849 cpl_msg_info(cpl_func,
"data %4.2e %d", probe_v, ignore);
852 cpl_image * linear_data = end_vacca_linearize_cds(data,
853 gain_lin, dit, nr, f,
854 rot, strx, stry, x_probe, y_probe);
857 double probe_v = cpl_image_get(linear_data, x_probe, y_probe,
859 cpl_msg_info(cpl_func,
"linear_data %4.2e %d", probe_v,
870 cpl_image * variance = cpl_image_duplicate(linear_data);
878 cpl_image_threshold(variance, 0.0, DBL_MAX, 0.0, DBL_MAX);
879 const double dt = 0.05;
880 cpl_image_multiply_scalar(variance,
881 (1.0 - dt * (nr * nr - 1) /
885 cpl_msg_info(cpl_func,
"photnoise factor %5.3e %d %5.3e %5.3e "
886 "%d %5.3e", dt, nr, dit, g, ndit,
887 (1.0 - dt * (nr * nr - 1) / (3.0 * dit * nr)) /
894 cpl_msg_info(cpl_func,
"readnoise comp %5.3e %5.3e %d %d"
895 "%5.3e% 5.3e", sigma_read, g, nr, ndit, dit,
896 2.0 * sigma_read * sigma_read /
897 (g * g * nr * ndit * dit * dit));
899 cpl_image_add_scalar(variance,
900 2.0 * sigma_read * sigma_read /
901 (g * g * nr * ndit * dit * dit));
905 cpl_image_fill_rejected(variance, 0.0);
909 cpl_image_power(variance, 0.5);
915 cpl_image_delete(data);
916 cpl_image_delete(linear_data);
917 cpl_image_delete(variance);
919 }
else if (!strcmp(det_mode,
"SLOW_UP_THE_RAMP") ||
920 !strcmp(det_mode,
"SLOW_GR_UTR")) {
922 cpl_msg_info(cpl_func,
"slow gr utr %s", cpl_error_get_message());
931 double dit =
enu_get_dit(limlist->limages[i]->plist);
932 const int ndit = cpl_propertylist_get_int(
933 (limlist->limages[i])->plist,
"ESO DET NDIT");
934 const int nr = cpl_propertylist_get_int(
935 (limlist->limages[i])->plist,
"ESO DET NDSAMPLES");
936 const double g = gain_lin->gain.data;
937 const double sigma_read = cpl_propertylist_get_double(
938 mdark->plist,
"ESO QC READ NOISE");
943 (limlist->limages[i])->himage));
944 cpl_image_divide_scalar(data, dit);
955 cpl_image * linear_data = end_vacca_linearize_ramp(data,
956 gain_lin, dit, nr, f,
957 rot, strx, stry, x_probe, y_probe);
966 cpl_image * variance = cpl_image_duplicate(linear_data);
967 cpl_image_multiply_scalar(variance, 1.2 * (nr*nr + 1) /
968 ((nr + 1) * nr * g * dit));
972 cpl_image_add_scalar(variance,
973 12.0 * sigma_read * sigma_read *
975 ((nr + 1) * nr * g * g * dit * dit));
980 cpl_image_divide_scalar(variance, (
double) ndit);
984 cpl_image_power(variance, 0.5);
989 cpl_mask * vbpm = cpl_mask_duplicate(cpl_image_get_bpm(variance));
990 cpl_mask * ignore = cpl_image_set_bpm(linear_data, vbpm);
991 cpl_mask_delete(ignore); ignore = NULL;
998 cpl_image_delete(data);
999 cpl_image_delete(linear_data);
1000 cpl_image_delete(variance);
1003 cpl_msg_warning(cpl_func,
"linearization not done - unsupported "
1004 "detector mode: %s", det_mode);
1011 cpl_image_delete(f);
1013 return cpl_error_get_code();
1048cpl_image * end_vacca_linearize_cds(cpl_image * intensity,
1049 const gain_linearity * gain_lin,
1052 const cpl_image * f,
1059 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
1061 cpl_ensure(intensity, CPL_ERROR_NULL_INPUT, NULL);
1062 cpl_ensure(gain_lin, CPL_ERROR_NULL_INPUT, NULL);
1063 cpl_ensure(nr > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1065 cpl_image * change = NULL;
1066 cpl_image * result = NULL;
1068 cpl_size nx = cpl_image_get_size_x(intensity);
1069 cpl_size ny = cpl_image_get_size_y(intensity);
1071 int probing = CPL_FALSE;
1072 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
1078 cpl_image ** iteration = cpl_calloc(LINEARIZE_MAXITER,
1079 sizeof(cpl_image *));
1081 iteration[0] = cpl_image_duplicate(intensity);
1086 const double dt = 0.05;
1088 while (niter+1 < LINEARIZE_MAXITER &&
1089 cpl_error_get_code() == CPL_ERROR_NONE) {
1094 cpl_image * pedestal = cpl_image_multiply_scalar_create(f, -1.0);
1095 cpl_image_add_scalar(pedestal, (
double) (nr + 1) / 2);
1096 cpl_image_multiply(pedestal, iteration[niter]);
1097 cpl_image_multiply_scalar(pedestal, dt);
1098 cpl_image * signal = cpl_image_multiply_scalar_create(iteration[0],
1100 cpl_image_add(signal, pedestal);
1104 double probe_val = cpl_image_get(iteration[niter], x_probe,
1107 double probe_p = cpl_image_get(pedestal, x_probe, y_probe,
1109 double probe_s = cpl_image_get(signal, x_probe, y_probe,
1111 cpl_msg_info(cpl_func,
"linearizing: (pix %d,%d) niter=%d "
1112 "I=%4.2e pedestal=%4.2e signal=%4.2e",
1113 (
int)x_probe, (
int)y_probe, (
int)niter,
1114 probe_val, probe_p, probe_s);
1116 cpl_msg_info(cpl_func,
"linearizing: (pix %d,%d) niter=%d "
1117 "bad pixel", (
int)x_probe, (
int)y_probe,
1124 end_linearize_image(pedestal, gain_lin, rot, strx, stry,
1126 end_linearize_image(signal, gain_lin, rot, strx, stry,
1132 iteration[niter] = cpl_image_subtract_create(signal, pedestal);
1133 cpl_image_divide_scalar(iteration[niter], dit);
1134 cpl_image_delete(pedestal);
1135 cpl_image_delete(signal);
1138 result = cpl_image_duplicate(iteration[niter]);
1144 change = cpl_image_divide_create(iteration[niter],
1145 iteration[niter-1]);
1146 cpl_mask_threshold_image(cpl_image_get_bpm(result), change, 0.99,
1147 1.01, CPL_BINARY_0);
1151 cpl_image_fill_rejected(result, 0.0);
1156 for (cpl_size i = 0; i < LINEARIZE_MAXITER; i++) {
1157 cpl_image_delete(iteration[i]);
1159 cpl_free(iteration);
1160 cpl_image_delete(change);
1164 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1165 cpl_image_delete(result);
1203cpl_image * end_vacca_linearize_ramp(cpl_image * intensity,
1204 const gain_linearity * gain_lin,
1207 const cpl_image * f,
1209 const cpl_size strx,
1210 const cpl_size stry,
1211 const cpl_size x_probe,
1212 const cpl_size y_probe) {
1214 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
1217 double time1, time2, time3, time4, time11, time12, time13, time14;
1218 time1 = omp_get_wtime();
1220 clock_t time1, time2, time3, time4, time11, time12, time13, time14;
1224 cpl_ensure(intensity, CPL_ERROR_NULL_INPUT, NULL);
1225 cpl_ensure(gain_lin, CPL_ERROR_NULL_INPUT, NULL);
1226 cpl_ensure(nr > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1228 cpl_image * result = NULL;
1229 cpl_image * change = NULL;
1231 cpl_size nx = cpl_image_get_size_x(intensity);
1232 cpl_size ny = cpl_image_get_size_y(intensity);
1233 int probing = CPL_FALSE;
1234 cpl_msg_info(cpl_func,
"%d %d %d %d", (
int)x_probe, (
int)y_probe, (
int)nx, (
int)ny);
1235 if (x_probe >= 1 && x_probe <= nx && y_probe >=1 && y_probe <= ny) {
1237 cpl_msg_info(cpl_func,
"messaging on");
1244 cpl_image ** iteration = cpl_calloc(LINEARIZE_MAXITER,
1245 sizeof(cpl_image *));
1247 iteration[0] = cpl_image_duplicate(intensity);
1249 s = cpl_image_get(intensity, x_probe, y_probe, &reject);
1250 cpl_msg_info(cpl_func,
"initial %s %5.2f", cpl_error_get_message(), s);
1254 time2 = omp_get_wtime();
1259 while (niter+1 < LINEARIZE_MAXITER &&
1260 cpl_error_get_code() == CPL_ERROR_NONE) {
1265 time11 = omp_get_wtime();
1269 eris_nix_samples * samples = end_calculate_samples(iteration[niter],
1274 cpl_msg_info(cpl_func,
"samples before linearization: is, reject, s");
1275 for (cpl_size is=0; is<samples->nr; is++) {
1276 s = cpl_image_get(samples->samples[is], x_probe, y_probe, &reject);
1277 cpl_msg_info(cpl_func,
"%d %d %5.2f", (
int)is, reject, s);
1284 time12 = omp_get_wtime();
1288 for (cpl_size i = 0; i < nr; i++) {
1289 end_linearize_image(samples->samples[i], gain_lin, rot,
1290 strx, stry, x_probe, y_probe);
1294 cpl_msg_info(cpl_func,
"samples after: is, reject, s");
1295 for (cpl_size is=0; is<samples->nr; is++) {
1296 s = cpl_image_get(samples->samples[is], x_probe, y_probe, &reject);
1297 cpl_msg_info(cpl_func,
"%d %d %5.2f", (
int)is, reject, s);
1304 time13 = omp_get_wtime();
1309 iteration[niter] = end_uptheramp_reduce(samples, dit);
1312 s = cpl_image_get(iteration[niter], x_probe, y_probe, &reject);
1313 cpl_msg_info(cpl_func,
"iteration %s %d %9.4e", cpl_error_get_message(),
1319 time14 = omp_get_wtime();
1320 cpl_msg_info(cpl_func,
"%d ramp samp %5.2e lin %5.2e calc %5.2e",
1327 cpl_msg_info(cpl_func,
"%d ramp samp %5.2e lin %5.2e calc %5.2e",
1329 (
double)(time12-time11) / CLOCKS_PER_SEC,
1330 (
double)(time13-time12) / CLOCKS_PER_SEC,
1331 (
double)(time14-time13) / CLOCKS_PER_SEC);
1333 end_samples_delete(samples);
1337 time3 = omp_get_wtime();
1342 result = cpl_image_duplicate(iteration[niter]);
1345 s = cpl_image_get(result, x_probe, y_probe, &reject);
1346 cpl_msg_info(cpl_func,
"result %s %5.2f", cpl_error_get_message(), s);
1354 change = cpl_image_divide_create(iteration[niter],
1355 iteration[niter-1]);
1356 cpl_mask_threshold_image(cpl_image_get_bpm(result), change, 0.99,
1357 1.01, CPL_BINARY_0);
1362 for (cpl_size i = 0; i < LINEARIZE_MAXITER; i++) {
1363 cpl_image_delete(iteration[i]);
1365 cpl_free(iteration);
1366 cpl_image_delete(change);
1370 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1371 cpl_image_delete(result);
1376 time4 = omp_get_wtime();
1377 cpl_msg_info(cpl_func,
"ramp setup %5.2e lin %5.2e tidy %5.2e",
1383 cpl_msg_info(cpl_func,
"ramp setup %5.2e lin %5.2e tidy %5.2e",
1384 (
double)(time2-time1) / CLOCKS_PER_SEC,
1385 (
double)(time3-time2) / CLOCKS_PER_SEC,
1386 (
double)(time4-time3) / CLOCKS_PER_SEC);
1410double engl_lin_correct(
const double obs,
1411 const cpl_size fit_order,
1412 const double* coeffs,
1413 const cpl_binary fit_quality,
1414 const double saturation,
1415 cpl_binary * rejected,
1416 cpl_binary * saturated,
1419 double result = obs;
1420 if (cpl_error_get_code())
return 0.0;
1422 cpl_msg_info(cpl_func,
"Saturation ptr: %p", (
const void*)saturated);
1424 engl_lin_correct_(&result,
1453void engl_lin_correct_(
double * pobs,
1454 const cpl_size fit_order,
1455 const double* coeffs,
1456 const cpl_binary fit_quality,
1457 const double saturation,
1458 cpl_binary * rejected,
1461 if (fit_quality == CPL_BINARY_1) {
1463 if (debug) cpl_msg_info(cpl_func,
"....debug bad quality");
1464 *rejected = CPL_BINARY_1;
1466 }
else if (coeffs[1] <= 0.0) {
1470 if (debug) cpl_msg_info(cpl_func,
"....debug bad slope");
1471 *rejected = CPL_BINARY_1;
1473 }
else if (*pobs > 0.0) {
1481 const double useobs = *pobs > saturation ? saturation : *pobs;
1484 const double t = engl_lin_find_(*pobs, 0.9 * useobs / coeffs[1],
1485 1.5 * useobs / coeffs[1],
1486 fit_order, coeffs, &curve);
1488 const double correction = (coeffs[1] * t) / curve;
1490 *pobs *= correction;
1491 *rejected = t > 0.0 ? CPL_BINARY_0 : CPL_BINARY_1;
1494 if (useobs == saturation)
1495 cpl_msg_info(cpl_func,
"....debug saturated");
1497 for (
int j = fit_order-1; j>-1; j--) {
1498 cpl_msg_info(cpl_func,
"....debug curve coeffs %d %5.3e",
1501 cpl_msg_info(cpl_func,
"....debug t %4.2f", t);
1502 cpl_msg_info(cpl_func,
"....debug correction %6.4e %4.2e "
1503 "%4.2e", correction, *pobs, curve);
1510 cpl_msg_info(cpl_func,
"....debug negative");
1529double engl_lin_find(
const double obs,
1532 const cpl_size fit_order,
1533 const double* coeffs) {
1536 return cpl_error_get_code() ? -1.0 :
1537 engl_lin_find_(obs, low_t, high_t, fit_order, coeffs, &dummy);
1559double engl_lin_find_(
const double obs,
1562 const cpl_size fit_order,
1563 const double* coeffs,
1566 double result = 0.0;
1569 double low_curve = 0.0;
1570 double high_curve = 0.0;
1578 if (low_curve == 0.0) {
1579 int j = fit_order-2;
1580 low_curve = coeffs[fit_order-1];
1581 for (; j >= 3; j--) {
1582 low_curve = low_curve * low_t + coeffs[j];
1586 low_curve = low_curve * low_t + coeffs[2];
1589 low_curve = low_curve * low_t + coeffs[1];
1595 if (high_curve == 0.0) {
1596 int j = fit_order-2;
1597 high_curve = coeffs[fit_order-1];
1598 for (; j >= 3; j--) {
1599 high_curve = high_curve * high_t + coeffs[j];
1603 high_curve = high_curve * high_t + coeffs[2];
1606 high_curve = high_curve * high_t + coeffs[1];
1609 high_curve *= high_t;
1612 double mid_t = (low_t + high_t) / 2.0;
1613 double mid_curve = coeffs[fit_order-1];
1614 int j = fit_order-2;
1615 for (; j >= 3; j--) {
1616 mid_curve = mid_curve * mid_t + coeffs[j];
1620 mid_curve = mid_curve * mid_t + coeffs[2];
1623 mid_curve = mid_curve * mid_t + coeffs[1];
1631 if (fabs(obs - mid_curve) < MAX_LIN_DIFFERENCE) {
1632 *pcurve = mid_curve;
1635 }
else if ((obs > low_curve) && (obs < mid_curve)) {
1638 }
else if ((obs > mid_curve) && (obs < high_curve)) {
1648 }
while (iter++ < MAX_LIN_DEPTH);
1652 if (iter >= MAX_LIN_DEPTH) {
1653 cpl_msg_info(cpl_func,
"max depth %4.2e %4.2e %4.2e %d %4.2e %4.2e "
1654 "%4.2e", obs, low_t, high_t,
1655 (
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