Add docstring

This commit is contained in:
Lukas Klass 2020-05-08 16:45:55 +02:00
parent 65f49de1c4
commit dd8767c1fa

View File

@ -10,6 +10,7 @@ from ..classes import optical_component as oc
from ..classes import sensor as sensor from ..classes import sensor as sensor
import difflib import difflib
import os.path import os.path
from typing import Union
class Configuration(object): class Configuration(object):
@ -40,12 +41,12 @@ class Configuration(object):
# Read configuration file # Read configuration file
logging.info("Reading configuration from file '" + file + "'.") logging.info("Reading configuration from file '" + file + "'.")
self.conf = self.parser(eT.parse(file).getroot()) self.conf = self.__parser(eT.parse(file).getroot())
self.check_config(self.conf) self.__check_config()
self.calc_metaoptions() self.__calc_metaoptions()
def parser(self, parent: eT.Element): def __parser(self, parent: eT.Element):
""" """
Parse a XML element tree to an Entry-tree Parse a XML element tree to an Entry-tree
@ -65,7 +66,7 @@ class Configuration(object):
for child in parent: for child in parent:
# recursively parse children of child element # recursively parse children of child element
parsed_child = self.parser(child) parsed_child = self.__parser(child)
# parse attributes of child element # parse attributes of child element
parsed_child.parse(child) parsed_child.parse(child)
@ -79,13 +80,13 @@ class Configuration(object):
setattr(obj, child.tag, parsed_child) setattr(obj, child.tag, parsed_child)
return obj return obj
def calc_metaoptions(self): def __calc_metaoptions(self):
""" """
Calculate additional attributes e.g. the wavelength grid Calculate additional attributes e.g. the wavelength grid
""" """
self.calc_metaoption_wl_delta() self.__calc_metaoption_wl_delta()
def calc_metaoption_wl_delta(self): def __calc_metaoption_wl_delta(self):
""" """
Calculate the wavelength grid used for the calculations. Calculate the wavelength grid used for the calculations.
""" """
@ -98,96 +99,112 @@ class Configuration(object):
self.conf.common.wl_max().to(u.nm).value, wl_delta.to(u.nm).value), self.conf.common.wl_max().to(u.nm).value, wl_delta.to(u.nm).value),
self.conf.common.wl_max().to(u.nm).value) << u.nm)) self.conf.common.wl_max().to(u.nm).value) << u.nm))
@staticmethod def __check_config(self):
def check_config(conf: Entry): """
Check and fix the parsed configuration file.
"""
# Check common # Check common
if not hasattr(conf, "common"): if not hasattr(self.conf, "common"):
error("Configuration check: Missing required container 'common'.") error("Configuration check: Missing required container 'common'.")
if not hasattr(conf.common, "wl_min"): if not hasattr(self.conf.common, "wl_min"):
error("Configuration check: common: Missing required container 'wl_min'.") error("Configuration check: common: Missing required container 'wl_min'.")
mes = conf.common.wl_min.check_quantity("val", u.m) mes = self.conf.common.wl_min.check_quantity("val", u.m)
mes is not None and error("Configuration check: common -> wl_min: " + mes) mes is not None and error("Configuration check: common -> wl_min: " + mes)
if not hasattr(conf.common, "wl_max"): if not hasattr(self.conf.common, "wl_max"):
error("Configuration check: common: Missing required container 'wl_max'.") error("Configuration check: common: Missing required container 'wl_max'.")
mes = conf.common.wl_max.check_quantity("val", u.m) mes = self.conf.common.wl_max.check_quantity("val", u.m)
mes is not None and error("Configuration check: common -> wl_max: " + mes) mes is not None and error("Configuration check: common -> wl_max: " + mes)
if hasattr(conf.common, "wl_delta"): if hasattr(self.conf.common, "wl_delta"):
mes = conf.common.wl_delta.check_quantity("val", u.m) mes = self.conf.common.wl_delta.check_quantity("val", u.m)
mes is not None and error("Configuration check: common -> wl_delta: " + mes) mes is not None and error("Configuration check: common -> wl_delta: " + mes)
elif hasattr(conf.common, "res"): elif hasattr(self.conf.common, "res"):
mes = conf.common.res.check_quantity("val", u.dimensionless_unscaled) mes = self.conf.common.res.check_quantity("val", u.dimensionless_unscaled)
mes is not None and error("Configuration check: common -> res: " + mes) mes is not None and error("Configuration check: common -> res: " + mes)
else: else:
error("Configuration check: common: Expected one of the containers 'wl_delta' or 'res' but got none.") error("Configuration check: common: Expected one of the containers 'wl_delta' or 'res' but got none.")
if not hasattr(conf.common, "d_aperture"): if not hasattr(self.conf.common, "d_aperture"):
error("Configuration check: common: Missing required container 'd_aperture'.") error("Configuration check: common: Missing required container 'd_aperture'.")
mes = conf.common.d_aperture.check_quantity("val", u.m) mes = self.conf.common.d_aperture.check_quantity("val", u.m)
mes is not None and error("Configuration check: common -> d_aperture: " + mes) mes is not None and error("Configuration check: common -> d_aperture: " + mes)
if not hasattr(conf.common, "psf"): if not hasattr(self.conf.common, "psf"):
setattr(conf.common, "psf", Entry(val="Airy")) setattr(self.conf.common, "psf", Entry(val="Airy"))
else: else:
if conf.common.psf().lower() != "airy": if self.conf.common.psf().lower() != "airy":
mes = conf.common.psf.check_file("val") mes = self.conf.common.psf.check_file("val")
mes is not None and error("Configuration check: common -> psf: " + mes) mes is not None and error("Configuration check: common -> psf: " + mes)
if hasattr(conf.common, "jitter_sigma"): if hasattr(self.conf.common, "jitter_sigma"):
mes = conf.common.jitter_sigma.check_quantity("val", u.arcsec) mes = self.conf.common.jitter_sigma.check_quantity("val", u.arcsec)
mes is not None and error("Configuration check: common -> jitter_sigma: " + mes) mes is not None and error("Configuration check: common -> jitter_sigma: " + mes)
if not hasattr(conf.common, "output_path"): if not hasattr(self.conf.common, "output_path"):
setattr(conf.common, "output_path", Entry(val=".")) setattr(self.conf.common, "output_path", Entry(val="."))
# Check astroscene # Check astroscene
if not hasattr(conf, "astroscene"): if not hasattr(self.conf, "astroscene"):
error("Configuration check: Missing required container 'astroscene'.") error("Configuration check: Missing required container 'astroscene'.")
if not hasattr(conf.astroscene, "target"): if not hasattr(self.conf.astroscene, "target"):
error("Configuration check: astroscene: Missing required container 'target'.") error("Configuration check: astroscene: Missing required container 'target'.")
if not hasattr(conf.astroscene.target, "type"): if not hasattr(self.conf.astroscene.target, "type"):
error("Configuration check: astroscene -> target: Missing required parameter 'type'.") error("Configuration check: astroscene -> target: Missing required parameter 'type'.")
if conf.astroscene.target.type not in dir(tg): if self.conf.astroscene.target.type not in dir(tg):
# noinspection PyTypeChecker # noinspection PyTypeChecker
error("Configuration check: astroscene -> target: Target type '" + conf.astroscene.target.type + error("Configuration check: astroscene -> target: Target type '" + self.conf.astroscene.target.type +
"' does not exist. Did you mean '" + difflib.get_close_matches(conf.astroscene.target.type, "' does not exist. Did you mean '" + difflib.get_close_matches(self.conf.astroscene.target.type,
dir(tg), 1)[0] + "'?") dir(tg), 1)[0] + "'?")
mes = getattr(tg, conf.astroscene.target.type).check_config(conf.astroscene.target) mes = getattr(tg, self.conf.astroscene.target.type).check_config(self.conf.astroscene.target)
mes is not None and error("Configuration check: astroscene -> target: " + mes) mes is not None and error("Configuration check: astroscene -> target: " + mes)
def check_optical_components(conf: Entry): mes = self.__check_optical_components(self.conf.astroscene)
if hasattr(conf, "optical_component"):
for component in (conf.optical_component if type(conf.optical_component) == list else
[conf.optical_component]):
if not hasattr(component, "type"):
return "optical_component: Missing required parameter 'type'."
if component.type not in dir(oc):
# noinspection PyTypeChecker
return "optical_component: optical component type '" + component.type + \
"' does not exist. Did you mean '" + \
difflib.get_close_matches(component.type, dir(tg), 1)[0] + "'?"
mes = getattr(oc, component.type).check_config(component)
if mes is not None:
print(component.type)
print(mes)
return "optical_component -> " + component.type + ": " + mes
mes = check_optical_components(conf.astroscene)
mes is not None and error("Configuration check: astroscene -> " + mes) mes is not None and error("Configuration check: astroscene -> " + mes)
# Check common_optics # Check common_optics
if hasattr(conf, "common_optics"): if hasattr(self.conf, "common_optics"):
mes = check_optical_components(conf.common_optics) mes = self.__check_optical_components(self.conf.common_optics)
mes is not None and error("Configuration check: common_optics -> " + mes) mes is not None and error("Configuration check: common_optics -> " + mes)
# Check instrument # Check instrument
if not hasattr(conf, "instrument"): if not hasattr(self.conf, "instrument"):
error("Configuration check: Missing required container 'instrument'.") error("Configuration check: Missing required container 'instrument'.")
mes = check_optical_components(conf.instrument) mes = self.__check_optical_components(self.conf.instrument)
mes is not None and error("Configuration check: instrument -> " + mes) mes is not None and error("Configuration check: instrument -> " + mes)
if not hasattr(conf.instrument, "sensor"): if not hasattr(self.conf.instrument, "sensor"):
error("Configuration check: instrument: Missing required container 'sensor'.") error("Configuration check: instrument: Missing required container 'sensor'.")
if not hasattr(conf.instrument.sensor, "type"): if not hasattr(self.conf.instrument.sensor, "type"):
error("Configuration check: instrument -> target: Missing required parameter 'type'.") error("Configuration check: instrument -> target: Missing required parameter 'type'.")
if conf.instrument.sensor.type not in dir(sensor): if self.conf.instrument.sensor.type not in dir(sensor):
# noinspection PyTypeChecker # noinspection PyTypeChecker
error("Configuration check: sensor -> target: Sensor type '" + conf.instrument.sensor.type + error("Configuration check: sensor -> target: Sensor type '" + self.conf.instrument.sensor.type +
"' does not exist. Did you mean '" + difflib.get_close_matches(conf.instrument.sensor.type, "' does not exist. Did you mean '" + difflib.get_close_matches(self.conf.instrument.sensor.type,
dir(sensor), 1)[0] + "'?") dir(sensor), 1)[0] + "'?")
mes = getattr(sensor, conf.instrument.sensor.type).check_config(conf.instrument.sensor) mes = getattr(sensor, self.conf.instrument.sensor.type).check_config(self.conf.instrument.sensor)
mes is not None and error("Configuration check: instrument -> sensor -> " + mes) mes is not None and error("Configuration check: instrument -> sensor -> " + mes)
@staticmethod
def __check_optical_components(conf: Union[Entry, list]):
"""
Check list of optical components in the parsed configuration.
Parameters
----------
conf : Union[Entry, list]
The configuration entry or the list of configuration entries of the optical components to be checked.
Returns
-------
mes : Union[None, str]
The error message of the check. This will be None if the check was successful.
"""
if hasattr(conf, "optical_component"):
for component in (conf.optical_component if type(conf.optical_component) == list else
[conf.optical_component]):
if not hasattr(component, "type"):
return "optical_component: Missing required parameter 'type'."
if component.type not in dir(oc):
# noinspection PyTypeChecker
return "optical_component: optical component type '" + component.type + \
"' does not exist. Did you mean '" + \
difflib.get_close_matches(component.type, dir(tg), 1)[0] + "'?"
mes = getattr(oc, component.type).check_config(component)
if mes is not None:
print(component.type)
print(mes)
return "optical_component -> " + component.type + ": " + mes