MOONS Pipeline Reference Manual 0.13.1
moo_correct_tell.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
31#include "moo_correct_tell.h"
32#include "moo_fibres_table.h"
33#include "moo_fits.h"
34#include "moo_pfits.h"
35#include "moo_badpix.h"
36#include "moo_utils.h"
37#include "moo_qc.h"
38#include "mf_calctrans.h"
39/*----------------------------------------------------------------------------*/
44/*----------------------------------------------------------------------------*/
45
48/*-----------------------------------------------------------------------------
49 Function codes
50 -----------------------------------------------------------------------------*/
51
52static cpl_table *
53_molecfit_data_create(double crpix1,
54 double crval1,
55 double cd1_1,
56 cpl_image *data,
57 cpl_image *data_err,
58 int id,
59 cpl_image *tell,
60 int idtell)
61{
62 cpl_table *result = NULL;
63 int nx = cpl_image_get_size_x(data);
64 int tell_nx = cpl_image_get_size_x(tell);
65
66 cpl_ensure(nx == tell_nx, CPL_ERROR_NULL_INPUT, NULL);
67
68 result = cpl_table_new(nx);
69 cpl_table_new_column(result, MOO_CORRECT_TELL_LAMBDA, CPL_TYPE_DOUBLE);
70 cpl_table_new_column(result, MOO_CORRECT_TELL_FLUX, CPL_TYPE_DOUBLE);
71 cpl_table_new_column(result, MOO_CORRECT_TELL_DFLUX, CPL_TYPE_DOUBLE);
72 cpl_table_new_column(result, MOO_CORRECT_TELL_MASK, CPL_TYPE_INT);
73 cpl_table_new_column(result, MOO_CORRECT_TELL_CFLUX, CPL_TYPE_DOUBLE);
74 cpl_table_new_column(result, MOO_CORRECT_TELL_CDFLUX, CPL_TYPE_DOUBLE);
75 cpl_table_new_column(result, MOO_CORRECT_TELL_QUAL, CPL_TYPE_INT);
76 cpl_table_new_column(result, MOO_CORRECT_TELL_MTRANS, CPL_TYPE_DOUBLE);
77
78 for (int i = 0; i < nx; i++) {
79 int rej1, rej2;
80 int ipix = i + 1;
81 double w = (ipix - crpix1) * cd1_1 + crval1;
82 double f = cpl_image_get(data, ipix, id, &rej1);
83
84 double e = cpl_image_get(data_err, ipix, id, &rej1);
85 double t = cpl_image_get(tell, ipix, idtell, &rej2);
86 cpl_table_set_double(result, MOO_CORRECT_TELL_LAMBDA, i, w);
87 cpl_table_set_double(result, MOO_CORRECT_TELL_FLUX, i, f);
88 cpl_table_set_double(result, MOO_CORRECT_TELL_DFLUX, i, e);
89 cpl_table_set_int(result, MOO_CORRECT_TELL_MASK, i, rej1);
90 cpl_table_set_double(result, MOO_CORRECT_TELL_CFLUX, i, f);
91 cpl_table_set_double(result, MOO_CORRECT_TELL_CDFLUX, i, e);
92 cpl_table_set_int(result, MOO_CORRECT_TELL_QUAL, i, rej1);
93 cpl_table_set_double(result, MOO_CORRECT_TELL_MTRANS, i, t);
94 }
95
96 return result;
97}
98
99static cpl_error_code
100_moo_update_primary_header(cpl_propertylist *primary_header)
101{
102 cpl_error_code status = CPL_ERROR_NONE;
103 status = moo_qc_set_is_tellcor(primary_header, CPL_TRUE);
104
105 return status;
106}
107/*----------------------------------------------------------------------------*/
122/*----------------------------------------------------------------------------*/
123cpl_error_code
124moo_correct_tell(moo_rbn *rbn, moo_telluric *tell)
125{
126 cpl_ensure_code(rbn != NULL, CPL_ERROR_NULL_INPUT);
127 cpl_ensure_code(tell != NULL, CPL_ERROR_NULL_INPUT);
128
129 cpl_errorstate prestate = cpl_errorstate_get();
130 cpl_msg_info(__func__, "Correct telluric");
131
132 int badpix_level = MOO_BADPIX_OUTSIDE_DATA_RANGE;
133 cpl_table *fibre_table = moo_rbn_get_fibre_table(rbn);
134 cpl_propertylist *primary_header = moo_rbn_get_primary_header(rbn);
135 _moo_update_primary_header(primary_header);
136 int nfibres = cpl_table_get_nrow(fibre_table);
137 int *idrbnt =
138 cpl_table_get_data_int(fibre_table, MOO_FIBRES_TABLE_INDEXRBN);
139 const int *spectrot =
140 cpl_table_get_data_int_const(fibre_table, MOO_FIBRES_TABLE_SPECTRO);
141
142 const char *trans_colnames[] = { MOO_FIBRES_TABLE_TRANS_RI,
143 MOO_FIBRES_TABLE_TRANS_YJ,
144 MOO_FIBRES_TABLE_TRANS_H };
145
146 for (int i = 0; i < 3; i++) {
147 moo_rbn_single *rbn_single = moo_rbn_load_single(rbn, i, badpix_level);
148
149 if (rbn_single != NULL) {
150 const char *trans_colname = trans_colnames[i];
151 const char *band = moo_telluric_get_band(i);
152 float *transt =
153 cpl_table_get_data_float(fibre_table, trans_colname);
154 cpl_image *tell_img = moo_telluric_get_image(tell, i);
155 int tnx = cpl_image_get_size_x(tell_img);
156
157 hdrl_image *himg = moo_rbn_single_get_image(rbn_single);
158 cpl_image *img = hdrl_image_get_image(himg);
159 cpl_image *err = hdrl_image_get_error(himg);
160 int nx = cpl_image_get_size_x(img);
161 cpl_propertylist *header = moo_rbn_single_get_header(rbn_single);
162 double cd1_1 = moo_pfits_get_cd1_1(header);
163 double crpix1 = moo_pfits_get_crpix1(header);
164 double crval1 = moo_pfits_get_crval1(header);
165
166 moo_try_assure(tnx == nx, CPL_ERROR_ILLEGAL_INPUT,
167 "Telluric correction file must have the rebin "
168 "size than RBN");
169
170 for (int f = 0; f < nfibres; f++) {
171 int idrbn = idrbnt[f];
172 double trans = transt[f];
173 int spectro = spectrot[f];
174
175 if (!isnan(trans) && trans > 0 && idrbn > 0) {
176 int tell_index =
177 moo_telluric_get_index(tell, idrbn, spectro, band);
178 if (tell_index > 0) {
179 cpl_table *mdata =
180 _molecfit_data_create(crpix1, crval1, cd1_1, img,
181 err, idrbn, tell_img,
182 tell_index);
183
184 mf_calctrans_correct_spectrum(
185 mdata, MF_PARAMETERS_TRANSMISSION_TRUE);
186#if MOO_DEBUG_CORRECT_TELL
187 {
188 char *name = cpl_sprintf("test_%d.fits", idrbn);
189 cpl_table_save(mdata, NULL, NULL, name,
190 CPL_IO_CREATE);
191 cpl_free(name);
192 }
193#endif
194
195 for (int x = 0; x < nx; x++) {
196 double flux_v =
197 cpl_table_get_double(mdata,
198 MOO_CORRECT_TELL_CFLUX, x,
199 NULL);
200 double err_v =
201 cpl_table_get_double(mdata,
202 MOO_CORRECT_TELL_CDFLUX, x,
203 NULL);
204 cpl_image_set(img, x + 1, idrbn, flux_v);
205 cpl_image_set(err, x + 1, idrbn, err_v);
206 }
207
208 cpl_table_delete(mdata);
209 }
210 else {
211 cpl_msg_warning(
212 __func__,
213 "No telluric reference for band %s indexrbn %d",
214 rbn_single->extname, idrbn);
215 }
216 }
217 }
218 }
219 }
220
221moo_try_cleanup:
222 if (!cpl_errorstate_is_equal(prestate)) {
223 cpl_msg_error(__func__, "Error in correct telluric");
224 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
225 }
226 return CPL_ERROR_NONE;
227}
228
229/*----------------------------------------------------------------------------*/
244/*----------------------------------------------------------------------------*/
245cpl_error_code
246moo_correct_tell_science(moo_sci *sci, moo_telluric *tell)
247{
248 cpl_ensure_code(sci != NULL, CPL_ERROR_NULL_INPUT);
249 cpl_ensure_code(tell != NULL, CPL_ERROR_NULL_INPUT);
250
251 cpl_errorstate prestate = cpl_errorstate_get();
252 cpl_msg_info(__func__, "Correct telluric");
253
254 int badpix_level = MOO_BADPIX_OUTSIDE_DATA_RANGE;
255 moo_target_table *target_table = moo_sci_get_target_table(sci);
256
257 int nbtarget = cpl_table_get_nrow(target_table->table);
258
259 int *idrbnt =
260 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_INDEXRBN);
261 int *idtargt =
262 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_INDEXTARG);
263 const int *spectrot =
264 cpl_table_get_data_int_const(target_table->table,
265 MOO_TARGET_TABLE_SPECTRO);
266 const char *trans_colnames[] = { MOO_TARGET_TABLE_TRANSRI,
267 MOO_TARGET_TABLE_TRANSYJ,
268 MOO_TARGET_TABLE_TRANSH };
269
270 for (int i = 0; i < 3; i++) {
271 moo_sci_single *sci_single = moo_sci_load_single(sci, i, badpix_level);
272
273 if (sci_single != NULL) {
274 const char *trans_colname = trans_colnames[i];
275 const char *band = moo_telluric_get_band(i);
276 float *transt =
277 cpl_table_get_data_float(target_table->table, trans_colname);
278 cpl_image *tell_img = moo_telluric_get_image(tell, i);
279
280 cpl_propertylist *header = moo_sci_single_get_header(sci_single);
281 double cd1_1 = moo_pfits_get_cd1_1(header);
282 double crpix1 = moo_pfits_get_crpix1(header);
283 double crval1 = moo_pfits_get_crval1(header);
284 hdrl_image *himg = moo_sci_single_get_image(sci_single);
285
286 cpl_image *img = hdrl_image_get_image(himg);
287 cpl_image *err = hdrl_image_get_error(himg);
288 int nx = cpl_image_get_size_x(img);
289
290 for (int f = 0; f < nbtarget; f++) {
291 int idrbn = idrbnt[f];
292 int idtarg = idtargt[f];
293 double trans = transt[f];
294 int spectro = spectrot[f];
295
296 if (!isnan(trans) && trans > 0) {
297 int tell_index =
298 moo_telluric_get_index(tell, idrbn, spectro, band);
299 if (tell_index > 0) {
300 cpl_table *mdata =
301 _molecfit_data_create(crpix1, crval1, cd1_1, img,
302 err, idtarg, tell_img,
303 tell_index);
304
305 mf_calctrans_correct_spectrum(
306 mdata, MF_PARAMETERS_TRANSMISSION_TRUE);
307#if MOO_DEBUG_CORRECT_TELL
308 {
309 char *name = cpl_sprintf("test_%d.fits", idrbn);
310 cpl_table_save(mdata, NULL, NULL, name,
311 CPL_IO_CREATE);
312 cpl_free(name);
313 }
314#endif
315
316 for (int x = 0; x < nx; x++) {
317 double flux_v =
318 cpl_table_get_double(mdata,
319 MOO_CORRECT_TELL_CFLUX, x,
320 NULL);
321 double err_v =
322 cpl_table_get_double(mdata,
323 MOO_CORRECT_TELL_CDFLUX, x,
324 NULL);
325 cpl_image_set(img, x + 1, idtarg, flux_v);
326 cpl_image_set(err, x + 1, idtarg, err_v);
327 }
328
329 cpl_table_delete(mdata);
330 }
331 else {
332 cpl_msg_info(__func__,
333 "no telluric correction for %s idrbn %d",
334 band, idrbn);
335 }
336 }
337 }
338 }
339 }
340
341 if (!cpl_errorstate_is_equal(prestate)) {
342 cpl_msg_error(__func__, "Error in correct telluric");
343 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
344 }
345 return CPL_ERROR_NONE;
346}
#define MOO_BADPIX_OUTSIDE_DATA_RANGE
Definition: moo_badpix.h:62
hdrl_image * moo_rbn_single_get_image(moo_rbn_single *self)
Get image of RBN_SINGLE.
cpl_propertylist * moo_rbn_single_get_header(moo_rbn_single *self)
Get header of rbn single.
moo_rbn_single * moo_rbn_load_single(moo_rbn *self, moo_detector_type type, unsigned int level)
Load the type part in RBN and return it.
Definition: moo_rbn.c:360
cpl_propertylist * moo_rbn_get_primary_header(moo_rbn *self)
Get the PRIMARY HEADER in RBN.
Definition: moo_rbn.c:512
cpl_table * moo_rbn_get_fibre_table(moo_rbn *self)
Get the FIBRE TABLE in RBN.
Definition: moo_rbn.c:397
hdrl_image * moo_sci_single_get_image(moo_sci_single *self)
Get image of SCI_SINGLE.
cpl_propertylist * moo_sci_single_get_header(moo_sci_single *self)
Get header of sci single.
moo_sci_single * moo_sci_load_single(moo_sci *self, moo_detector_type type, int level)
Load the type part in SCI and return it.
Definition: moo_sci.c:323
moo_target_table * moo_sci_get_target_table(moo_sci *self)
Get the target table of SCI file.
Definition: moo_sci.c:284
int moo_telluric_get_index(moo_telluric *self, int idrbn, int fspectro, const char *fband)
Get the index of the telluric for a given indexrbn.
Definition: moo_telluric.c:463
const char * moo_telluric_get_band(moo_detector_type type)
Get the band of the telluric
Definition: moo_telluric.c:511
cpl_image * moo_telluric_get_image(moo_telluric *self, moo_detector_type type)
Get a telluric image from TELLURIC.
Definition: moo_telluric.c:116
cpl_error_code moo_correct_tell(moo_rbn *rbn, moo_telluric *tell)
Apply the telluric correction to 1D rebinned spectra.
cpl_error_code moo_correct_tell_science(moo_sci *sci, moo_telluric *tell)
Apply the telluric correction to SCI.
double moo_pfits_get_cd1_1(const cpl_propertylist *plist)
find out the CD1_1 value
Definition: moo_pfits.c:1256
double moo_pfits_get_crval1(const cpl_propertylist *plist)
find out the CRVAL1 value
Definition: moo_pfits.c:1176
double moo_pfits_get_crpix1(const cpl_propertylist *plist)
find out the CRPIX1 value
Definition: moo_pfits.c:1196
cpl_error_code moo_qc_set_is_tellcor(cpl_propertylist *plist, cpl_boolean val)
Set the QC.IS.TELLCOR value.
Definition: moo_qc.c:2451
the different type of detectors