Source code for pyretlife.retrieval.configuration_conversion_ini_yaml

"""
Read in configuration files.
"""
import os
import sys
import glob
import numpy as np
import subprocess
import astropy.units as u

# -----------------------------------------------------------------------------
# IMPORTS
# -----------------------------------------------------------------------------

from pathlib import Path
from typing import Union, Tuple
import warnings
import hashlib
import yaml

from deepdiff import DeepDiff

from pyretlife.retrieval.units import UnitsUtil


# -----------------------------------------------------------------------------
# DEFINITIONS
# -----------------------------------------------------------------------------

def __init__(self,input_file = 'config.ini',retrieval = True):
    '''
    This function reads the config.ini file and initializes all
    the variables. It also ensures that the run is not rewritten
    unintentionally.
    '''

    config = configparser.ConfigParser(inline_comment_prefixes=('#',))
    config.optionxform = str
    config.read(input_file, encoding=None)

    self.path_prt = config.get('PATHS', 'settings_pRT')
    self.path_opacity = config.get('PATHS', 'settings_opacity_database')
    self.path_multinest = config.get('PATHS', 'settings_multinest')
    sys.path.append(self.path_multinest)

    # If we are running a retrieval create the run directory and check that
    # we are not overwriting an existing run
    if retrieval:
        self.prefix = config.get('PREFIX', 'settings_prefix')+'/'
        if os.path.isdir(self.prefix):
            if 'input.ini' in  os.listdir(self.prefix):
                st = os.system('diff ' + input_file + ' ' +
                                self.prefix + 'input.ini')

                # Protecting from unintentional rewriting
                if st == 256:
                        sys.exit('ERROR! same prefix but different input files. ')
        else:
            try:
                os.mkdir(self.prefix)
            except OSError:
                pass
            os.system('cp '+ input_file + ' ' + self.prefix + 'input.ini')

    f = open(self.path_prt + '/petitRADTRANS/path.txt', "r")
    orig_path = f.read()

    if not orig_path == "#\n" + self.path_opacity:
        with open(self.path_prt + '/petitRADTRANS/path.txt', 'w+') as input_data:
            input_data.write("#\n" + self.path_opacity)

    self.log_top_pressure=-5 #-6
    self.config_file = config
    self.params = OrderedDict()
    self.knowns = OrderedDict()
        
    # Initialization of the standard settings
    self.settings = {}
    self.settings['directlight']=False
    self.settings['CIA']=False
    self.settings['clouds']='transparent'
    self.settings['moon']=False
    self.settings['scattering']=False
    self.settings['extra_lines'] =''
    # Import PRt
    sys.path.append(self.path_prt)
    os.environ['pRT_input_data_path'] = self.path_opacity
    self.rt = __import__('petitRADTRANS')
    self.nc = self.rt.nat_cst

    # Create a units object to enable unit conversions
    self.units = units.units_util(self.rt.nat_cst)



[docs] def read_var(self): ''' This function reads the config.ini file and fills up the three dictionaries: settings, params, knowns. ''' # Check if there are units defined by the user and add these to the unis if 'USER DEFINED UNITS' in self.config_file.sections(): for (key, val) in self.config_file.items('USER DEFINED UNITS'): self.units.custom_unit(key,u.Quantity(val)) # Read the sections of the config file for section in self.config_file.sections(): if section != 'USER DEFINED UNITS': for (key, val) in self.config_file.items(section): if 'settings' in key: self.settings[key[9:]] = val # Check if the first element is a letter (the priors) elif val[0].upper().isupper(): # Extract the units from the input string. If none are # provided the standard input units are assumed. input_unit, val = self.units.unit_extract(key,val) # Extract the input values input_prior = [u.Quantity(val[i]).value for i in range(1,3)] #try: input_truth = u.Quantity(val[4]).value if (len(val)>=5 and val[3] == 'T') else None #except: # input_truth = None # Convert the input to retrieval units conv_unit = self.units.return_units(key,self.units.retrieval_units) conv_truth, conv_prior = self.units.unit_conv(key,input_unit,conv_unit,input_truth,prior_type=val[0],input_prior=input_prior) # Store the retrieved parameters param = {'prior_type': val[0], 'prior': conv_prior, 'input_prior': input_prior, 'truth': conv_truth, 'input_truth': input_truth, 'unit': conv_unit, 'input_unit': input_unit, 'type': section} self.params[key] = param # The parameters that are fixed during the retrieval else: # Extract the units from the input string. If none are # provided the standard input units are assumed. input_unit, val = self.units.unit_extract(key,val) # Extract the input values input_truth = u.Quantity(val[0]).value # Convert the input to retrieval units conv_unit = self.units.return_units(key,self.units.retrieval_units) conv_truth = self.units.unit_conv(key,input_unit,conv_unit,input_truth) # Store the knowns known = {'value': conv_truth, 'input_value': input_truth, 'unit': conv_unit, 'input_unit': input_unit, 'type': section} self.knowns[key] = known
[docs] def read_data(self,retrieval=True,result_dir=None): """ Reads the input data, trims to the wavelength range of interest and converts the units to CGS. """ self.instrument = {} for name in self.config_file['INPUT FILES'].keys(): input_string = self.config_file.get('INPUT FILES', name) # Case handling for the retrieval plotting if not retrieval: if os.path.isfile(result_dir+'/input_'+input_string.split('/')[-1].split(' ')[0]): input_string = result_dir+'/input_'+input_string.split('/')[-1] else: input_string = result_dir+ '/input_spectrum.txt '+ ' '.join(input_string.split('/')[-1].split(' ')[1:]) # Extract the Units from the config file and load the data. If non are provided the standard units are assumed. input_unit_wl, input_unit_flux, spectrum_dir = self.units.unit_spectrum_extract(input_string) input_data = np.genfromtxt(spectrum_dir) # Trim the spectra to the desired wl input_data = input_data[input_data[:, 0] >= (self.knowns['WMIN']['value']*self.knowns['WMIN']['unit']).to(input_unit_wl).value] input_data = input_data[input_data[:, 0] <= (self.knowns['WMAX']['value']*self.knowns['WMAX']['unit']).to(input_unit_wl).value] # Convert the Units to retrieval units conv_unit_wl = self.units.return_units('wavelength',self.units.retrieval_units) conv_unit_flux = self.units.return_units('flux',self.units.retrieval_units) conv_data = self.units.unit_spectrum_conv(name,[input_unit_wl,input_unit_flux],[conv_unit_wl,conv_unit_flux],input_data) # Store the spectra for each instrument self.instrument[name] = {'wl':conv_data[:, 0], 'flux':conv_data[:, 1], 'error':conv_data[:, 2], 'input_wl':input_data[:, 0], 'input_flux':input_data[:, 1], 'input_error':input_data[:, 2], 'unit_wl':conv_unit_wl, 'unit_flux':conv_unit_flux, 'input_unit_wl':input_unit_wl, 'input_unit_flux':input_unit_flux,} # If we are running retrievals copy the input spectra if retrieval: os.system('cp '+ spectrum_dir + ' ' + self.prefix + '/input_'+spectrum_dir.split('/')[-1])