34#include <mf_wrap_config.h>
35#include <telluriccorr.h>
48#define RECIPE_ID "xsh_molecfit_calctrans"
49#define RECIPE_AUTHOR "N. Fernando, B. Miszalski"
50#define RECIPE_CONTACT "nuwanthika.fernando@partner.eso.org"
74"Applies molecfit_calctrans to input spectra";
77"Applies molecfit_calctrans to input spectra";
125 cpl_recipe *recipe = NULL;
126 cpl_plugin *plugin = NULL;
128 recipe = cpl_calloc(1,
sizeof(*recipe));
129 if ( recipe == NULL ){
133 plugin = &recipe->interface ;
135 cpl_plugin_init(plugin,
138 CPL_PLUGIN_TYPE_RECIPE,
149 cpl_pluginlist_append(list, plugin);
151 return (cpl_error_get_code() != CPL_ERROR_NONE);
167 cpl_recipe *recipe = NULL;
173 assure( plugin != NULL, CPL_ERROR_NULL_INPUT,
"Null plugin");
176 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
177 CPL_ERROR_TYPE_MISMATCH,
178 "Plugin is not a recipe");
180 recipe = (cpl_recipe *)plugin;
183 recipe->parameters = cpl_parameterlist_new();
184 assure( recipe->parameters != NULL,
185 CPL_ERROR_ILLEGAL_OUTPUT,
186 "Memory allocation failed!");
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."));
215 if ( cpl_error_get_code() != CPL_ERROR_NONE ){
234 cpl_recipe *recipe = NULL;
237 assure( plugin != NULL, CPL_ERROR_NULL_INPUT,
"Null plugin" );
240 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
241 CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
243 recipe = (cpl_recipe *)plugin;
248 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
267 cpl_recipe *recipe = NULL;
270 assure( plugin != NULL, CPL_ERROR_NULL_INPUT,
"Null plugin" );
273 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
274 CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
276 recipe = (cpl_recipe *)plugin;
281 if (cpl_error_get_code() != CPL_ERROR_NONE)
306 cpl_frame* f = cpl_frameset_find(frameset,input_name);
307 cpl_frame_set_group(f,CPL_FRAME_GROUP_RAW);
379 cpl_parameterlist* ilist, cpl_parameterlist* iframelist){
381 cpl_msg_info(cpl_func,
"xsh_molecfit_calctrans_config");
382 cpl_msg_info(cpl_func,
"FRAMESET");
384 cpl_msg_info(cpl_func,
"PARLIST");
385 cpl_parameterlist_dump(parlist,stdout);
388 cpl_parameterlist* iframe = cpl_parameterlist_new();
394 cpl_error_code err= CPL_ERROR_NONE;
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"));
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);
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"));
428 cpl_boolean USE_INPUT_KERNEL;
429 cpl_boolean APPLY_WLC_CORR;
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;
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));
450 const char* input_tag;
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";
501 USE_ONLY_INPUT_PRIMARY_DATA = CPL_TRUE;
502 USE_DATA_EXTENSION_AS_DFLUX = 1;
503 MAPPING_ATMOSPHERIC =
"1";
504 MAPPING_CONVOLVE =
"1";
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));
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));
519 CHIP_EXTENSIONS = CPL_FALSE ;
521 cpl_parameterlist_append(ilist,cpl_parameter_new_value(
"CHIP_EXTENSIONS",CPL_TYPE_BOOL, NULL ,NULL, CHIP_EXTENSIONS));
541 cpl_error_code err= CPL_ERROR_NONE;
549 cpl_parameterlist* ilist = cpl_parameterlist_new();
550 cpl_parameterlist* iframelist = cpl_parameterlist_new();
551 cpl_errorstate initial_errorstate = cpl_errorstate_get();
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"));
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);
572 if(cpl_frameset_find(frameset, bf_sci)){
573 combined_suffix = cpl_sprintf(
"%s_%s",
"SCI",arm);
575 else if(cpl_frameset_find(frameset, bf_std)){
576 combined_suffix = cpl_sprintf(
"%s_%s",
"STD",arm);
579 cpl_msg_info(cpl_func,
"params retrieved from iframelist");
586 cpl_parameterlist* mergedlist = cpl_parameterlist_new();
588 cpl_msg_info(cpl_func,
"calling mf_wrap_merge_parameterlists");
589 err = mf_wrap_merge_parameterlists(ilist, parlist,mergedlist);
591 cpl_msg_info(cpl_func,
"calling xsh_molecfit_setup_frameset");
597 cpl_msg_info(cpl_func,
"calling cpl_fits_count_extensions");
600 mf_wrap_fits *
data = NULL;
601 data = mf_wrap_fits_load(fname, CPL_FALSE);
604 cpl_msg_info(cpl_func,
"AFTER mf_wrap_calc_data() next=%d ; %s",
data->n_ext,cpl_error_get_message());
607 cpl_msg_info(cpl_func,
"calling mf_wrap_config_calc_init");
610 molecfit_calctrans_parameter* parameters = mf_wrap_config_calc_init(frameset,mergedlist,
data->v_ext[0].header,
data->n_ext, combined_suffix);
612 cpl_msg_info(cpl_func,
"AFTER mf_wrap_config_calc_init() %s",cpl_error_get_message());
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());
628 cpl_msg_info(cpl_func,
"calling mf_wrap_calc_molecules");
630 cpl_table *molecules = NULL;
631 err= mf_wrap_calc_molecules(frameset,&molecules,arm);
634 mf_wrap_fits *kernel_data = NULL;
635 cpl_table *mapping_kernel = NULL;
637 err= mf_wrap_calc_kernel_library(kernel_data,&mapping_kernel,frameset,parameters,arm);
640 cpl_table *mapping_atmospheric = NULL;
641 err= mf_wrap_calc_mapping_atm(frameset,&mapping_atmospheric,parameters,arm);
644 cpl_table *mapping_convolve = NULL;
645 err= mf_wrap_calc_mapping_conv(frameset,&mapping_convolve,parameters,arm);
649 cpl_msg_info(cpl_func,
"Save generic multi-extension output FITS file ('%s','%s') ...", MOLECFIT_TELLURIC_DATA, MOLECFIT_TELLURIC_CORR);
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);
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);
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);
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);
670 cpl_msg_info(cpl_func,
"AFTER saving lots of files %s",cpl_error_get_message());
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;
682 cpl_msg_info(cpl_func,
"AFTER Execution extensions %s",cpl_error_get_message());
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());
688 if (
data->v_ext[ext].spectrum_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);
696 cpl_size index_atmospheric = cpl_table_get(mapping_atmospheric, MOLECFIT_MAPPING_ATMOSPHERIC_EXT, ext, &null);
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.");
705 parameters->best_fit_parameters_table[ext] = cpl_table_duplicate(parameters->best_fit_parameters->v_ext[index_atmospheric].table);
708 const double wl_start = -1.;
709 const double wl_end = -1.;
710 parameters->results_lblrtm[ext] = mf_calctrans_lblrtm( parameters->mf_config,
711 parameters->telluriccorr_data[ext],
715 parameters->atm_parameters->v_ext[index_atmospheric].table,
716 parameters->best_fit_parameters->v_ext[index_atmospheric].table);
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(...)");
725 cpl_size n_range = parameters->mf_config->parameters->internal.n_range;
726 if (n_range != 1 && !parameters->chip_extensions) {
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);
734 if (parameters->results_lblrtm[ext]->range_status[0] != CPL_ERROR_NONE) {
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);
742 err = cpl_error_get_code();
751 for (cpl_size ext = 0; ext < n_ext && !err; ext++) {
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;
764 if (parameters->results_lblrtm[index_lblrtm_results]) {
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);
769 cpl_propertylist *header_kernel = NULL;
770 cpl_matrix *kernel = NULL;
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;
778 header_kernel = kernel_data->v_ext[ext].header;
779 kernel = kernel_data->v_ext[ext].matrix;
784 const double wl_start = -1.;
785 const double wl_end = -1.;
786 parameters->results_convolution[ext] = mf_calctrans_convolution( parameters->mf_config->parameters,
787 parameters->results_lblrtm[index_lblrtm_results],
788 parameters->telluriccorr_head[index_lblrtm_results],
789 parameters->telluriccorr_data[index_lblrtm_results],
794 parameters->best_fit_parameters_table[index_lblrtm_results]);
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(...)");
801 err = cpl_error_get_code();
807 for (cpl_size ext = 0; ext < n_ext && !err; ext++) {
809 cpl_propertylist *lblrtm_header = cpl_propertylist_duplicate(
data->v_ext[ext].header);
810 cpl_table *lblrtm_spec_out = NULL;
812 cpl_table *telluric_data = NULL;
813 cpl_vector *telluric_vec = NULL;
815 cpl_matrix *kernel_matrix = NULL;
817 if (parameters->results_lblrtm[ext]) {
819 cpl_msg_info(cpl_func,
"LBLRTM_RESULTS exist in this ext = %lld ... saving ...", ext);
822 cpl_propertylist_update_string(lblrtm_header, MF_PARAMETERS_CONTEX_DEFAULT
" "MF_PARAMETERS_TMP_PATH, parameters->results_lblrtm[ext]->tmp_folder);
825 lblrtm_spec_out = parameters->results_lblrtm[ext]->spec_out[0];
828 if (parameters->results_convolution[ext]) {
831 telluric_data = (parameters->results_convolution[ext])->spec_telluriccorr_format;
834 double *telluric_corr_column = cpl_table_get_data_double(telluric_data, MF_COL_OUT_TELLURIC_CORR);
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);
842 if (parameters->results_convolution[ext]->kernel_resampled_normalized) {
843 kernel_matrix = parameters->results_convolution[ext]->kernel_resampled_normalized;
848 if (!err && (parameters->use_only_input_pri_ext || ext > 0)) {
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);
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 );
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 );
866 if (lblrtm_header) cpl_propertylist_delete(lblrtm_header);
867 if (telluric_vec ) cpl_vector_delete(telluric_vec);
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 );
882 if (!err && cpl_errorstate_is_equal(initial_errorstate)) {
883 cpl_msg_info(cpl_func,
"Recipe successfully!");
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());
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,...)
#define xsh_error_dump(level)
void xsh_free_parameterlist(cpl_parameterlist **p)
Deallocate a parameter list and set the pointer to NULL.
const char * xsh_get_license(void)
Get the pipeline copyright and license.
void xsh_init(void)
Reset library state.
char xsh_molecfit_calctrans_description_short[]
char xsh_molecfit_calctrans_description[]
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)