MOONS Pipeline Reference Manual 0.13.2
moons_molecfit_model.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
28#include "hdrl.h"
29#include "moo_dfs.h"
30#include "moo_drl.h"
31#include "moo_molecfit.h"
32#include "moo_molectable.h"
33#include "moo_params.h"
34#include "moo_pfits.h"
35#include "moo_products.h"
36#include "moo_utils.h"
37#include <cpl.h>
38#include <string.h>
39/*-----------------------------------------------------------------------------
40 Plugin registration
41 -----------------------------------------------------------------------------*/
42
43int cpl_plugin_get_info(cpl_pluginlist *list);
44
45/*-----------------------------------------------------------------------------
46 Private function prototypes
47 -----------------------------------------------------------------------------*/
48
49static int _moons_molecfit_model_create(cpl_plugin *plugin);
50static int _moons_molecfit_model_exec(cpl_plugin *plugin);
51static int _moons_molecfit_model_destroy(cpl_plugin *plugin);
52static int
53_moons_molecfit_model(cpl_frameset *frameset, const cpl_parameterlist *parlist);
54
55/*-----------------------------------------------------------------------------
56 Static variables
57 -----------------------------------------------------------------------------*/
58
59static const char *const _moons_molecfit_model_description =
60 "Produces the model using molecfit\n"
61 "INPUT FRAMES\n"
62 " * file (SCI) with tag SCIENCE 1 file : "
63 "molecfit_model star file\n"
64 " * file (MOLECULES) with tag MOLECULES 1 file : "
65 "molecules list file\n"
66 "PRODUCTS\n"
67 " * GDAS User GDAS profile"
68 " * GDAS_BEFORE If ESO DB GDAS is used, file before the MJD-OBS"
69 " * GDAS_AFTER If ESO DB GDAS is used, file after the MJD-OBS"
70 "\n";
71
72/*-----------------------------------------------------------------------------
73 Function code
74 -----------------------------------------------------------------------------*/
75
76/*----------------------------------------------------------------------------*/
86/*----------------------------------------------------------------------------*/
87
88int
89cpl_plugin_get_info(cpl_pluginlist *list)
90{
91 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
92 cpl_plugin *plugin = &recipe->interface;
93
94 if (cpl_plugin_init(
95 plugin, CPL_PLUGIN_API, MOONS_BINARY_VERSION,
96 CPL_PLUGIN_TYPE_RECIPE, "moons_molecfit_model",
97 "Produces the instrumental response for relative flux calibration, "
98 "and the telluric absorption spectrum.",
99 _moons_molecfit_model_description, "Regis Haigron",
100 PACKAGE_BUGREPORT, moo_get_license(), _moons_molecfit_model_create,
101 _moons_molecfit_model_exec, _moons_molecfit_model_destroy)) {
102 cpl_msg_error(cpl_func, "Plugin initialization failed");
103 (void)cpl_error_set_where(cpl_func);
104 return 1;
105 }
106
107 if (cpl_pluginlist_append(list, plugin)) {
108 cpl_msg_error(cpl_func, "Error adding plugin to list");
109 (void)cpl_error_set_where(cpl_func);
110 return 1;
111 }
112
113 return 0;
114}
115
116/*----------------------------------------------------------------------------*/
124/*----------------------------------------------------------------------------*/
125
126static int
127_moons_molecfit_model_create(cpl_plugin *plugin)
128{
129 cpl_recipe *recipe;
130
131 /* Do not create the recipe if an error code is already set */
132 if (cpl_error_get_code() != CPL_ERROR_NONE) {
133 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
134 cpl_func, __LINE__, cpl_error_get_where());
135 return (int)cpl_error_get_code();
136 }
137
138 if (plugin == NULL) {
139 cpl_msg_error(cpl_func, "Null plugin");
140 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
141 }
142
143 /* Verify plugin type */
144 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
145 cpl_msg_error(cpl_func, "Plugin is not a recipe");
146 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
147 }
148
149 /* Get the recipe */
150 recipe = (cpl_recipe *)plugin;
151
152 /* Create the parameters list in the cpl_recipe object */
153 recipe->parameters = cpl_parameterlist_new();
154 if (recipe->parameters == NULL) {
155 cpl_msg_error(cpl_func, "Parameter list allocation failed");
156 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
157 }
158
159 moo_params *params = moo_params_new("moons", "moons_molecfit_model");
160
161 /* Fill the parameters list */
162 moo_params_add_keep_temp(params, recipe->parameters);
163 moo_params_add_molecfit_model(params, recipe->parameters);
164 moo_params_delete(params);
165
166 return 0;
167}
168
169/*----------------------------------------------------------------------------*/
175/*----------------------------------------------------------------------------*/
176
177static int
178_moons_molecfit_model_exec(cpl_plugin *plugin)
179{
180 cpl_recipe *recipe;
181 int recipe_status;
182 cpl_errorstate initial_errorstate = cpl_errorstate_get();
183
184 /* Return immediately if an error code is already set */
185 if (cpl_error_get_code() != CPL_ERROR_NONE) {
186 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
187 cpl_func, __LINE__, cpl_error_get_where());
188 return (int)cpl_error_get_code();
189 }
190
191 if (plugin == NULL) {
192 cpl_msg_error(cpl_func, "Null plugin");
193 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
194 }
195
196 /* Verify plugin type */
197 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
198 cpl_msg_error(cpl_func, "Plugin is not a recipe");
199 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
200 }
201
202 /* Get the recipe */
203 recipe = (cpl_recipe *)plugin;
204
205 /* Verify parameter and frame lists */
206 if (recipe->parameters == NULL) {
207 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
208 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
209 }
210 if (recipe->frames == NULL) {
211 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
212 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
213 }
214
215 /* Invoke the recipe */
216 recipe_status = _moons_molecfit_model(recipe->frames, recipe->parameters);
217
218 /* Ensure DFS-compliance of the products */
219 if (cpl_dfs_update_product_header(recipe->frames)) {
220 if (!recipe_status)
221 recipe_status = (int)cpl_error_get_code();
222 }
223
224 if (!cpl_errorstate_is_equal(initial_errorstate)) {
225 /* Dump the error history since recipe execution start.
226 At this point the recipe cannot recover from the error */
227 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
228 }
229
230 return recipe_status;
231}
232
233/*----------------------------------------------------------------------------*/
239/*----------------------------------------------------------------------------*/
240
241static int
242_moons_molecfit_model_destroy(cpl_plugin *plugin)
243{
244 cpl_recipe *recipe;
245
246 if (plugin == NULL) {
247 cpl_msg_error(cpl_func, "Null plugin");
248 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
249 }
250
251 /* Verify plugin type */
252 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
253 cpl_msg_error(cpl_func, "Plugin is not a recipe");
254 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
255 }
256
257 /* Get the recipe */
258 recipe = (cpl_recipe *)plugin;
259
260 cpl_parameterlist_delete(recipe->parameters);
261
262 return 0;
263}
264
265static cpl_error_code
266_moons_molecfit_model_check_sof(cpl_frameset *frameset,
267 const cpl_frame **sci_frame,
268 const cpl_frame **molecules_frame,
269 const cpl_frame **winc_frame)
270{
271 cpl_ensure_code(moo_dfs_set_groups(frameset) == CPL_ERROR_NONE,
272 cpl_error_get_code());
273 int i;
274
275 for (i = 0; i < cpl_frameset_get_size(frameset); ++i) {
276 cpl_frame *current_frame = cpl_frameset_get_position(frameset, i);
277 if (!strcmp(cpl_frame_get_tag(current_frame), MOONS_TAG_MOLECFIT_SCI)) {
278 *sci_frame = current_frame;
279 }
280 else if (!strcmp(cpl_frame_get_tag(current_frame),
281 MOONS_TAG_MOLECFIT_MOLECULES)) {
282 *molecules_frame = current_frame;
283 }
284 else if (!strcmp(cpl_frame_get_tag(current_frame),
285 MOONS_TAG_MOLECFIT_WINCLUDE)) {
286 *winc_frame = current_frame;
287 }
288 }
289 if (*sci_frame == NULL) {
290 return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
291 "SOF does not have any file tagged "
292 "with %s",
293 MOONS_TAG_MOLECFIT_SCI);
294 }
295
296 if (*molecules_frame == NULL) {
297 return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
298 "SOF does not have any file tagged "
299 "with %s",
300 MOONS_TAG_MOLECFIT_MOLECULES);
301 }
302
303 if (*winc_frame == NULL) {
304 return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
305 "SOF does not have any file tagged "
306 "with %s",
307 MOONS_TAG_MOLECFIT_WINCLUDE);
308 }
309 return CPL_ERROR_NONE;
310}
311
312/*----------------------------------------------------------------------------*/
319/*----------------------------------------------------------------------------*/
320static int
321_moons_molecfit_model(cpl_frameset *frameset, const cpl_parameterlist *parlist)
322{
323 /* parameters */
324 moo_mode_type mode;
325 const char *modename = NULL;
326 const cpl_frame *sci_frame = NULL;
327 const cpl_frame *molecule_frame = NULL;
328 const cpl_frame *winc_frame = NULL;
329 moo_molecfit_model_params *molecfit_model_params = NULL;
330
331 moo_molectable *atm_fitted = NULL;
332 moo_molectable *best_fitted_params = NULL;
333 moo_molectable *best_fitted_model = NULL;
334
335 char *best_fitted_params_name = NULL;
336 char *best_fitted_model_name = NULL;
337 char *atm_fitted_name = NULL;
338
339 moo_products *products =
340 moo_products_new(frameset, parlist, "moons_molecfit_model",
341 PACKAGE "/" PACKAGE_VERSION);
342
343 const moo_params *params = moo_products_get_params(products);
344 moo_try_check(molecfit_model_params =
345 moo_params_get_molecfit_model(params, parlist),
346 " ");
347
348 /* SOF file */
349 moo_try_check(_moons_molecfit_model_check_sof(frameset, &sci_frame,
350 &molecule_frame, &winc_frame),
351 " ");
352
353 moo_try_check(mode = moo_mode_get(sci_frame), " ");
354
355 modename = moo_mode_get_name(mode);
356
357 moo_try_check(best_fitted_params =
358 moo_molecfit_model(sci_frame, modename, molecule_frame,
359 winc_frame, &atm_fitted,
360 &best_fitted_model,
361 molecfit_model_params),
362 " ");
363 atm_fitted_name = cpl_sprintf("%s_%s.fits", MOONS_TAG_MOLECFIT_ATM_PARAMS,
364 moo_mode_get_name(mode));
365 best_fitted_params_name =
366 cpl_sprintf("%s_%s.fits", MOONS_TAG_MOLECFIT_BEST_FIT_PARAMS,
367 moo_mode_get_name(mode));
368 best_fitted_model_name =
369 cpl_sprintf("%s_%s.fits", MOONS_TAG_MOLECFIT_BEST_FIT_MODEL,
370 moo_mode_get_name(mode));
371
372 moo_try_check(moo_products_add_molectable(
373 products, best_fitted_params, CPL_FRAME_LEVEL_FINAL,
374 MOONS_TAG_MOLECFIT_BEST_FIT_PARAMS,
375 best_fitted_params_name, sci_frame),
376 " ");
377 moo_try_check(moo_products_add_molectable(products, best_fitted_model,
378 CPL_FRAME_LEVEL_INTERMEDIATE,
379 MOONS_TAG_MOLECFIT_BEST_FIT_MODEL,
380 best_fitted_model_name,
381 sci_frame),
382 " ");
383 moo_try_check(moo_products_add_molectable(products, atm_fitted,
384 CPL_FRAME_LEVEL_FINAL,
385 MOONS_TAG_MOLECFIT_ATM_PARAMS,
386 atm_fitted_name, sci_frame),
387 " ");
388
389moo_try_cleanup:
390 cpl_free(best_fitted_params_name);
391 cpl_free(best_fitted_model_name);
392 cpl_free(atm_fitted_name);
393 moo_molectable_delete(best_fitted_model);
394 moo_molectable_delete(atm_fitted);
395 moo_molectable_delete(best_fitted_params);
396 moo_molecfit_model_params_delete(molecfit_model_params);
397 moo_products_delete(products);
398 return (int)cpl_error_get_code();
399}
moo_mode_type moo_mode_get(const cpl_frame *frame)
Get the name of a mode from a frame.
Definition: moo_detector.c:224
const char * moo_mode_get_name(moo_mode_type type)
Get the name of a mode.
Definition: moo_detector.c:204
void moo_molectable_delete(moo_molectable *self)
Delete a moo_molectable.
void moo_molecfit_model_params_delete(moo_molecfit_model_params *self)
Delete a moo_molecfit_model_params.
Definition: moo_params.c:2278
void moo_params_delete(moo_params *self)
Delete a moo_params.
Definition: moo_params.c:85
cpl_error_code moo_params_add_molecfit_model(moo_params *self, cpl_parameterlist *list)
Add default parameters for molecfit_model.
Definition: moo_params.c:2373
moo_molecfit_model_params * moo_params_get_molecfit_model(const moo_params *self, const cpl_parameterlist *list)
Get molecfit model parameters from moons parameters list.
Definition: moo_params.c:1554
cpl_error_code moo_params_add_keep_temp(moo_params *self, cpl_parameterlist *list)
Add default parameters for keep-temp.
Definition: moo_params.c:932
moo_params * moo_params_new(const char *pid, const char *recipe_id)
Create a new moo_params.
Definition: moo_params.c:62
cpl_error_code moo_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: moo_dfs.c:206
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.
moo_products * moo_products_new(cpl_frameset *framelist, const cpl_parameterlist *parlist, const char *recid, const char *pipeline_id)
create a moo_product object for a recipe
Definition: moo_products.c:53
cpl_frame * moo_products_add_molectable(moo_products *self, moo_molectable *mtable, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a MOLECTABLE object
Definition: moo_products.c:600
const moo_params * moo_products_get_params(const moo_products *self)
get the moo_params object
Definition: moo_products.c:87
const char * moo_get_license(void)
Get the pipeline copyright and license.
Definition: moo_utils.c:81