aboutsummaryrefslogtreecommitdiffstats
path: root/fg21sim/configs/checkers.py
diff options
context:
space:
mode:
Diffstat (limited to 'fg21sim/configs/checkers.py')
-rw-r--r--fg21sim/configs/checkers.py179
1 files changed, 179 insertions, 0 deletions
diff --git a/fg21sim/configs/checkers.py b/fg21sim/configs/checkers.py
new file mode 100644
index 0000000..e225234
--- /dev/null
+++ b/fg21sim/configs/checkers.py
@@ -0,0 +1,179 @@
+# Copyright (c) 2016 Weitian LI <liweitianux@live.com>
+# MIT license
+
+"""
+Custom checkers to further validate the configurations.
+
+NOTE
+----
+These functions further check the configurations as a whole, which means
+one config option may be checked against its context.
+Therefore, they are very different to the checker functions used in the
+``validate.Validator``.
+"""
+
+import os
+
+from ..errors import ConfigError
+
+
+def _check_missing(configs, keys):
+ """Check whether the required config is provided by the user."""
+ results = {}
+ if isinstance(keys, str):
+ keys = [keys, ]
+ for key in keys:
+ if not configs.getn(key):
+ results[key] = "Value required but missing"
+ return results
+
+
+def _check_existence(configs, keys):
+ """Check whether the file/directory corresponding to the config exists."""
+ if isinstance(keys, str):
+ keys = [keys, ]
+ results = {}
+ for key in keys:
+ res = _check_missing(configs, key)
+ if res == {}:
+ # Both "key" and "dir_key" are valid
+ path = configs.get_path(key)
+ if not os.path.exists(path):
+ res[key] = 'File/directory not exist: "%s"' % path
+ results.update(res)
+ return results
+
+
+def check_frequency(configs):
+ """Check the "[frequency]" section of the configurations."""
+ results = {}
+ if configs.getn("frequency/type") == "custom":
+ results.update(_check_missing(configs, "frequency/frequencies"))
+ elif configs.getn("frequency/type") == "calc":
+ results.update(
+ _check_missing(configs, ["frequency/start",
+ "frequency/stop",
+ "frequency/step"])
+ )
+ return results
+
+
+def check_output(configs):
+ """Check the "[output]" section of the configurations."""
+ results = {}
+ if configs.getn("output/combine"):
+ results.update(_check_missing(configs, "output/output_dir"))
+ return results
+
+
+def check_galactic_synchrotron(configs):
+ """Check the "[galactic][synchrotron]" section of the configurations."""
+ comp = "galactic/synchrotron"
+ comp_enabled = configs.getn("common/components")
+ results = {}
+ if comp in comp_enabled:
+ # Only validate the configs if this component is enabled
+ results.update(
+ _check_missing(configs, [comp+"/template_freq",
+ comp+"/template_unit"])
+ )
+ results.update(
+ _check_existence(configs, [comp+"/template", comp+"/indexmap"])
+ )
+ if configs.getn(comp+"/save"):
+ results.update(_check_missing(configs, comp+"/output_dir"))
+ return results
+
+
+def check_galactic_freefree(configs):
+ """Check the "[galactic][freefree]" section of the configurations."""
+ comp = "galactic/freefree"
+ comp_enabled = configs.getn("common/components")
+ results = {}
+ if comp in comp_enabled:
+ # Only validate the configs if this component is enabled
+ results.update(
+ _check_missing(configs, [comp+"/halphamap_unit",
+ comp+"/dustmap_unit"])
+ )
+ results.update(
+ _check_existence(configs, [comp+"/halphamap", comp+"/dustmap"])
+ )
+ if configs.getn(comp+"/save"):
+ results.update(_check_missing(configs, comp+"/output_dir"))
+ return results
+
+
+def check_galactic_snr(configs):
+ """Check the "[galactic][snr]" section of the configurations."""
+ comp = "galactic/snr"
+ comp_enabled = configs.getn("common/components")
+ results = {}
+ if comp in comp_enabled:
+ # Only validate the configs if this component is enabled
+ results.update(
+ _check_existence(configs, comp+"/catalog")
+ )
+ if configs.getn(comp+"/save"):
+ results.update(_check_missing(configs, comp+"/output_dir"))
+ return results
+
+
+# Available checkers to validate the configurations
+_CHECKERS = [
+ check_frequency,
+ check_output,
+ check_galactic_synchrotron,
+ check_galactic_freefree,
+ check_galactic_snr,
+]
+
+
+def check_configs(configs, raise_exception=True, checkers=_CHECKERS):
+ """Check/validate the whole configurations through all the supplied
+ checker functions.
+
+ These checker functions may check one config option against its context
+ if necessary to determine whether it has a valid value.
+
+ Parameters
+ ----------
+ configs : `ConfigManager` instance
+ An ``ConfigManager`` instance contains both default and user
+ configurations.
+ raise_exception : bool, optional
+ Whether raise a ``ConfigError`` exception if there is any invalid
+ config options?
+ checkers : list of functions, optional
+ List of checker functions through which the configurations
+ will be checked.
+
+ Returns
+ -------
+ result : bool
+ ``True`` if the configurations pass all checker functions.
+ errors : dict
+ An dictionary containing the details about the invalid config options,
+ with the keys identifying the config options and values indicating
+ the error message.
+ If above ``result=True``, then this is an empty dictionary ``{}``.
+
+ Raises
+ ------
+ ConfigError
+ If any config option failed to pass any of the checkers, a
+ ``ConfigError`` with details is raised.
+ """
+ errors = {}
+ for checker in checkers:
+ errors.update(checker(configs))
+ #
+ if errors == {}:
+ result = True
+ else:
+ result = False
+ if raise_exception:
+ msg = "\n".join(['Config "{key}": {val}'.format(key=key, val=val)
+ for key, val in errors.items()])
+ raise ConfigError(msg)
+ return (result, errors)