X-shooter Pipeline Reference Manual 3.8.15
xsh_molecfit_telluric.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_telluric"
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_telluric_create(cpl_plugin *);
61int xsh_molecfit_telluric_exec(cpl_plugin *);
62int xsh_molecfit_telluric_destroy(cpl_plugin *);
63
64/* The actual executor function */
65int xsh_molecfit_telluric(cpl_frameset *frameset, const cpl_parameterlist *parlist);
66
67/*----------------------------------------------------------------------------*/
71/*----------------------------------------------------------------------------*/
72
74"Normalize the reduced telluric spectrum by its continuum.";
75
77"Normalize the reduced telluric 1D spectrum by its continuum to compute the atmosperic telluric correction to feed to xshooter_molecfit_correct.";
78
79/*----------------------------------------------------------------------------*/
83/*----------------------------------------------------------------------------*/
84
85/*----------------------------------------------------------------------------*/
89/*----------------------------------------------------------------------------*/
90
91
92/*----------------------------------------------------------------------------*/
96/*----------------------------------------------------------------------------*/
97
98/*----------------------------------------------------------------------------*/
102/*----------------------------------------------------------------------------*/
103
106/*----------------------------------------------------------------------------*/
110/*----------------------------------------------------------------------------*/
111
112/*--------------------------------------------------------------------------*/
121/*--------------------------------------------------------------------------*/
122
123int cpl_plugin_get_info(cpl_pluginlist *list) {
124 cpl_recipe *recipe = NULL;
125 cpl_plugin *plugin = NULL;
126
127 recipe = cpl_calloc(1, sizeof(*recipe));
128 if ( recipe == NULL ){
129 return -1;
130 }
131
132 plugin = &recipe->interface ;
133
134 cpl_plugin_init(plugin,
135 CPL_PLUGIN_API, /* Plugin API */
136 XSH_BINARY_VERSION, /* Plugin version */
137 CPL_PLUGIN_TYPE_RECIPE, /* Plugin type */
138 RECIPE_ID, /* Plugin name */
140 xsh_molecfit_telluric_description, /* Detailed help */
141 RECIPE_AUTHOR, /* Author name */
142 RECIPE_CONTACT, /* Contact address */
143 xsh_get_license(), /* Copyright */
147
148 cpl_pluginlist_append(list, plugin);
149
150 return (cpl_error_get_code() != CPL_ERROR_NONE);
151 }
152
153/*--------------------------------------------------------------------------*/
163/*--------------------------------------------------------------------------*/
164
165int xsh_molecfit_telluric_create(cpl_plugin *plugin){
166 cpl_recipe *recipe = NULL;
167 /*xsh_clipping_param detarc_clip_param = {2.0, 0, 0.7, 0, 0.3};
168 xsh_detect_arclines_param detarc_param =
169 {6, 3, 0, 5, 4, 1, 5, 5.0,
170 XSH_GAUSSIAN_METHOD, FALSE};
171 xsh_dispersol_param dispsol_param = { 4, 5 } ;
172 char paramname[256];
173 cpl_parameter* p=NULL;
174 int ival=DECODE_BP_FLAG_DEF;
175 */
176
177 /* Reset library state */
178 xsh_init();
179
180 /* Check input */
181 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin");
182
183 /* Get the recipe out of the plugin */
184 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
185 CPL_ERROR_TYPE_MISMATCH,
186 "Plugin is not a recipe");
187
188 recipe = (cpl_recipe *)plugin;
189
190 /* Create the parameter list in the cpl_recipe object */
191 recipe->parameters = cpl_parameterlist_new();
192 assure( recipe->parameters != NULL,
193 CPL_ERROR_ILLEGAL_OUTPUT,
194 "Memory allocation failed!");
195
196 //xsh_molecfit_telluric parameters
197
198 //column_wave
199 check(xsh_parameters_new_string(recipe->parameters,RECIPE_ID,
200 "COLUMN_WAVE","WAVE",
201 "Name of the column in the input that identifies the wavelength. This parameter has effect only for inputs in binary table format."));
202
203 //column_flux
204 check(xsh_parameters_new_string(recipe->parameters,RECIPE_ID,
205 "COLUMN_FLUX","FLUX",
206 "Name of the column in the input that identifies the flux. This parameter has effect only for inputs in binary table format."));
207
208 //column_dflux
209 check(xsh_parameters_new_string(recipe->parameters,RECIPE_ID,
210 "COLUMN_DFLUX","ERR",
211 "Name of the column in the input that identifies the flux errors. This parameter has effect only for inputs in binary table format."));
212
213 //nodes
214 check(xsh_parameters_new_string(recipe->parameters,RECIPE_ID,
215 "NODES","30",
216 "If a list of entries, it specifies the position (in microns) of the nodes to be used to compute the continuum. If a single entry, it specifies the number of equispaced nodes to be calculated."));
217
218 //method
219 check(xsh_parameters_new_string(recipe->parameters,RECIPE_ID,
220 "METHOD","spline",
221 "Specifies the method to determine the continuum. Valid entries are `spline' (cubic spline), or `poly' (polynomial fit)."));
222
223 //degree
224 check(xsh_parameters_new_int(recipe->parameters,RECIPE_ID,
225 "DEGREE",2,
226 "Degree of polynomium to fit the continuum in the case --method=poly"));
227
228 //half_width
229 check(xsh_parameters_new_double(recipe->parameters,RECIPE_ID,
230 "HALF_WIDTH",10.0,
231 "Semi-width of the nodes in pixels."));
232
233 cleanup:
234 if ( cpl_error_get_code() != CPL_ERROR_NONE ){
235 xsh_error_dump(CPL_MSG_ERROR);
236 return 1;
237 }
238 else {
239 return 0;
240 }
241}
242
243
244/*--------------------------------------------------------------------------*/
250/*--------------------------------------------------------------------------*/
251
252int xsh_molecfit_telluric_exec(cpl_plugin *plugin) {
253 cpl_recipe *recipe = NULL;
254
255 /* Check parameter */
256 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
257
258 /* Get the recipe out of the plugin */
259 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
260 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
261
262 recipe = (cpl_recipe *)plugin;
263 /* Check recipe */
264 xsh_molecfit_telluric( recipe->frames, recipe->parameters);
265
266 cleanup:
267 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
268 xsh_error_dump(CPL_MSG_ERROR);
269 cpl_error_reset();
270 return 1;
271 }
272 else {
273 return 0;
274 }
275}
276
277/*--------------------------------------------------------------------------*/
283/*--------------------------------------------------------------------------*/
284int xsh_molecfit_telluric_destroy(cpl_plugin *plugin)
285{
286 cpl_recipe *recipe = NULL;
287
288 /* Check parameter */
289 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
290
291 /* Get the recipe out of the plugin */
292 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
293 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
294
295 recipe = (cpl_recipe *)plugin;
296
297 xsh_free_parameterlist(&recipe->parameters);
298
299 cleanup:
300 if (cpl_error_get_code() != CPL_ERROR_NONE)
301 {
302 return 1;
303 }
304 else
305 {
306 return 0;
307 }
308}
309
310/*cpl_error_code xsh_molecfit_setup_frameset(cpl_frameset* frameset,cpl_parameterlist* list,const char* arm,const char* input_name){
311
312 const char* tag;
313 //check the input frame (SCIENCE); we know the tag already thanks to the input_name parameter
314 //so no need to search frameset for it
315 //input_name may be one of the following:
316 //SCI_SLIT_FLUX_IDP_XXX
317 //SCI_SLIT_FLUX_MERGE1D_XXX
318 //TELL_SLIT_MERGE1D_XXX
319 //TELL_SLIT_FLUX_MERGE1D_XXX
320 //STD_SLIT_FLUX_IDP_YYY_XXX
321 //where XXX is the arm and YYY is NOD, STARE or OFFSET
322
323 tag = input_name;
324 cpl_frame* f = cpl_frameset_find(frameset,input_name);
325 cpl_frame_set_group(f,CPL_FRAME_GROUP_RAW);
326
327 //cpl_frame_set_type(f,CPL_FRAME_TYPE_NONE);
328 //cpl_frame_set_tag(f,"SCIENCE");
329 //cpl_frame_set_level(f,CPL_FRAME_LEVEL_NONE);
330
331 //other inputs
332
333 //KERNEL_LIBRARY_XXX
334 tag = cpl_sprintf("%s_%s",MOLECFIT_KERNEL_LIBRARY,arm);
335 f = cpl_frameset_find(frameset,tag);
336 if(f){
337 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
338 }
339 //GDAS_XXX
340 tag = cpl_sprintf("%s_%s",MOLECFIT_GDAS,arm);
341 f = cpl_frameset_find(frameset,tag);
342 if(f){
343 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
344 }
345 //WAVE_INCLUDE_XXX
346 tag = cpl_sprintf("%s_%s",MOLECFIT_WAVE_INCLUDE,arm);
347 f = cpl_frameset_find(frameset,tag);
348 if(f){
349 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
350 }
351 //WAVE_EXCLUDE_XXX
352 tag = cpl_sprintf("%s_%s",MOLECFIT_WAVE_EXCLUDE,arm);
353 f = cpl_frameset_find(frameset,tag);
354 if(f){
355 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
356 }
357 //PIX_EXCLUDE_XXX
358 tag = cpl_sprintf("%s_%s",MOLECFIT_PIXEL_EXCLUDE,arm);
359 f = cpl_frameset_find(frameset,tag);
360 if(f){
361 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
362 }
363 //MOLECULES_XXX
364 tag = cpl_sprintf("%s_%s",MOLECFIT_MOLECULES,arm);
365 f = cpl_frameset_find(frameset,tag);
366 if(f){
367 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
368 }
369 //ATM_PROFILE_STANDARD_XXX
370 tag = cpl_sprintf("%s_%s",MOLECFIT_ATM_PROFILE_STANDARD,arm);
371 f = cpl_frameset_find(frameset,tag);
372 if(f){
373 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
374 }
375 //ATM_PROFILE_COMBINED_XXX
376 tag = cpl_sprintf("%s_%s",MOLECFIT_ATM_PROFILE_COMBINED,arm);
377 f = cpl_frameset_find(frameset,tag);
378 if(f){
379 cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
380 }
381}
382*/
383
384
385/*----------------------------------------------------------------------------*/
395/*----------------------------------------------------------------------------*/
396
397/*Instrument sid- example instrument - XSHOOTER?*/
398int xsh_molecfit_telluric(cpl_frameset *frameset, const cpl_parameterlist *parlist)
399{
400 cpl_msg_info(cpl_func,"xsh_molecfit_telluric");
401 //TODO: cpl_errorstate_ensure NOT DEFINED???
402
403 //cpl_errorstate_ensure(frameset && parlist, CPL_ERROR_NULL_INPUT, return, CPL_ERROR_NULL_INPUT, 'NULL input: framset and/or parlist');
404 cpl_error_code err= CPL_ERROR_NONE;
405 cpl_errorstate initial_errorstate = cpl_errorstate_get();
406
407 //INPUT FRAMES WILL BE NAMED DIFFERENT TO MOLECFIT_SCIENCE, MOLECFIT_STD* etc.
408 //TODO: implement xsh_check_and_set_input_tags (if needed?)
409 //err = xsh_check_and_set_input_tags(frameset); //INSTRUMENT_SPECIFIC
410 //cpl_boolean* science_data_is_table;
411
412 //err = mf_wrap_preconfig_check(frameset, parlist,science_data_is_table);/*Check parameters and frameset for correct inputs - returns CPL_ERROR*/
413
414 //cpl_parameterlist* ilist = cpl_parameterlist_new();
415 //cpl_parameterlist* iframelist = cpl_parameterlist_new();
416 //cpl_parameterlist_dump(parlist,stdout);
417 //since this is a relatively simple recipe, get the parameters from the parlist...
418 const char* col_wave = cpl_parameter_get_string(cpl_parameterlist_find(parlist,"COLUMN_WAVE"));
419 const char* col_flux = cpl_parameter_get_string(cpl_parameterlist_find(parlist,"COLUMN_FLUX"));
420 const char* col_dflux = cpl_parameter_get_string(cpl_parameterlist_find(parlist,"COLUMN_DFLUX"));
421 const char* nodes = cpl_parameter_get_string(cpl_parameterlist_find(parlist,"NODES"));
422 const char* method= cpl_parameter_get_string(cpl_parameterlist_find(parlist,"METHOD"));
423 int degree_poly = cpl_parameter_get_int(cpl_parameterlist_find(parlist,"DEGREE"));
424 double half_width = cpl_parameter_get_double(cpl_parameterlist_find(parlist,"HALF_WIDTH"));
425
426 cpl_msg_info(cpl_func,"loaded params");
427 //do error checking on params
428 //if(degree_poly < 0) raise error
429 //if(method != spline or poly ; raise error)
430
431 cpl_parameterlist* iframe = cpl_parameterlist_new();
432 err=xsh_molecfit_utils_find_input_frame(frameset, iframe);
433 cpl_msg_info(cpl_func,"finished xsh_molecfit_utils_find_input_frame");
434
435 const char* input_name = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"INPUTNAME"));
436 const char* arm = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"ARM"));
437 //const char* obsmode = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"OBSMODE"));
438 const char* is_idp = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"IDP"));
439 const char* fname = cpl_parameter_get_string(cpl_parameterlist_find(iframe,"INPUTFILENAME"));
440
441 //if not IDP, this is TRUE
442 cpl_boolean USE_ONLY_INPUT_PRIMARY_DATA = CPL_TRUE;
443 int ext = 1;
444 if(!strcmp(is_idp,"TRUE")){
445 USE_ONLY_INPUT_PRIMARY_DATA = CPL_FALSE;
446 ext = 0;
447 }
448 cpl_table* table = NULL;
449 cpl_msg_info(cpl_func,"loading input table %s",fname);
450 table = cpl_table_load(fname,1,0);
451 cpl_msg_info(cpl_func,"loaded input table");
452 if(table){
453 cpl_msg_info(cpl_func,"loading columns");
454 //cpl_table_dump(table,0,cpl_table_get_nrow(table),stdout);
455 //cpl_type t = cpl_table_get_column_type(table,col_wave);
456 //cpl_msg_info(cpl_func,"%s",cpl_type_get_name(t));
457 cpl_array* wave = cpl_table_get_array(table,col_wave,0);
458 cpl_array* flux = cpl_table_get_array(table,col_flux,0);
459 cpl_array* dflux = cpl_table_get_array(table,col_dflux,0);
460
461 cpl_msg_info(cpl_func,"loading data");
462
463 //xshooter functions use cpl_vectors instead?
464 double wmin, wmax;
465 int wn = cpl_array_get_size(wave);
466 double* wave_data = cpl_array_get_data_double(wave);
467 wmin = wave_data[0];
468 wmax = wave_data[wn-1];
469 cpl_msg_info(cpl_func,"wmin %.2f wmax %.2f",wmin,wmax);
470
471 //xsh_extract_points_to_fit
472
473 //cpl_array_dump(a,0,cpl_array_get_size(a),stdout);
474 //double* wave=cpl_table_get_data_double(table,col_wave);
475 //if(wave){
476 // cpl_msg_info(cpl_func,"wave[0] %.2f",wave[0]);
477 //}/
478 }
479
480 return err;
481
482}
483
484
485cpl_error_code xsh_molecfit_telluric_spec_data_calcs(mf_wrap_fits* data, const char* is_idp, cpl_parameterlist* ilist,mf_wrap_model_parameter* parameters){
486 //work out which extension to access for the spectrum
487
488 cpl_error_code err = CPL_ERROR_NONE;
489 cpl_boolean USE_ONLY_INPUT_PRIMARY_DATA = CPL_TRUE;
490 if(!strcmp(is_idp,"TRUE")){
491 USE_ONLY_INPUT_PRIMARY_DATA = CPL_FALSE;
492 }
493
494
495 //code from molecfit_model - to work out which is which...
496 //unused //cpl_size n_ext;
497 int spec_ext = 0;
498 //TO LATER TEST/CUSTOMISE PER XSHOOTER DATA FORMATS...
499 if(USE_ONLY_INPUT_PRIMARY_DATA){
500 spec_ext = 0;
501 } else {
502 spec_ext = 1;
503 }
504 cpl_msg_info(cpl_func,"spec_ext: %d",spec_ext);
505 //cpl_msg_info(cpl_func,"flux column: %s",MF_PARAMETERS_COLUMN_FLUX);
506 //cpl_table* spectrum = data->v_ext[spec_ext].spectrum_data;
507 //algorithm to work out the median continuum flux (perhaps RETURN LATER to do some sigma clipping)
508 //median of flux - XSHOOTER_INPUT_DATA_FLUX_COLUMN is defined in xsh_molecfit_telluric.h
509 //TODO: check input data and see what it uses
510 //if(data == NULL){
511 // cpl_msg_info(cpl_func,"mf_wrap_fits* data == NULL");
512 // }
513
514 cpl_size nrows = cpl_table_get_nrow(data->v_ext[spec_ext].spectrum_data);
515 cpl_msg_info(cpl_func,"nrows: %lld",nrows);
516 //cpl_table_dump(data->v_ext[spec_ext].spectrum_data,0,nrows,stdout);
517
518 const char* FLUX_COLUMN = cpl_parameter_get_string(cpl_parameterlist_find(ilist,MF_PARAMETERS_COLUMN_FLUX));
519 cpl_msg_info(cpl_func,"flux column: %s",FLUX_COLUMN);
520
521 //TODO: MUST REMOVE NANs HERE...HOW TO DO THAT?
522
523 double median = cpl_table_get_column_median(data->v_ext[spec_ext].spectrum_data,FLUX_COLUMN);
524 cpl_msg_info(cpl_func,"spectrum median: %.4e",median);
525
526 //cpl_propertylist_update_string(ilist,"CONTINUUM_CONST",cpl_sprintf("%.4e",median));
527 cpl_parameterlist_append(ilist,cpl_parameter_new_value(MF_PARAMETERS_CONTINUUM_CONST,CPL_TYPE_DOUBLE,NULL,NULL,median));
528 //because we are setting up CONTINUUM_CONST **AFTER** mf_wrap_config_model_init, it will be missing from the parameters...
529 //update that here...(could also be done in xsh_molecfit_telluric(), but it's neater and more self-contained to have it here
530 mf_parameters_fitting *fitting = &(parameters->mf_config->parameters->fitting);
531 fitting->fit_continuum.const_val = median;
532 cpl_propertylist_update_double(parameters->pl, MF_PARAMETERS_CONTEX_DEFAULT" "MF_PARAMETERS_CONTINUUM_CONST, fitting->fit_continuum.const_val);
533 parameters->mf_config->parameters->fitting = *fitting;
534
535 return err;
536}
537
538
539cpl_error_code xsh_molecfit_telluric_spec_header_calcs(const char* fname,const char* arm, cpl_parameterlist* ilist){
540
541 cpl_msg_info(cpl_func,"xsh_molecfit_telluric_spec_header_calcs");
542 //const char* fname = cpl_frame_get_filename(f);
543 cpl_msg_info(cpl_func,"reading in %s",fname);
544 //assume header info is in first extension
545 cpl_size ext = 0;
546 //cpl_size n_ext = cpl_frame_get_nextensions(f);
547 //Is this always in the first extension????
548 //for (cpl_size ext=0;ext< n_ext;ext++){
549 cpl_propertylist* hdr= cpl_propertylist_load(fname, ext);
550 if(hdr){
551 //SLIT_WIDTH_VALUE
552 const char* slit_width_kw;
553 if(!strcmp(arm,"UVB")){
554 slit_width_kw = "ESO INS OPTI3 NAME";
555 } else if(!strcmp(arm,"VIS")){
556 slit_width_kw = "ESO INS OPTI4 NAME";
557 } else if(!strcmp(arm,"NIR")){
558 slit_width_kw = "ESO INS OPTI5 NAME";
559 }
560 cpl_msg_info(cpl_func,"to read in %s value",slit_width_kw);
561 cpl_property *prop_hval = cpl_propertylist_get_property(hdr, slit_width_kw);
562 if(prop_hval){
563 const char* hval = cpl_property_get_string(prop_hval);
564 if(hval){
565 cpl_msg_info(cpl_func,"SLIT_WIDTH_VALUE: %s (read from %s)",strtok(hval,"x"),slit_width_kw);
566 //if the keyword value is 0.5x11, return 0.5 as slit width
567 //write to SLIT_WIDTH_VALUE parameter
568 //set to NONE to ensure the SLIT_WIDTH_VALUE parameter value is utilised
569 //cpl_propertylist_update_string(ilist,"SLIT_WIDTH_KEYWORD","NONE");
570 //cpl_propertylist_update_string(ilist,"SLIT_WIDTH_VALUE",strtok(hval,"x"));
571 cpl_parameterlist_append(ilist,cpl_parameter_new_value("SLIT_WIDTH_KEYWORD",CPL_TYPE_STRING,NULL,NULL,"NONE"));
572 cpl_parameterlist_append(ilist,cpl_parameter_new_value("SLIT_WIDTH_VALUE",CPL_TYPE_DOUBLE,NULL,NULL,atof(strtok(hval,"x"))));
573 }
574 }
575 //WAVELENGTH_FRAME *AND* OBS_ERF_RV_KEY
576 const char* WAVELENGTH_FRAME;
577 const char* OBS_ERF_RV_KEY;
578
579 cpl_property *prop_tu = cpl_propertylist_get_property(hdr,"TUCD1");
580 cpl_property *prop_ss = cpl_propertylist_get_property(hdr,"SPECSYS");
581 cpl_property *prop_hb = cpl_propertylist_get_property(hdr,"ESO QC VRAD BARYCOR");
582 cpl_property *prop_hh = cpl_propertylist_get_property(hdr,"ESO QC VRAD HELICOR");
583 //cpl_msg_info(cpl_func,"HDR values: TUCD1: %s; SPECSYS: %s; ESO QC VRAD BARYCOR: %s; ESO QC VRAD HELICOR: %s;",
584 //cpl_property_get_string(prop_tu),cpl_property_get_string(prop_ss),cpl_property_get_string(prop_hb),cpl_property_get_string(prop_hh));
585
586
587 if(prop_tu){
588 const char* val = cpl_property_get_string(prop_tu);
589 cpl_msg_info(cpl_func,"TUCD1 found: %s",val);
590 if(!strcmp(val,"em.wl;obs.atmos")){
591 WAVELENGTH_FRAME="AIR";
592 } else if(!strcmp(val,"em.wl")){
593 WAVELENGTH_FRAME="VAC";
594 }
595 } else {
596 //if TUCD1 not found, set to AIR (i.e. same as TUCD1 = em.wl;obs.atmos)
597 WAVELENGTH_FRAME="AIR";
598 }
599
600 if(prop_ss){
601 const char* val = cpl_property_get_string(prop_ss);
602 cpl_msg_info(cpl_func,"SPECSYS found: %s",val);
603 if(!strcmp(val,"TOPOCENT")){
604 OBS_ERF_RV_KEY = "NONE";
605 } else if(!strcmp(val,"BARYCENT")){
606 OBS_ERF_RV_KEY = "ESO QC VRAD BARYCOR";
607 sprintf(WAVELENGTH_FRAME,"%s_RV",WAVELENGTH_FRAME);
608 } else if(!strcmp(val,"HELIOCENT")){
609 OBS_ERF_RV_KEY = "ESO QC VRAD HELICOR";
610 sprintf(WAVELENGTH_FRAME,"%s_RV",WAVELENGTH_FRAME);
611 }
612 } else {
613 //if SPECSYS not found, set to NONE (i.e. same as SPECSYS = TOPOCENT)
614 OBS_ERF_RV_KEY = "NONE";
615 }
616 /*if(prop_hb){
617 double val = cpl_property_get_double(prop_hb);
618 cpl_msg_info(cpl_func,"ESO QC VRAD BARYCOR found: %.2f",val);
619 }
620 if(prop_hh){
621 double val = cpl_property_get_double(prop_hh);
622 cpl_msg_info(cpl_func,"ESO QC VRAD HELICOR found: %.2f",val);
623 }*/
624
625 if(!prop_hb || !prop_hh){
626 OBS_ERF_RV_KEY = "NONE";
627 }
628
629 if(WAVELENGTH_FRAME){
630 //cpl_propertylist_update_string(ilist,"WAVELENGTH_FRAME",WAVELENGTH_FRAME);
631 cpl_msg_info(cpl_func,"WAVELENGTH_FRAME: %s",WAVELENGTH_FRAME);
632 cpl_parameterlist_append(ilist,cpl_parameter_new_value("WAVELENGTH_FRAME",CPL_TYPE_STRING,NULL,NULL,WAVELENGTH_FRAME));
633
634 }
635 if(OBS_ERF_RV_KEY){
636 cpl_msg_info(cpl_func,"OBS_ERF_RV_KEY: %s",OBS_ERF_RV_KEY);
637 //cpl_propertylist_update_string(ilist,"OBS_ERF_RV_KEY",OBS_ERF_RV_KEY);
638 cpl_parameterlist_append(ilist,cpl_parameter_new_value("OBS_ERF_RV_KEY",CPL_TYPE_STRING,NULL,NULL,OBS_ERF_RV_KEY));
639 }
640 }
641
642 //CONTINUUM_CONST
643 //calculate median of spectrum FLUX values...
644 //this is handled in xsh_molecfit_telluric_spec_data_calcs()
645
646 //cleanup - cleanup cpl_property variables too?
647 if (hdr) {
648 cpl_propertylist_delete(hdr);
649 }
650
651
652 return CPL_ERROR_NONE;
653
654}
655
656
657
658/* -----------------------------------------------------------------------------------------------------/
659 *
660 * OVERVIEW OF STEPS
661 * 1. DO SOME ERROR CHECKING ON FRAMESET? (may be done later in setup config, but just being thorough)
662 * 1.5 GET *TAG* OF INPUT SCIENCE from FRAMSET using either MOLECFIT_STD_MODEL, MOLECFIT_SCIENCE_CALCTRANS or MOLECFIT_SCIENCE
663 * 1.55 (Check for YYY in this FILENAME, in case we need it later...)
664 * 2. DETERMINE IF SUFFIX NEEDED FROM DATASET (e.g. UVB/VIS/NIR for xshooter)
665 * 3. SETUP INPUT FILE NAME TAGS
666 * 4. SETUP OUTPUT FILE NAME TAGS
667 * 5. SETUP PARAMETERS (e.g. --list_molec, etc.)
668 * N.B. We expect to be provided a FITS binary table of WAVE_INCLUDE & MOLECULES params,
669 * but FOR NOW, we setup these values internally via the string parameter versions.
670 * 6. SETUP *EXTRA* PARAMETERS
671 *
672 *
673-------------------------------------------------------------------------------------------------------*/
674
cpl_error_code xsh_molecfit_telluric_spec_header_calcs(const char *fname, const char *arm, cpl_parameterlist *ilist)
int xsh_molecfit_telluric_create(cpl_plugin *)
Setup the recipe options.
int xsh_molecfit_telluric(cpl_frameset *frameset, const cpl_parameterlist *parlist)
Interpret the command line options and execute the data processing.
int xsh_molecfit_telluric_exec(cpl_plugin *)
Execute the plugin instance given by the interface.
int xsh_molecfit_telluric_destroy(cpl_plugin *)
Destroy what has been created by the 'create' function.
cpl_error_code xsh_molecfit_telluric_spec_data_calcs(mf_wrap_fits *data, const char *is_idp, cpl_parameterlist *ilist, mf_wrap_model_parameter *parameters)
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
Definition: xsh_2dmap.c:151
#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
const char * method
Definition: xsh_detmon_lg.c:78
#define RECIPE_CONTACT
char xsh_molecfit_telluric_description[]
char xsh_molecfit_telluric_description_short[]
#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_double(cpl_parameterlist *list, const char *recipe_id, const char *name, double value, const char *comment)
void xsh_parameters_new_string(cpl_parameterlist *list, const char *recipe_id, const char *name, const char *value, const char *comment)
void xsh_parameters_new_int(cpl_parameterlist *list, const char *recipe_id, const char *name, int value, const char *comment)