MOONS Pipeline Reference Manual 0.13.2
moo_compute_fibtrans.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_badpix.h"
33#include "moo_ext.h"
34#include "moo_ext_single.h"
35#include "moo_compute_fibtrans.h"
36#include "moo_utils.h"
37#include "moo_fibres_table.h"
38#ifdef _OPENMP
39#include <omp.h>
40#endif
41/*----------------------------------------------------------------------------*/
46/*----------------------------------------------------------------------------*/
49/*-----------------------------------------------------------------------------
50 Function codes
51 -----------------------------------------------------------------------------*/
52
53static double
54_moo_compute_fibtrans_fibre(hdrl_image *himage, int ifib, cpl_image *qual)
55{
56 double integrated_flux = 0.0;
57 double thresh = MOO_COMPUTE_FIBTRANS_NORMALISE_THRESH;
58 int nx = hdrl_image_get_size_x(himage);
59 int nbgood = 0;
60 cpl_image *idata = hdrl_image_get_image(himage);
61 cpl_image *ierrs = hdrl_image_get_error(himage);
62 int nbrej = 0;
63 for (int i = 1; i <= nx; i++) {
64 int isrejected = cpl_image_is_rejected(idata, i, ifib);
65 if (isrejected) {
66 nbrej++;
67 }
68 }
69 nbgood = nx - nbrej;
70 if (nbgood > 0) {
71 //double mean_flux = cpl_image_get_mean_window(idata, 1, ifib, nx, ifib);
72 double median_flux =
73 cpl_image_get_median_window(idata, 1, ifib, nx, ifib);
74 integrated_flux = median_flux;
75
76 for (int i = 1; i <= nx; i++) {
77 int rej;
78 double flux = cpl_image_get(idata, i, ifib, &rej);
79 double tflux = flux / integrated_flux;
80 double err = cpl_image_get(ierrs, i, ifib, &rej);
81
82 cpl_image_set(idata, i, ifib, tflux);
83 cpl_image_set(ierrs, i, ifib, err / integrated_flux);
84 if (tflux < thresh) {
85 int q = cpl_image_get(qual, i, ifib, &rej);
87 cpl_image_set(qual, i, ifib, q);
88 }
89 }
90 }
91 return integrated_flux;
92}
93
94static cpl_vector *
95_moo_compute_fibtrans_single(moo_ext_single *ext,
96 const int *health,
97 const int *index,
98 int fibref)
99{
100 cpl_vector *res = NULL;
101 cpl_errorstate prestate = cpl_errorstate_get();
102
103 cpl_ensure(ext != NULL, CPL_ERROR_NULL_INPUT, NULL);
104 cpl_ensure(health != NULL, CPL_ERROR_NULL_INPUT, NULL);
105 cpl_ensure(index != NULL, CPL_ERROR_NULL_INPUT, NULL);
106
107 hdrl_image *himage = moo_ext_single_get_image(ext);
108 cpl_image *qual = moo_ext_single_get_qual(ext);
109
110 if (himage != NULL) {
111 int nb_fibres = hdrl_image_get_size_y(himage);
112 res = cpl_vector_new(nb_fibres);
113/* The following addresses an issue with the gcc9 compiler series prior to
114 * gcc 9.3. These compiler versions require that the variable '__func__'
115 * appears in the data sharing clause if default(none) is used. However
116 * adding it to the data sharing clause breaks older compiler versions where
117 * these variables are pre-determined as shared.
118 * This was fixed in gcc 9.3 and OpenMP 5.1.
119 */
120#ifdef _OPENMP
121#if (__GNUC__ == 9) && (__GNUC_MINOR__ < 3)
122#pragma omp parallel shared(nb_fibres, health, himage, res, qual)
123#else
124#pragma omp parallel default(none) shared(nb_fibres, health, himage, res, qual)
125#endif
126 {
127#pragma omp for
128#endif
129 for (int i = 1; i <= nb_fibres; i++) {
130 int h = health[i - 1];
131 double iflux = 0.0;
132 if (h == 1) {
133 iflux = _moo_compute_fibtrans_fibre(himage, i, qual);
134 }
135 cpl_vector_set(res, i - 1, iflux);
136 }
137#ifdef _OPENMP
138 }
139#endif
140 double ref_flux = NAN;
141
142 for (int i = 0; i < nb_fibres; i++) {
143 int ref_idx = index[i];
144 if (ref_idx == fibref) {
145 ref_flux = cpl_vector_get(res, i);
146 break;
147 }
148 }
149 if (!isnan(ref_flux) && ref_flux > 0) {
150 cpl_msg_info("compute_fibtrans", "Use reference flux %f", ref_flux);
151 cpl_vector_divide_scalar(res, ref_flux);
152 }
153 else {
154 cpl_error_set_message("compute_fibtrans", CPL_ERROR_ILLEGAL_INPUT,
155 "Reference fibre %d not found", fibref);
156 cpl_vector_delete(res);
157 res = NULL;
158 }
159 }
160 // dump error from the state
161 if (!cpl_errorstate_is_equal(prestate)) {
162 cpl_msg_error(__func__, "Error in extraction");
163 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
164 // Recover from the error(s) (Reset to prestate))
165 cpl_errorstate_set(prestate);
166 }
167 return res;
168}
169
170/*----------------------------------------------------------------------------*/
191/*----------------------------------------------------------------------------*/
192moo_f2f *
194 moo_compute_fibtrans_params *params,
195 const char *filename)
196{
197 moo_f2f *res = NULL;
198
199 cpl_ensure(ext != NULL, CPL_ERROR_NULL_INPUT, NULL);
200 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
201
202 cpl_errorstate prestate = cpl_errorstate_get();
203
204 cpl_msg_info(__func__, "Compute fibre transmission");
205
206 cpl_table *fibres_table = moo_ext_get_fibre_table(ext);
207 cpl_ensure(fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
208
209 int nrows = cpl_table_get_nrow(fibres_table);
210
211 unsigned int badpix_level = MOO_BADPIX_CALIB_DEFECT | MOO_BADPIX_HOT |
214
215 res = moo_f2f_create(nrows, fibres_table);
216 cpl_table_save(res->table, NULL, NULL, filename, CPL_IO_CREATE);
217
218 cpl_msg_indent_more();
219
220 for (int i = 1; i <= 2; i++) {
221 int fibref = params->fibref[i - 1];
222 cpl_table_unselect_all(fibres_table);
223 int fibname = i;
224
225 cpl_table_or_selected_int(fibres_table, MOO_FIBRES_TABLE_SPECTRO,
226 CPL_EQUAL_TO, fibname);
227 cpl_table *selected = cpl_table_extract_selected(fibres_table);
228 const int *health =
229 cpl_table_get_data_int_const(selected, MOO_FIBRES_TABLE_HEALTH);
230 const int *index =
231 cpl_table_get_data_int_const(selected, MOO_FIBRES_TABLE_INDEX);
232 cpl_array *selected_idx = cpl_table_where_selected(fibres_table);
233
234 if (health != NULL) {
235 for (int j = 0; j < 3; j++) {
236 moo_ext_single *ext_single =
237 moo_ext_load_single(ext, j, i, badpix_level);
238 if (ext_single != NULL) {
239 cpl_msg_info(__func__,
240 "Computing transmission for extension %s "
241 "using fibref %d",
242 moo_detector_get_extname(j, i), fibref);
243 cpl_vector *fluxes =
244 _moo_compute_fibtrans_single(ext_single, health, index,
245 fibref);
246 if (fluxes != NULL) {
247 moo_f2f_set_trans(res, j, selected_idx, fluxes);
248 cpl_vector_delete(fluxes);
249 }
250 }
251 }
252 }
253 cpl_array_delete(selected_idx);
254 cpl_table_delete(selected);
255 }
256
257 cpl_msg_indent_less();
258
259 cpl_table_unselect_all(fibres_table);
260 cpl_table_or_selected_int(fibres_table, MOO_FIBRES_TABLE_HEALTH,
261 CPL_EQUAL_TO, 0);
262 cpl_array *bad = cpl_table_where_selected(fibres_table);
263
264 moo_f2f_compute_qc(res, params->fibref, bad);
265
266 cpl_array_delete(bad);
267
268 if (!cpl_errorstate_is_equal(prestate)) {
269 cpl_msg_error(__func__, "Error in compute fibtrans");
270 moo_f2f_delete(res);
271 res = NULL;
272 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
273 // Recover from the error(s) (Reset to prestate))
274 cpl_errorstate_set(prestate);
275 }
276 return res;
277}
#define MOO_BADPIX_LOW_QE
Definition: moo_badpix.h:45
#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_COSMETIC
Definition: moo_badpix.h:57
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
Definition: moo_detector.c:137
hdrl_image * moo_ext_single_get_image(moo_ext_single *self)
Get image of EXT_SINGLE.
cpl_image * moo_ext_single_get_qual(moo_ext_single *self)
Get image of qual.
moo_ext_single * moo_ext_load_single(moo_ext *self, moo_detector_type type, int num, unsigned int level)
Load the type part in EXT and return it.
Definition: moo_ext.c:156
cpl_table * moo_ext_get_fibre_table(moo_ext *self)
Get the FIBRE TABLE in EXT.
Definition: moo_ext.c:344
void moo_f2f_delete(moo_f2f *self)
Delete a moo_f2f.
Definition: moo_f2f.c:413
cpl_error_code moo_f2f_set_trans(moo_f2f *self, moo_detector_type type, cpl_array *idxtab, cpl_vector *values)
Set transmission values in table.
Definition: moo_f2f.c:216
moo_f2f * moo_f2f_create(int nbrows, cpl_table *fibre_table)
Create a new moo_f2f and an empty structure in memory.
Definition: moo_f2f.c:86
moo_f2f * moo_compute_fibtrans(moo_ext *ext, moo_compute_fibtrans_params *params, const char *filename)
Computes fibre-to-fibre relative transmission table.