33#include "moo_params.h"
34#include "moo_single.h"
35#include "moo_psf_single.h"
36#include "moo_badpix.h"
37#include "moo_compute_p2p.h"
39#include "moo_fibres_table.h"
56_moo_compute_p2p_qc(moo_single *single,
int level)
58 cpl_error_code status = CPL_ERROR_NONE;
60 cpl_ensure_code(single != NULL, CPL_ERROR_NULL_INPUT);
63 cpl_mask *mask = hdrl_image_get_mask(single->image);
66 cpl_image *data = hdrl_image_get_image(himage);
67 cpl_ensure_code(data != NULL, CPL_ERROR_NULL_INPUT);
69 double min = cpl_image_get_min(data);
70 double max = cpl_image_get_max(data);
71 double rms = cpl_image_get_stdev(data);
73 double median = cpl_image_get_mad(data, &mad);
74 double mean = cpl_image_get_mean(data);
76 cpl_propertylist *header = moo_single_get_header(single);
77 cpl_ensure_code(header != NULL, CPL_ERROR_NULL_INPUT);
90_moo_reproject_model_fibre(cpl_image *image,
99 int nx = cpl_image_get_size_x(image);
100 int ny = cpl_image_get_size_y(model);
102 double *data = cpl_image_get_data(result);
103 int *contrib_data = cpl_image_get_data(contrib);
105 for (
int x = 1; x <= nx; x++) {
107 double centroid = cpl_image_get(centroids, x, numfib, &rej);
108 if (!isnan(centroid)) {
109 double y_lo = centroid + (1 - crpix2) * cd2_2;
110 double y_up = centroid + (ny - crpix2) * cd2_2;
111 int y_start = (int)ceil(y_lo);
112 int y_stop = (int)floor(y_up);
114 for (
int y = y_start; y <= y_stop; y++) {
115 double y_model = centroid + (model_idx - crpix2) * cd2_2;
116 while (y_model < y) {
118 y_model = centroid + (model_idx - crpix2) * cd2_2;
120 double y_model1 = centroid + (model_idx - 1 - crpix2) * cd2_2;
123 cpl_image_get(model, x, model_idx - 1, &rej);
124 double y_model2 = y_model;
125 double flux_model2 = cpl_image_get(model, x, model_idx, &rej);
126 double y_flux = flux_model1 + (flux_model2 - flux_model1) /
127 (y_model2 - y_model1) *
129 data[(y - 1) * nx + x - 1] += y_flux;
130 contrib_data[(y - 1) * nx + x - 1]++;
137_moo_reproject_model(moo_single *det,
139 moo_psf_single *psf_single,
142 cpl_ensure(det != NULL, CPL_ERROR_NULL_INPUT, NULL);
143 cpl_ensure(loc != NULL, CPL_ERROR_NULL_INPUT, NULL);
144 cpl_ensure(psf_single != NULL, CPL_ERROR_NULL_INPUT, NULL);
145 cpl_ensure(health != NULL, CPL_ERROR_NULL_INPUT, NULL);
147 cpl_errorstate prestate = cpl_errorstate_get();
149 cpl_image *res = NULL;
152 cpl_image *image = hdrl_image_get_image(himage);
154 int nx = hdrl_image_get_size_x(himage);
155 int ny = hdrl_image_get_size_y(himage);
156 int nb_fibres = cpl_image_get_size_y(fcentroids);
159 double crpix2, cd2_2;
161 res = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
162 cpl_image *contrib = cpl_image_new(nx, ny, CPL_TYPE_INT);
163 cpl_msg_debug(__func__,
"start %d", cpl_error_get_code());
176#if (__GNUC__ == 9) && (__GNUC_MINOR__ < 3)
177#pragma omp parallel shared(nb_fibres, health, cube, image, fcentroids, \
178 crpix2, cd2_2, res, contrib)
180#pragma omp parallel default(none) \
181 shared(nb_fibres, health, cube, image, fcentroids, crpix2, cd2_2, res, \
187 for (
int i = 1; i <= nb_fibres; i++) {
188 int h = health[i - 1];
189 cpl_msg_debug(__func__,
"reproject fibre %d", i);
192 cpl_image *model = cpl_imagelist_get(cube, i - 1);
193 _moo_reproject_model_fibre(image, i, fcentroids, model, crpix2,
194 cd2_2, res, contrib);
200 double *data = cpl_image_get_data(res);
202 int *contrib_data = cpl_image_get_data(contrib);
203 for (
int i = 0; i < nx * ny; i++) {
204 if (contrib_data[i] != 0) {
205 data[i] /= contrib_data[i];
208 cpl_image_delete(contrib);
211 if (!cpl_errorstate_is_equal(prestate)) {
212 cpl_msg_error(__func__,
"Error in modelize flat");
213 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
215 cpl_errorstate_set(prestate);
234 moo_psf *model_flat1,
235 const char *filename)
237 cpl_ensure_code(flat1 != NULL, CPL_ERROR_NULL_INPUT);
238 cpl_ensure_code(loc1 != NULL, CPL_ERROR_NULL_INPUT);
239 cpl_ensure_code(model_flat1 != NULL, CPL_ERROR_NULL_INPUT);
241 cpl_msg_info(__func__,
"Reproject model");
244 cpl_ensure_code(fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT);
251 cpl_msg_indent_more();
253 for (
int i = 1; i <= 2; i++) {
254 cpl_table_unselect_all(fibres_table);
256 cpl_table_or_selected_int(fibres_table, MOO_FIBRES_TABLE_SPECTRO,
257 CPL_EQUAL_TO, fibname);
258 cpl_table *selected = cpl_table_extract_selected(fibres_table);
260 cpl_table_get_data_int_const(selected, MOO_FIBRES_TABLE_HEALTH);
262 for (
int j = 0; j < 3; j++) {
263 moo_single *flat_single1 =
270 if (flat_single1 != NULL && loc_single1 != NULL && psf_single1) {
272 _moo_reproject_model(flat_single1, loc_single1, psf_single1,
275 flat_single1->extname,
276 CPL_TYPE_FLOAT, NULL);
277 cpl_image_delete(model);
280 cpl_table_delete(selected);
282 cpl_msg_indent_less();
283 return CPL_ERROR_NONE;
287_moo_compute_p2p_single(moo_single *flat1,
288 moo_loc_single *loc1,
289 moo_psf_single *model_flat1,
291 moo_loc_single *loc2,
292 moo_psf_single *model_flat2,
295 moo_single *result = NULL;
296 cpl_mask *mask_loc1 = NULL;
297 cpl_mask *mask_loc2 = NULL;
299 cpl_msg_indent_more();
300 cpl_msg_info(
"moo_compute_p2p",
"Reproject model");
301 cpl_ensure(flat1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
302 cpl_ensure(loc1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
303 cpl_ensure(model_flat1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
304 cpl_ensure(flat2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
305 cpl_ensure(loc2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
306 cpl_ensure(model_flat2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
307 cpl_ensure(health != NULL, CPL_ERROR_NULL_INPUT, NULL);
309 cpl_errorstate prestate = cpl_errorstate_get();
311 cpl_image *model1 = NULL;
312 cpl_image *model2 = NULL;
313 cpl_image *model_sum = NULL;
314 hdrl_image *model = NULL;
315 cpl_mask *orig = NULL;
317 moo_try_check(model1 =
318 _moo_reproject_model(flat1, loc1, model_flat1, health),
319 " Reproject model1 failed");
320 moo_try_check(model2 =
321 _moo_reproject_model(flat2, loc2, model_flat2, health),
322 "reproject model2 failed");
324 moo_try_check(model_sum = cpl_image_add_create(model1, model2),
" ");
326#if MOO_DEBUG_P2P_MODEL
328 flat1->extname, CPL_TYPE_FLOAT, NULL);
330 flat1->extname, CPL_TYPE_FLOAT, NULL);
332 result = moo_single_add_create(flat1, flat2);
334 model = hdrl_image_create(model_sum, NULL);
336 cpl_mask *mask = hdrl_image_get_mask(result->image);
338 int size_y = hdrl_image_get_size_y(result->image);
341 cpl_mask_and(mask_loc1, mask_loc2);
344 cpl_mask_or(mask, mask_loc1);
346 orig = cpl_mask_duplicate(mask);
347 hdrl_image_div_image(result->image, model);
350 cpl_mask_and(orig, mask);
351 cpl_msg_info(
"",
"new bad pix %" CPL_SIZE_FORMAT, cpl_mask_count(orig));
355 cpl_msg_indent_less();
356 cpl_mask_delete(mask_loc1);
357 cpl_mask_delete(mask_loc2);
358 cpl_image_delete(model1);
359 cpl_image_delete(model2);
360 cpl_mask_delete(orig);
361 hdrl_image_delete(model);
362 cpl_image_delete(model_sum);
364 if (!cpl_errorstate_is_equal(prestate)) {
365 cpl_msg_error(__func__,
"Error in model flat");
366 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
368 cpl_errorstate_set(prestate);
400 moo_psf *model_flat1,
403 moo_psf *model_flat2)
405 moo_det *result = NULL;
407 cpl_errorstate prestate = cpl_errorstate_get();
409 cpl_table *selected = NULL;
411 cpl_ensure(flat1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
412 cpl_ensure(loc1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
413 cpl_ensure(model_flat1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
414 cpl_ensure(flat2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
415 cpl_ensure(loc2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
416 cpl_ensure(model_flat2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
418 cpl_msg_info(__func__,
"Compute pixel-to-pixel variation map");
421 cpl_ensure(fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
426#if MOO_DEBUG_P2P_MODEL
429 cpl_msg_indent_more();
433 result->primary_header = cpl_propertylist_new();
435 for (
int i = 1; i <= 2; i++) {
436 cpl_table_unselect_all(fibres_table);
438 cpl_table_or_selected_int(fibres_table, MOO_FIBRES_TABLE_SPECTRO,
439 CPL_EQUAL_TO, fibname);
440 moo_try_check(selected = cpl_table_extract_selected(fibres_table),
" ");
442 cpl_table_get_data_int_const(selected, MOO_FIBRES_TABLE_HEALTH);
443 for (
int j = 0; j < 3; j++) {
444 moo_single *single = NULL;
445 moo_single *det_single1 =
450 moo_single *det_single2 =
455 if (det_single1 != NULL && loc_single1 != NULL && psf_single1 &&
456 det_single2 != NULL && loc_single2 != NULL && psf_single2) {
457 cpl_msg_info(__func__,
"Compute p2p for extension %s",
460 moo_try_check(single = _moo_compute_p2p_single(
461 det_single1, loc_single1, psf_single1,
462 det_single2, loc_single2, psf_single2,
465 moo_try_check(_moo_compute_p2p_qc(single, badpix_level),
" ");
466 moo_try_check(moo_det_set_single(result, j, i, single),
" ");
468#if MOO_DEBUG_P2P_MODEL
472 CPL_TYPE_FLOAT, NULL);
475 CPL_TYPE_FLOAT, NULL);
479 cpl_table_delete(selected);
482 cpl_msg_indent_less();
485 if (!cpl_errorstate_is_equal(prestate)) {
486 cpl_msg_error(__func__,
"Error in compute_p2p");
488 cpl_table_delete(selected);
490 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
492 cpl_errorstate_set(prestate);
cpl_error_code moo_mask_to_badpix(cpl_image *badpix, cpl_mask *mask, unsigned int level)
Add the mask of the badpix level to the badpix map.
#define MOO_BADPIX_LOW_QE
#define MOO_BADPIX_OUTSIDE_DATA_RANGE
#define MOO_BADPIX_CALIB_DEFECT
cpl_error_code moo_badpix_to_mask(cpl_image *badpix, cpl_mask *mask, unsigned int level)
Apply the badpix map on the given mask.
moo_single * moo_det_load_single(moo_det *self, moo_detector_type type, int num, int level)
Load the type part in DET and return it.
moo_det * moo_det_new(void)
Create a new moo_det.
void moo_det_delete(moo_det *self)
Delete a moo_det.
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
cpl_error_code moo_fits_write_extension_image(cpl_image *image, const char *filename, const char *name, const char *detectorname, cpl_type type, cpl_propertylist *header)
Write an image as extension in FITS file.
cpl_error_code moo_fits_create(const char *filename)
Create a new fits file with empty propertylist.
cpl_image * moo_loc_single_get_f_centroids(moo_loc_single *self)
Get image of fit centroids.
cpl_mask * moo_loc_single_get_ODR(moo_loc_single *self, int size_y)
Get outside data range mask far a DET single.
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.
cpl_error_code moo_psf_single_get_cube_ref(moo_psf_single *self, double *crpix2, double *cd2_2)
Set cube parameters.
cpl_imagelist * moo_psf_single_get_cube(moo_psf_single *self)
Get cube.
moo_psf_single * moo_psf_get_single(moo_psf *self, moo_detector_type type, int ntas)
Get a PSF single from PSF.
hdrl_image * moo_single_get_image(moo_single *self)
Get the IMAGE part (DATA,ERR) of single DET.
moo_det * moo_compute_p2p(moo_det *flat1, moo_loc *loc1, moo_psf *model_flat1, moo_det *flat2, moo_loc *loc2, moo_psf *model_flat2)
To compute pixel-to-pixel variation map.
cpl_error_code moo_reproject_model(moo_det *flat1, moo_loc *loc1, moo_psf *model_flat1, const char *filename)
Reporject a model on detector.
cpl_error_code moo_qc_set_p2p_max(cpl_propertylist *plist, double val)
Set the QC.P2P.MAX value.
cpl_error_code moo_qc_set_p2p_med(cpl_propertylist *plist, double val)
Set the QC.P2P.MED value.
cpl_error_code moo_qc_set_p2p_min(cpl_propertylist *plist, double val)
Set the QC.P2P.MIN value.
cpl_error_code moo_qc_set_p2p_mad(cpl_propertylist *plist, double val)
Set the QC.P2P.MAD value.
cpl_error_code moo_qc_set_p2p_avg(cpl_propertylist *plist, double val)
Set the QC.P2P.AVG value.
cpl_error_code moo_qc_set_p2p_rms(cpl_propertylist *plist, double val)
Set the QC.P2P.RMS value.