30#include "moo_detector.h"
31#include "moo_badpix.h"
32#include "moo_fibres_table.h"
36#include "moo_compute_linearity.h"
51_moo_compute_trace_mask(cpl_mask *mask,
56 cpl_array *sel = NULL;
57 int nx = cpl_mask_get_size_x(mask);
58 int ny = cpl_mask_get_size_y(mask);
61 for (
int x = 1; x <= nx; x++) {
62 for (
int y = 1; y <= ny; y++) {
63 cpl_mask_set(mask, x, y, CPL_BINARY_1);
68 int spectro_name = moo_fibres_table_get_spectro(num);
71 moo_try_check(cpl_table_select_all(ft1),
" ");
72 moo_try_check(cpl_table_and_selected_int(ft1, MOO_FIBRES_TABLE_SPECTRO,
73 CPL_EQUAL_TO, spectro_name),
75 moo_try_check(cpl_table_and_selected_int(ft1, MOO_FIBRES_TABLE_HEALTH,
78 sel = cpl_table_where_selected(ft1);
79 cpl_size nsel = cpl_array_get_size(sel);
84 for (
int i = 0; i < nsel; i++) {
86 cpl_size idx = cpl_array_get_cplsize(sel, i, NULL);
88 cpl_table_get_int(ft1, MOO_FIBRES_TABLE_INDEXEXT, idx, &rej);
89 for (
int x = 1; x <= nx; x++) {
92 cpl_image_get(centroid_img, x, indexext, &rej2);
93 double wlo = cpl_image_get(wlo_img, x, indexext, &rej2);
94 double wup = cpl_image_get(wup_img, x, indexext, &rej2);
95 int yl = (int)floor(centroid - wlo);
99 int yu = (int)ceil(centroid + wup);
103 for (
int y = yl; y <= yu; y++) {
104 cpl_mask_set(mask, x, y, CPL_BINARY_1);
110 cpl_array_delete(sel);
116_moo_compute_linearity_single(moo_detlist *detlist,
123 cpl_imagelist *result = NULL;
124 cpl_imagelist *list = NULL;
125 cpl_mask *mask = NULL;
126 cpl_vector *exptime = NULL;
127 cpl_vector *fluxes = NULL;
129 cpl_errorstate prestate = cpl_errorstate_get();
131 cpl_ensure(detlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
132 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
135 int degree = MOO_COMPUTE_LINEARITY_DEGREE;
141 if (list != NULL && cpl_imagelist_get_size(list) > 0) {
142 cpl_msg_info(__func__,
"Compute coefficients map for %s",
145 int nx = cpl_image_get_size_x(cpl_imagelist_get(list, 0));
146 int ny = cpl_image_get_size_y(cpl_imagelist_get(list, 0));
148 result = cpl_imagelist_new();
149 mask = cpl_mask_new(nx, ny);
151 moo_try_check(_moo_compute_trace_mask(mask, loc, type, num),
" ");
152 exptime = cpl_vector_new(size);
153 fluxes = cpl_vector_new(size);
155 for (
int i = 0; i < size; i++) {
159 cpl_propertylist *extheader =
160 moo_det_get_single_header(det, type, num);
165 cpl_vector_set(exptime, i, t);
169 cpl_imagelist *coefs = NULL;
171 for (
int j = 1; j <= ny; j++) {
172 for (
int i = 1; i <= nx; i++) {
174 int v = cpl_image_get(saturate, i, j, &rej);
180 for (
int k = kdx; k < size; k++) {
181 cpl_image *im = cpl_imagelist_get(list, k);
182 cpl_image_reject(im, i, j);
188 for (
int i = 0; i < size; i++) {
189 cpl_image *im = cpl_imagelist_get(list, i);
190 cpl_mask *m = cpl_image_get_bpm(im);
191 cpl_mask_or(m, mask);
194 cpl_image *chi2 = NULL;
195 coefs = cpl_fit_imagelist_polynomial(exptime, list, 0, degree,
196 CPL_FALSE, CPL_TYPE_DOUBLE, chi2);
198#if MOO_DEBUG_COMPUTE_LINEARITY
202 cpl_image_save(chi2, chiname, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
205 cpl_image_delete(chi2);
207 for (
int i = 0; i <= degree; i++) {
208 cpl_image *coef = cpl_imagelist_get(coefs, i);
209 cpl_imagelist_set(result, cpl_image_duplicate(coef), i);
211 cpl_imagelist_delete(coefs);
213 int ntime = hdrl_imagelist_get_size(list);
214 cpl_image *c0_img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
215 cpl_image *c1_img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
216 cpl_image *c2_img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
217 cpl_imagelist_set(result, c0_img, 0);
218 cpl_imagelist_set(result, c1_img, 1);
219 cpl_imagelist_set(result, c2_img, 2);
220 for (
int y = 1; y <= ny; y++) {
221 for (
int x = 1; x <= nx; x++) {
222 for (
int t = 0; t < ntime; t++) {
223 hdrl_image *himg = hdrl_imagelist_get(list, t);
225 hdrl_value val = hdrl_image_get_pixel(himg, x, y, &rej);
226 cpl_vector_set(fluxes, t, val.data);
228 int illuminated = cpl_mask_get(mask, x, y);
233 if (illuminated == 1) {
234 const cpl_size coef0 = 0;
235 const cpl_size coef1 = 1;
237 cpl_polynomial *poly_linfit = cpl_polynomial_new(1);
238 cpl_matrix *samppos1d =
239 cpl_matrix_wrap(1, ntime, cpl_vector_get_data(exptime));
240 cpl_vector *fitvals = fluxes;
241 const cpl_size maxdeg1d = degree;
242 cpl_polynomial_fit(poly_linfit, samppos1d, NULL, fitvals,
243 NULL, CPL_FALSE, NULL, &maxdeg1d);
244 c0 = cpl_polynomial_get_coeff(poly_linfit, &coef0);
245 c1 = cpl_polynomial_get_coeff(poly_linfit, &coef1);
246 c2 = cpl_polynomial_get_coeff(poly_linfit, &coef2);
248 cpl_matrix_unwrap(samppos1d);
249 cpl_polynomial_delete(poly_linfit);
251 cpl_image_set(c0_img, x, y, c0);
252 cpl_image_set(c1_img, x, y, c1);
253 cpl_image_set(c2_img, x, y, c2);
260 cpl_mask_delete(mask);
261 cpl_imagelist_delete(list);
262 cpl_vector_delete(exptime);
263 cpl_vector_delete(fluxes);
264 if (!cpl_errorstate_is_equal(prestate)) {
265 cpl_imagelist_delete(result);
272moo_compute_linearity(moo_detlist *detlist,
274 moo_saturate_map *saturate_map,
275 const char *cube_name)
277 cpl_errorstate prestate = cpl_errorstate_get();
278 moo_cube *result = NULL;
280 cpl_ensure(detlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
281 cpl_ensure(cube_name != NULL, CPL_ERROR_NULL_INPUT, NULL);
282 cpl_ensure(saturate_map != NULL, CPL_ERROR_NULL_INPUT, NULL);
287 result->primary_header = cpl_propertylist_new();
288 moo_try_check(result->filename = cpl_strdup(cube_name),
" ");
290 for (
int num = 1; num <= 2; num++) {
291 for (
int type = 0; type < 3; type++) {
292 cpl_imagelist *data = NULL;
293 data = _moo_compute_linearity_single(
294 detlist, loc, type, num,
295 saturate_map->data[type + (num - 1) * 3], result);
300 if (!cpl_errorstate_is_equal(prestate)) {
308_moo_compute_bpm_linear_single(cpl_imagelist *coeffs,
317 cpl_image *result = NULL;
318 cpl_mask *cold_mask = NULL;
319 cpl_mask *hot_mask = NULL;
320 cpl_mask *trace_mask = NULL;
322 cpl_errorstate prestate = cpl_errorstate_get();
323 cpl_ensure(coeffs != NULL, CPL_ERROR_NULL_INPUT, NULL);
324 cpl_ensure(index != NULL, CPL_ERROR_NULL_INPUT, NULL);
325 int nx = cpl_image_get_size_x(index);
326 int ny = cpl_image_get_size_y(index);
328 result = cpl_image_new(nx, ny, CPL_TYPE_INT);
330 cold_mask = cpl_mask_new(nx, ny);
331 hot_mask = cpl_mask_new(nx, ny);
333 for (
int j = 1; j <= ny; j++) {
334 for (
int i = 1; i <= nx; i++) {
336 double vi = cpl_image_get(flux, i, j, &rej);
338 cpl_image_reject(flux, i, j);
344 double medflux = cpl_image_get_median(flux);
345 for (
int j = 1; j <= ny; j++) {
346 for (
int i = 1; i <= nx; i++) {
348 int vi = cpl_image_get(index, i, j, &rej);
350 double vf = cpl_image_get(flux, i, j, &rej);
352 cpl_mask_set(hot_mask, i, j, CPL_BINARY_1);
355 cpl_mask_set(cold_mask, i, j, CPL_BINARY_1);
362 for (
int j = 1; j <= ny; j++) {
363 for (
int i = 1; i <= nx; i++) {
365 int vi = cpl_image_get(index, i, j, &rej);
367 double vf = cpl_image_get(flux, i, j, &rej);
368 if (fabs(vf) <= DBL_EPSILON) {
369 cpl_mask_set(hot_mask, i, j, CPL_BINARY_1);
373 cpl_mask_set(cold_mask, i, j, CPL_BINARY_1);
381 trace_mask = cpl_mask_new(nx, ny);
382 moo_try_check(_moo_compute_trace_mask(trace_mask, loc, type, num),
" ");
383 cpl_mask_not(trace_mask);
385 cpl_msg_info(__func__,
386 "Compute bad pixels map for %s using kappa %f and min snr %f",
389 int size = cpl_imagelist_get_size(coeffs);
391 cpl_msg_indent_more();
392 for (
int k = 1; k < size; k++) {
393 cpl_image *im = cpl_imagelist_get(coeffs, k);
394 cpl_mask *mask = cpl_image_get_bpm(im);
395 cpl_mask_or(mask, trace_mask);
396 cpl_mask_or(mask, hot_mask);
397 cpl_mask_or(mask, cold_mask);
401 double median = cpl_image_get_mad(im, &s);
402 s *= CPL_MATH_STD_MAD;
403 cpl_msg_info(__func__,
"coef%d find median %f sigma %f", k, median, s);
404 for (
int j = 1; j <= ny; j++) {
405 for (
int i = 1; i <= nx; i++) {
407 double c = cpl_image_get(im, i, j, &rej);
408 if (rej == 0 && (fabs(c - median) > kappa * s)) {
414 cpl_msg_indent_less();
453 cpl_mask_delete(cold_mask);
454 cpl_mask_delete(hot_mask);
455 cpl_mask_delete(trace_mask);
457 if (!cpl_errorstate_is_equal(prestate)) {
458 cpl_image_delete(result);
465moo_compute_bpm_linearity(moo_cube *cube,
467 moo_saturate_map *saturate_map,
468 moo_linear_params *params,
469 const char *bpm_name)
471 cpl_errorstate prestate = cpl_errorstate_get();
472 moo_bpm *result = NULL;
474 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
475 cpl_ensure(saturate_map != NULL, CPL_ERROR_NULL_INPUT, NULL);
476 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
477 cpl_ensure(bpm_name != NULL, CPL_ERROR_NULL_INPUT, NULL);
481 result->primary_header = cpl_propertylist_new();
482 moo_try_check(result->filename = cpl_strdup(bpm_name),
" ");
484 double *ktab = params->kappa;
485 double *snrtab = params->min_snr;
486 for (
int num = 1; num <= 2; num++) {
487 for (
int type = 0; type < 3; type++) {
488 int idx = type + (num - 1) * 3;
489 double kappa = ktab[idx];
490 double min_snr = snrtab[idx];
491 cpl_image *index = saturate_map->data[idx];
492 cpl_image *flux = saturate_map->flux[idx];
493 cpl_imagelist *cdata = cube->data[idx];
494 cpl_image *resdata = NULL;
497 _moo_compute_bpm_linear_single(cdata, loc, type, num, kappa,
498 index, flux, min_snr);
504 if (!cpl_errorstate_is_equal(prestate)) {
513_moo_compute_saturate_pixels_single(moo_detlist *detlist,
518 cpl_image **flux_img,
520 cpl_image **exptime_img)
522 cpl_image *result = NULL;
523 cpl_mask *mask = NULL;
524 hdrl_imagelist *list = NULL;
525 cpl_image *sub = NULL;
526 cpl_vector *exptime = NULL;
528 cpl_errorstate prestate = cpl_errorstate_get();
530 cpl_ensure(detlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
531 cpl_ensure(flux_img != NULL, CPL_ERROR_NULL_INPUT, NULL);
532 cpl_ensure(err_img != NULL, CPL_ERROR_NULL_INPUT, NULL);
533 cpl_ensure(exptime_img != NULL, CPL_ERROR_NULL_INPUT, NULL);
542 if (list != NULL && hdrl_imagelist_get_size(list) > 0) {
543 cpl_msg_info(__func__,
544 "Compute saturate pixels map for %s using threshold %f",
547 int nx = hdrl_imagelist_get_size_x(list);
548 int ny = hdrl_imagelist_get_size_y(list);
550 result = cpl_image_new(nx, ny, CPL_TYPE_INT);
551 *exptime_img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
552 *flux_img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
553 *err_img = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
554 mask = cpl_mask_new(nx, ny);
555 _moo_compute_trace_mask(mask, loc, type, num);
557 for (
int j = 1; j <= ny; j++) {
558 for (
int i = 1; i <= nx; i++) {
559 cpl_binary b = cpl_mask_get(mask, i, j);
560 if (b == CPL_BINARY_0) {
562 cpl_image_set(result, i, j, size - 1);
565 cpl_image_set(result, i, j, NAN);
566 cpl_image_reject(result, i, j);
571 for (
int k = size - 1; k >= 0; k--) {
572 cpl_image *im1 = hdrl_image_get_image(hdrl_imagelist_get(list, k));
575 for (
int j = 1; j <= ny; j++) {
576 for (
int i = 1; i <= nx; i++) {
578 double v = cpl_image_get(im1, i, j, &rej);
579 cpl_binary m = cpl_mask_get(mask, i, j);
580 if (m == CPL_BINARY_0) {
581 if (v <= threshold) {
582 cpl_mask_set(mask, i, j, CPL_BINARY_1);
583 cpl_image_set(result, i, j, k);
591 if (nb_saturate == 0) {
595 cpl_msg_info(__func__,
"Find at %d : %d saturate pixels", k,
600 exptime = cpl_vector_new(size);
602 for (
int i = 0; i < size; i++) {
606 cpl_propertylist *extheader =
607 moo_det_get_single_header(det, type, num);
612 cpl_vector_set(exptime, i, t);
615 for (
int j = 1; j <= ny; j++) {
616 for (
int i = 1; i <= nx; i++) {
619 int v = cpl_image_get(result, i, j, &rej);
623 cpl_image *im1 = hdrl_image_get_image(
624 hdrl_imagelist_get(list, size - 1));
625 cpl_image *im2 = hdrl_image_get_image(
626 hdrl_imagelist_get(list, size - 2));
627 cpl_image *im3 = hdrl_image_get_image(
628 hdrl_imagelist_get(list, size - 3));
629 double v1 = cpl_image_get(im1, i, j, &rej);
630 double v2 = cpl_image_get(im2, i, j, &rej);
631 double v3 = cpl_image_get(im3, i, j, &rej);
632 double t1 = cpl_vector_get(exptime, size - 1);
633 double t2 = cpl_vector_get(exptime, size - 2);
634 double t3 = cpl_vector_get(exptime, size - 3);
635 double f1 = (v1 - v2) / (t1 - t2);
636 double f2 = (v2 - v3) / (t2 - t3);
640 cpl_image_set(result, i, j, v);
647 hdrl_image_get_image(hdrl_imagelist_get(list, v));
649 hdrl_image_get_error(hdrl_imagelist_get(list, v));
650 double f = cpl_image_get(im1, i, j, &rej);
651 double fe = cpl_image_get(err1, i, j, &rej);
652 double e = cpl_vector_get(exptime, v);
653 cpl_image_set(*flux_img, i, j, f);
654 cpl_image_set(*err_img, i, j, fe);
655 cpl_image_set(*exptime_img, i, j, e);
658 cpl_image_set(*flux_img, i, j, NAN);
659 cpl_image_set(*err_img, i, j, NAN);
660 cpl_image_set(*exptime_img, i, j, NAN);
668 hdrl_imagelist_unwrap(list);
669 cpl_mask_delete(mask);
670 cpl_vector_delete(exptime);
671 if (!cpl_errorstate_is_equal(prestate)) {
672 cpl_image_delete(sub);
673 cpl_image_delete(*flux_img);
674 cpl_image_delete(*err_img);
675 cpl_image_delete(*exptime_img);
676 cpl_image_delete(result);
686moo_compute_saturate_pixels(moo_detlist *detlist,
688 moo_linear_params *params)
690 moo_saturate_map *result = NULL;
691 cpl_image *data = NULL;
693 cpl_errorstate prestate = cpl_errorstate_get();
695 cpl_ensure(detlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
696 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
698 double threshold = params->saturate_threshold;
701 result->primary_header = cpl_propertylist_new();
703 for (
int num = 1; num <= 2; num++) {
704 for (
int type = 0; type < 3; type++) {
705 cpl_image *flux = NULL;
706 cpl_image *err = NULL;
707 cpl_image *exptime = NULL;
708 moo_try_check(data = _moo_compute_saturate_pixels_single(
709 detlist, loc, type, num, threshold, &flux, &err,
712 cpl_propertylist *header = cpl_propertylist_new();
719 if (!cpl_errorstate_is_equal(prestate)) {
#define MOO_BADPIX_NON_LINEAR
void moo_bpm_delete(moo_bpm *self)
Delete a moo_bpm.
cpl_error_code moo_bpm_add_data(moo_bpm *self, cpl_image *img, moo_detector_type type, int ntas)
Add CPL_IMAGE extension to BPM filename and update moo_bpm structure.
moo_bpm * moo_bpm_new(void)
Create a new moo_bpm.
moo_cube * moo_cube_new(void)
Create a new moo_cube.
cpl_error_code moo_cube_add_data(moo_cube *self, cpl_imagelist *list, moo_detector_type type, int ntas)
Add CPL_IMAGELIST extension to CUBE filename and update moo_cube structure.
void moo_cube_delete(moo_cube *self)
Delete a moo_cube.
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
enum _moo_detector_type_ moo_detector_type
The type code type.
hdrl_imagelist * moo_detlist_get_image(const moo_detlist *self, moo_detector_type type, int num)
Get the all the images of the type part in the detlist.
cpl_size moo_detlist_get_size(const moo_detlist *self)
Get the number of DET in the detlist.
cpl_error_code moo_detlist_free_single(const moo_detlist *self, moo_detector_type type, int num)
Free the type part for all DET in the detlist.
cpl_imagelist * moo_detlist_get_single_data(const moo_detlist *self, moo_detector_type type, int num)
Get the type data part for all DET in the detlist.
cpl_error_code moo_detlist_load_single(const moo_detlist *self, moo_detector_type type, int num, int level)
Load the type part for all DET in the detlist.
moo_det * moo_detlist_get(moo_detlist *self, int i)
Get the DET at the position i in the list.
cpl_error_code moo_fits_create(const char *filename)
Create a new fits file with empty propertylist.
cpl_image * moo_loc_single_get_f_wup(moo_loc_single *self)
Get image of width low.
cpl_image * moo_loc_single_get_f_centroids(moo_loc_single *self)
Get image of fit centroids.
cpl_image * moo_loc_single_get_f_wlo(moo_loc_single *self)
Get image of width low.
moo_loc_single * moo_loc_get_single(moo_loc *self, moo_detector_type type, int ntas)
Get the type part in LOC and return it.
cpl_table * moo_loc_get_fibre_table(moo_loc *self)
Get the FIBRE TABLE in LOC.
moo_saturate_map * moo_saturate_map_new(void)
Create a new moo_saturate_map.
void moo_saturate_map_delete(moo_saturate_map *self)
Delete a moo_map_saturate.
cpl_error_code moo_saturate_map_set_data(moo_saturate_map *self, moo_detector_type type, int ntas, cpl_image *data, cpl_image *flux, cpl_image *err, cpl_image *exptime, cpl_propertylist *header)
set saturate map data for relevant extension
int moo_pfits_get_ndit(const cpl_propertylist *plist)
find out the ESO DET NDIT value
double moo_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
double moo_pfits_get_exptime(const cpl_propertylist *plist)
find out the EXPTIME value