Source code for pyLARDA.ParameterInfo

#!/usr/bin/python3

import toml
import numpy as np
import pprint
import collections
import logging
import re
logger = logging.getLogger(__name__)


[docs]def deep_update(source, overrides): """Update a nested dictionary. Only additions, no removal modify ``source`` in place. """ for key, value in overrides.items(): if isinstance(value, collections.Mapping) and value: returned = deep_update(source.get(key, {}), value) source[key] = returned else: source[key] = overrides[key] return source
[docs]def select_matching_template(syskey, templates, fname): """templates either match by exact name or regex in also_match Example: in a template ``` [CLOUDNET] also_match = "CLOUDNET_.+" [CLOUDNET.generic] ... ``` also matches ``CLOUDNET_LIMRAD`` """ if syskey in templates: return templates[syskey] else: logger.info('no direct hit in template, try also_match') # (?=a)b regex will never match matches = [ k for k, v in templates.items() if bool(re.findall(v.get('also_match', '(?=a)b'), syskey))] assert len(matches) == 1, \ f'more than one matching pattern found in template, check also_match tag in {fname}' return templates[matches[0]]
[docs]def check_filter(filter, config): """ filter for a specific key in the config file, i.e. instr_name, instr_id, ... Args: filter: dict with name (instr_name) and matching value (MIRA_NMRA) config: dict loaded from the config file Returns: True or False TODO: maybe at one point we will need path level filtering """ if filter[0] in config and config[filter[0]] == filter[1]: return True else: return False
[docs]def do_parameter_generic_inheritance(config, cinfo_hand_down={}): """inhert the parameter.generic information to the single variables Args: config (dict): config dict as read from toml cinfo_hand_down (dict, optional): campaign information to inherit Returns: config """ # do the inheritance of system level parameters here for syskey, sysval in config.items(): #print("system level keys ", # [e for e in sysval.keys()]) defaults = {**cinfo_hand_down, **sysval['generic']} #defaults = {k: v for k, v in sysval['generic'].items()} #pprint.pprint(defaults) for pkey, pval in sysval["params"].items(): #print("param", pkey) #logger.debug( # "paraminfo "+ pprint.pformat({**defaults, **pval, **{'system': syskey, 'name': pkey}})) config[syskey]["params"][pkey] = { **defaults, **pval, **{'system': syskey, 'paramkey': pkey}} if 'meta' in defaults and 'meta' in pval: config[syskey]["params"][pkey]['meta'] = { **defaults['meta'], **pval['meta']} return config
[docs]class ParameterInfo: """load the config file right here no need for prior allocation Args: config_path: location of the ``.toml`` config file config_file: name of the ``.toml`` config file """ def __init__(self, config_path, config_file, cinfo_hand_down={}, root=None): logger.info("ParameterInfo: load config file {}".format(config_path, config_file)) config = toml.load(config_path / config_file) self.config = {} for syskey, sysval in config.items(): # get the template if 'template' in sysval: print(config_path / sysval['template']) # if local template is available use that one # otherwise fall back to default template if (config_path / sysval['template']).is_file(): templates = toml.load(config_path / sysval['template']) else: #print('no local template available, check global') templates = toml.load(root.parent / 'template_params' / sysval['template']) temp = select_matching_template(syskey, templates, sysval['template']) #print('template', temp.keys()) sysval = deep_update(temp, sysval) self.config[syskey] = sysval self.config = do_parameter_generic_inheritance(self.config, cinfo_hand_down=cinfo_hand_down)
[docs] def iterate_systems(self, keys=None, filter=None): """provide iterator for the systems structure Args: keys: just iterate over the given (i.e. valid) systems Yields: syskey, config """ if filter: filtered_keys = [k for k,v in self.config.items() if check_filter(filter, v)] else: filtered_keys = self.config.keys() if keys == None: keys = filtered_keys else: keys = set(keys).intersection(filtered_keys) for syskey in keys: yield syskey, self.config[syskey]
def name_and_unit(self): #if self.system_type=="Cloudnet": # output = self.parameter_name #else : if self.unit == "" or self.unit == "[]": output = self.parameter_name else: if self.unit[0]=="[": output = self.parameter_name + " "+self.unit else: output = self.parameter_name + " ["+self.unit+"]" return output def print_info(self): print("Parameter Name : ", self.parameter_name) print("System Type : ", self.system_type) print("Value Range Min : ", self.value_range_min) print("Value Range Max : ", self.value_range_max) print("COLORMAP : ", self.colormap) print("DIMENSIONS : ", self.dimensions) print("Variable Name : ", self.variable_name) print("Time Var. : ", self.time_variable_name) print("Time Dim. : ", self.time_dimension_name) print("Range Dim. : ", self.range_dimension_name) print("Range Resolution: ", self.range_resolution) print("Zero Bin : ", self.zero_bin) print("Zero Bin Height : ", self.zero_bin_height) print("Unit : ", self.unit) print("Data Directory : ", self.data_dir) print("Filemask : ", self.filemask) print("Storage Type : ", self.storage_type) print("Display Type : ", self.display_type) print("Read Line : ", self.read_line) print("File Extension : ", self.file_extension)