MOONS Pipeline Reference Manual 0.13.1
moo_molecfit.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 <telluriccorr.h>
31
32#include "moo_molecfit.h"
33#include "moo_pfits.h"
34#include "moo_badpix.h"
35#include "moo_utils.h"
36#include "moo_molectable.h"
37#include "moo_fibres_table.h"
38#include "mf_model.h"
39#include "moo_kernel.h"
40/*----------------------------------------------------------------------------*/
45/*----------------------------------------------------------------------------*/
46
49/*-----------------------------------------------------------------------------
50 Function codes
51 -----------------------------------------------------------------------------*/
52
53static cpl_table *
54_molecfit_data_create(double crpix1,
55 double crval1,
56 double cd1_1,
57 cpl_image *data,
58 cpl_image *data_err,
59 int idrbn)
60{
61 cpl_table *result = NULL;
62 int nx = cpl_image_get_size_x(data);
63
64 result = cpl_table_new(nx);
65 cpl_table_new_column(result, "WAVE", CPL_TYPE_DOUBLE);
66 cpl_table_new_column(result, "FLUX", CPL_TYPE_DOUBLE);
67 cpl_table_new_column(result, "ERR", CPL_TYPE_DOUBLE);
68 cpl_table_new_column(result, "mask", CPL_TYPE_INT);
69
70 for (int i = 0; i < nx; i++) {
71 int rej1;
72 double w = (i - crpix1) * cd1_1 + crval1;
73 double f = cpl_image_get(data, i + 1, idrbn, &rej1);
74 double e = cpl_image_get(data_err, i + 1, idrbn, &rej1);
75 cpl_table_set_double(result, "WAVE", i, w);
76 cpl_table_set_double(result, "FLUX", i, f);
77 cpl_table_set_double(result, "ERR", i, e);
78 cpl_table_set_int(result, "mask", i, rej1);
79 }
80 return result;
81}
82
83static cpl_error_code
84_moo_molecfit_update_mf_conf(mf_configuration *config,
85 moo_molecfit_model_params *params)
86{
87 mf_parameters_inputs *inputs = &(config->parameters->inputs);
88 inputs->wlg_to_micron = 0.001;
89 cpl_free(inputs->column_dflux);
90 cpl_free(inputs->column_lambda);
91 cpl_free(inputs->column_flux);
92 cpl_free(inputs->wavelengths_frame);
93 inputs->column_dflux = cpl_strdup("ERR");
94 inputs->column_lambda = cpl_strdup("WAVE");
95 inputs->column_flux = cpl_strdup("FLUX");
96 inputs->wavelengths_frame = cpl_strdup("AIR");
97 inputs->transmission = CPL_TRUE;
98 inputs->clean_flux = CPL_FALSE;
99 inputs->silent_external_bins = CPL_TRUE;
100
101 /*config->parameters->directories.telluric_path="/home/haigron/pipelines";
102 config->parameters->directories.telluriccorr_data_path="/home/haigron/pipelines/share/molecfit/data/";
103 */
104 mf_parameters_fitting *fitting = &(config->parameters->fitting);
105 fitting->ftol = 1E-10;
106 fitting->xtol = 1E-10;
107 fitting->flux_unit = 0;
108 fitting->fit_telescope_background.fit = CPL_TRUE;
109 fitting->fit_telescope_background.const_val = 0.1;
110 fitting->fit_continuum.fit = CPL_TRUE;
111 if (params) {
112 fitting->fit_continuum.const_val = params->continuum_const;
113 fitting->kern_mode = params->kern_mode;
114 fitting->kern_fac = params->kern_fac;
115 fitting->var_kern = params->var_kern;
116 }
117 else {
118 fitting->fit_continuum.const_val = 1.;
119 fitting->kern_mode = CPL_FALSE;
120 fitting->kern_fac = 3;
121 fitting->var_kern = CPL_TRUE;
122 }
123 fitting->fit_wavelenght.fit = CPL_TRUE;
124 fitting->fit_wavelenght.n = 1;
125 fitting->fit_wavelenght.const_val = 0.0;
126 fitting->fit_gauss.fit = CPL_TRUE;
127 fitting->fit_gauss.const_val = 1.0;
128
129 fitting->fit_res_box.fit = CPL_FALSE;
130 fitting->fit_res_box.const_val = 0;
131 fitting->fit_lorentz.fit = CPL_FALSE;
132 fitting->fit_lorentz.const_val = 0;
133
134 fitting->fit_chips[0] = CPL_TRUE;
135
136 mf_parameters_instrumental *instrumental =
137 &(config->parameters->instrumental);
138 cpl_free(instrumental->slit_width.key);
139 cpl_free(instrumental->pixel_scale.key);
140 instrumental->slit_width.key = cpl_strdup("NONE");
141 instrumental->slit_width.value = 1.0;
142 instrumental->pixel_scale.key = cpl_strdup("NONE");
143 instrumental->pixel_scale.value = 0.015;
144
145 mf_parameters_atmospheric *atmospheric = &(config->parameters->atmospheric);
146 cpl_free(atmospheric->ref_atm);
147 atmospheric->ref_atm = cpl_strdup("equ.fits");
148 atmospheric->layers = CPL_TRUE;
149 atmospheric->emix = 5.;
150 atmospheric->pwv = -1;
151
152 mf_io_lnfl_config *lnfl = config->lnfl;
153 cpl_free(lnfl->line_db);
154 lnfl->line_db = cpl_strdup("aer_v_3.8.1.2");
155 lnfl->line_db_fmt = 100.0;
156
157 mf_io_lblrtm_config *lblrtm = config->lblrtm;
158 lblrtm->alfal0 = 0.0;
159 lblrtm->altd[0] = 0;
160 lblrtm->altd[1] = 0;
161 lblrtm->icntnm = 5;
162 lblrtm->avmass = 0;
163 lblrtm->avtrat = 2.;
164 lblrtm->beta = 0;
165 lblrtm->delv = 1.;
166 lblrtm->dptfac = 0.001;
167 lblrtm->dptmin = 2e-4;
168 lblrtm->h[0] = 2.635;
169 lblrtm->h[1] = 0.;
170 lblrtm->hobs = 0.;
171 lblrtm->hspace = 120.;
172 lblrtm->iaersl = 0.;
173 lblrtm->ipunch = 0;
174 lblrtm->itype = 3;
175 lblrtm->len = 0;
176 lblrtm->model = 0;
177 lblrtm->mpts = 5;
178 lblrtm->noprnt = 0;
179 lblrtm->nozero = 0;
180 lblrtm->npts = 5;
181 lblrtm->range = 0.;
182 lblrtm->re = 0.;
183 lblrtm->sample = 4;
184 lblrtm->sremis[0] = 0.;
185 lblrtm->sremis[1] = 0.;
186 lblrtm->sremis[2] = 0.;
187 lblrtm->srrefl[0] = 0.;
188 lblrtm->srrefl[1] = 0.;
189 lblrtm->srrefl[2] = 0.;
190 lblrtm->tbound = 0.;
191 lblrtm->tdiff[0] = 5.;
192 lblrtm->tdiff[1] = 8.;
193 lblrtm->v[0] = 1.9;
194 lblrtm->v[1] = 2.4;
195
196 return CPL_ERROR_NONE;
197}
198
199static cpl_error_code
200_moo_molecfit_update_mf_conf_with_propertylist(
201 mf_configuration *config,
202 cpl_propertylist *parameters_header)
203{
204 cpl_ensure_code(config != NULL, CPL_ERROR_NULL_INPUT);
205 cpl_ensure_code(parameters_header != NULL, CPL_ERROR_NULL_INPUT);
206
207 // mf_parameters_inputs *inputs = &(config->parameters->inputs);
208 // mf_parameters_fitting *fitting = &(config->parameters->fitting);
209 // mf_parameters_ambient *ambient = &(config->parameters->ambient);
210 // mf_parameters_instrumental *instrumental =
211 // &(config->parameters->instrumental);
212 // mf_parameters_atmospheric *atmospheric = &(config->parameters->atmospheric);
213
214 /*** Set Molecfit configuration with recipe parameters ***/
215
216#if 0
217 /*** Directories ***/
218 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TELLURICCORR_PATH;
219 if (cpl_propertylist_has(parameters_header, p)) {
220 if (directories->telluric_path) cpl_free(directories->telluric_path);
221 directories->telluric_path = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
222 cpl_propertylist_update_string(pl, p, directories->telluric_path);
223 }
224
225 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TELLURICCORR_DATA_PATH;
226 if (cpl_propertylist_has(parameters_header, p)) {
227 if (directories->telluriccorr_data_path) cpl_free(directories->telluriccorr_data_path);
228 directories->telluriccorr_data_path = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
229 cpl_propertylist_update_string(pl, p, directories->telluriccorr_data_path);
230 }
231
232 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TMP_PATH;
233 if (cpl_propertylist_has(parameters_header, p)) {
234 if (directories->tmp_path) cpl_free(directories->tmp_path);
235 directories->tmp_path = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
236 cpl_propertylist_update_string(pl, p, directories->tmp_path);
237 }
238
239 /*p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OUTPUT_PATH;
240 if (cpl_propertylist_has(parameters_header, p)) {
241 if (directories->output_path) cpl_free(directories->output_path);
242 directories->output_path = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
243 cpl_propertylist_update_string(pl, p, directories->output_path);
244 }*/
245
246 /*p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OUTPUT_NAME;
247 if (cpl_propertylist_has(parameters_header, p)) {
248 if (directories->output_name) cpl_free(directories->output_name);
249 directories->output_name = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
250 cpl_propertylist_update_string(pl, p, directories->output_name);
251 }*/
252#endif
253#if 0
254 /*** Input parameters ***/
255 /*p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OMP_NUM_THREADS;
256 if (cpl_propertylist_has(parameters_header, p)) {
257 inputs->omp_num_threads = cpl_propertylist_get_int(parameters_header, p);
258 cpl_propertylist_update_int(pl, p, inputs->omp_num_threads);
259 }*/
260
261 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_SILENT_EXTERNAL_BINS;
262 if (cpl_propertylist_has(parameters_header, p)) {
263 inputs->silent_external_bins = cpl_propertylist_get_bool(parameters_header, p);
264 cpl_propertylist_update_bool(pl, p, inputs->silent_external_bins);
265 }
266
267 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TRANSMISSION;
268 if (cpl_propertylist_has(parameters_header, p)) {
269 inputs->transmission = cpl_propertylist_get_bool(parameters_header, p);
270 cpl_propertylist_update_bool(pl, p, inputs->transmission);
271 }
272
273 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_COLUMN_LAMBDA;
274 if (cpl_propertylist_has(parameters_header, p)) {
275 if (inputs->column_lambda) cpl_free(inputs->column_lambda);
276 inputs->column_lambda = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
277 cpl_propertylist_update_string(pl, p, inputs->column_lambda);
278 }
279
280 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_COLUMN_FLUX;
281 if (cpl_propertylist_has(parameters_header, p)) {
282 if (inputs->column_flux) cpl_free(inputs->column_flux);
283 inputs->column_flux = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
284 cpl_propertylist_update_string(pl, p, inputs->column_flux);
285 }
286
287 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_COLUMN_DFLUX;
288 if (cpl_propertylist_has(parameters_header, p)) {
289 if (inputs->column_dflux) cpl_free(inputs->column_dflux);
290 inputs->column_dflux = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
291 cpl_propertylist_update_string(pl, p, inputs->column_dflux);
292 }
293
294 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_COLUMN_MASK;
295 if (cpl_propertylist_has(parameters_header, p)) {
296 if (inputs->column_mask) cpl_free(inputs->column_mask);
297 inputs->column_mask = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
298 cpl_propertylist_update_string(pl, p, inputs->column_mask);
299 }
300
301
302 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_DEFAULT_ERROR;
303 if (cpl_propertylist_has(parameters_header, p)) {
304 inputs->default_error = cpl_propertylist_get_double(parameters_header, p);
305 cpl_propertylist_update_double(pl, p, inputs->default_error);
306 }
307
308 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_WLG_TO_MICRON;
309 if (cpl_propertylist_has(parameters_header, p)) {
310 inputs->wlg_to_micron = cpl_propertylist_get_double(parameters_header, p);
311 cpl_propertylist_update_double(pl, p, inputs->wlg_to_micron);
312 }
313
314 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_WAVELENGTH_FRAME;
315 if (cpl_propertylist_has(parameters_header, p)) {
316 if (inputs->wavelengths_frame) cpl_free(inputs->wavelengths_frame);
317 inputs->wavelengths_frame = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
318 cpl_propertylist_update_string(pl, p, inputs->wavelengths_frame);
319 }
320
321 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OBSERVATORY_ERF_RV_KEYWORD;
322 if (cpl_propertylist_has(parameters_header, p)) {
323 if (inputs->observing_erv_rv.key) cpl_free(inputs->observing_erv_rv.key);
324 inputs->observing_erv_rv.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
325 cpl_propertylist_update_string(pl, p, inputs->observing_erv_rv.key);
326 }
327 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OBSERVATORY_ERF_RV_VALUE;
328 if (cpl_propertylist_has(parameters_header, p)) {
329 inputs->observing_erv_rv.value = cpl_propertylist_get_double(parameters_header, p);
330 cpl_propertylist_update_double(pl, p, inputs->observing_erv_rv.value);
331 }
332
333 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_CLEAN_MODEL_FLUX;
334 if (cpl_propertylist_has(parameters_header, p)) {
335 inputs->clean_flux = cpl_propertylist_get_bool(parameters_header, p);
336 cpl_propertylist_update_bool(pl, p, inputs->clean_flux);
337 }
338
339
340
341 /*** Convergence criterion ***/
342 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FTOL;
343 if (cpl_propertylist_has(parameters_header, p)) {
344 fitting->ftol = cpl_propertylist_get_double(parameters_header, p);
345 cpl_propertylist_update_double(pl, p, fitting->ftol);
346 }
347
348 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_XTOL;
349 if (cpl_propertylist_has(parameters_header, p)) {
350 fitting->xtol = cpl_propertylist_get_double(parameters_header, p);
351 cpl_propertylist_update_double(pl, p, fitting->xtol);
352 }
353
354 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FLUX_UNIT;
355 if (cpl_propertylist_has(parameters_header, p)) {
356 fitting->flux_unit = cpl_propertylist_get_int(parameters_header, p);
357 cpl_propertylist_update_int(pl, p, fitting->flux_unit);
358 }
359
360
361 /*** Telescope background ***/
362 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FIT_TELESCOPE_BACK;
363 if (cpl_propertylist_has(parameters_header, p)) {
364 fitting->fit_telescope_background.fit = cpl_propertylist_get_bool(parameters_header, p);
365 cpl_propertylist_update_bool(pl, p, fitting->fit_telescope_background.fit);
366 }
367
368 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TELESCOPE_BACK_CONST;
369 if (cpl_propertylist_has(parameters_header, p)) {
370 fitting->fit_telescope_background.const_val = cpl_propertylist_get_double(parameters_header, p);
371 cpl_propertylist_update_int(pl, p, fitting->fit_telescope_background.const_val);
372 }
373
374
375 /*** Continuum ***/
376 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FIT_CONTINUUM;
377 if (cpl_propertylist_has(parameters_header, p)) {
378 fitting->fit_continuum.fit = cpl_propertylist_get_bool(parameters_header, p);
379 cpl_propertylist_update_bool(pl, p, fitting->fit_continuum.fit);
380 }
381
382 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_CONTINUUM_N;
383 if (cpl_propertylist_has(parameters_header, p)) {
384 fitting->fit_continuum.n = cpl_propertylist_get_int(parameters_header, p);
385 cpl_propertylist_update_int(pl, p, fitting->fit_continuum.n);
386 }
387
388 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_CONTINUUM_CONST;
389 if (cpl_propertylist_has(parameters_header, p)) {
390 fitting->fit_continuum.const_val = cpl_propertylist_get_double(parameters_header, p);
391 cpl_propertylist_update_double(pl, p, fitting->fit_continuum.const_val);
392 }
393
394 /*p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OBSERVATORY_BARY_RV;
395 if (cpl_propertylist_has(parameters_header, p)) {
396 fitting->obs_bary_rv = cpl_propertylist_get_double(parameters_header, p);
397 cpl_propertylist_update_double(pl, p, fitting->obs_bary_rv);
398 }
399 */
400
401
402 /*** Wavelength solution fit/adjustment ***/
403 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FIT_WLC;
404 if (cpl_propertylist_has(parameters_header, p)) {
405 fitting->fit_wavelenght.fit = cpl_propertylist_get_bool(parameters_header, p);
406 cpl_propertylist_update_bool(pl, p, fitting->fit_wavelenght.fit);
407 }
408
409 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_WLC_N;
410 if (cpl_propertylist_has(parameters_header, p)) {
411 fitting->fit_wavelenght.n = cpl_propertylist_get_int(parameters_header, p);
412 cpl_propertylist_update_int(pl, p, fitting->fit_wavelenght.n);
413 }
414
415 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_WLC_CONST;
416 if (cpl_propertylist_has(parameters_header, p)) {
417 fitting->fit_wavelenght.const_val = cpl_propertylist_get_double(parameters_header, p);
418 cpl_propertylist_update_double(pl, p, fitting->fit_wavelenght.const_val);
419 }
420
421 /* p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_WLC_REF;
422 if (cpl_propertylist_has(parameters_header, p)) {
423 if (fitting->wlc_ref) cpl_free(fitting->wlc_ref);
424 fitting->wlc_ref = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
425 cpl_propertylist_update_string(pl, p, fitting->wlc_ref);
426 } */
427
428
429 /*** Default kernel: Boxcar kernel ***/
430 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FIT_RES_BOX;
431 if (cpl_propertylist_has(parameters_header, p)) {
432 fitting->fit_res_box.fit = cpl_propertylist_get_bool(parameters_header, p);
433 cpl_propertylist_update_bool(pl, p, fitting->fit_res_box.fit);
434 }
435
436 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_RES_BOX;
437 if (cpl_propertylist_has(parameters_header, p)) {
438 fitting->fit_res_box.const_val = cpl_propertylist_get_double(parameters_header, p);
439 cpl_propertylist_update_double(pl, p, fitting->fit_res_box.const_val);
440 }
441
442
443 /*** Default kernel: Gaussian kernel ***/
444 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FIT_GAUSS;
445 if (cpl_propertylist_has(parameters_header, p)) {
446 fitting->fit_gauss.fit = cpl_propertylist_get_bool(parameters_header, p);
447 cpl_propertylist_update_bool(pl, p, fitting->fit_gauss.fit);
448 }
449
450 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_RES_GAUSS;
451 if (cpl_propertylist_has(parameters_header, p)) {
452 fitting->fit_gauss.const_val = cpl_propertylist_get_double(parameters_header, p);
453 cpl_propertylist_update_double(pl, p, fitting->fit_gauss.const_val);
454 }
455
456
457 /*** Default kernel: Lorentz kernel ***/
458 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_FIT_LORENTZ;
459 if (cpl_propertylist_has(parameters_header, p)) {
460 fitting->fit_lorentz.fit = cpl_propertylist_get_bool(parameters_header, p);
461 cpl_propertylist_update_bool(pl, p, fitting->fit_lorentz.fit);
462 }
463
464 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_RES_LORENTZ;
465 if (cpl_propertylist_has(parameters_header, p)) {
466 fitting->fit_lorentz.const_val = cpl_propertylist_get_double(parameters_header, p);
467 cpl_propertylist_update_double(pl, p, fitting->fit_lorentz.const_val);
468 }
469
470
471 /*** Default kernels: Generic parameters ***/
472 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_KERN_MODE;
473 if (cpl_propertylist_has(parameters_header, p)) {
474 fitting->kern_mode = cpl_propertylist_get_bool(parameters_header, p);
475 cpl_propertylist_update_bool(pl, p, fitting->kern_mode);
476 }
477
478 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_KERN_FAC;
479 if (cpl_propertylist_has(parameters_header, p)) {
480 fitting->kern_fac = cpl_propertylist_get_double(parameters_header, p);
481 cpl_propertylist_update_double(pl, p, fitting->kern_fac);
482 }
483
484 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_VAR_KERN;
485 if (cpl_propertylist_has(parameters_header, p)) {
486 fitting->var_kern = cpl_propertylist_get_bool(parameters_header, p);
487 cpl_propertylist_update_bool(pl, p, fitting->var_kern);
488 }
489
490
491 /*** Ambient ***/
492 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OBSERVING_DATE_KEYWORD;
493 if (cpl_propertylist_has(parameters_header, p)) {
494 if (ambient->observing_date.key) cpl_free(ambient->observing_date.key);
495 ambient->observing_date.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
496 cpl_propertylist_update_string(pl, p, ambient->observing_date.key);
497 }
498 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_OBSERVING_DATE_VALUE;
499 if (cpl_propertylist_has(parameters_header, p)) {
500 ambient->observing_date.value = cpl_propertylist_get_double(parameters_header, p);
501 cpl_propertylist_update_double(pl, p, ambient->observing_date.value);
502 }
503
504 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_UTC_KEYWORD;
505 if (cpl_propertylist_has(parameters_header, p)) {
506 if (ambient->utc.key) cpl_free(ambient->utc.key);
507 ambient->utc.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
508 cpl_propertylist_update_string(pl, p, ambient->utc.key);
509 }
510 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_UTC_VALUE;
511 if (cpl_propertylist_has(parameters_header, p)) {
512 ambient->utc.value = cpl_propertylist_get_double(parameters_header, p);
513 cpl_propertylist_update_double(pl, p, ambient->utc.value);
514 }
515
516 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TELESCOPE_ANGLE_KEYWORD;
517 if (cpl_propertylist_has(parameters_header, p)) {
518 if (ambient->telescope_angle.key) cpl_free(ambient->telescope_angle.key);
519 ambient->telescope_angle.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
520 cpl_propertylist_update_string(pl, p, ambient->telescope_angle.key);
521 }
522 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TELESCOPE_ANGLE_VALUE;
523 if (cpl_propertylist_has(parameters_header, p)) {
524 ambient->telescope_angle.value = cpl_propertylist_get_double(parameters_header, p);
525 cpl_propertylist_update_double(pl, p, ambient->telescope_angle.value);
526 }
527
528 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_RELATIVE_HUMIDITY_KEYWORD;
529 if (cpl_propertylist_has(parameters_header, p)) {
530 if (ambient->relative_humidity.key) cpl_free(ambient->relative_humidity.key);
531 ambient->relative_humidity.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
532 cpl_propertylist_update_string(pl, p, ambient->relative_humidity.key);
533 }
534 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_RELATIVE_HUMIDITY_VALUE;
535 if (cpl_propertylist_has(parameters_header, p)) {
536 ambient->relative_humidity.value = cpl_propertylist_get_double(parameters_header, p);
537 cpl_propertylist_update_double(pl, p, ambient->relative_humidity.value);
538 }
539
540 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_PRESSURE_KEYWORD;
541 if (cpl_propertylist_has(parameters_header, p)) {
542 if (ambient->pressure.key) cpl_free(ambient->pressure.key);
543 ambient->pressure.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
544 cpl_propertylist_update_string(pl, p, ambient->pressure.key);
545 }
546 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_PRESSURE_VALUE;
547 if (cpl_propertylist_has(parameters_header, p)) {
548 ambient->pressure.value = cpl_propertylist_get_double(parameters_header, p);
549 cpl_propertylist_update_double(pl, p, ambient->pressure.value);
550 }
551
552 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TEMPERATURE_KEYWORD;
553 if (cpl_propertylist_has(parameters_header, p)) {
554 if (ambient->temperature.key) cpl_free(ambient->temperature.key);
555 ambient->temperature.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
556 cpl_propertylist_update_string(pl, p, ambient->temperature.key);
557 }
558 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TEMPERATURE_VALUE;
559 if (cpl_propertylist_has(parameters_header, p)) {
560 ambient->temperature.value = cpl_propertylist_get_double(parameters_header, p);
561 cpl_propertylist_update_double(pl, p, ambient->temperature.value);
562 }
563
564 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_MIRROR_TEMPERATURE_KEYWORD;
565 if (cpl_propertylist_has(parameters_header, p)) {
566 if (ambient->mirror_temperature.key) cpl_free(ambient->mirror_temperature.key);
567 ambient->mirror_temperature.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
568 cpl_propertylist_update_string(pl, p, ambient->mirror_temperature.key);
569 }
570 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_MIRROR_TEMPERATURE_VALUE;
571 if (cpl_propertylist_has(parameters_header, p)) {
572 ambient->mirror_temperature.value = cpl_propertylist_get_double(parameters_header, p);
573 cpl_propertylist_update_double(pl, p, ambient->mirror_temperature.value);
574 }
575
576 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_ELEVATION_KEYWORD;
577 if (cpl_propertylist_has(parameters_header, p)) {
578 if (ambient->elevation.key) cpl_free(ambient->elevation.key);
579 ambient->elevation.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
580 cpl_propertylist_update_string(pl, p, ambient->elevation.key);
581 }
582 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_ELEVATION_VALUE;
583 if (cpl_propertylist_has(parameters_header, p)) {
584 ambient->elevation.value = cpl_propertylist_get_double(parameters_header, p);
585 cpl_propertylist_update_double(pl, p, ambient->elevation.value);
586 }
587
588 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_LONGITUDE_KEYWORD;
589 if (cpl_propertylist_has(parameters_header, p)) {
590 if (ambient->longitude.key) cpl_free(ambient->longitude.key);
591 ambient->longitude.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
592 cpl_propertylist_update_string(pl, p, ambient->longitude.key);
593 }
594 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_LONGITUDE_VALUE;
595 if (cpl_propertylist_has(parameters_header, p)) {
596 ambient->longitude.value = cpl_propertylist_get_double(parameters_header, p);
597 cpl_propertylist_update_double(pl, p, ambient->longitude.value);
598 }
599
600 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_LATITUDE_KEYWORD;
601 if (cpl_propertylist_has(parameters_header, p)) {
602 if (ambient->latitude.key) cpl_free(ambient->latitude.key);
603 ambient->latitude.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
604 cpl_propertylist_update_string(pl, p, ambient->latitude.key);
605 }
606 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_LATITUDE_VALUE;
607 if (cpl_propertylist_has(parameters_header, p)) {
608 ambient->latitude.value = cpl_propertylist_get_double(parameters_header, p);
609 cpl_propertylist_update_double(pl, p, ambient->latitude.value);
610 }
611
612
613 /*** Instrumental ***/
614 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_SLIT_WIDTH_KEYWORD;
615 if (cpl_propertylist_has(parameters_header, p)) {
616 if (instrumental->slit_width.key) cpl_free(instrumental->slit_width.key);
617 instrumental->slit_width.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
618 cpl_propertylist_update_string(pl, p, instrumental->slit_width.key);
619 }
620 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_SLIT_WIDTH_VALUE;
621 if (cpl_propertylist_has(parameters_header, p)) {
622 instrumental->slit_width.value = cpl_propertylist_get_double(parameters_header, p);
623 cpl_propertylist_update_double(pl, p, instrumental->slit_width.value);
624 }
625
626 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_PIXEL_SCALE_KEYWORD;
627 if (cpl_propertylist_has(parameters_header, p)) {
628 if (instrumental->pixel_scale.key) cpl_free(instrumental->pixel_scale.key);
629 instrumental->pixel_scale.key = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
630 cpl_propertylist_update_string(pl, p, instrumental->pixel_scale.key);
631 }
632 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_PIXEL_SCALE_VALUE;
633 if (cpl_propertylist_has(parameters_header, p)) {
634 instrumental->pixel_scale.value = cpl_propertylist_get_double(parameters_header, p);
635 cpl_propertylist_update_double(pl, p, instrumental->pixel_scale.value);
636 }
637
638
639 /*** Atmospheric ***/
640 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_REFERENCE_ATMOSPHERIC;
641 if (cpl_propertylist_has(parameters_header, p)) {
642 if (atmospheric->ref_atm) cpl_free(atmospheric->ref_atm);
643 atmospheric->ref_atm = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
644 cpl_propertylist_update_string(pl, p, atmospheric->ref_atm);
645 }
646
647 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_GDAS_PROFILE;
648 if (cpl_propertylist_has(parameters_header, p)) {
649 if (atmospheric->gdas_prof) cpl_free(atmospheric->gdas_prof);
650 atmospheric->gdas_prof = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
651 cpl_propertylist_update_string(pl, p, atmospheric->gdas_prof);
652 }
653
654 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_LAYERS;
655 if (cpl_propertylist_has(parameters_header, p)) {
656 atmospheric->layers = cpl_propertylist_get_bool(parameters_header, p);
657 cpl_propertylist_update_bool(pl, p, atmospheric->layers);
658 }
659
660 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_EMIX;
661 if (cpl_propertylist_has(parameters_header, p)) {
662 atmospheric->emix = cpl_propertylist_get_double(parameters_header, p);
663 cpl_propertylist_update_double(pl, p, atmospheric->emix);
664 }
665
666 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_PWV;
667 if (cpl_propertylist_has(parameters_header, p)) {
668 atmospheric->pwv = cpl_propertylist_get_double(parameters_header, p);
669 cpl_propertylist_update_double(pl, p, atmospheric->pwv);
670 }
671
672
673 /*** LNFL ***/
674 mf_io_lnfl_config *lnfl = mf_config->lnfl;
675
676 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LNFL_LINE_DB;
677 if (cpl_propertylist_has(parameters_header, p)) {
678 if (lnfl->line_db) cpl_free(lnfl->line_db);
679 lnfl->line_db = cpl_strdup(cpl_propertylist_get_string(parameters_header, p));
680 cpl_propertylist_update_string(pl, p, lnfl->line_db);
681 }
682
683 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LNFL_LINE_DB_FMT;
684 if (cpl_propertylist_has(parameters_header, p)) {
685 lnfl->line_db_fmt = cpl_propertylist_get_double(parameters_header, p);
686 cpl_propertylist_update_double(pl, p, lnfl->line_db_fmt);
687 }
688
689
690 /*** LBLRTM ***/
691 mf_io_lblrtm_config *lblrtm = mf_config->lblrtm;
692
693 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_ICNTNM;
694 if (cpl_propertylist_has(parameters_header, p)) {
695 lblrtm->icntnm = cpl_propertylist_get_int(parameters_header, p);
696 cpl_propertylist_update_int(pl, p, lblrtm->icntnm);
697 }
698
699 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_IAERSL;
700 if (cpl_propertylist_has(parameters_header, p)) {
701 lblrtm->iaersl = cpl_propertylist_get_int(parameters_header, p);
702 cpl_propertylist_update_int(pl, p, lblrtm->iaersl);
703 }
704
705 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_MPTS;
706 if (cpl_propertylist_has(parameters_header, p)) {
707 lblrtm->mpts = cpl_propertylist_get_int(parameters_header, p);
708 cpl_propertylist_update_int(pl, p, lblrtm->mpts);
709 }
710
711 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_NPTS;
712 if (cpl_propertylist_has(parameters_header, p)) {
713 lblrtm->npts = cpl_propertylist_get_int(parameters_header, p);
714 cpl_propertylist_update_int(pl, p, lblrtm->npts);
715 }
716
717 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_V1;
718 if (cpl_propertylist_has(parameters_header, p)) {
719 lblrtm->v[0] = cpl_propertylist_get_double(parameters_header, p);
720 cpl_propertylist_update_double(pl, p, lblrtm->v[0]);
721 }
722 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_V2;
723 if (cpl_propertylist_has(parameters_header, p)) {
724 lblrtm->v[1] = cpl_propertylist_get_double(parameters_header, p);
725 cpl_propertylist_update_double(pl, p, lblrtm->v[1]);
726 }
727
728 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_SAMPLE;
729 if (cpl_propertylist_has(parameters_header, p)) {
730 lblrtm->sample = cpl_propertylist_get_int(parameters_header, p);
731 cpl_propertylist_update_int(pl, p, lblrtm->sample);
732 }
733
734 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_ALFAL0;
735 if (cpl_propertylist_has(parameters_header, p)) {
736 lblrtm->alfal0 = cpl_propertylist_get_double(parameters_header, p);
737 cpl_propertylist_update_double(pl, p, lblrtm->alfal0);
738 }
739
740 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_AVMASS;
741 if (cpl_propertylist_has(parameters_header, p)) {
742 lblrtm->avmass = cpl_propertylist_get_double(parameters_header, p);
743 cpl_propertylist_update_double(pl, p, lblrtm->avmass);
744 }
745
746 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_DPTMIN;
747 if (cpl_propertylist_has(parameters_header, p)) {
748 lblrtm->dptmin = cpl_propertylist_get_double(parameters_header, p);
749 cpl_propertylist_update_double(pl, p, lblrtm->dptmin);
750 }
751
752 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_DPTFAC;
753 if (cpl_propertylist_has(parameters_header, p)) {
754 lblrtm->dptfac = cpl_propertylist_get_double(parameters_header, p);
755 cpl_propertylist_update_double(pl, p, lblrtm->dptfac);
756 }
757
758 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_TBOUND;
759 if (cpl_propertylist_has(parameters_header, p)) {
760 lblrtm->tbound = cpl_propertylist_get_double(parameters_header, p);
761 cpl_propertylist_update_double(pl, p, lblrtm->tbound);
762 }
763
764 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_SREMIS1;
765 if (cpl_propertylist_has(parameters_header, p)) {
766 lblrtm->sremis[0] = cpl_propertylist_get_double(parameters_header, p);
767 cpl_propertylist_update_double(pl, p, lblrtm->sremis[0]);
768 }
769 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_SREMIS2;
770 if (cpl_propertylist_has(parameters_header, p)) {
771 lblrtm->sremis[1] = cpl_propertylist_get_double(parameters_header, p);
772 cpl_propertylist_update_double(pl, p, lblrtm->sremis[1]);
773 }
774 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_SREMIS3;
775 if (cpl_propertylist_has(parameters_header, p)) {
776 lblrtm->sremis[2] = cpl_propertylist_get_double(parameters_header, p);
777 cpl_propertylist_update_double(pl, p, lblrtm->sremis[2]);
778 }
779
780 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_SRREFL1;
781 if (cpl_propertylist_has(parameters_header, p)) {
782 lblrtm->srrefl[0] = cpl_propertylist_get_double(parameters_header, p);
783 cpl_propertylist_update_double(pl, p, lblrtm->srrefl[0]);
784 }
785 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_SRREFL2;
786 if (cpl_propertylist_has(parameters_header, p)) {
787 lblrtm->srrefl[1] = cpl_propertylist_get_double(parameters_header, p);
788 cpl_propertylist_update_double(pl, p, lblrtm->srrefl[1]);
789 }
790 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_SRREFL3;
791 if (cpl_propertylist_has(parameters_header, p)) {
792 lblrtm->srrefl[2] = cpl_propertylist_get_double(parameters_header, p);
793 cpl_propertylist_update_double(pl, p, lblrtm->srrefl[2]);
794 }
795
796 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_MODEL;
797 if (cpl_propertylist_has(parameters_header, p)) {
798 lblrtm->model = cpl_propertylist_get_int(parameters_header, p);
799 cpl_propertylist_update_int(pl, p, lblrtm->model);
800 }
801
802 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_ITYPE;
803 if (cpl_propertylist_has(parameters_header, p)) {
804 lblrtm->itype = cpl_propertylist_get_int(parameters_header, p);
805 cpl_propertylist_update_int(pl, p, lblrtm->itype);
806 }
807
808 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_NOZERO;
809 if (cpl_propertylist_has(parameters_header, p)) {
810 lblrtm->nozero = cpl_propertylist_get_int(parameters_header, p);
811 cpl_propertylist_update_int(pl, p, lblrtm->nozero);
812 }
813
814 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_NOPRNT;
815 if (cpl_propertylist_has(parameters_header, p)) {
816 lblrtm->noprnt = cpl_propertylist_get_int(parameters_header, p);
817 cpl_propertylist_update_int(pl, p, lblrtm->noprnt);
818 }
819
820 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_IPUNCH;
821 if (cpl_propertylist_has(parameters_header, p)) {
822 lblrtm->ipunch = cpl_propertylist_get_int(parameters_header, p);
823 cpl_propertylist_update_int(pl, p, lblrtm->ipunch);
824 }
825
826 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_RE;
827 if (cpl_propertylist_has(parameters_header, p)) {
828 lblrtm->re = cpl_propertylist_get_double(parameters_header, p);
829 cpl_propertylist_update_double(pl, p, lblrtm->re);
830 }
831
832 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_HSPACE;
833 if (cpl_propertylist_has(parameters_header, p)) {
834 lblrtm->hspace = cpl_propertylist_get_double(parameters_header, p);
835 cpl_propertylist_update_double(pl, p, lblrtm->hspace);
836 }
837
838 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_LATITUDE_VALUE; // MF_LBLRTM_REF_LAT; // MF_PARAMETERS_LATITUDE_VALUE
839 if (cpl_propertylist_has(parameters_header, p)) {
840 lblrtm->ref_lat = cpl_propertylist_get_double(parameters_header, p);
841 cpl_propertylist_update_double(pl, p, lblrtm->ref_lat);
842 }
843
844 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_ELEVATION_VALUE; // MF_LBLRTM_H1;
845 if (cpl_propertylist_has(parameters_header, p)) {
846 lblrtm->h[0] = ambient->elevation.value /1000.00 ; // cpl_propertylist_get_double(parameters_header, p);
847 /*cpl_propertylist_update_double(pl, p, lblrtm->h[0]);*/
848 }
849 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_H2;
850 if (cpl_propertylist_has(parameters_header, p)) {
851 lblrtm->h[1] = cpl_propertylist_get_double(parameters_header, p);
852 cpl_propertylist_update_double(pl, p, lblrtm->h[1]);
853 }
854
855 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_RANGE;
856 if (cpl_propertylist_has(parameters_header, p)) {
857 lblrtm->range = cpl_propertylist_get_double(parameters_header, p);
858 cpl_propertylist_update_double(pl, p, lblrtm->range);
859 }
860
861 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_BETA;
862 if (cpl_propertylist_has(parameters_header, p)) {
863 lblrtm->beta = cpl_propertylist_get_double(parameters_header, p);
864 cpl_propertylist_update_double(pl, p, lblrtm->beta);
865 }
866
867 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_LEN;
868 if (cpl_propertylist_has(parameters_header, p)) {
869 lblrtm->len = cpl_propertylist_get_int(parameters_header, p);
870 cpl_propertylist_update_int(pl, p, lblrtm->len);
871 }
872
873 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_HOBS;
874 if (cpl_propertylist_has(parameters_header, p)) {
875 lblrtm->hobs = cpl_propertylist_get_double(parameters_header, p);
876 cpl_propertylist_update_double(pl, p, lblrtm->hobs);
877 }
878
879 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_AVTRAT;
880 if (cpl_propertylist_has(parameters_header, p)) {
881 lblrtm->avtrat = cpl_propertylist_get_double(parameters_header, p);
882 cpl_propertylist_update_double(pl, p, lblrtm->avtrat);
883 }
884
885 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_TDIFF1;
886 if (cpl_propertylist_has(parameters_header, p)) {
887 lblrtm->tdiff[0] = cpl_propertylist_get_double(parameters_header, p);
888 cpl_propertylist_update_double(pl, p, lblrtm->tdiff[0]);
889 }
890 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_TDIFF2;
891 if (cpl_propertylist_has(parameters_header, p)) {
892 lblrtm->tdiff[1] = cpl_propertylist_get_double(parameters_header, p);
893 cpl_propertylist_update_double(pl, p, lblrtm->tdiff[1]);
894 }
895
896 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_ALTD1;
897 if (cpl_propertylist_has(parameters_header, p)) {
898 lblrtm->altd[0] = cpl_propertylist_get_double(parameters_header, p);
899 cpl_propertylist_update_double(pl, p, lblrtm->altd[0]);
900 }
901 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_ALTD2;
902 if (cpl_propertylist_has(parameters_header, p)) {
903 lblrtm->altd[1] = cpl_propertylist_get_double(parameters_header, p);
904 cpl_propertylist_update_double(pl, p, lblrtm->altd[1]);
905 }
906
907 p = MF_PARAMETERS_CONTEX_DEFAULT" "MF_LBLRTM_DELV;
908 if (cpl_propertylist_has(parameters_header, p)) {
909 lblrtm->delv = cpl_propertylist_get_double(parameters_header, p);
910 cpl_propertylist_update_double(pl, p, lblrtm->delv);
911 }
912
913
914 /*** Update the Molecfit configuration with the header ***/
915 cpl_error_code e = mf_parameters_config_update_with_header_keywords(mf_config->parameters, data_header);
916
917
918 cpl_msg_info(cpl_func, "Columns : wave[%s], flux[%s], dflux[%s], mask[%s]", inputs->column_lambda, inputs->column_flux, inputs->column_dflux, inputs->column_mask);
919
920
921 /* Check possible errors */
922 if (!cpl_errorstate_is_equal(pre_state) || e != CPL_ERROR_NONE) {
923 mf_configuration_delete(mf_config);
924 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
925 "Error loading Molecfit default configuration");
926 return NULL;
927 }
928#endif
929 return CPL_ERROR_NONE;
930}
931
932static cpl_error_code
933_moo_molecfit_update_mf_conf_with_winc(mf_configuration *config,
934 cpl_table *inc_wranges)
935{
936 // mf_parameters_inputs *inputs = &(config->parameters->inputs);
937
938 mf_parameters_fitting *fitting = &(config->parameters->fitting);
939 int nrange = cpl_table_get_nrow(inc_wranges);
940 int max_order = 0;
941 for (int i = 0; i < nrange; i++) {
942 cpl_boolean flag = CPL_TRUE;
943
944 int ival =
945 cpl_table_get_int(inc_wranges, MF_COL_WAVE_RANGE_CONT_FIT, i, NULL);
946 int order = cpl_table_get_int(inc_wranges, MF_COL_WAVE_RANGE_CONT_ORDER,
947 i, NULL);
948 if (order > max_order) {
949 max_order = order;
950 }
951 if (ival == 0)
952 flag = CPL_FALSE;
953 fitting->fit_ranges[i] = flag;
954 fitting->cont_poly_order[i] = order;
955 fitting->cont_coeffs[i][0] = fitting->fit_continuum.const_val;
956 fitting->cont_coeffs[i][1] = 1;
957 }
958 fitting->fit_continuum.n = max_order;
959 fitting->fit_chips[0] = CPL_TRUE;
960
961 return CPL_ERROR_NONE;
962}
963
964static void
965_mf_parameters_fit_dump(const char *name, mf_parameters_fit *fit, FILE *out)
966{
967 fprintf(out, "%s.fit : %d\n", name, fit->fit);
968 fprintf(out, "%s.n : %lld\n", name, fit->n);
969 fprintf(out, "%s.const_val : %e\n", name, fit->const_val);
970}
971
972static void
973_mf_parameters_key_dump(const char *name, mf_parameters_keyword *key, FILE *out)
974{
975 fprintf(out, "%s.key : %s\n", name, key->key);
976 fprintf(out, "%s.value : %e\n", name, key->value);
977}
978
979static cpl_error_code
980_moo_molecfit_mf_conf_dump(mf_configuration *config, int nrange, FILE *out)
981{
982 mf_parameters_inputs *inputs = &(config->parameters->inputs);
983 fprintf(out, "---INPUTS\n");
984 fprintf(out, "wlg_to_micron: %f\n", inputs->wlg_to_micron);
985
986 fprintf(out, "column_lambda: %s\n", inputs->column_lambda);
987 fprintf(out, "column_flux: %s\n", inputs->column_flux);
988 fprintf(out, "column_dflux: %s\n", inputs->column_dflux);
989 fprintf(out, "column_mask: %s\n", inputs->column_mask);
990 fprintf(out, "default_error: %e\n", inputs->default_error);
991 fprintf(out, "mask_binary: %d\n", inputs->mask_binary);
992 fprintf(out, "mask_threshold: %d\n", inputs->mask_threshold);
993 fprintf(out, "wavelengths_frame: %s\n", inputs->wavelengths_frame);
994 fprintf(out, "transmission : %d\n", inputs->transmission);
995 fprintf(out, "clean_flux : %d\n", inputs->clean_flux);
996 fprintf(out, "silent_external_bins : %d\n",
997 inputs->silent_external_bins);
998 _mf_parameters_key_dump("observing_erv_rv", &(inputs->observing_erv_rv),
999 out);
1000
1001 fprintf(out, "\n---DIRECTORIES\n");
1002 fprintf(out, "telluric_path : %s\n",
1003 config->parameters->directories.telluric_path);
1004 fprintf(out, "telluriccorr_data_path : %s\n",
1005 config->parameters->directories.telluriccorr_data_path);
1006 fprintf(out, "tmp_path : %s\n",
1007 config->parameters->directories.tmp_path);
1008
1009 mf_parameters_fitting *fitting = &(config->parameters->fitting);
1010 fprintf(out, "\n---FITTING\n");
1011 fprintf(out, "ftol : %e\n", fitting->ftol);
1012 fprintf(out, "xtol : %e\n", fitting->xtol);
1013 fprintf(out, "flux_unit : %d\n", fitting->flux_unit);
1014 _mf_parameters_fit_dump("fit_telescope_background",
1015 &(fitting->fit_telescope_background), out);
1016 _mf_parameters_fit_dump("fit_continuum", &(fitting->fit_continuum), out);
1017 _mf_parameters_fit_dump("fit_wavelength",
1018 &(fitting->fit_telescope_background), out);
1019 _mf_parameters_fit_dump("fit_gauss", &(fitting->fit_gauss), out);
1020 _mf_parameters_fit_dump("fit_res_box", &(fitting->fit_res_box), out);
1021 _mf_parameters_fit_dump("fit_lorentz", &(fitting->fit_lorentz), out);
1022 fprintf(out, "kern_mode : %d\n", fitting->kern_mode);
1023 fprintf(out, "kern_fac : %e\n", fitting->kern_fac);
1024 fprintf(out, "var_kern : %d\n", fitting->var_kern);
1025 fprintf(out, "expert_mode : %d\n", fitting->expert_mode);
1026 fprintf(out, "fit_n_cflags : %d\n", fitting->fit_n_cflags);
1027 fprintf(out, "fit_n_rflags : %d\n", fitting->fit_n_rflags);
1028
1029 for (int i = 0; i < nrange; i++) {
1030 fprintf(out, "fit_ranges [%d] : %d\n", i, fitting->fit_ranges[i]);
1031 fprintf(out, "fit_chips [%d] : %d\n", i, fitting->fit_chips[i]);
1032 fprintf(out, "cont_poly_order[%d] : %d\n", i,
1033 fitting->cont_poly_order[i]);
1034 for (int j = 0; j < fitting->cont_poly_order[i]; j++) {
1035 fprintf(out, "cont_coeffs [%d][%d] : %f\n", i, j,
1036 fitting->cont_coeffs[i][j]);
1037 }
1038 fprintf(out, "wlc_poly_order [%d] : %d\n", i,
1039 fitting->wlc_poly_order[i]);
1040 fprintf(out, "wlc_coeffs [%d][0] : %f\n", i,
1041 fitting->wlc_coeffs[i][0]);
1042 }
1043
1044 mf_parameters_instrumental *instrumental =
1045 &(config->parameters->instrumental);
1046 fprintf(out, "\n---INSTRUMENTAL\n");
1047 _mf_parameters_key_dump("slit_width", &(instrumental->slit_width), out);
1048 _mf_parameters_key_dump("pixel_scale", &(instrumental->pixel_scale), out);
1049
1050 mf_parameters_atmospheric *atmospheric = &(config->parameters->atmospheric);
1051 fprintf(out, "\n---ATMOSPHERIC\n");
1052
1053 fprintf(out, "ref_atm : %s\n", atmospheric->ref_atm);
1054 fprintf(out, "layers : %d\n", atmospheric->layers);
1055 fprintf(out, "emix : %e\n", atmospheric->emix);
1056 fprintf(out, "pwv : %e\n", atmospheric->pwv);
1057 fprintf(out, "gdas_prof : %s\n", atmospheric->gdas_prof);
1058
1059 mf_io_lnfl_config *lnfl = config->lnfl;
1060 fprintf(out, "\n---LNLF\n");
1061 fprintf(out, "line_db : %s\n", lnfl->line_db);
1062 fprintf(out, "line_db_fmt : %d\n", lnfl->line_db_fmt);
1063
1064 mf_io_lblrtm_config *lblrtm = config->lblrtm;
1065#if 0
1066 int icntnm; /* Continua and Rayleigh extinction [0,1,2,3,4,5] */
1067 int iaersl; /* Aerosols [0,1] */
1068 int mpts; /* Number of optical depth values */
1069 int npts; /* Number of values for each panel */
1070 double v[2]; /* Ending wavenumber value for the calculation */
1071 int sample; /* Number of sample points per mean halfwidth [between 1 to 4] */
1072 double alfal0; /* Average collision broadened halfwidth [cm-1/atm] */
1073 double avmass; /* Average molecular mass [amu] for Doppler halfwidth */
1074 double dptmin; /* Min molecular optical depth below lines will be rejected */
1075 double dptfac; /* Factor multiplying molecular continuum optical depth */
1076 double tbound; /* Temperature of boundary [K] */
1077 double sremis[3]; /* Emissivity coefficients */
1078 double srrefl[3]; /* Reflectivity coefficients */
1079 int model; /* Atmospheric profile [0,1,2,3,4,5,6] */
1080 int itype; /* Type of path [1,2,3] */
1081 int nozero; /* Zeroing of small amounts of absorbers [0,1] */
1082 int noprnt; /* Do not print output? [0,1] */
1083 int ipunch; /* Write out layer data to TAPE7 [0,1] */
1084 double re; /* Radius of earth [km] */
1085 double hspace; /* Altitude definition for space [km] */
1086 double ref_lat; /* Latitude of location of calculation [degrees] [-90.-90] */
1087 double h[2]; /* h[0] = Observer altitude, h[1] = Upper height limit; [km] */
1088 double range; /* Length of a straight path from H1 to H2 [km] */
1089 double beta; /* Earth centered angle from H1 to H2 [degrees] */
1090 int len; /* Path length [0,1] */
1091 double hobs; /* Height of observer */
1092 double avtrat; /* Maximum Voigt width ratio across a layer */
1093 double tdiff[2]; /* Maximum layer temperature difference at ALTD1, ALTD2 [K] */
1094 double altd[2]; /* Altitude of TDIFF1, TDIFF2 [km] */
1095 double delv; /* Number of wavenumbers [cm-1] per major division */
1096#endif
1097 fprintf(out, "\n---LBLRTM\n");
1098 fprintf(out, "alfal0 : %e\n", lblrtm->alfal0);
1099 fprintf(out, "altd[0] : %e\n", lblrtm->altd[0]);
1100 fprintf(out, "altd[1] : %e\n", lblrtm->altd[1]);
1101 fprintf(out, "avmass : %e\n", lblrtm->avmass);
1102 fprintf(out, "avtrat : %e\n", lblrtm->avtrat);
1103 fprintf(out, "beta : %e\n", lblrtm->beta);
1104 fprintf(out, "dptfac : %e\n", lblrtm->dptfac);
1105 fprintf(out, "dptmin : %e\n", lblrtm->dptmin);
1106 fprintf(out, "h[0] : %e\n", lblrtm->h[0]);
1107 fprintf(out, "h[1] : %e\n", lblrtm->h[1]);
1108 fprintf(out, "hobs : %e\n", lblrtm->hobs);
1109 fprintf(out, "hspace : %e\n", lblrtm->hspace);
1110 fprintf(out, "iaersl : %d\n", lblrtm->iaersl);
1111 fprintf(out, "icntnm : %d\n", lblrtm->icntnm);
1112 fprintf(out, "ipunch : %d\n", lblrtm->ipunch);
1113 fprintf(out, "itype : %d\n", lblrtm->itype);
1114 fprintf(out, "len : %d\n", lblrtm->len);
1115 fprintf(out, "model : %d\n", lblrtm->mpts);
1116 fprintf(out, "npprnt : %d\n", lblrtm->noprnt);
1117 fprintf(out, "nozero : %d\n", lblrtm->nozero);
1118 fprintf(out, "npts : %d\n", lblrtm->npts);
1119 fprintf(out, "range : %e\n", lblrtm->range);
1120 fprintf(out, "re : %e\n", lblrtm->re);
1121 fprintf(out, "sample : %d\n", lblrtm->sample);
1122 fprintf(out, "sremis[0] :%e\n", lblrtm->sremis[0]);
1123 fprintf(out, "sremis[1] :%e\n", lblrtm->sremis[1]);
1124 fprintf(out, "sremis[2] :%e\n", lblrtm->sremis[2]);
1125 fprintf(out, "srrefl[0] :%e\n", lblrtm->srrefl[0]);
1126 fprintf(out, "srrefl[1] :%e\n", lblrtm->srrefl[1]);
1127 fprintf(out, "srrefl[2] :%e\n", lblrtm->srrefl[2]);
1128 fprintf(out, "tbound :%e\n", lblrtm->tbound);
1129 fprintf(out, "tdiff[0] :%e\n", lblrtm->tdiff[0]);
1130 fprintf(out, "tdiff[1] :%e\n", lblrtm->tdiff[1]);
1131 fprintf(out, "v[0] :%e\n", lblrtm->v[0]);
1132 fprintf(out, "v[1] :%e\n", lblrtm->v[1]);
1133
1134 return CPL_ERROR_NONE;
1135}
1136/*----------------------------------------------------------------------------*/
1156/*----------------------------------------------------------------------------*/
1157moo_molectable *
1158moo_molecfit_model(const cpl_frame *sci_frame,
1159 const char *modename,
1160 const cpl_frame *molecule_frame,
1161 const cpl_frame *winc_frame,
1162 moo_molectable **pmt_atm_fitted,
1163 moo_molectable **best_fitted_model,
1164 moo_molecfit_model_params *params)
1165{
1166 mf_configuration *mf_config = NULL;
1167 moo_molectable *mt_molecules = NULL;
1168 moo_molectable *mt_winc = NULL;
1169 moo_molectable *mt_lblrtm_input = NULL;
1170 moo_molectable *mt_excprange_input = NULL;
1171 moo_molectable *mt_excwrange_input = NULL;
1172
1173 moo_molectable *mt_gdas_interp = NULL;
1174 moo_molectable *mt_gdas_after = NULL;
1175 moo_molectable *mt_gdas_before = NULL;
1176 moo_molectable *mt_atm_combined = NULL;
1177 moo_molectable *mt_atm_fitted = NULL;
1178 moo_molectable *mt_atm_standard = NULL;
1179 moo_molectable *mt_best_fitted = NULL;
1180 moo_molectable *mt_best_model = NULL;
1181
1182 cpl_table *molecules_table = NULL;
1183 cpl_table *winc_table = NULL;
1184 cpl_table *spec = NULL;
1185 cpl_table *gdas_user = NULL;
1186 cpl_table *atm_profile_standard = NULL;
1187 cpl_table *atm_profile_combined = NULL;
1188 cpl_error_code err = CPL_ERROR_NONE;
1189 moo_sci *sci = NULL;
1190 mf_model_results *results = NULL;
1191 cpl_table *mdata = NULL;
1192
1193 cpl_errorstate prestate = cpl_errorstate_get();
1194
1195 cpl_ensure(pmt_atm_fitted != NULL, CPL_ERROR_NULL_INPUT, NULL);
1196
1197 cpl_msg_info(__func__, "use molecfit model");
1198 mf_config = mf_configuration_create();
1199 sci = moo_sci_create(sci_frame);
1200
1201 mt_molecules = moo_molectable_load(molecule_frame, modename);
1202 mt_winc = moo_molectable_load(winc_frame, modename);
1203
1204 mt_lblrtm_input = moo_molectable_new();
1205 mt_excprange_input = moo_molectable_new();
1206 mt_excwrange_input = moo_molectable_new();
1207
1208 mt_gdas_after = moo_molectable_new();
1209 mt_gdas_interp = moo_molectable_new();
1210 mt_gdas_before = moo_molectable_new();
1211 mt_atm_combined = moo_molectable_new();
1212 mt_atm_standard = moo_molectable_new();
1213
1214 mt_atm_fitted = moo_molectable_new();
1215 mt_best_fitted = moo_molectable_new();
1216 mt_best_model = moo_molectable_new();
1217 mt_atm_fitted->primary_header = cpl_propertylist_new();
1218 mt_best_fitted->primary_header = cpl_propertylist_new();
1219 mt_best_model->primary_header = cpl_propertylist_new();
1220
1221
1222 for (int type = 0; type < 3; type++) {
1223 moo_sci_single *sci_single = moo_sci_get_single(sci, type);
1224 molecules_table = moo_molectable_get_data(mt_molecules, type);
1225 winc_table = moo_molectable_get_data(mt_winc, type);
1226 if (sci_single != NULL && molecules_table != NULL &&
1227 winc_table != NULL) {
1228 cpl_msg_info(__func__, "Do molecfit_model for %s",
1229 sci_single->extname);
1230 cpl_msg_indent_more();
1231 cpl_propertylist *header = moo_sci_single_get_header(sci_single);
1232 double cd1_1 = moo_pfits_get_cd1_1(header);
1233 double crpix1 = moo_pfits_get_crpix1(header);
1234 double crval1 = moo_pfits_get_crval1(header);
1235
1236 // int nrange = cpl_table_get_nrow(winc_table);
1237 err = mf_parameters_config_update_with_header_keywords(
1238 mf_config->parameters, sci->primary_header);
1239
1240 if (err != CPL_ERROR_NONE) {
1241 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
1242 "Error updating molecfit parameters with "
1243 "the raw primary header configuration");
1244 }
1245 _moo_molecfit_update_mf_conf(mf_config, params);
1246 _moo_molecfit_update_mf_conf_with_winc(mf_config, winc_table);
1248 hdrl_image *hdata = moo_sci_single_get_image(sci_single);
1249 cpl_image *img = hdrl_image_get_image(hdata);
1250 cpl_image *ierr = hdrl_image_get_error(hdata);
1251 mdata = _molecfit_data_create(crpix1, crval1, cd1_1, img, ierr, 1);
1252 /* Running molecfit */
1253 cpl_msg_info(cpl_func, "MNB About to call mf_model, err=%d", err);
1254
1255
1256 if (!err) {
1257 cpl_table *exc_wranges = NULL;
1258 cpl_table *exc_pranges = NULL;
1259 cpl_propertylist *header_kernel = NULL;
1260 cpl_matrix *kernel = NULL;
1261
1262 /* Create input molecfit spec format */
1263 cpl_table *spec_telluriccorr_lblrtm =
1264 mf_spectrum_create(mf_config->parameters, mdata);
1265 spec = spec_telluriccorr_lblrtm;
1266
1267#if MOO_DEBUG_MOLECFIT_MODEL
1268 const char *arm = moo_detector_get_name(type);
1269 if (atm_profile_standard != NULL) {
1270 char *testname =
1271 cpl_sprintf("ATM_PROFILE_STANDARD_INPUT_%s.fits", arm);
1272 cpl_table_save(atm_profile_standard, NULL, NULL, testname,
1273 CPL_IO_CREATE);
1274 cpl_free(testname);
1275 }
1276 if (atm_profile_combined != NULL) {
1277 char *testname =
1278 cpl_sprintf("ATM_PROFILE_COMBINED_INPUT_%s.fits", arm);
1279 cpl_table_save(atm_profile_combined, NULL, NULL, testname,
1280 CPL_IO_CREATE);
1281 cpl_free(testname);
1282 }
1283 if (gdas_user != NULL) {
1284 char *testname =
1285 cpl_sprintf("GDAS_USER_INPUT_%s.fits", arm);
1286 cpl_table_save(gdas_user, NULL, NULL, testname,
1287 CPL_IO_CREATE);
1288 cpl_free(testname);
1289 }
1290 moo_molectable_set_data(mt_lblrtm_input, type, spec);
1291 moo_molectable_set_data(mt_excprange_input, type, exc_pranges);
1292 moo_molectable_set_data(mt_excwrange_input, type, exc_wranges);
1293 if (sci_single->header) {
1294 char *testname =
1295 cpl_sprintf("HEADER_SPEC_INPUT_%s.txt", arm);
1296 FILE *f = fopen(testname, "w");
1297 cpl_propertylist_dump(sci_single->header, f);
1298 fclose(f);
1299 cpl_free(testname);
1300 }
1301 if (header_kernel != NULL) {
1302 char *testname =
1303 cpl_sprintf("HEADER_KERNEL_INPUT_%s.txt", arm);
1304 FILE *f = fopen(testname, "w");
1305 cpl_propertylist_dump(header_kernel, f);
1306 fclose(f);
1307 cpl_free(testname);
1308 }
1309 if (kernel != NULL) {
1310 char *testname = cpl_sprintf("KERNEL_INPUT_%s.txt", arm);
1311 FILE *f = fopen(testname, "w");
1312 cpl_matrix_dump(kernel, f);
1313 fclose(f);
1314 cpl_free(testname);
1315 }
1316 if (mf_config != NULL) {
1317 char *testname = cpl_sprintf("MF_CONFIG_INPUT_%s.txt", arm);
1318 cpl_msg_info("test", "save config %s", testname);
1319 FILE *f = fopen(testname, "w");
1320 _moo_molecfit_mf_conf_dump(mf_config, nrange, f);
1321 fclose(f);
1322 cpl_free(testname);
1323 }
1324#endif
1325 results = mf_model(
1326 mf_config, molecules_table, sci_single->header,
1327 spec, /* const cpl_table *spec_telluriccorr */
1328 winc_table, /* cpl_table *inc_wranges */
1329 exc_wranges, /* cpl_table *exc_wranges */
1330 exc_pranges, /* cpl_table *exc_wranges */
1331 header_kernel, /* const cpl_propertylist *header_kernel */
1332 kernel, /* const cpl_matrix *kernel */
1333 gdas_user, /* const cpl_table *gdas_user */
1334 atm_profile_standard, /* const cpl_table *atm_profile_standard */
1335 atm_profile_combined); /* const cpl_table *atm_profile_combined */
1336 err = cpl_error_get_code();
1337
1338 if (!err && results != NULL) {
1339 moo_molectable_set_data(mt_gdas_interp, type,
1340 results->gdas_interpolate);
1341 moo_molectable_set_data(mt_gdas_before, type,
1342 results->gdas_before);
1343 moo_molectable_set_data(mt_gdas_after, type,
1344 results->gdas_after);
1345 moo_molectable_set_data(mt_atm_standard, type,
1346 results->atm_profile_standard);
1347 moo_molectable_set_data(mt_atm_combined, type,
1348 results->atm_profile_combined);
1349 moo_molectable_set_data(mt_atm_fitted, type,
1350 results->atm_profile_fitted);
1351 moo_molectable_set_data(mt_best_fitted, type, results->res);
1352 moo_molectable_set_data(mt_best_model, type, results->spec);
1353 }
1354
1355 if (results != NULL) {
1356 if (results->atm_profile_combined != NULL) {
1357 cpl_table_delete(results->atm_profile_combined);
1358 results->atm_profile_combined = NULL;
1359 }
1360 if (results->atm_profile_standard != NULL) {
1361 cpl_table_delete(results->atm_profile_standard);
1362 results->atm_profile_standard = NULL;
1363 }
1364 mf_model_results_delete(results);
1365 results = NULL;
1366 }
1367 cpl_table_delete(exc_pranges);
1368 cpl_table_delete(exc_wranges);
1369 cpl_table_delete(spec);
1370 spec = NULL;
1371 }
1372
1373 cpl_table_delete(mdata);
1374 mdata = NULL;
1375 }
1376 }
1377
1378 if (!cpl_errorstate_is_equal(prestate)) {
1379 moo_molectable_delete(mt_best_fitted);
1380 moo_molectable_delete(mt_atm_fitted);
1381 moo_molectable_delete(mt_best_model);
1382 mt_best_fitted = NULL;
1383 mt_atm_fitted = NULL;
1384 mt_best_model = NULL;
1385 cpl_table_delete(mdata);
1386 mf_model_results_delete(results);
1387 }
1388 *pmt_atm_fitted = mt_atm_fitted;
1389 *best_fitted_model = mt_best_model;
1390 moo_molectable_delete(mt_molecules);
1391 moo_molectable_delete(mt_winc);
1392 moo_molectable_delete(mt_lblrtm_input);
1393 moo_molectable_delete(mt_excprange_input);
1394 moo_molectable_delete(mt_excwrange_input);
1395 moo_molectable_delete(mt_gdas_interp);
1396 moo_molectable_delete(mt_gdas_after);
1397 moo_molectable_delete(mt_gdas_before);
1398 moo_molectable_delete(mt_atm_standard);
1399 moo_molectable_delete(mt_atm_combined);
1400 mf_configuration_delete(mf_config);
1401 moo_sci_delete(sci);
1402 return mt_best_fitted;
1403}
1404
1405/*----------------------------------------------------------------------------*/
1425/*----------------------------------------------------------------------------*/
1426
1427moo_telluric *
1428moo_molecfit_calctrans(const cpl_frame *rbn_frame,
1429 const char *modename,
1430 const cpl_frame *molecules_frame,
1431 const cpl_frame *atm_frame,
1432 const cpl_frame *best_fit_frame,
1433 const cpl_frame *kernel_lib_frame,
1434 moo_molecfit_calctrans_params *params)
1435{
1436 moo_rbn *rbn = NULL;
1437
1438 mf_configuration *mf_config = NULL;
1439 moo_molectable *mt_molecules = NULL;
1440 moo_molectable *mt_atm = NULL;
1441 moo_molectable *mt_bfit = NULL;
1442 moo_kernel *mkernel = NULL;
1443 cpl_table *mdata = NULL;
1444 moo_molectable *mt_lblrtm_results = NULL;
1445 cpl_error_code err = CPL_ERROR_NONE;
1446 cpl_array *sel = NULL;
1447 moo_telluric *result = NULL;
1448 int filter_skyfibre = 1;
1449 cpl_ensure(rbn_frame != NULL, CPL_ERROR_NULL_INPUT, NULL);
1450 cpl_ensure(atm_frame != NULL, CPL_ERROR_NULL_INPUT, NULL);
1451 cpl_ensure(best_fit_frame != NULL, CPL_ERROR_NULL_INPUT, NULL);
1452 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
1453
1454 filter_skyfibre = params->filter_skyfibre;
1455 mf_config = mf_configuration_create();
1456
1457 rbn = moo_rbn_create(rbn_frame);
1458 mt_molecules = moo_molectable_load(molecules_frame, modename);
1459 mt_atm = moo_molectable_load(atm_frame, NULL);
1460 mt_bfit = moo_molectable_load(best_fit_frame, NULL);
1461 mt_lblrtm_results = moo_molectable_new();
1462
1463 cpl_table *fibre_table = moo_rbn_get_fibre_table(rbn);
1464 mkernel = moo_kernel_load(kernel_lib_frame);
1465
1466 const char *snrcolnames[] = { MOO_FIBRES_TABLE_MEDSNR_RI_EXT,
1467 MOO_FIBRES_TABLE_MEDSNR_YJ_EXT,
1468 MOO_FIBRES_TABLE_MEDSNR_H_EXT };
1469 const char *bandcolnames[] = { MOO_TELLURIC_EXT_RI, MOO_TELLURIC_EXT_YJ,
1470 MOO_TELLURIC_EXT_H };
1471 result = moo_telluric_new();
1472 result->primary_header = cpl_propertylist_new();
1473 result->telluric_table = cpl_table_new(0);
1474
1475 cpl_table_new_column(result->telluric_table, MOO_TELLURIC_TABLE_INDEXRBN,
1476 CPL_TYPE_INT);
1477 cpl_table_new_column(result->telluric_table, MOO_TELLURIC_TABLE_SPECTRO,
1478 CPL_TYPE_INT);
1479 cpl_table_new_column(result->telluric_table, MOO_TELLURIC_TABLE_BAND,
1480 CPL_TYPE_STRING);
1481 cpl_table_new_column(result->telluric_table, MOO_TELLURIC_TABLE_TELLURIC,
1482 CPL_TYPE_INT);
1483
1484 for (int type = 0; type < 3; type++) {
1485 moo_rbn_single *rbn_single = moo_rbn_get_single(rbn, type);
1486 cpl_table *molecules_table =
1487 moo_molectable_get_data(mt_molecules, type);
1488
1489 cpl_table *atm_parameters_table = moo_molectable_get_data(mt_atm, type);
1490
1491 cpl_table *best_fit_parameters_table =
1492 moo_molectable_get_data(mt_bfit, type);
1493
1494 if (rbn_single != NULL && molecules_table != NULL &&
1495 atm_parameters_table != NULL && best_fit_parameters_table != NULL) {
1496 cpl_table *telluric_table = NULL;
1497 double min_snr = params->min_snr[type];
1498 const char *band = bandcolnames[type];
1499 cpl_table_unselect_all(fibre_table);
1500 int size = 0;
1501 for (int i = 0; i < cpl_table_get_nrow(fibre_table); i++) {
1502 int rej;
1503 double val = cpl_table_get_float(fibre_table, snrcolnames[type],
1504 i, &rej);
1505 if (!isnan(val)) {
1506 cpl_table_select_row(fibre_table, i);
1507 size++;
1508 }
1509 }
1510
1511 size =
1512 cpl_table_and_selected_int(fibre_table, MOO_FIBRES_TABLE_HEALTH,
1513 CPL_NOT_EQUAL_TO,
1514 MOO_FIBRES_TABLE_HEALTH_BROKEN);
1515 if (filter_skyfibre) {
1516 size = cpl_table_and_selected_string(fibre_table,
1517 MOO_FIBRES_TABLE_TYPE,
1518 CPL_NOT_EQUAL_TO,
1519 MOO_FIBRES_TABLE_TYPE_SKY);
1520 size = cpl_table_and_selected_string(
1521 fibre_table, MOO_FIBRES_TABLE_TYPE, CPL_NOT_EQUAL_TO,
1522 MOO_FIBRES_TABLE_TYPE_SKYCONTAM);
1523 }
1524 size = cpl_table_and_selected_float(fibre_table, snrcolnames[type],
1525 CPL_GREATER_THAN, min_snr);
1526
1527 sel = cpl_table_where_selected(fibre_table);
1528
1529 cpl_msg_info(__func__,
1530 "Do molecfit_calctrans for %s (%d selected fibres)",
1531 rbn_single->extname, size);
1532 cpl_msg_indent_more();
1533 cpl_propertylist *header = moo_rbn_single_get_header(rbn_single);
1534 double cd1_1 = moo_pfits_get_cd1_1(header);
1535 double crpix1 = moo_pfits_get_crpix1(header);
1536 double crval1 = moo_pfits_get_crval1(header);
1537
1538 err = mf_parameters_config_update_with_header_keywords(
1539 mf_config->parameters, rbn->primary_header);
1540
1541 if (err != CPL_ERROR_NONE) {
1542 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
1543 "Error updating molecfit parameters with "
1544 "the raw primary header configuration");
1545 }
1546
1547 _moo_molecfit_update_mf_conf(mf_config, NULL);
1549 hdrl_image *hdata = moo_rbn_single_get_image(rbn_single);
1550 cpl_image *img = hdrl_image_get_image(hdata);
1551 cpl_image *ierr = hdrl_image_get_error(hdata);
1552 int nx = cpl_image_get_size_x(img);
1553 telluric_table = cpl_table_new(size);
1554
1555 cpl_table_new_column(telluric_table, MOO_TELLURIC_TABLE_INDEXRBN,
1556 CPL_TYPE_INT);
1557 cpl_table_new_column(telluric_table, MOO_TELLURIC_TABLE_SPECTRO,
1558 CPL_TYPE_INT);
1559 cpl_table_new_column(telluric_table, MOO_TELLURIC_TABLE_BAND,
1560 CPL_TYPE_STRING);
1561 cpl_table_new_column(telluric_table, MOO_TELLURIC_TABLE_TELLURIC,
1562 CPL_TYPE_INT);
1563
1564 cpl_propertylist *theader = cpl_propertylist_new();
1565 cpl_propertylist_copy_property(theader, header, MOO_PFITS_CD1_1);
1566 cpl_propertylist_copy_property(theader, header, MOO_PFITS_CRVAL1);
1567 cpl_propertylist_copy_property(theader, header, MOO_PFITS_CRPIX1);
1568 cpl_propertylist_copy_property(theader, header, MOO_PFITS_CUNIT1);
1569 result->data_header[type] = theader;
1570
1571 cpl_image *im = cpl_image_new(nx, size, CPL_TYPE_DOUBLE);
1572 moo_telluric_set_image(result, type, im);
1573 mf_calctrans_lblrtm_results *lblrtm_results = NULL;
1574 const double wl_start = -1.;
1575 const double wl_end = -1.;
1576 const cpl_propertylist *spec_telluriccorr_head = rbn_single->header;
1577
1578 if (size > 0) {
1579 cpl_msg_info(__func__, "Do LBLRTM for %s", rbn_single->extname);
1580 int idx = cpl_array_get_cplsize(sel, 0, NULL);
1581 int idrbn =
1582 cpl_table_get_int(fibre_table, MOO_FIBRES_TABLE_INDEXRBN,
1583 idx, NULL);
1584
1585 mdata = _molecfit_data_create(crpix1, crval1, cd1_1, img, ierr,
1586 idrbn);
1587
1588 /* Create input molecfit spec format */
1589 cpl_table *spec_telluriccorr =
1590 mf_spectrum_create(mf_config->parameters, mdata);
1591
1592 lblrtm_results =
1593 mf_calctrans_lblrtm(mf_config, spec_telluriccorr,
1594 molecules_table, wl_start, wl_end,
1595 atm_parameters_table,
1596 best_fit_parameters_table);
1597 cpl_table_delete(spec_telluriccorr);
1598 cpl_table_delete(mdata);
1599 }
1600
1601 if (!(lblrtm_results)) {
1602 err = cpl_error_set_message(
1603 cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
1604 "Unexpected error in the Molecfit call "
1605 "mf_calctrans_lblrtm(...)");
1606 }
1607 else {
1608 cpl_size n_range = mf_config->parameters->internal.n_range;
1609
1610 if (n_range != 1) {
1611 err = cpl_error_set_message(
1612 cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
1613 "Unexpected n_ranges in the "
1614 "mf_calctrans_lblrtm(...) Molecfit execution : "
1615 "n_ranges = %lld (Mandatory == 1)",
1616 n_range);
1617 }
1618 else {
1619 err = cpl_error_get_code();
1620 }
1621 if (!err) {
1622 for (int i = 0; i < size; i++) {
1623 mf_calctrans_convolution_results *convolution_results =
1624 NULL;
1625 int idx = cpl_array_get_cplsize(sel, i, NULL);
1626 int idrbn = cpl_table_get_int(fibre_table,
1627 MOO_FIBRES_TABLE_INDEXRBN,
1628 idx, NULL);
1629 const int spectro =
1630 cpl_table_get_int(fibre_table,
1631 MOO_FIBRES_TABLE_SPECTRO, idx,
1632 NULL);
1633 cpl_table_set_int(telluric_table,
1634 MOO_TELLURIC_TABLE_INDEXRBN, i,
1635 idrbn);
1636 cpl_table_set_int(telluric_table,
1637 MOO_TELLURIC_TABLE_SPECTRO, i,
1638 spectro);
1639 cpl_table_set_string(telluric_table,
1640 MOO_TELLURIC_TABLE_BAND, i, band);
1641 cpl_table_set_int(telluric_table,
1642 MOO_TELLURIC_TABLE_TELLURIC, i,
1643 i + 1);
1644
1645 cpl_msg_info(__func__, "Do convolution for %d:%d",
1646 idrbn, cpl_error_get_code());
1647
1648 mdata = _molecfit_data_create(crpix1, crval1, cd1_1,
1649 img, ierr, idrbn);
1650 /* Create input molecfit spec format */
1651 cpl_table *spec_telluriccorr =
1652 mf_spectrum_create(mf_config->parameters, mdata);
1653 cpl_msg_info(
1654 cpl_func,
1655 "Convolve input spectrum "
1656 "(ext_orig[ATM_PARAMETERS/BEST_FIT_PARAMETERS]");
1657 cpl_propertylist *header_kernel = NULL;
1658 cpl_matrix *kernel = NULL;
1659
1660 header_kernel =
1661 moo_kernel_get_header(mkernel, type, 1, idrbn);
1662
1663 kernel = moo_kernel_get_matrix(mkernel, type, 1, idrbn);
1664 convolution_results =
1665 mf_calctrans_convolution(mf_config->parameters,
1666 lblrtm_results,
1667 spec_telluriccorr_head,
1668 spec_telluriccorr,
1669 header_kernel, kernel,
1670 wl_start, wl_end,
1671 best_fit_parameters_table);
1672 if (!convolution_results) {
1673 err = cpl_error_set_message(
1674 cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
1675 "Unexpected error in the Molecfit call "
1676 "mf_calctrans_convolution(...)");
1677 }
1678 else {
1679 cpl_table *telluric_data =
1680 convolution_results->spec_telluriccorr_format;
1681 for (int k = 0; k < nx; k++) {
1682 double mt = cpl_table_get(telluric_data,
1683 "mtrans", k, NULL);
1684 cpl_image_set(im, k + 1, i + 1, mt);
1685 }
1686#if MOO_DEBUG_MOLECFIT_CALCTRANS
1687 {
1688 char *testname =
1689 cpl_sprintf("TELLURICDATA_%s_%d.fits",
1690 rbn_single->extname, idrbn);
1691 cpl_table_save(telluric_data, NULL, NULL,
1692 testname, CPL_IO_CREATE);
1693 cpl_free(testname);
1694 }
1695#endif
1696 err = cpl_error_get_code();
1697 }
1698
1699 cpl_propertylist_delete(header_kernel);
1700 cpl_matrix_delete(kernel);
1701 mf_calctrans_convolution_results_delete(
1702 convolution_results);
1703 cpl_table_delete(spec_telluriccorr);
1704 cpl_table_delete(mdata);
1705 }
1706 mf_calctrans_lblrtm_results_delete(lblrtm_results);
1707 }
1708 }
1709
1710 int nrow = cpl_table_get_nrow(result->telluric_table);
1711 cpl_table_insert(result->telluric_table, telluric_table, nrow);
1712
1713 cpl_table_delete(telluric_table);
1714 cpl_array_delete(sel);
1715 }
1716 }
1717
1718 moo_kernel_delete(mkernel);
1719 mf_configuration_delete(mf_config);
1720 moo_molectable_delete(mt_molecules);
1721 moo_molectable_delete(mt_atm);
1722 moo_molectable_delete(mt_bfit);
1723 moo_molectable_delete(mt_lblrtm_results);
1724 moo_rbn_delete(rbn);
1725
1726 return result;
1727}
#define MOO_BADPIX_GOOD
Definition: moo_badpix.h:36
const char * moo_detector_get_name(moo_detector_type type)
Get the extension name of a detector.
Definition: moo_detector.c:183
void moo_kernel_delete(moo_kernel *self)
Delete a moo_kernel.
Definition: moo_kernel.c:113
cpl_propertylist * moo_kernel_get_header(moo_kernel *self, moo_detector_type type, int ntas, int rbn)
Get the header of the kernel for given idrbn or NULL.
Definition: moo_kernel.c:142
moo_kernel * moo_kernel_load(const cpl_frame *frame)
Load a new moo_kernel.
Definition: moo_kernel.c:80
cpl_matrix * moo_kernel_get_matrix(moo_kernel *self, moo_detector_type type, int ntas, int rbn)
Get the mtarix of the kernel for given idrbn or NULL.
Definition: moo_kernel.c:170
cpl_error_code moo_molectable_set_data(moo_molectable *self, moo_detector_type type, cpl_table *data)
Set table in molectable.
moo_molectable * moo_molectable_load(const cpl_frame *frame, const char *modename)
Load a moo_molectable.
cpl_table * moo_molectable_get_data(moo_molectable *self, moo_detector_type type)
Get table from molec_table.
void moo_molectable_delete(moo_molectable *self)
Delete a moo_molectable.
moo_molectable * moo_molectable_new(void)
Create a new moo_molectable.
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.
cpl_error_code moo_rbn_single_load(moo_rbn_single *self, unsigned int level)
load the data of a moo_rbn_single
void moo_rbn_delete(moo_rbn *self)
Delete a moo_rbn.
Definition: moo_rbn.c:120
moo_rbn_single * moo_rbn_get_single(moo_rbn *self, moo_detector_type type)
Get a RBN single from RBN.
Definition: moo_rbn.c:325
moo_rbn * moo_rbn_create(const cpl_frame *frame)
Create a new empty RBN filename.
Definition: moo_rbn.c:85
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_error_code moo_sci_single_load(moo_sci_single *self, unsigned int level)
Load a moo_sci_single from the filename.
cpl_propertylist * moo_sci_single_get_header(moo_sci_single *self)
Get header of sci single.
void moo_sci_delete(moo_sci *self)
Delete a moo_sci.
Definition: moo_sci.c:84
moo_sci * moo_sci_create(const cpl_frame *frame)
Create a new empty SCI filename.
Definition: moo_sci.c:249
moo_sci_single * moo_sci_get_single(moo_sci *self, moo_detector_type type)
Get the type part in SCI and return it.
Definition: moo_sci.c:351
#define MOO_TELLURIC_EXT_RI
TELLURIC format.
Definition: moo_telluric.h:35
cpl_error_code moo_telluric_set_image(moo_telluric *self, moo_detector_type type, cpl_image *im)
assign image in moo_telluric
Definition: moo_telluric.c:87
moo_telluric * moo_telluric_new(void)
Create a new moo_telluric.
Definition: moo_telluric.c:67
moo_telluric * moo_molecfit_calctrans(const cpl_frame *rbn_frame, const char *modename, const cpl_frame *molecules_frame, const cpl_frame *atm_frame, const cpl_frame *best_fit_frame, const cpl_frame *kernel_lib_frame, moo_molecfit_calctrans_params *params)
Apply the molcecfit calctrans to the RBN to compute telle telluric correction.
moo_molectable * moo_molecfit_model(const cpl_frame *sci_frame, const char *modename, const cpl_frame *molecule_frame, const cpl_frame *winc_frame, moo_molectable **pmt_atm_fitted, moo_molectable **best_fitted_model, moo_molecfit_model_params *params)
Apply the relative flux calibration to 1D rebinned spectra.
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
KERNEL format.
Definition: moo_kernel.h:44