MOONS Pipeline Reference Manual 0.13.2
moo_extract.c
1/*
2 * This file is part of the MOONS Pipeline
3 * Copyright (C) 2002-2016 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27#include <math.h>
28#include <string.h>
29#include <cpl.h>
30#include <hdrl.h>
31#include "moo_params.h"
32#include "moo_single.h"
33#include "moo_badpix.h"
34#include "moo_ext.h"
35#include "moo_ext_single.h"
36#include "moo_extract.h"
37#include "moo_fibres_table.h"
38#include "moo_fits.h"
39#include "moo_pfits.h"
40#include "moo_qc.h"
41#include "moo_utils.h"
42#ifdef _OPENMP
43#include <omp.h>
44#endif
45/*----------------------------------------------------------------------------*/
50/*----------------------------------------------------------------------------*/
53/*-----------------------------------------------------------------------------
54 Function codes
55 -----------------------------------------------------------------------------*/
56
57
58static hdrl_value
59_moo_integrate_flux(hdrl_image *image,
60 int *det_qual,
61 int x,
62 double y,
63 int *qual,
64 double frac,
65 int *rej)
66{
67 double y1 = round(y);
68
69 hdrl_value v1 = hdrl_image_get_pixel(image, x, (int)y1, rej);
70 int nx = hdrl_image_get_size_x(image);
71
72 *qual = det_qual[x - 1 + nx * ((int)y1 - 1)];
73 double val = v1.data * frac;
74 double err = v1.error * frac;
75
76 hdrl_value res;
77
78 res.data = val;
79 res.error = err;
80
81 return res;
82}
83
84static cpl_error_code
85_moo_extract_fibre_opt(hdrl_image *image,
86 cpl_image *model,
87 cpl_image *det_qual,
88 int fibnum,
89 double *centroids,
90 double *wlo,
91 double *wup,
92 cpl_image *fluxes,
93 cpl_image *errs,
94 cpl_image *qual,
95 double aperture)
96{
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);
103
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;
107
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];
112
113 if (aperture > 0) {
114 yl = yc - aperture / 2.;
115 yu = yc + aperture / 2.;
116 }
117
118 if (!isnan(yc)) {
119 int rej;
120 int ql = 0, qu = 0;
121 int qflag = 0;
122 double m1 = 0.0;
123 double m2 = 0.0;
124 double y1 = round(yl);
125 double y2 = round(yu);
126
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);
134
135 double frac = y1 + 0.5 - yl;
136 hdrl_value vl = _moo_integrate_flux(image, det_qual_data, i + 1, yl,
137 &ql, frac, &rej);
138 vrej[0] = rej;
139
140 m1 = cpl_image_get(model, i + 1, y1, &rej);
141 m1 *= frac;
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);
146
147 if (rej == 0) {
148 qflag |= ql;
149 }
150
151 frac = yu - y2 + 0.5;
152 hdrl_value vu = _moo_integrate_flux(image, det_qual_data, i + 1, yu,
153 &qu, frac, &rej);
154 vrej[size - 1] = rej;
155
156 m2 = cpl_image_get(model, i + 1, y2, &rej);
157 m2 *= frac;
158
159 if (rej == 0) {
160 qflag |= qu;
161 }
162
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);
167
168 int vi = 1;
169
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)];
174
175 vrej[vi] = rej;
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);
180 vi++;
181 }
182
183 double mmin = cpl_vector_get_min(vmodel);
184 if (mmin < 0) {
185 cpl_vector_subtract_scalar(vmodel, mmin);
186 }
187 double msum = cpl_vector_get_sum(vmodel);
188
189 cpl_vector_divide_scalar(vmodel, msum);
190
191 for (int j = 0; j < size; j++) {
192 double w = 0.0;
193 double m = cpl_vector_get(vmodel, j);
194 if (vrej[j] == 0) {
195 w = sqrt(m);
196 }
197 cpl_vector_set(vw, j, w);
198 }
199
200 double wsum = cpl_vector_get_sum(vw);
201
202 if (wsum == 0) {
203 for (int j = 0; j < size; j++) {
204 double qv = cpl_vector_get(vq, j);
205 qflag |= (int)qv;
206 }
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);
211 }
212 else {
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);
217 if (isnan(sum)) {
219 }
220 cpl_image_set(errs, i + 1, fibnum, errors);
221 cpl_image_set(qual, i + 1, fibnum, qflag);
222 }
223
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);
229 cpl_free(vrej);
230 }
231 else {
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);
235 cpl_image_set(qual, i + 1, fibnum, MOO_BADPIX_OUTSIDE_DATA_RANGE);
236 }
237 }
238
239 return cpl_error_get_code();
240}
241
242static cpl_error_code
243_moo_extract_fibre_sum(hdrl_image *image,
244 cpl_image *det_qual,
245 int fibnum,
246 double *centroids,
247 double *wlo,
248 double *wup,
249 cpl_image *fluxes,
250 cpl_image *errs,
251 cpl_image *qual,
252 double aperture)
253{
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();
260
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;
264
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];
269 if (aperture > 0) {
270 yl = yc - aperture / 2.;
271 yu = yc + aperture / 2.;
272 }
273 if (yl < 0.5) {
274 cpl_msg_error("moo_extract",
275 "#%d Invalid localisation low limit (%f) at x %d",
276 fibnum, yl, i + 1);
277 break;
278 }
279 if (!isnan(yc)) {
280 double sum = 0, errors = 0;
281 int ql = 0, qu = 0;
282 int qflag = 0;
283 int rej;
284
285 double y1 = round(yl);
286 double y3 = round(yc);
287 double frac = y1 + 0.5 - yl;
288 if (y1 == y3) {
289 frac = yc - yl;
290 }
291
292 hdrl_value vl = _moo_integrate_flux(image, det_qual_data, i + 1, yl,
293 &ql, frac, &rej);
294
295 double y2 = round(yu);
296 frac = yu - y2 + 0.5;
297 if (y1 == y3) {
298 frac = yu - yc;
299 }
300 hdrl_value vu = _moo_integrate_flux(image, det_qual_data, i + 1, yu,
301 &qu, frac, &rej);
302
303 sum = vl.data + vu.data;
304
305 errors = vl.error * vl.error + vu.error * vu.error;
306 qflag |= ql;
307 qflag |= qu;
308
309
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)];
313 sum += v.data;
314 errors += v.error * v.error;
315 }
316
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);
321 }
322 else {
323 cpl_image_set(fluxes, i + 1, fibnum, NAN);
324 cpl_image_set(errs, i + 1, fibnum, NAN);
325 cpl_image_set(qual, i + 1, fibnum, MOO_BADPIX_OUTSIDE_DATA_RANGE);
326 }
327 }
328
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);
332 // Recover from the error(s) (Reset to prestate))
333 cpl_errorstate_set(prestate);
334 }
335 return cpl_error_get_code();
336}
337
338static moo_ext_single *
339_moo_extract_single(moo_single *det,
340 moo_loc_single *loc,
341 moo_psf_single *master_flat,
342 const char *filename,
343 const int *health,
344 cpl_array *indexes,
345 const int *indexext,
346 double aperture)
347{
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);
352
353 cpl_errorstate prestate = cpl_errorstate_get();
354 moo_ext_single *res = moo_ext_single_new(det->type, det->ntas);
355
356 cpl_image *fcentroids = moo_loc_single_get_f_centroids(loc);
357 moo_try_assure(fcentroids != NULL, CPL_ERROR_NULL_INPUT,
358 "No data in localisation %s for extension %s", loc->filename,
359 loc->extname);
360 cpl_image *fwlo = moo_loc_single_get_f_wlo(loc);
361 cpl_image *fwup = moo_loc_single_get_f_wup(loc);
362 hdrl_image *image = moo_single_get_image(det);
363 cpl_image *det_qual = moo_single_get_qual(det);
364
365 int nb_fibres = cpl_image_get_size_y(fcentroids);
366 int nx = cpl_image_get_size_x(fcentroids);
367
368 moo_pfits_append_hduclass_data(res->header, det->type, det->ntas);
369 cpl_propertylist_copy_property_regexp(res->header, det->header, "ESO DET *",
370 0);
371
372 cpl_propertylist_copy_property(res->header, det->header, MOO_PFITS_BUNIT);
373
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);
379
380 // FIXME: Use cpl_propertylist_update family of functions, rather than
381 // cpl_propertylist_append. This avoids unintentional keyword
382 // duplication!
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);
387
388 cpl_propertylist_append_double(res->header, MOO_PFITS_CD1_2, 0.);
389 cpl_propertylist_append_double(res->header, MOO_PFITS_CD2_1, 0.);
390
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);
395
396 res->filename = filename;
397
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);
402
403 res->image = himage;
404 res->qual = ext_qual;
405
406 double *centroids = cpl_image_get_data(fcentroids);
407
408 double *wlo = cpl_image_get_data(fwlo);
409 double *wup = cpl_image_get_data(fwup);
410
411 if (master_flat != NULL) {
412 cpl_image *model = moo_psf_single_reproject_model(master_flat, det, loc,
413 health, indexes);
414 for (int i = 1; i <= nb_fibres; i++) {
415 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
416 int h = health[idx];
417 if (h == 1) {
418 cpl_msg_debug(__func__,
419 "extract fibres %d index %d indexext %d", i, idx,
420 indexext[idx]);
421 moo_try_check(_moo_extract_fibre_opt(image, model, det_qual, i,
422 centroids, wlo, wup,
423 ext_fluxes, ext_errs,
424 ext_qual, aperture),
425 " ");
426 }
427 }
428 cpl_image_delete(model);
429 }
430 else {
431/* The following addresses an issue with the gcc9 compiler series prior to
432 * gcc 9.3. These compiler versions require that the variable '__func__'
433 * appears in the data sharing clause if default(none) is used. However
434 * adding it to the data sharing clause breaks older compiler versions where
435 * these variables are pre-determined as shared.
436 * This was fixed in gcc 9.3 and OpenMP 5.1.
437 */
438#ifdef _OPENMP
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, \
442 aperture)
443#else
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)
447#endif
448 {
449#pragma omp for
450#endif
451 for (int i = 1; i <= nb_fibres; i++) {
452 //for (int i = 500; i <= 500; i++) {
453 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
454 int h = health[idx];
455 if (h == 1) {
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,
459 aperture);
460 }
461 }
462#ifdef _OPENMP
463 }
464#endif
465 }
466
467moo_try_cleanup:
468 // dump error from the state
469 if (!cpl_errorstate_is_equal(prestate)) {
470 cpl_msg_error(__func__, "Error in extraction extension %s",
471 det->extname);
472 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
473
475 res = NULL;
476 // Recover from the error(s) (Reset to prestate))
477 cpl_errorstate_set(prestate);
478 }
479 return res;
480}
481
482
483static cpl_propertylist *
484_moo_create_primary_header(cpl_propertylist *det_primary_header)
485{
486 cpl_propertylist *primary_header = NULL;
487
488 primary_header = cpl_propertylist_new();
489 cpl_propertylist_copy_property(primary_header, det_primary_header,
490 MOO_PFITS_EXPTIME);
491 cpl_propertylist_copy_property_regexp(primary_header, det_primary_header,
492 "TM*", 0);
493 cpl_propertylist_copy_property_regexp(primary_header, det_primary_header,
494 "ESO QC IS*", 0);
495 moo_qc_set_snr_range(primary_header, MOONS_QC_SNR_RANGE_FULL);
496
497 return primary_header;
498}
499/*----------------------------------------------------------------------------*/
521/*----------------------------------------------------------------------------*/
522moo_ext *
523moo_extract(moo_det *det,
524 moo_loc *loc,
525 moo_psf *master_flat,
526 moo_extract_params *params,
527 const char *filename)
528{
529 moo_ext *result = NULL;
530 int *indexext = NULL;
531 int *health = NULL;
532 const char **names = NULL;
533 const char **loc_names = NULL;
534 int *loc_indexext = NULL;
535 const int *loc_health = NULL;
536
537 cpl_errorstate prestate = cpl_errorstate_get();
538
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);
542
543 cpl_msg_info(__func__, "Extracting using method %s ", params->method);
544
545 unsigned int badpix_level = MOO_BADPIX_GOOD;
546
547 if (strcmp(params->method, MOO_EXTRACT_METHOD_OPTIMAL) == 0) {
548 cpl_ensure(master_flat != NULL, CPL_ERROR_NULL_INPUT, NULL);
549 badpix_level = MOO_BADPIX_COSMETIC | MOO_BADPIX_HOT |
551 }
552 moo_fits_create(filename);
553
554 result = moo_ext_new();
555 result->filename = filename;
556 result->primary_header = _moo_create_primary_header(det->primary_header);
557
558 cpl_table *fibres_table = moo_det_get_fibre_table(det);
559 cpl_ensure(fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
560 cpl_table *loc_fibres_table = moo_loc_get_fibre_table(loc);
561 cpl_ensure(loc_fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
562
563 moo_fibres_table_by_index(loc_fibres_table);
564 moo_fibres_table_by_index(fibres_table);
565
566 cpl_table *ext_fibres_table = cpl_table_duplicate(fibres_table);
567
568 result->fibre_table = ext_fibres_table;
569 moo_try_check(moo_fibres_table_add_extract_cols(ext_fibres_table), " ");
570
571 int nrow = cpl_table_get_nrow(ext_fibres_table);
572 int loc_nrow = cpl_table_get_nrow(loc_fibres_table);
573
574 // cpl_ensure(loc_nrow==nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
575 moo_try_check(indexext = cpl_table_get_data_int(ext_fibres_table,
576 MOO_FIBRES_TABLE_INDEXEXT),
577 " ");
578 moo_try_check(health = cpl_table_get_data_int(ext_fibres_table,
579 MOO_FIBRES_TABLE_HEALTH),
580 " ");
581 moo_try_check(names =
582 cpl_table_get_data_string_const(ext_fibres_table,
583 MOO_FIBRES_TABLE_FIBRE),
584 " ");
585 moo_try_check(loc_names =
586 cpl_table_get_data_string_const(loc_fibres_table,
587 MOO_FIBRES_TABLE_FIBRE),
588 " ");
589 moo_try_check(loc_indexext =
590 cpl_table_get_data_int(loc_fibres_table,
591 MOO_FIBRES_TABLE_INDEXEXT),
592 " ");
593 moo_try_check(loc_health =
594 cpl_table_get_data_int_const(loc_fibres_table,
595 MOO_FIBRES_TABLE_HEALTH),
596 " ");
597
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];
606 }
607 }
608 }
609 }
610 cpl_msg_indent_more();
611
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++) {
618 cpl_array *indexes =
619 moo_fibres_table_get_spectro_indexext(ext_fibres_table, i);
620
621 int nb_selected = cpl_array_get_size(indexes);
622
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);
631 // Recover from the error(s) (Reset to prestate))
632 cpl_errorstate_set(prestate);
633 }
634 moo_single *det_single =
635 moo_det_load_single(det, j, i, badpix_level);
636 moo_loc_single *loc_single = moo_loc_get_single(loc, j, i);
637 moo_psf_single *psf_single = NULL;
638 if (strcmp(params->method, MOO_EXTRACT_METHOD_OPTIMAL) == 0) {
639 psf_single = moo_psf_get_single(master_flat, j, i);
640 }
641 moo_ext_single *ext_single = NULL;
642 if (det_single != NULL && loc_single != NULL) {
643 double aperture = params->aperture[j + (i - 1) * 3];
644 if (aperture > 0) {
645 cpl_msg_info(
646 __func__,
647 "Extracting %d fibres in extension %s using "
648 "aperture %f",
649 nb_selected, moo_detector_get_extname(j, i),
650 aperture);
651 }
652 else {
653 cpl_msg_info(
654 __func__,
655 "Extracting %d fibres in extension %s using "
656 "aperture LOCALISATION edges",
657 nb_selected, moo_detector_get_extname(j, i));
658 }
659 ext_single =
660 _moo_extract_single(det_single, loc_single, psf_single,
661 filename, health, indexes, indexext,
662 aperture);
663 moo_try_check(moo_ext_single_compute_qc(ext_single,
664 colnames[j],
665 dersnr_colnames[j],
666 ext_fibres_table),
667 " ");
668 }
669 moo_ext_add_single(result, ext_single, j, i);
670 }
671 }
672 cpl_array_delete(indexes);
673 }
674
675 moo_ext_add_fibre_table(result, ext_fibres_table);
676
677moo_try_cleanup:
678 cpl_msg_indent_less();
679
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);
683 moo_ext_delete(result);
684 result = NULL;
685 }
686 return result;
687}
#define MOO_BADPIX_OUTSIDE_DATA_RANGE
Definition: moo_badpix.h:62
#define MOO_BADPIX_CALIB_DEFECT
Definition: moo_badpix.h:48
#define MOO_BADPIX_HOT
Definition: moo_badpix.h:51
#define MOO_BADPIX_GOOD
Definition: moo_badpix.h:36
#define MOO_BADPIX_COSMETIC
Definition: moo_badpix.h:57
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.
Definition: moo_det.c:197
cpl_table * moo_det_get_fibre_table(moo_det *self)
Get the FIBRE TABLE in DET.
Definition: moo_det.c:424
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
Definition: moo_detector.c:137
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.
Definition: moo_ext.c:69
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.
Definition: moo_ext.c:309
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.
Definition: moo_ext.c:276
void moo_ext_delete(moo_ext *self)
Delete a moo_ext.
Definition: moo_ext.c:370
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.
Definition: moo_fits.c:533
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.
Definition: moo_loc.c:155
cpl_table * moo_loc_get_fibre_table(moo_loc *self)
Get the FIBRE TABLE in LOC.
Definition: moo_loc.c:306
moo_psf_single * moo_psf_get_single(moo_psf *self, moo_detector_type type, int ntas)
Get a PSF single from PSF.
Definition: moo_psf.c:151
hdrl_image * moo_single_get_image(moo_single *self)
Get the IMAGE part (DATA,ERR) of single DET.
Definition: moo_single.c:330
cpl_image * moo_single_get_qual(moo_single *self)
Get the QUAL part of single DET.
Definition: moo_single.c:312
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
Definition: moo_extract.c:523
cpl_error_code moo_pfits_append_hduclass_data(cpl_propertylist *plist, moo_detector_type type, int ntas)
Set the HDUCLASS DATA Keyword.
Definition: moo_pfits.c:1504
cpl_error_code moo_qc_set_snr_range(cpl_propertylist *plist, const char *val)
Set the QC.SNR.RANGE value.
Definition: moo_qc.c:2238
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...
Definition: moo_utils.c:1567