MOONS Pipeline Reference Manual 0.13.2
moons_molecfit_correct.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 "moo_utils.h"
29#include "moo_pfits.h"
30#include "moo_dfs.h"
31#include "moo_params.h"
32#include "moo_drl.h"
33#include "moo_products.h"
34#include <cpl.h>
35#include "hdrl.h"
36#include <string.h>
37#include "moo_correct_tell.h"
38#include "moo_molecfit.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_correct_create(cpl_plugin *plugin);
50static int _moons_molecfit_correct_exec(cpl_plugin *plugin);
51static int _moons_molecfit_correct_destroy(cpl_plugin *plugin);
52static int _moons_molecfit_correct(cpl_frameset *frameset,
53 const cpl_parameterlist *parlist);
54
55/*-----------------------------------------------------------------------------
56 Static variables
57 -----------------------------------------------------------------------------*/
58
59static const char *const _moons_molecfit_correct_description =
60 "Apply telluric correction on science files\n"
61 "INPUT FRAMES\n"
62 " * file (SCI) with tag SCIENCE 1 to n files : "
63 " star file to correct \n"
64 " * file (TELLURIC_CORR) with tag TELLURIC_CORR 1 file : "
65 "telluric correction file\n"
66 "PRODUCTS\n"
67 " * SCIENCE_TELLCORSPECTRA_i.fits (SCI) with tag SCIENCE_TELLCORSPECTRA : "
68 "science with telluric correction apply"
69 "\n";
70
71/*-----------------------------------------------------------------------------
72 Function code
73 -----------------------------------------------------------------------------*/
74
75/*----------------------------------------------------------------------------*/
85/*----------------------------------------------------------------------------*/
86
87int
88cpl_plugin_get_info(cpl_pluginlist *list)
89{
90 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
91 cpl_plugin *plugin = &recipe->interface;
92
93 if (cpl_plugin_init(plugin, CPL_PLUGIN_API, MOONS_BINARY_VERSION,
94 CPL_PLUGIN_TYPE_RECIPE, "moons_molecfit_correct",
95 "Apply telluric correction to the science",
96 _moons_molecfit_correct_description, "Regis Haigron",
97 PACKAGE_BUGREPORT, moo_get_license(),
98 _moons_molecfit_correct_create,
99 _moons_molecfit_correct_exec,
100 _moons_molecfit_correct_destroy)) {
101 cpl_msg_error(cpl_func, "Plugin initialization failed");
102 (void)cpl_error_set_where(cpl_func);
103 return 1;
104 }
105
106 if (cpl_pluginlist_append(list, plugin)) {
107 cpl_msg_error(cpl_func, "Error adding plugin to list");
108 (void)cpl_error_set_where(cpl_func);
109 return 1;
110 }
111
112 return 0;
113}
114
115
116/*----------------------------------------------------------------------------*/
124/*----------------------------------------------------------------------------*/
125
126static int
127_moons_molecfit_correct_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_correct");
160
161 /* Fill the parameters list */
162 moo_params_add_keep_temp(params, recipe->parameters);
163 moo_params_delete(params);
164
165 return 0;
166}
167
168
169/*----------------------------------------------------------------------------*/
175/*----------------------------------------------------------------------------*/
176
177static int
178_moons_molecfit_correct_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_correct(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
234/*----------------------------------------------------------------------------*/
240/*----------------------------------------------------------------------------*/
241
242static int
243_moons_molecfit_correct_destroy(cpl_plugin *plugin)
244{
245 cpl_recipe *recipe;
246
247 if (plugin == NULL) {
248 cpl_msg_error(cpl_func, "Null plugin");
249 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
250 }
251
252 /* Verify plugin type */
253 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
254 cpl_msg_error(cpl_func, "Plugin is not a recipe");
255 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
256 }
257
258 /* Get the recipe */
259 recipe = (cpl_recipe *)plugin;
260
261 cpl_parameterlist_delete(recipe->parameters);
262
263 return 0;
264}
265
266static cpl_error_code
267_moons_molecfit_correct_check_sof(cpl_frameset *frameset,
268 cpl_frameset **sci_frameset,
269 const cpl_frame **tell_frame)
270{
271 cpl_ensure_code(moo_dfs_set_groups(frameset) == CPL_ERROR_NONE,
272 cpl_error_get_code());
273 int i;
274
275 moo_try_check(*sci_frameset = cpl_frameset_new(), " ");
276
277 for (i = 0; i < cpl_frameset_get_size(frameset); ++i) {
278 cpl_frame *current_frame = cpl_frameset_get_position(frameset, i);
279 if (!strcmp(cpl_frame_get_tag(current_frame), MOONS_TAG_MOLECFIT_SCI)) {
280 cpl_frame *new_frame = cpl_frame_duplicate(current_frame);
281 cpl_frameset_insert(*sci_frameset, new_frame);
282 }
283 else if (!strcmp(cpl_frame_get_tag(current_frame),
284 MOONS_TAG_TELLURIC_CORR)) {
285 *tell_frame = current_frame;
286 }
287 }
288 if (*tell_frame == NULL) {
289 return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
290 "SOF does not have any file tagged "
291 "with %s",
292 MOONS_TAG_TELLURIC_CORR);
293 }
294
295moo_try_cleanup:
296 return CPL_ERROR_NONE;
297}
298
299
300static cpl_frameset *
301_moons_correct_set(cpl_frameset *set,
302 moo_telluric *tell,
303 moo_products *products)
304{
305 moo_sci *sci = NULL;
306 char *sci_name = NULL;
307 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, NULL);
308 cpl_ensure(tell != NULL, CPL_ERROR_NULL_INPUT, NULL);
309 cpl_ensure(products != NULL, CPL_ERROR_NULL_INPUT, NULL);
310
311 cpl_frameset *result = cpl_frameset_new();
312 int i;
313
314 cpl_errorstate prestate = cpl_errorstate_get();
315
316 for (i = 0; i < cpl_frameset_get_size(set); ++i) {
317 const cpl_frame *current_frame = NULL;
318 moo_try_check(current_frame = cpl_frameset_get_position_const(set, i),
319 " ");
320 sci = moo_sci_create(current_frame);
321 moo_try_check(moo_correct_tell_science(sci, tell), " ");
322 sci_name =
323 cpl_sprintf("%s_%d.fits", MOONS_TAG_SCIENCE_TELLCORRSPECTRA, i);
324 cpl_frame *product =
325 moo_products_add_sci(products, sci, CPL_FRAME_LEVEL_FINAL,
326 MOONS_TAG_SCIENCE_TELLCORRSPECTRA, sci_name,
327 current_frame);
328 cpl_free(sci_name);
329 moo_try_check(cpl_frameset_insert(result, cpl_frame_duplicate(product)),
330 " ");
331 moo_sci_delete(sci);
332 sci = NULL;
333 }
334moo_try_cleanup:
335 if (!cpl_errorstate_is_equal(prestate)) {
336 cpl_msg_error(__func__, "dump error ");
337 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
338 moo_sci_delete(sci);
339 cpl_frameset_delete(result);
340 result = NULL;
341 cpl_free(sci_name);
342 }
343 return result;
344}
345/*----------------------------------------------------------------------------*/
352/*----------------------------------------------------------------------------*/
353static int
354_moons_molecfit_correct(cpl_frameset *frameset,
355 const cpl_parameterlist *parlist)
356{
357 /* parameters */
358 cpl_frameset *science_set = NULL;
359 const cpl_frame *tell_frame = NULL;
360 moo_telluric *tell = NULL;
361 cpl_frameset *result_set = NULL;
362
363 moo_products *products =
364 moo_products_new(frameset, parlist, "moons_molecfit_correct",
365 PACKAGE "/" PACKAGE_VERSION);
366
367
368 /* SOF file */
369 moo_try_check(_moons_molecfit_correct_check_sof(frameset, &science_set,
370 &tell_frame),
371 " ");
372
373 moo_try_check(tell = moo_telluric_load(tell_frame), " ");
374 moo_try_check(result_set = _moons_correct_set(science_set, tell, products),
375 " ");
376
377moo_try_cleanup:
378 moo_products_delete(products);
379 cpl_frameset_delete(science_set);
381 cpl_frameset_delete(result_set);
382
383 return (int)cpl_error_get_code();
384}
void moo_params_delete(moo_params *self)
Delete a moo_params.
Definition: moo_params.c:85
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
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_telluric * moo_telluric_load(const cpl_frame *frame)
Load a TELLURIC frame and create a moo_telluric.
Definition: moo_telluric.c:405
void moo_telluric_delete(moo_telluric *self)
Delete a moo_telluric.
Definition: moo_telluric.c:334
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
cpl_error_code moo_correct_tell_science(moo_sci *sci, moo_telluric *tell)
Apply the telluric correction to SCI.
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_sci(moo_products *self, moo_sci *sci, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a SCI object
Definition: moo_products.c:420
const char * moo_get_license(void)
Get the pipeline copyright and license.
Definition: moo_utils.c:81