ESBO-ETC/esbo_etc/classes/config.py

138 lines
4.3 KiB
Python
Raw Normal View History

2020-04-06 17:17:31 +02:00
import xml.etree.ElementTree as eT
import numpy as np
2020-04-08 09:45:59 +02:00
import astropy.units as u
2020-04-06 17:17:31 +02:00
import os
import logging
2020-04-08 09:45:59 +02:00
from esbo_etc.lib.helpers import error
2020-04-06 17:17:31 +02:00
class Entry(object):
"""
A class used to represent a configuration entry.
2020-04-08 09:45:59 +02:00
Copied from ExoSim (https://github.com/ExoSim/ExoSimPublic)
2020-04-06 17:17:31 +02:00
"""
def __call__(self):
2020-04-08 09:45:59 +02:00
return self.val if hasattr(self, "val") else None
2020-04-06 17:17:31 +02:00
def parse(self, xml):
"""
2020-04-08 09:45:59 +02:00
Parse attributes of a XML element
2020-04-06 17:17:31 +02:00
2020-04-08 09:45:59 +02:00
:param xml: XML element to parse the attributes from
2020-04-06 17:17:31 +02:00
"""
2020-04-08 09:45:59 +02:00
# Copy the XML attributes to object attributes
for attrib in xml.attrib.keys():
setattr(self, attrib, xml.attrib[attrib])
2020-04-06 17:17:31 +02:00
2020-04-08 09:45:59 +02:00
# Convert to python datatype and apply the corresponding unit (if applicable)
2020-04-06 17:17:31 +02:00
if hasattr(self, 'units'):
try:
2020-04-08 09:45:59 +02:00
self.val = u.Quantity(list(map(float, self.val.split(','))),
self.units)
# if self.units == 'deg':
# self.val = [val * pq.rad for val in self.val] # workaround for qt unit conversion
2020-04-06 17:17:31 +02:00
if len(self.val) == 1:
self.val = self.val[0]
except (ValueError, LookupError):
2020-04-08 09:45:59 +02:00
error("unable to convert units in entry '" + xml.tag + "': " + self.val + " " + self.units, exit_=False)
elif hasattr(self, "val") and self.val.lower() in ["false", "true"]:
self.val = (self.val.lower() == "true")
2020-04-06 17:17:31 +02:00
class Configuration(object):
"""
A Class to parse the XML configuration file.
2020-04-08 09:45:59 +02:00
Adapted from ExoSim (https://github.com/ExoSim/ExoSimPublic)
2020-04-06 17:17:31 +02:00
Attributes
----------
2020-04-08 09:45:59 +02:00
conf : Entry
Parsed configuration file as Entry-tree
2020-04-06 17:17:31 +02:00
"""
conf = None
def __init__(self, filename="esbo-etc_defaults.xml", default_path=None):
"""
Parse a XML configuration file.
Parameters
----------
filename : str
configuration file to parse
default_path : str
default path to use for relative paths
"""
2020-04-08 09:45:59 +02:00
# Check if configuration file exists
2020-04-06 17:17:31 +02:00
if not os.path.exists(filename):
2020-04-08 09:45:59 +02:00
error("Configuration file '" + filename + "' doesn't exist.")
2020-04-06 17:17:31 +02:00
2020-04-08 09:45:59 +02:00
# Read configuration file
2020-04-06 17:17:31 +02:00
logging.info("Reading configuration from file '" + filename + "'.")
self.conf = self.parser(eT.parse(filename).getroot())
self.calc_metaoptions()
2020-04-08 09:45:59 +02:00
def parser(self, parent):
2020-04-06 17:17:31 +02:00
"""
2020-04-08 09:45:59 +02:00
Parse a XML element tree to an Entry-tree
2020-04-06 17:17:31 +02:00
Parameters
----------
2020-04-08 09:45:59 +02:00
parent : ElementTree
The parent XML tree to be parsed
2020-04-06 17:17:31 +02:00
Returns
-------
obj : Entry
The parsed XML tree
"""
2020-04-08 09:45:59 +02:00
# Initialize empty Entry object
2020-04-06 17:17:31 +02:00
obj = Entry()
2020-04-08 09:45:59 +02:00
for child in parent:
# recursively parse children of child element
parsed_child = self.parser(child)
# parse attributes of child element
parsed_child.parse(child)
2020-04-06 17:17:31 +02:00
2020-04-08 09:45:59 +02:00
# Add or append the parsed child to the prepared Entry object
if hasattr(obj, child.tag):
if isinstance(getattr(obj, child.tag), list):
getattr(obj, child.tag).append(parsed_child)
2020-04-06 17:17:31 +02:00
else:
2020-04-08 09:45:59 +02:00
setattr(obj, child.tag, [getattr(obj, child.tag), parsed_child])
2020-04-06 17:17:31 +02:00
else:
2020-04-08 09:45:59 +02:00
setattr(obj, child.tag, parsed_child)
2020-04-06 17:17:31 +02:00
return obj
def calc_metaoptions(self):
2020-04-08 09:45:59 +02:00
"""
Calculate additional attributes e.g. the wavelength grid
Returns
-------
"""
2020-04-06 17:17:31 +02:00
self.calc_metaoption_wl_delta()
def calc_metaoption_wl_delta(self):
2020-04-08 09:45:59 +02:00
"""
Calculate the wavelength grid used for the calculations.
Returns
-------
"""
if hasattr(self.conf.common, "wl_delta"):
wl_delta = self.conf.common.wl_delta()
else:
wl_delta = self.conf.common.wl_min() / self.conf.common.res()
setattr(self.conf.common, 'wl_bins', np.arange(self.conf.common.wl_min().to(u.micron).value,
self.conf.common.wl_max().to(u.micron).value,
wl_delta.to(u.micron).value) * u.micron)
2020-04-06 17:17:31 +02:00
if __name__ == "__main__":
conf = Configuration()