X-shooter Pipeline Reference Manual 3.8.15
xsh_molecfit_calctrans.c
Go to the documentation of this file.
1/*
2 * This file is part of the ESO X-Shooter Pipeline
3 * Copyright (C) 2001-2018 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/*----------------------------------------------------------------------------*/
24/*----------------------------------------------------------------------------*/
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28/* xshooter headers */
29#include <xsh_error.h>
30#include <xsh_utils.h>
31
32/* Molecfit Model */
34#include <mf_wrap_config.h>
35#include <telluriccorr.h>
36//#include <mf_spectrum.h>
37//#include <mf_wrap.h>
38/*----------------------------------------------------------------------------*/
42/*----------------------------------------------------------------------------*/
43
44/*---------------------------------------------------------------------------
45 Recipe Defines
46 ---------------------------------------------------------------------------*/
47
48#define RECIPE_ID "xsh_molecfit_calctrans"
49#define RECIPE_AUTHOR "N. Fernando, B. Miszalski"
50#define RECIPE_CONTACT "nuwanthika.fernando@partner.eso.org"
51
52/*---------------------------------------------------------------------------
53 Functions prototypes
54 ---------------------------------------------------------------------------*/
55
56/*
57 * Plugin initalization, execute and cleanup handlers
58 */
59
60int xsh_molecfit_calctrans_create(cpl_plugin *);
61int xsh_molecfit_calctrans_exec(cpl_plugin *);
62int xsh_molecfit_calctrans_destroy(cpl_plugin *);
63
64/* The actual executor function */
65int xsh_molecfit_calctrans(cpl_frameset *frameset, const cpl_parameterlist *parlist);
66
67/*----------------------------------------------------------------------------*/
71/*----------------------------------------------------------------------------*/
72
74"Applies molecfit_calctrans to input spectra";
75
77"Applies molecfit_calctrans to input spectra";
78
79/*----------------------------------------------------------------------------*/
83/*----------------------------------------------------------------------------*/
84
85/*----------------------------------------------------------------------------*/
89/*----------------------------------------------------------------------------*/
90
91
92/*----------------------------------------------------------------------------*/
96/*----------------------------------------------------------------------------*/
97
98/*----------------------------------------------------------------------------*/
102/*----------------------------------------------------------------------------*/
103
106/*----------------------------------------------------------------------------*/
110/*----------------------------------------------------------------------------*/
111
112
113/*--------------------------------------------------------------------------*/
122/*--------------------------------------------------------------------------*/
123
124int cpl_plugin_get_info(cpl_pluginlist *list) {
125 cpl_recipe *recipe = NULL;
126 cpl_plugin *plugin = NULL;
127
128 recipe = cpl_calloc(1, sizeof(*recipe));
129 if ( recipe == NULL ){
130 return -1;
131 }
132
133 plugin = &recipe->interface ;
134
135 cpl_plugin_init(plugin,
136 CPL_PLUGIN_API, /* Plugin API */
137 XSH_BINARY_VERSION, /* Plugin version */
138 CPL_PLUGIN_TYPE_RECIPE, /* Plugin type */
139 RECIPE_ID, /* Plugin name */
141 xsh_molecfit_calctrans_description, /* Detailed help */
142 RECIPE_AUTHOR, /* Author name */
143 RECIPE_CONTACT, /* Contact address */
144 xsh_get_license(), /* Copyright */
148
149 cpl_pluginlist_append(list, plugin);
150
151 return (cpl_error_get_code() != CPL_ERROR_NONE);
152 }
153
154/*--------------------------------------------------------------------------*/
164/*--------------------------------------------------------------------------*/
165
166int xsh_molecfit_calctrans_create(cpl_plugin *plugin){
167 cpl_recipe *recipe = NULL;
168
169 /* Reset library state */
170 xsh_init();
171
172 /* Check input */
173 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin");
174
175 /* Get the recipe out of the plugin */
176 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
177 CPL_ERROR_TYPE_MISMATCH,
178 "Plugin is not a recipe");
179
180 recipe = (cpl_recipe *)plugin;
181
182 /* Create the parameter list in the cpl_recipe object */
183 recipe->parameters = cpl_parameterlist_new();
184 assure( recipe->parameters != NULL,
185 CPL_ERROR_ILLEGAL_OUTPUT,
186 "Memory allocation failed!");
187
188 //xsh_molecfit_calctrans parameters
189
190 //MOLECFIT_PARAMETER_USE_INPUT_KERNEL
191 //use_input_kernel
192 check(xsh_parameters_new_boolean(recipe->parameters,RECIPE_ID,
193 MOLECFIT_PARAMETER_USE_INPUT_KERNEL,CPL_TRUE,
194 "If TRUE, then the input KERNEL_LIBRARY_XXX given in the SOF is used, where XXX is UVB, VIS or NIR. If FALSE, or if the KERNEL_LIBRARY_XXX is not given, then the information stored in BEST_FIT_PARAMETERS_YYY_XXX will be used to compute the line spread function, where YYY is SCI or STD, and XXX is UVB, VIS or NIR."));
195
196 //apply_wlc_corr
197 //check(xsh_parameters_new_boolean(recipe->parameters,RECIPE_ID,
198 //"APPLY_WLC_CORR",CPL_FALSE,
199 //""));
200
201 //MF_PARAMETERS_SCALE_TO_PWV
202 //scale_to_obs_pwv
203//check(xsh_parameters_new_string(recipe->parameters,RECIPE_ID,
204//MF_PARAMETERS_SCALE_TO_PWV,"TEL AMBI PWV START",
205//" \
206// "));
209//check(xsh_parameters_new_boolean(recipe->parameters,RECIPE_ID,
210//MOLECFIT_PARAMETER_USE_MOLEC_DATABASE,false,
211//" \
212// "));
213
214 cleanup:
215 if ( cpl_error_get_code() != CPL_ERROR_NONE ){
216 xsh_error_dump(CPL_MSG_ERROR);
217 return 1;
218 }
219 else {
220 return 0;
221 }
222}
223
224
225/*--------------------------------------------------------------------------*/
231/*--------------------------------------------------------------------------*/
232
233int xsh_molecfit_calctrans_exec(cpl_plugin *plugin) {
234 cpl_recipe *recipe = NULL;
235
236 /* Check parameter */
237 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
238
239 /* Get the recipe out of the plugin */
240 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
241 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
242
243 recipe = (cpl_recipe *)plugin;
244 /* Check recipe */
245 xsh_molecfit_calctrans( recipe->frames, recipe->parameters);
246
247 cleanup:
248 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
249 xsh_error_dump(CPL_MSG_ERROR);
250 cpl_error_reset();
251 return 1;
252 }
253 else {
254 return 0;
255 }
256}
257
258/*--------------------------------------------------------------------------*/
264/*--------------------------------------------------------------------------*/
265int xsh_molecfit_calctrans_destroy(cpl_plugin *plugin)
266{
267 cpl_recipe *recipe = NULL;
268
269 /* Check parameter */
270 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
271
272 /* Get the recipe out of the plugin */
273 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
274 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
275
276 recipe = (cpl_recipe *)plugin;
277
278 xsh_free_parameterlist(&recipe->parameters);
279
280 cleanup:
281 if (cpl_error_get_code() != CPL_ERROR_NONE)
282 {
283 return 1;
284 }
285 else
286 {
287 return 0;
288 }
289}
290
291
292cpl_error_code xsh_molecfit_calc_setup_frameset(cpl_frameset* frameset,cpl_parameterlist* list,const char* arm,const char* input_name){
293
294 const char* tag;
295 //check the input frame (SCIENCE); we know the tag already thanks to the input_name parameter
296 //so no need to search frameset for it
297 //input_name may be one of the following:
298 //SCI_SLIT_FLUX_IDP_XXX
299 //SCI_SLIT_FLUX_MERGE1D_XXX
300 //TELL_SLIT_MERGE1D_XXX
301 //TELL_SLIT_FLUX_MERGE1D_XXX
302 //STD_SLIT_FLUX_IDP_YYY_XXX
303 //where XXX is the arm and YYY is NOD, STARE or OFFSET
304
305 tag = input_name;
306 cpl_frame* f = cpl_frameset_find(frameset,input_name);
307 cpl_frame_set_group(f,CPL_FRAME_GROUP_RAW);
308
309 //cpl_frame_set_type(f,CPL_FRAME_TYPE_NONE);
310 //cpl_frame_set_tag(f,"SCIENCE");
311 //cpl_frame_set_level(f,CPL_FRAME_LEVEL_NONE);
312
313 //other inputs
314/*
315 //KERNEL_LIBRARY_XXX
316 tag = cpl_sprintf("%s_%s",MOLECFIT_KERNEL_LIBRARY,arm);
317 f = cpl_frameset_find(frameset,tag);
318 if(f){
319 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
320 }
321 //ATM_PARAMETERS_YYY_XXX
322 tag = cpl_sprintf("%s_%s",MOLECFIT_ATM_PARAMETERS,arm);
323 f = cpl_frameset_find(frameset,tag);
324 if(f){
325 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
326 }
327 //BEST_FIT_PARAMETERS_YYY_XXX
328 tag = cpl_sprintf("%s_%s",MOLECFIT_BEST_FIT_PARAMETERS,arm);
329 f = cpl_frameset_find(frameset,tag);
330 if(f){
331 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
332 }
333 //BEST_FIT_MODEL_YYY_XXX
334 tag = cpl_sprintf("%s_%s",MOLECFIT_BEST_FIT_MODEL,arm);
335 f = cpl_frameset_find(frameset,tag);
336 if(f){
337 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
338 }
339 //MODEL_MOLECULES_XXX
340 tag = cpl_sprintf("%s_%s",MOLECFIT_MODEL_MOLECULES,arm);
341 f = cpl_frameset_find(frameset,tag);
342 if(f){
343 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
344 }
345 */
346
347}
348
349/*--------------------------------------------------------------------------*/
358/*--------------------------------------------------------------------------*/
359
360
361 /* -----------------------------------------------------------------------------------------------------/
362 *
363 * OVERVIEW OF STEPS
364 * 1. DO SOME ERROR CHECKING ON FRAMESET? (may be done later in setup config, but just being thorough)
365 * 1.5 GET *TAG* OF INPUT SCIENCE from FRAMSET using either MOLECFIT_STD_MODEL, MOLECFIT_SCIENCE_CALCTRANS or MOLECFIT_SCIENCE
366 * 1.55 (Check for YYY in this FILENAME, in case we need it later...)
367 * 2. DETERMINE IF SUFFIX NEEDED FROM DATASET (e.g. UVB/VIS/NIR for xshooter)
368 * 3. SETUP INPUT FILE NAME TAGS
369 * 4. SETUP OUTPUT FILE NAME TAGS
370 * 5. SETUP PARAMETERS (e.g. --list_molec, etc.)
371 * N.B. We expect to be provided a FITS binary table of WAVE_INCLUDE & MOLECULES params,
372 * but FOR NOW, we setup these values internally via the string parameter versions.
373 * 6. SETUP *EXTRA* PARAMETERS
374 *
375 *
376 -------------------------------------------------------------------------------------------------------*/
377
378 cpl_error_code xsh_molecfit_calctrans_config(cpl_frameset *frameset, const cpl_parameterlist *parlist,
379 cpl_parameterlist* ilist, cpl_parameterlist* iframelist){
380
381 cpl_msg_info(cpl_func,"xsh_molecfit_calctrans_config");
382 cpl_msg_info(cpl_func,"FRAMESET");
383 //cpl_frameset_dump(frameset,stdout);
384 cpl_msg_info(cpl_func,"PARLIST");
385 cpl_parameterlist_dump(parlist,stdout);
386 //cpl_msg_info(cpl_func,"");
387
388 cpl_parameterlist* iframe = cpl_parameterlist_new();
389 //INPUTNAME == input tag name
390 //ARM == UVB, VIS, NIR
391 //OBSMODE == NOD, STARE or OFFSET; If none of these, it is set to DEFAULT
392 //IDP (bool) == TRUE or FALSE
393 //1. Get all the input params into the iframe parameterlist (INPUTNAME,ARM,OBSMODE,IDP)
394 cpl_error_code err= CPL_ERROR_NONE;
395 err=xsh_molecfit_utils_find_input_frame(frameset, iframe);
396 if(err){
397 return err;
398 }
399
400
401 const char* input_name = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"INPUTNAME"));
402 const char* arm = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"ARM"));
403 const char* obsmode = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"OBSMODE"));
404 const char* is_idp = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"IDP"));
405 const char* fname = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"INPUTFILENAME"));
406
407 cpl_msg_info(cpl_func,"iframe details; INPUTNAME: %s; ARM: %s; IDP: %s; OBSMODE: %s; INPUTFILENAME: %s",input_name,arm,is_idp,obsmode,fname);
408
409 //add iframe parameters (INPUTNAME,ARM,OBSMODE,IDP) to iframelist so that we can access them from xsh_molecfit_model
410 //these are not added to ilist, as they are only meant to be instrument dependent molecfit parameters
411 err = cpl_parameterlist_append(iframelist,cpl_parameterlist_find(iframe,"INPUTNAME"));
412 err = cpl_parameterlist_append(iframelist,cpl_parameterlist_find(iframe,"ARM"));
413 err = cpl_parameterlist_append(iframelist,cpl_parameterlist_find(iframe,"OBSMODE"));
414 err = cpl_parameterlist_append(iframelist,cpl_parameterlist_find(iframe,"IDP"));
415 err = cpl_parameterlist_append(iframelist,cpl_parameterlist_find(iframe,"INPUTFILENAME"));
416
417 //cpl_msg_info(cpl_func,"finishing up xsh_molecfit_model list_molec: %s",val);
418
419
420 //return err;
421
422 //5. SETUP PARAMETERS (e.g. --list_molec, etc.)
424 //(We may define specific values for its parameters later)
425 /*By default, these are all NULL -- just to spell it out here, so we remind ourselves that we are satisfying the requirements*/
426
427
428 cpl_boolean USE_INPUT_KERNEL;
429 cpl_boolean APPLY_WLC_CORR;
430 //const char* SCALE_TO_OBS_PWV;
431 //cpl_boolean USE_MOLEC_DATABASE;
432
433 const char* CALCTRANS_MAPPING_KERNEL;
434 char * MAPPING_ATMOSPHERIC;
435 char * MAPPING_CONVOLVE;
436 cpl_boolean USE_ONLY_INPUT_PRIMARY_DATA;
437 int USE_DATA_EXTENSION_AS_DFLUX;
438 int USE_DATA_EXTENSION_AS_MASK;
439 cpl_boolean CHIP_EXTENSIONS;
440
441 //the input framset will have _YYY_XXX suffixes ; we have to be mindful of that!
442
443
444 //this maps to parameters->mapping_kernel which is a const char*
445 //cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_PARAMETER_CALCTRANS_MAPPING_KERNEL,CPL_TYPE_STRING,NULL,NULL,"1"));
446 cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_PARAMETER_CALCTRANS_MAPPING_KERNEL,CPL_TYPE_STRING,NULL,NULL,"0,1"));
447 cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_PARAMETER_USE_INPUT_KERNEL,CPL_TYPE_BOOL,NULL,NULL,CPL_FALSE));
448 //cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_PARAMETER_CALCTRANS_MAPPING_KERNEL,CPL_TYPE_INT,NULL,NULL,1));
449
450 const char* input_tag;
451 //const char* combined_suffix = cpl_sprintf("%s_%s","SCI",arm);
452 //first try "SCI" as YYY
453 //if the sof does not have ATM_PARAMETER_YYY_XXX, add this default param
454 /*input_tag = mf_wrap_tag_suffix(MOLECFIT_ATM_PARAMETERS,combined_suffix,CPL_FALSE);
455 if(!cpl_frameset_find(frameset,input_tag)){
456 cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_ATM_PARAMETERS,CPL_TYPE_STRING,NULL,NULL,"NULL"));
457 }
458 //if the sof does not have BEST_FIT_PARAMETERS_YYY_XXX, add this default param
459 input_tag = mf_wrap_tag_suffix(MOLECFIT_BEST_FIT_PARAMETERS,combined_suffix,CPL_FALSE);
460 if(!cpl_frameset_find(frameset,input_tag)){
461 cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_BEST_FIT_PARAMETERS,CPL_TYPE_STRING,NULL,NULL,"NULL"));
462 }
463 //if the sof does not have BEST_FIT_MODEL_YYY_XXX, add this default param
464 input_tag = mf_wrap_tag_suffix(MOLECFIT_BEST_FIT_MODEL,combined_suffix,CPL_FALSE);
465 if(!cpl_frameset_find(frameset,input_tag)){
466 cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_BEST_FIT_MODEL,CPL_TYPE_STRING,NULL,NULL,"auto"));
467 }*/
468
469/* input_tag = mf_wrap_tag_suffix(MOLECFIT_KERNEL_LIBRARY,arm,CPL_FALSE);
470 if(!cpl_frameset_find(frameset,input_tag)){
471 //cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_MODEL_MAPPING_KERNEL,CPL_TYPE_STRING,NULL,NULL,"NULL"));
472 cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_PARAMETER_USE_INPUT_KERNEL,CPL_TYPE_BOOL,NULL,NULL,false));
473 }
474 //if we have an actual input kernel, we will have to set MOLECFIT_MODEL_MAPPING_KERNEL!
475
476*/
477
478
479
480 //if the sof does not have MODEL_MOLECULES_XXX, add this default param
481 //input_tag = mf_wrap_tag_suffix(MOLECFIT_MODEL_MOLECULES,arm,CPL_FALSE);
482 //if(!cpl_frameset_find(frameset,input_tag)){
483 // cpl_parameterlist_append(ilist,cpl_parameter_new_value(MOLECFIT_MODEL_MOLECULES,CPL_TYPE_STRING,NULL,NULL,"auto"));
484 // }
485
486 //FOR ALL CASES, even if IDP or not
487
488 //CALCTRANS_MAPPING_KERNEL = 1;
489 //cpl_propertylist_update_string(ilist,"USE_DATA_EXTENSION_AS_DFLUX",USE_DATA_EXTENSION_AS_DFLUX);
490 //cpl_parameterlist_append(ilist,cpl_parameter_new_value("CALCTRANS_MAPPING_KERNEL",CPL_TYPE_INT,NULL,NULL,CALCTRANS_MAPPING_KERNEL));
491
492 //IDP format...
493 if (!strcmp(is_idp,"TRUE")){
494 USE_ONLY_INPUT_PRIMARY_DATA = CPL_FALSE;
495 USE_DATA_EXTENSION_AS_DFLUX = 0;
496 MAPPING_ATMOSPHERIC = "0,1";
497 MAPPING_CONVOLVE = "0,1";
498
499 }
500 else {
501 USE_ONLY_INPUT_PRIMARY_DATA = CPL_TRUE;
502 USE_DATA_EXTENSION_AS_DFLUX = 1;
503 MAPPING_ATMOSPHERIC = "1";
504 MAPPING_CONVOLVE = "1";
505
506 }
507 cpl_parameterlist_append(ilist,cpl_parameter_new_value("USE_ONLY_INPUT_PRIMARY_DATA",CPL_TYPE_BOOL,NULL,NULL,USE_ONLY_INPUT_PRIMARY_DATA));
508 cpl_parameterlist_append(ilist,cpl_parameter_new_value("USE_DATA_EXTENSION_AS_DFLUX",CPL_TYPE_INT,NULL,NULL,USE_DATA_EXTENSION_AS_DFLUX));
509 cpl_parameterlist_append(ilist,cpl_parameter_new_value("MAPPING_ATMOSPHERIC",CPL_TYPE_STRING,NULL,NULL,MAPPING_ATMOSPHERIC));
510 cpl_parameterlist_append(ilist,cpl_parameter_new_value("MAPPING_CONVOLVE",CPL_TYPE_STRING,NULL,NULL,MAPPING_CONVOLVE));
511
512
513
514 //default is 0 - do not need to set?
515 USE_DATA_EXTENSION_AS_MASK = 0;
516 cpl_parameterlist_append(ilist,cpl_parameter_new_value("USE_DATA_EXTENSION_AS_MASK",CPL_TYPE_INT,NULL,NULL,USE_DATA_EXTENSION_AS_MASK));
517
518
519 CHIP_EXTENSIONS = CPL_FALSE ;//e-3;//0.001;
520 //cpl_propertylist_update_string(ilist,"WLG_TO_MICRON",WLG_TO_MICRON);
521 cpl_parameterlist_append(ilist,cpl_parameter_new_value("CHIP_EXTENSIONS",CPL_TYPE_BOOL, NULL ,NULL, CHIP_EXTENSIONS));
522
523 //cpl_msg_info(cpl_func,"calling xsh_molecfit_model_spec_header_calcs with fname = %s",fname);
524 //err = xsh_molecfit_model_spec_header_calcs(fname,arm,ilist);
525
526 //CONTINUUM_CONST
527 //this is handled in xsh_molecfit_model_spec_data_calcs()
528
529 //free up iframe
530 //have to do this at the end, otherwise strings (e.g. fname) get deleted
531 //cpl_parameterlist_delete(iframe);
532
533 return err;
534 }
535
536
537/*Instrument sid- example instrument - XSHOOTER?*/
538int xsh_molecfit_calctrans(cpl_frameset *frameset, const cpl_parameterlist *parlist)
539{
540 //cpl_errorstate_ensure(frameset && parlist, CPL_ERROR_NULL_INPUT, return, CPL_ERROR_NULL_INPUT, 'NULL input: framset and/or parlist');
541 cpl_error_code err= CPL_ERROR_NONE;
542
543 //INPUT FRAMES WILL BE NAMED DIFFERENT TO MOLECFIT_SCIENCE, MOLECFIT_STD* etc.
544 //err = xsh_check_and_set_input_tags(frameset); //INSTRUMENT_SPECIFIC
545
546 //TO WRITE
547 //err = mf_wrap_calc_preconfig_check(frameset, parlist);/*Check parameters and frameset for correct inputs - returns CPL_ERROR*/
548
549 cpl_parameterlist* ilist = cpl_parameterlist_new();
550 cpl_parameterlist* iframelist = cpl_parameterlist_new();
551 cpl_errorstate initial_errorstate = cpl_errorstate_get();
552 // get instrument specific parameter defaults
553 err = xsh_molecfit_calctrans_config(frameset,parlist,ilist,iframelist);
554 if(err){
555 return err;
556 }
557
558 //these are in iframelist, so they don't end up as input parameters for molecfit via
559 const char* input_name = cpl_parameter_get_string(cpl_parameterlist_find(iframelist,"INPUTNAME"));
560 const char* arm = cpl_parameter_get_string(cpl_parameterlist_find(iframelist,"ARM"));
561 const char* obsmode = cpl_parameter_get_string(cpl_parameterlist_find(iframelist,"OBSMODE"));
562 const char* is_idp = cpl_parameter_get_string(cpl_parameterlist_find(iframelist,"IDP"));
563 const char* fname = cpl_parameter_get_string(cpl_parameterlist_find(iframelist,"INPUTFILENAME"));
564
565 //if MOLECFIT_BEST_FIT_PARAMETERS_STD
566
567 const char* bf_sci = cpl_sprintf("%s_%s_%s",MOLECFIT_BEST_FIT_PARAMETERS,"SCI",arm);
568 const char* bf_std = cpl_sprintf("%s_%s_%s",MOLECFIT_BEST_FIT_PARAMETERS,"STD",arm);
569 const char* combined_suffix = cpl_sprintf("%s_%s",(strstr(input_name,"SCI")) ? "SCI" : "STD",arm);
570
571 //fix for PIPE-10006
572 if(cpl_frameset_find(frameset, bf_sci)){
573 combined_suffix = cpl_sprintf("%s_%s","SCI",arm);
574 }
575 else if(cpl_frameset_find(frameset, bf_std)){
576 combined_suffix = cpl_sprintf("%s_%s","STD",arm);
577 }
578
579 cpl_msg_info(cpl_func,"params retrieved from iframelist");
580
581
582 //Calculate CONTINUUM_CONST
583 //err = xsh_molecfit_model_spec_data_calcs(data,is_idp,ilist);
584
585 //parlist2 is NOW called mergedlist
586 cpl_parameterlist* mergedlist = cpl_parameterlist_new();
587
588 cpl_msg_info(cpl_func,"calling mf_wrap_merge_parameterlists");
589 err = mf_wrap_merge_parameterlists(ilist, parlist,mergedlist);
590
591 cpl_msg_info(cpl_func,"calling xsh_molecfit_setup_frameset");
592 err = xsh_molecfit_calc_setup_frameset(frameset,mergedlist,arm,input_name);
593
594
595 //err = set_output_filename_suffix(suffix, parlist); // This could be moved to instlist create function mf_inst_config();
596
597 cpl_msg_info(cpl_func,"calling cpl_fits_count_extensions");
598 //cpl_size n_ext = cpl_fits_count_extensions(fname);
599
600 mf_wrap_fits * data = NULL;
601 data = mf_wrap_fits_load(fname, CPL_FALSE);
602
603 //err = mf_wrap_calc_data(data,fname); // parlist2, parameters->use_only_input_pri_ext);
604 cpl_msg_info(cpl_func,"AFTER mf_wrap_calc_data() next=%d ; %s",data->n_ext,cpl_error_get_message());
605
606 //mf_wrap_model_parameter parameters = mf_wrap_config_init(frameset, parlist2);
607 cpl_msg_info(cpl_func,"calling mf_wrap_config_calc_init");
608 //cpl_propertylist_dump(data->v_ext[0].header,stdout);
609
610 molecfit_calctrans_parameter* parameters = mf_wrap_config_calc_init(frameset,mergedlist,data->v_ext[0].header, data->n_ext, combined_suffix);
611 //TODO: Do we need to add code from /* Recipe Parameters : Need scientific_header_primary */ in molecfit_calctrans.c????
612 cpl_msg_info(cpl_func,"AFTER mf_wrap_config_calc_init() %s",cpl_error_get_message());
613 //cpl_frame* input_frame = cpl_frameset_find(frameset,input_name);
614
615 err = mf_wrap_data_convert_to_table( data,
616 parameters->chip_extensions,
617 parameters->use_only_input_pri_ext,
618 parameters->dflux_extension_data,
619 parameters->mask_extension_data,
620 parameters->mf_config->parameters->inputs.column_lambda,
621 parameters->mf_config->parameters->inputs.column_flux,
622 parameters->mf_config->parameters->inputs.column_dflux,
623 parameters->mf_config->parameters->inputs.column_mask);
624 cpl_msg_info(cpl_func,"AFTER mf_wrap_data_convert_to_table() %s",cpl_error_get_message());
625
626
627
628 cpl_msg_info(cpl_func,"calling mf_wrap_calc_molecules");
629 //LOAD MODEL_MOLECULES
630 cpl_table *molecules = NULL;
631 err= mf_wrap_calc_molecules(frameset,&molecules,arm);
632
633 //LOAD CALCTRANS_MAPPING_KERNEL // CALCTRANS_KERNEL_LIBRARY
634 mf_wrap_fits *kernel_data = NULL;
635 cpl_table *mapping_kernel = NULL;
636
637 err= mf_wrap_calc_kernel_library(kernel_data,&mapping_kernel,frameset,parameters,arm);
638
639 //LOAD MAPPING_ATMOSPHERIC
640 cpl_table *mapping_atmospheric = NULL;
641 err= mf_wrap_calc_mapping_atm(frameset,&mapping_atmospheric,parameters,arm);
642
643 //LOAD MAPPING_CONVOLVE
644 cpl_table *mapping_convolve = NULL;
645 err= mf_wrap_calc_mapping_conv(frameset,&mapping_convolve,parameters,arm);
646 /*** Save generic output files */
647 if (!err) {
648
649 cpl_msg_info(cpl_func, "Save generic multi-extension output FITS file ('%s','%s') ...", MOLECFIT_TELLURIC_DATA, MOLECFIT_TELLURIC_CORR);
650
651 const char* output_fname = mf_wrap_tag_suffix(MOLECFIT_LBLRTM_RESULTS,arm,CPL_TRUE);
652 const char* tag_name = mf_wrap_tag_suffix(MOLECFIT_LBLRTM_RESULTS,arm,CPL_FALSE);
653 err += mf_wrap_save(frameset, frameset, parlist, RECIPE_NAME, parameters->pl, tag_name, output_fname);
654
655 output_fname = mf_wrap_tag_suffix(MOLECFIT_TELLURIC_DATA,arm,CPL_TRUE);
656 tag_name = mf_wrap_tag_suffix(MOLECFIT_TELLURIC_DATA,arm,CPL_FALSE);
657 err += mf_wrap_save(frameset, frameset, parlist, RECIPE_NAME, parameters->pl, tag_name, output_fname);
658
659 output_fname = mf_wrap_tag_suffix(MOLECFIT_TELLURIC_CORR,arm,CPL_TRUE);
660 tag_name = mf_wrap_tag_suffix(MOLECFIT_TELLURIC_CORR,arm,CPL_FALSE);
661 err += mf_wrap_save(frameset, frameset, parlist, RECIPE_NAME, parameters->pl, tag_name, output_fname);
662
663 if (kernel_data) {
664 output_fname = mf_wrap_tag_suffix(MOLECFIT_CALCTRANS_KERNEL_LIBRARY,arm,CPL_TRUE);
665 tag_name = mf_wrap_tag_suffix(MOLECFIT_CALCTRANS_KERNEL_LIBRARY,arm,CPL_FALSE);
666 err += mf_wrap_save(frameset, frameset, parlist, RECIPE_NAME, parameters->pl, tag_name, output_fname);
667 }
668 }
669
670 cpl_msg_info(cpl_func,"AFTER saving lots of files %s",cpl_error_get_message());
671 /*** Execute molecfit (lblrtm) ***/
672 if (!err) {
673
674 int null;
675
676 /* Execution extensions */
677 cpl_size n_ext;
678 if ( parameters->use_only_input_pri_ext) n_ext = 1;
679 else if (parameters->chip_extensions ) n_ext = data->v_ext[0].spectrum_data ? 1 : 2;
680 else n_ext = data->n_ext;
681
682 cpl_msg_info(cpl_func,"AFTER Execution extensions %s",cpl_error_get_message());
683
684 for (cpl_size ext = 0; ext < n_ext && !err; ext++) {
685 cpl_msg_info(cpl_func,"look over extensions %lld %s",ext,cpl_error_get_message());
686
687 /* Create input molecfit spec format */
688 if (data->v_ext[ext].spectrum_data) {
689
690 /* Get extension header/table data */
691 cpl_msg_info(cpl_func, "Load spectrum for execute mf_calctrans_lblrtm(...) in ext = %lld ...", ext);
692 parameters->telluriccorr_head[ext] = cpl_propertylist_duplicate(data->v_ext[ext].spectrum_head);
693 parameters->telluriccorr_data[ext] = mf_spectrum_create(parameters->mf_config->parameters, data->v_ext[ext].spectrum_data);
694
695 /* Get ATM_PARAMETERS/BEST_FIT_PARAMETERS index */
696 cpl_size index_atmospheric = cpl_table_get(mapping_atmospheric, MOLECFIT_MAPPING_ATMOSPHERIC_EXT, ext, &null);
697
698 /* This adds a clarifying message to the 'Access beyond boundaries' error that pops up if the MAPPING is incorrect */
699 if(parameters->atm_parameters->v_ext[index_atmospheric].table == NULL){
700 err = cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
701 "Cannot find atm_parameters. Please check the incorrectly set MAPPING_ATMOSPHERIC parameter.");
702 }
703
704 /* Save BEST_FIT_PARAMETERS cpl_table for CONVOLUTION */
705 parameters->best_fit_parameters_table[ext] = cpl_table_duplicate(parameters->best_fit_parameters->v_ext[index_atmospheric].table);
706
707 /* CALL CALCTRANS_LBLRTM : Select all wavelength range for the Molecfit executions : wl_start = -1 and wl_end = -1 */
708 const double wl_start = -1.;
709 const double wl_end = -1.;
710 parameters->results_lblrtm[ext] = mf_calctrans_lblrtm( parameters->mf_config, /* mf_configuration *config */
711 parameters->telluriccorr_data[ext], /* const cpl_table *spec_telluriccorr */
712 molecules, /* cpl_table *molecules */
713 wl_start, /* double wl_start */
714 wl_end, /* double wl_end */
715 parameters->atm_parameters->v_ext[index_atmospheric].table, /* cpl_table *atm_parameters */
716 parameters->best_fit_parameters->v_ext[index_atmospheric].table); /* cpl_table *best_fit_parameters */
717
718 /* Check possible errors */
719 if (!(parameters->results_lblrtm[ext])) {
720 err = cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
721 "Unexpected error in the Molecfit call mf_calctrans_lblrtm(...)");
722 } else {
723
724 /* Only one range allow in the mf_calctrans_lblrtm(...) execution --> Mandatory */
725 cpl_size n_range = parameters->mf_config->parameters->internal.n_range;
726 if (n_range != 1 && !parameters->chip_extensions) {
727
728 err = cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
729 "Unexpected n_ranges in the mf_calctrans_lblrtm(...) Molecfit execution : n_ranges = %lld (Mandatory == 1)", n_range);
730
731 } else {
732
733 /* Check execution results for the only range (position == 0) */
734 if (parameters->results_lblrtm[ext]->range_status[0] != CPL_ERROR_NONE) {
735
736 err = cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
737 "mf_calctrans_lblrtm(...) Molecfit execution : n_ranges = %lld (Mandatory == 1)", n_range);
738
739 } else {
740
741 /* Check other errors */
742 err = cpl_error_get_code();
743 }
744 }
745 }
746 }
747 }
748
749
750 /*** Execute molecfit (convolution) ***/
751 for (cpl_size ext = 0; ext < n_ext && !err; ext++) {
752
753 /* Get ATM_PARAMETERS/BEST_FIT_PARAMETERS index */
754 cpl_size index_convolve = cpl_table_get(mapping_convolve, MOLECFIT_MAPPING_CONVOLVE_EXT, ext, &null);
755 cpl_size index_lblrtm_results = index_convolve - parameters->use_only_input_pri_ext;
756
757 /* This adds a clarifying message to the 'Access beyond boundaries' error that pops up if the MAPPING is incorrect */
758/*
759 if(parameters->results_lblrtm[index_lblrtm_results] == NULL){
760 err = cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT, "Cannot find lblrtm_results. Please check the incorrectly set MAPPING_CONVOLVE parameter.");
761 }
762*/
763 /* Create input molecfit spec format */
764 if (parameters->results_lblrtm[index_lblrtm_results]) {
765
766 /* Get extension header data */
767 cpl_msg_info(cpl_func, "Convolve input spectrum (ext_orig[ATM_PARAMETERS/BEST_FIT_PARAMETERS] = %lld) for execute mf_calctrans_convolve(...) in ext = %lld ...", index_convolve, ext);
768
769 cpl_propertylist *header_kernel = NULL;
770 cpl_matrix *kernel = NULL;
771 if (kernel_data) {
772
773 if (mapping_kernel) {
774 cpl_size index_kernel_ext = cpl_table_get(mapping_kernel, MOLECFIT_MAPPING_KERNEL_EXT, ext, &null);
775 header_kernel = kernel_data->v_ext[index_kernel_ext].header;
776 kernel = kernel_data->v_ext[index_kernel_ext].matrix;
777 } else {
778 header_kernel = kernel_data->v_ext[ext].header;
779 kernel = kernel_data->v_ext[ext].matrix;
780 }
781 }
782
783 /* CALL CALCTRANS_CONVOLUTION : Select all wavelength range for the Molecfit executions : wl_start = -1 and wl_end = -1 */
784 const double wl_start = -1.;
785 const double wl_end = -1.;
786 parameters->results_convolution[ext] = mf_calctrans_convolution( parameters->mf_config->parameters, /* mf_parameters_config *config */
787 parameters->results_lblrtm[index_lblrtm_results], /* mf_calctrans_lblrtm_results *lblrtm_results */
788 parameters->telluriccorr_head[index_lblrtm_results], /* const cpl_propertylist *header_spec */
789 parameters->telluriccorr_data[index_lblrtm_results], /* const cpl_table *spec_telluriccorr */
790 header_kernel, /* const cpl_propertylist *header_kernel */
791 kernel, /* const cpl_matrix *kernel */
792 wl_start, /* double wl_start */
793 wl_end, /* double wl_end */
794 parameters->best_fit_parameters_table[index_lblrtm_results]); /* cpl_table *best_fit_parameters */
795
796 /* Check possible errors */
797 if (!(parameters->results_convolution[ext])) {
798 err = cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
799 "Unexpected error in the Molecfit call mf_calctrans_convolution(...)");
800 } else {
801 err = cpl_error_get_code();
802 }
803 }
804 }
805
806 /* Save results */
807 for (cpl_size ext = 0; ext < n_ext && !err; ext++) {
808
809 cpl_propertylist *lblrtm_header = cpl_propertylist_duplicate(data->v_ext[ext].header);
810 cpl_table *lblrtm_spec_out = NULL;
811
812 cpl_table *telluric_data = NULL;
813 cpl_vector *telluric_vec = NULL;
814
815 cpl_matrix *kernel_matrix = NULL;
816
817 if (parameters->results_lblrtm[ext]) {
818
819 cpl_msg_info(cpl_func, "LBLRTM_RESULTS exist in this ext = %lld ... saving ...", ext);
820
821 /* Save tmp_dir in the LBLRTM_RESULTS header */
822 cpl_propertylist_update_string(lblrtm_header, MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_TMP_PATH, parameters->results_lblrtm[ext]->tmp_folder);
823
824 /* Get LBLRTM results spectrum */
825 lblrtm_spec_out = parameters->results_lblrtm[ext]->spec_out[0];
826 }
827
828 if (parameters->results_convolution[ext]) {
829
830 /* Get CONVOLUTION results cpl_table */
831 telluric_data = (parameters->results_convolution[ext])->spec_telluriccorr_format;
832
833 /* Wrap the data */
834 double *telluric_corr_column = cpl_table_get_data_double(telluric_data, MF_COL_OUT_TELLURIC_CORR);
835
836 /* Convert in a spectrum (cpl_vector) */
837 cpl_vector *vAux = cpl_vector_wrap(cpl_table_get_nrow(telluric_data), telluric_corr_column);
838 telluric_vec = cpl_vector_duplicate(vAux);
839 cpl_vector_unwrap(vAux);
840
841 /* Get Kernel results */
842 if (parameters->results_convolution[ext]->kernel_resampled_normalized) {
843 kernel_matrix = parameters->results_convolution[ext]->kernel_resampled_normalized;
844 }
845 }
846
847 /*** SAVE results : LBLRTM_RESULTS, TELLURIC_DATA, TELLURIC_CORR and KERNEL_MOLECFIT results ***/
848 if (!err && (parameters->use_only_input_pri_ext || ext > 0)) {
849
850 cpl_msg_info(cpl_func, "Saving %s, %s, %s, %s ... (ext =%lld : lblrtm_results ? %d, convolution_results ? %d)", MOLECFIT_LBLRTM_RESULTS, MOLECFIT_CALCTRANS_KERNEL_LIBRARY, MOLECFIT_TELLURIC_DATA, MOLECFIT_TELLURIC_CORR, ext, lblrtm_spec_out != NULL, telluric_data != NULL);
851
852 const char* output_fname = mf_wrap_tag_suffix(MOLECFIT_LBLRTM_RESULTS,arm,CPL_TRUE);
853 err += mf_wrap_save_mf_results( lblrtm_header, output_fname, CPL_FALSE, NULL, lblrtm_spec_out, NULL );
854 output_fname = mf_wrap_tag_suffix(MOLECFIT_TELLURIC_DATA,arm,CPL_TRUE);
855 err += mf_wrap_save_mf_results( data->v_ext[ext].header, output_fname, CPL_FALSE, NULL, telluric_data, NULL );
856 output_fname = mf_wrap_tag_suffix(MOLECFIT_TELLURIC_CORR,arm,CPL_TRUE);
857 err += mf_wrap_save_mf_results( data->v_ext[ext].header, output_fname, CPL_FALSE, NULL, NULL, telluric_vec );
858
859 if (kernel_data) {
860 output_fname = mf_wrap_tag_suffix(MOLECFIT_CALCTRANS_KERNEL_LIBRARY,arm,CPL_TRUE);
861 err += mf_wrap_save_mf_results( kernel_data->v_ext[ext].header, output_fname, CPL_FALSE, kernel_matrix, NULL, NULL );
862 }
863 }
864
865 /* Cleanup */
866 if (lblrtm_header) cpl_propertylist_delete(lblrtm_header);
867 if (telluric_vec ) cpl_vector_delete(telluric_vec);
868 }
869 }
870
871 /* Cleanup */
872 if (parameters ) molecfit_calctrans_parameter_delete( parameters );
873 if (data ) mf_wrap_fits_delete( data );
874 if (molecules ) cpl_table_delete( molecules );
875 if (kernel_data ) mf_wrap_fits_delete( kernel_data );
876 if (mapping_kernel ) cpl_table_delete( mapping_kernel );
877 if (mapping_atmospheric) cpl_table_delete( mapping_atmospheric);
878 if (mapping_convolve ) cpl_table_delete( mapping_convolve );
879
880
881 /* Check Recipe status and end */
882 if (!err && cpl_errorstate_is_equal(initial_errorstate)) {
883 cpl_msg_info(cpl_func,"Recipe successfully!");
884 } else {
885 /* Dump the error history */
886 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
887 cpl_msg_error(cpl_func,"Recipe failed!, error(%d)=%s", err, cpl_error_get_message());
888 }
889
890
891
892
893 //----------------
894 //ROUGH OUTLINE OF MOLECFIT_CALCTRANS()
895 //-------------------------
896
897 //initial frameset checks
898 //BLOCK:
899 /* Check mandatory TAGS/Parameters */
900 //to go into mf_wrap_calc_preconfig_check
901 //SCIENCE_CALCTRANS/SCIENCE;
902 //MODEL_MOLECULES
903 //ATM_PARAMETERS
904 //BEST_FIT_PARAMETERS
905 //MAPPING_CONVOLVE
906 //TEST KERNEL MAPPING
907 //TEST _ATMOSPHERIC: MAPPING
908 //TEST _CONVOLVE: MAPPING
909
910//Separate functions for each ; TODO: Check if we can just reuse the same function from molecfit_model (if we change parameter == the TAG == to these functions)
911 /* Load TAG = SCIENCE_CALCTRANS/SCIENCE */
912
913 /* Load TAG = MOLECULES */ //SAME
914 /* Load TAG : CALCTRANS_KERNEL_LIBRARY */
915 /* Load TAG = MAPPING_ATMOSPHERIC */
916 /* Load TAG = MAPPING_CONVOLVE */
917
918//Parameters: molecfit_calctrans_parameter* parameters
919//call to mf_wrap_data_convert_to_table
920
921//Saving output files
922
923//DO THE CALCTRANS STUFF
924 /*** Execute molecfit (lblrtm) ***/
925 //1. mf_calctrans_lblrtm
926 //2. mf_calctrans_convolution
927
928//SAVE RESULTS
929
930 //Load up calctrans *input files*
931 //ATM_PARAMETERS_(SCI/STD)_(UVB/VIS/NIR) - molecfit_calctrans_parameters()
932 //BEST_FIT_PARAMETERS_(SCI/STD)_(UVB/VIS/NIR) - molecfit_calctrans_parameters()
933 //BEST_FIT_MODEL_(SCI/STD)_(UVB/VIS/NIR) -
934 //MODEL_MOLECULES_(UVB/VIS/NIR) - mf_wrap_calc_molecules()
935 //KERNEL_LIBRARY_(UVB/VIS/NIR) - mf_wrap_calc_kernel_library()
936
937
938
939
940 //Load up calctrans *parameters*
941 //DO ON TELLURICCORR SIDE -> mf_wrap_calc.c
942
943 //CALCTRANS_MAPPING_KERNEL
944 //MAPPING_ATMOSPHERIC
945 //MAPPING_CONVOLVE
946
947 //USE_ONLY_INPUT_PRIMARY_DATA
948 //USE_DATA_EXTENSION_AS_DFLUX
949 //USE_DATA_EXTENSION_AS_MASK
950 //CHIP_EXTENSIONS
951
952
953
954
955
956
957
958
959
960
961
962
963
964 return err;
965
966}
967
968
969//cpl_error_code xsh_check_and_set_input_tags(frameset){
970 //map the XSHOOTER input frame tags to MOLECFIT SCIENCE etc.
971
972 //check the frameset for the following tags =>
973 //SCI_SLIT_FLUX_IDP_XXX, SCI_SLIT_FLUX_MERGE1D_XXX,
974 //TELL_SLIT_FLUX_MERGE_XXX, TELL_SLIT_MERGE1D_XXX,
975 //STD_SLIT_FLUX_IDP_YYY_XXX
976 //where XXX = VIS/NIR/ UBB, and YYY= NOD, STARE, OFFSET
977
978 //call a function in Telluriccorr that maps out the input frame names to molecfit defaults();
979
980// return CPL_ERROR_OK;
981//}
982
983
int xsh_molecfit_calctrans_create(cpl_plugin *)
Setup the recipe options.
cpl_error_code xsh_molecfit_calctrans_config(cpl_frameset *frameset, const cpl_parameterlist *parlist, cpl_parameterlist *ilist, cpl_parameterlist *iframelist)
Build the list of available plugins, for this module.
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
int xsh_molecfit_calctrans_exec(cpl_plugin *)
Execute the plugin instance given by the interface.
int xsh_molecfit_calctrans_destroy(cpl_plugin *)
Destroy what has been created by the 'create' function.
cpl_error_code xsh_molecfit_calc_setup_frameset(cpl_frameset *frameset, cpl_parameterlist *list, const char *arm, const char *input_name)
int xsh_molecfit_calctrans(cpl_frameset *frameset, const cpl_parameterlist *parlist)
#define assure(CONDITION, ERROR_CODE,...)
Definition: xsh_error.h:54
#define check(COMMAND)
Definition: xsh_error.h:71
#define xsh_error_dump(level)
Definition: xsh_error.h:92
void xsh_free_parameterlist(cpl_parameterlist **p)
Deallocate a parameter list and set the pointer to NULL.
Definition: xsh_utils.c:2224
const char * xsh_get_license(void)
Get the pipeline copyright and license.
Definition: xsh_utils.c:1193
void xsh_init(void)
Reset library state.
Definition: xsh_utils.c:1160
#define RECIPE_CONTACT
char xsh_molecfit_calctrans_description_short[]
char xsh_molecfit_calctrans_description[]
#define RECIPE_ID
#define RECIPE_AUTHOR
cpl_error_code xsh_molecfit_utils_find_input_frame(cpl_frameset *frameset, cpl_parameterlist *iframe)
void xsh_parameters_new_boolean(cpl_parameterlist *list, const char *recipe_id, const char *name, int value, const char *comment)