31#include "moo_params.h"
32#include "moo_single.h"
33#include "moo_badpix.h"
35#include "moo_ext_single.h"
36#include "moo_extract.h"
37#include "moo_fibres_table.h"
59_moo_integrate_flux(hdrl_image *image,
69 hdrl_value v1 = hdrl_image_get_pixel(image, x, (
int)y1, rej);
70 int nx = hdrl_image_get_size_x(image);
72 *qual = det_qual[x - 1 + nx * ((int)y1 - 1)];
73 double val = v1.data * frac;
74 double err = v1.error * frac;
85_moo_extract_fibre_opt(hdrl_image *image,
97 cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
98 cpl_ensure_code(model != NULL, CPL_ERROR_NULL_INPUT);
99 cpl_ensure_code(det_qual != NULL, CPL_ERROR_NULL_INPUT);
100 cpl_ensure_code(centroids != NULL, CPL_ERROR_NULL_INPUT);
101 cpl_ensure_code(wlo != NULL, CPL_ERROR_NULL_INPUT);
102 cpl_ensure_code(wup != NULL, CPL_ERROR_NULL_INPUT);
104 int nx = hdrl_image_get_size_x(image);
105 int *det_qual_data = cpl_image_get_data_int(det_qual);
106 int idfib = fibnum - 1;
108 for (
int i = 0; i < nx; i++) {
109 double yc = centroids[idfib * nx + i];
110 double yl = yc - wlo[idfib * nx + i];
111 double yu = yc + wup[idfib * nx + i];
114 yl = yc - aperture / 2.;
115 yu = yc + aperture / 2.;
124 double y1 = round(yl);
125 double y2 = round(yu);
127 int size = y2 - y1 + 1;
128 cpl_vector *vmodel = cpl_vector_new(size);
129 cpl_vector *vobs = cpl_vector_new(size);
130 cpl_vector *verrobs = cpl_vector_new(size);
131 int *vrej = cpl_calloc(size,
sizeof(
int));
132 cpl_vector *vw = cpl_vector_new(size);
133 cpl_vector *vq = cpl_vector_new(size);
135 double frac = y1 + 0.5 - yl;
136 hdrl_value vl = _moo_integrate_flux(image, det_qual_data, i + 1, yl,
140 m1 = cpl_image_get(model, i + 1, y1, &rej);
142 cpl_vector_set(vobs, 0, vl.data);
143 cpl_vector_set(verrobs, 0, vl.error);
144 cpl_vector_set(vmodel, 0, m1);
145 cpl_vector_set(vq, 0, ql);
151 frac = yu - y2 + 0.5;
152 hdrl_value vu = _moo_integrate_flux(image, det_qual_data, i + 1, yu,
154 vrej[size - 1] = rej;
156 m2 = cpl_image_get(model, i + 1, y2, &rej);
163 cpl_vector_set(vmodel, size - 1, m2);
164 cpl_vector_set(vq, size - 1, qu);
165 cpl_vector_set(vobs, size - 1, vu.data);
166 cpl_vector_set(verrobs, size - 1, vu.error);
170 for (
int j = y1 + 1; j <= y2 - 1; j++) {
171 double m = cpl_image_get(model, i + 1, j, &rej);
172 hdrl_value v = hdrl_image_get_pixel(image, i + 1, j, &rej);
173 int qualv = det_qual_data[i + nx * (j - 1)];
176 cpl_vector_set(vobs, vi, v.data);
177 cpl_vector_set(verrobs, vi, v.error);
178 cpl_vector_set(vmodel, vi, m);
179 cpl_vector_set(vq, vi, qualv);
183 double mmin = cpl_vector_get_min(vmodel);
185 cpl_vector_subtract_scalar(vmodel, mmin);
187 double msum = cpl_vector_get_sum(vmodel);
189 cpl_vector_divide_scalar(vmodel, msum);
191 for (
int j = 0; j < size; j++) {
193 double m = cpl_vector_get(vmodel, j);
197 cpl_vector_set(vw, j, w);
200 double wsum = cpl_vector_get_sum(vw);
203 for (
int j = 0; j < size; j++) {
204 double qv = cpl_vector_get(vq, j);
207 cpl_image_reject(fluxes, i + 1, fibnum);
208 cpl_image_set(fluxes, i + 1, fibnum, NAN);
209 cpl_image_set(errs, i + 1, fibnum, NAN);
210 cpl_image_set(qual, i + 1, fibnum, qflag);
213 cpl_vector_divide_scalar(vw, wsum);
214 double sum = 0, errors = 0;
215 moo_fit_mul(vmodel, vw, vobs, verrobs, &sum, &errors);
216 cpl_image_set(fluxes, i + 1, fibnum, sum);
220 cpl_image_set(errs, i + 1, fibnum, errors);
221 cpl_image_set(qual, i + 1, fibnum, qflag);
224 cpl_vector_delete(vmodel);
225 cpl_vector_delete(vobs);
226 cpl_vector_delete(verrobs);
227 cpl_vector_delete(vw);
228 cpl_vector_delete(vq);
232 cpl_image_reject(fluxes, i + 1, fibnum);
233 cpl_image_set(fluxes, i + 1, fibnum, NAN);
234 cpl_image_set(errs, i + 1, fibnum, NAN);
239 return cpl_error_get_code();
243_moo_extract_fibre_sum(hdrl_image *image,
254 cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
255 cpl_ensure_code(det_qual != NULL, CPL_ERROR_NULL_INPUT);
256 cpl_ensure_code(centroids != NULL, CPL_ERROR_NULL_INPUT);
257 cpl_ensure_code(wlo != NULL, CPL_ERROR_NULL_INPUT);
258 cpl_ensure_code(wup != NULL, CPL_ERROR_NULL_INPUT);
259 cpl_errorstate prestate = cpl_errorstate_get();
261 int nx = hdrl_image_get_size_x(image);
262 int *det_qual_data = cpl_image_get_data_int(det_qual);
263 int idfib = fibnum - 1;
265 for (
int i = 0; i < nx; i++) {
266 double yc = centroids[idfib * nx + i];
267 double yl = yc - wlo[idfib * nx + i];
268 double yu = yc + wup[idfib * nx + i];
270 yl = yc - aperture / 2.;
271 yu = yc + aperture / 2.;
274 cpl_msg_error(
"moo_extract",
275 "#%d Invalid localisation low limit (%f) at x %d",
280 double sum = 0, errors = 0;
285 double y1 = round(yl);
286 double y3 = round(yc);
287 double frac = y1 + 0.5 - yl;
292 hdrl_value vl = _moo_integrate_flux(image, det_qual_data, i + 1, yl,
295 double y2 = round(yu);
296 frac = yu - y2 + 0.5;
300 hdrl_value vu = _moo_integrate_flux(image, det_qual_data, i + 1, yu,
303 sum = vl.data + vu.data;
305 errors = vl.error * vl.error + vu.error * vu.error;
310 for (
int j = y1 + 1; j <= y2 - 1; j++) {
311 hdrl_value v = hdrl_image_get_pixel(image, i + 1, j, &rej);
312 qflag |= det_qual_data[i + nx * (j - 1)];
314 errors += v.error * v.error;
317 errors = sqrt(errors);
318 cpl_image_set(fluxes, i + 1, fibnum, sum);
319 cpl_image_set(errs, i + 1, fibnum, errors);
320 cpl_image_set(qual, i + 1, fibnum, qflag);
323 cpl_image_set(fluxes, i + 1, fibnum, NAN);
324 cpl_image_set(errs, i + 1, fibnum, NAN);
329 if (!cpl_errorstate_is_equal(prestate)) {
330 cpl_msg_error(__func__,
"Error in extraction");
331 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
333 cpl_errorstate_set(prestate);
335 return cpl_error_get_code();
338static moo_ext_single *
339_moo_extract_single(moo_single *det,
341 moo_psf_single *master_flat,
342 const char *filename,
348 cpl_ensure(det != NULL, CPL_ERROR_NULL_INPUT, NULL);
349 cpl_ensure(loc != NULL, CPL_ERROR_NULL_INPUT, NULL);
350 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
351 cpl_ensure(health != NULL, CPL_ERROR_NULL_INPUT, NULL);
353 cpl_errorstate prestate = cpl_errorstate_get();
357 moo_try_assure(fcentroids != NULL, CPL_ERROR_NULL_INPUT,
358 "No data in localisation %s for extension %s", loc->filename,
365 int nb_fibres = cpl_image_get_size_y(fcentroids);
366 int nx = cpl_image_get_size_x(fcentroids);
369 cpl_propertylist_copy_property_regexp(res->header, det->header,
"ESO DET *",
372 cpl_propertylist_copy_property(res->header, det->header, MOO_PFITS_BUNIT);
374 cpl_propertylist_copy_property(res->header, det->header, MOO_PFITS_CRPIX1);
375 cpl_propertylist_copy_property(res->header, det->header, MOO_PFITS_CRVAL1);
376 cpl_propertylist_copy_property(res->header, det->header, MOO_PFITS_CD1_1);
377 cpl_propertylist_copy_property(res->header, det->header, MOO_PFITS_CTYPE1);
378 cpl_propertylist_copy_property(res->header, det->header, MOO_PFITS_CUNIT1);
383 cpl_propertylist_append_double(res->header, MOO_PFITS_CRPIX2,
384 MOO_EXT_SINGLE_CRPIX2);
385 cpl_propertylist_append_double(res->header, MOO_PFITS_CRVAL2,
386 MOO_EXT_SINGLE_CRVAL2);
388 cpl_propertylist_append_double(res->header, MOO_PFITS_CD1_2, 0.);
389 cpl_propertylist_append_double(res->header, MOO_PFITS_CD2_1, 0.);
391 cpl_propertylist_append_double(res->header, MOO_PFITS_CD2_2,
392 MOO_EXT_SINGLE_CDELT2);
393 cpl_propertylist_append_string(res->header, MOO_PFITS_CTYPE2,
394 MOO_EXT_SINGLE_CTYPE2);
396 res->filename = filename;
398 hdrl_image *himage = hdrl_image_new(nx, nb_fibres);
399 cpl_image *ext_fluxes = hdrl_image_get_image(himage);
400 cpl_image *ext_errs = hdrl_image_get_error(himage);
401 cpl_image *ext_qual = cpl_image_new(nx, nb_fibres, CPL_TYPE_INT);
404 res->qual = ext_qual;
406 double *centroids = cpl_image_get_data(fcentroids);
408 double *wlo = cpl_image_get_data(fwlo);
409 double *wup = cpl_image_get_data(fwup);
411 if (master_flat != NULL) {
412 cpl_image *model = moo_psf_single_reproject_model(master_flat, det, loc,
414 for (
int i = 1; i <= nb_fibres; i++) {
415 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
418 cpl_msg_debug(__func__,
419 "extract fibres %d index %d indexext %d", i, idx,
421 moo_try_check(_moo_extract_fibre_opt(image, model, det_qual, i,
423 ext_fluxes, ext_errs,
428 cpl_image_delete(model);
439#if (__GNUC__ == 9) && (__GNUC_MINOR__ < 3)
440#pragma omp parallel shared(nb_fibres, health, ext_fluxes, ext_errs, ext_qual, \
441 wlo, wup, centroids, image, det_qual, indexes, \
444#pragma omp parallel default(none) \
445 shared(nb_fibres, health, ext_fluxes, ext_errs, ext_qual, wlo, wup, \
446 centroids, image, det_qual, indexes, aperture)
451 for (
int i = 1; i <= nb_fibres; i++) {
453 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
456 cpl_msg_debug(__func__,
"extract fibres %d", i);
457 _moo_extract_fibre_sum(image, det_qual, i, centroids, wlo,
458 wup, ext_fluxes, ext_errs, ext_qual,
469 if (!cpl_errorstate_is_equal(prestate)) {
470 cpl_msg_error(__func__,
"Error in extraction extension %s",
472 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
477 cpl_errorstate_set(prestate);
483static cpl_propertylist *
484_moo_create_primary_header(cpl_propertylist *det_primary_header)
486 cpl_propertylist *primary_header = NULL;
488 primary_header = cpl_propertylist_new();
489 cpl_propertylist_copy_property(primary_header, det_primary_header,
491 cpl_propertylist_copy_property_regexp(primary_header, det_primary_header,
493 cpl_propertylist_copy_property_regexp(primary_header, det_primary_header,
497 return primary_header;
525 moo_psf *master_flat,
526 moo_extract_params *params,
527 const char *filename)
529 moo_ext *result = NULL;
530 int *indexext = NULL;
532 const char **names = NULL;
533 const char **loc_names = NULL;
534 int *loc_indexext = NULL;
535 const int *loc_health = NULL;
537 cpl_errorstate prestate = cpl_errorstate_get();
539 cpl_ensure(det != NULL, CPL_ERROR_NULL_INPUT, NULL);
540 cpl_ensure(loc != NULL, CPL_ERROR_NULL_INPUT, NULL);
541 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
543 cpl_msg_info(__func__,
"Extracting using method %s ", params->method);
547 if (strcmp(params->method, MOO_EXTRACT_METHOD_OPTIMAL) == 0) {
548 cpl_ensure(master_flat != NULL, CPL_ERROR_NULL_INPUT, NULL);
555 result->filename = filename;
556 result->primary_header = _moo_create_primary_header(det->primary_header);
559 cpl_ensure(fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
561 cpl_ensure(loc_fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
566 cpl_table *ext_fibres_table = cpl_table_duplicate(fibres_table);
568 result->fibre_table = ext_fibres_table;
571 int nrow = cpl_table_get_nrow(ext_fibres_table);
572 int loc_nrow = cpl_table_get_nrow(loc_fibres_table);
575 moo_try_check(indexext = cpl_table_get_data_int(ext_fibres_table,
576 MOO_FIBRES_TABLE_INDEXEXT),
578 moo_try_check(health = cpl_table_get_data_int(ext_fibres_table,
579 MOO_FIBRES_TABLE_HEALTH),
581 moo_try_check(names =
582 cpl_table_get_data_string_const(ext_fibres_table,
583 MOO_FIBRES_TABLE_FIBRE),
585 moo_try_check(loc_names =
586 cpl_table_get_data_string_const(loc_fibres_table,
587 MOO_FIBRES_TABLE_FIBRE),
589 moo_try_check(loc_indexext =
590 cpl_table_get_data_int(loc_fibres_table,
591 MOO_FIBRES_TABLE_INDEXEXT),
593 moo_try_check(loc_health =
594 cpl_table_get_data_int_const(loc_fibres_table,
595 MOO_FIBRES_TABLE_HEALTH),
598 for (
int i = 0; i < nrow; i++) {
599 const char *ext_name = names[i];
600 for (
int j = 0; j < loc_nrow; j++) {
601 const char *loc_name = loc_names[j];
602 if (strcmp(ext_name, loc_name) == 0) {
603 indexext[i] = loc_indexext[j];
604 if (health[i] != 0) {
605 health[i] = loc_health[j];
610 cpl_msg_indent_more();
612 const char *colnames[] = {
"MEDIAN_SNR_RI_EXT",
"MEDIAN_SNR_YJ_EXT",
613 "MEDIAN_SNR_H_EXT" };
614 const char *dersnr_colnames[] = { MOO_FIBRES_TABLE_DERSNR_RI_EXT,
615 MOO_FIBRES_TABLE_DERSNR_YJ_EXT,
616 MOO_FIBRES_TABLE_DERSNR_H_EXT };
617 for (
int i = 1; i <= 2; i++) {
621 int nb_selected = cpl_array_get_size(indexes);
623 if (health != NULL) {
624 for (
int j = 0; j < 3; j++) {
625 if (!cpl_errorstate_is_equal(prestate)) {
626 cpl_msg_error(__func__,
627 "Error in extraction for DET %s LOC %s",
628 det->filename, loc->filename);
629 cpl_errorstate_dump(prestate, CPL_FALSE,
630 cpl_errorstate_dump_one);
632 cpl_errorstate_set(prestate);
634 moo_single *det_single =
637 moo_psf_single *psf_single = NULL;
638 if (strcmp(params->method, MOO_EXTRACT_METHOD_OPTIMAL) == 0) {
641 moo_ext_single *ext_single = NULL;
642 if (det_single != NULL && loc_single != NULL) {
643 double aperture = params->aperture[j + (i - 1) * 3];
647 "Extracting %d fibres in extension %s using "
655 "Extracting %d fibres in extension %s using "
656 "aperture LOCALISATION edges",
660 _moo_extract_single(det_single, loc_single, psf_single,
661 filename, health, indexes, indexext,
663 moo_try_check(moo_ext_single_compute_qc(ext_single,
672 cpl_array_delete(indexes);
678 cpl_msg_indent_less();
680 if (!cpl_errorstate_is_equal(prestate)) {
681 cpl_msg_error(__func__,
"Error in extraction for DET %s LOC %s",
682 det->filename, loc->filename);
#define MOO_BADPIX_OUTSIDE_DATA_RANGE
#define MOO_BADPIX_CALIB_DEFECT
#define MOO_BADPIX_COSMETIC
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.
cpl_table * moo_det_get_fibre_table(moo_det *self)
Get the FIBRE TABLE in DET.
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
moo_ext_single * moo_ext_single_new(moo_detector_type type, int ntas)
Create a new moo_ext_single.
void moo_ext_single_delete(moo_ext_single *self)
Delete a moo_ext_single.
moo_ext * moo_ext_new(void)
Create a new moo_ext.
cpl_error_code moo_ext_add_fibre_table(moo_ext *self, cpl_table *fibre_table)
Add fibre table to EXT filename and update moo_ext structure.
cpl_error_code moo_ext_add_single(moo_ext *self, moo_ext_single *single, moo_detector_type type, int ntas)
Add EXT_SINGLE extension to EXT filename and update moo_ext structure.
void moo_ext_delete(moo_ext *self)
Delete a moo_ext.
cpl_error_code moo_fibres_table_by_index(cpl_table *table)
Order fibres table by INDEX (ASC)
cpl_array * moo_fibres_table_get_spectro_indexext(cpl_table *table, int num)
get the index of a spectro in the fibre table sort by spetcro,indexext
cpl_error_code moo_fibres_table_add_extract_cols(cpl_table *table)
add extract additional columns
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_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.
cpl_image * moo_single_get_qual(moo_single *self)
Get the QUAL part of single DET.
moo_ext * moo_extract(moo_det *det, moo_loc *loc, moo_psf *master_flat, moo_extract_params *params, const char *filename)
extract the 1D spectrum of fibres
cpl_error_code moo_pfits_append_hduclass_data(cpl_propertylist *plist, moo_detector_type type, int ntas)
Set the HDUCLASS DATA Keyword.
cpl_error_code moo_qc_set_snr_range(cpl_propertylist *plist, const char *val)
Set the QC.SNR.RANGE value.
cpl_error_code moo_fit_mul(const cpl_vector *vx, const cpl_vector *vw, const cpl_vector *vy, const cpl_vector *vy_err, double *c, double *sig_c)
This function computes the best-fit linear regression coefficient c1 of the model Y = c_1 X for the w...