def __init__(self, unittest=False, verbose=0): if unittest: # value not used, when we're testing will mock out call to read_json # below with actual translation table to use for test config_files = ['dummy_filename'] else: config = ConfigManager() glob_pattern = os.path.join( config.paths.CODE_ROOT, 'src', 'fieldlist_*.jsonc' ) config_files = glob.glob(glob_pattern) # always have CF-compliant option, which does no translation self.axes = { 'CF': { "lon" : {"axis" : "X", "MDTF_envvar" : "lon_coord"}, "lat" : {"axis" : "Y", "MDTF_envvar" : "lat_coord"}, "lev" : {"axis" : "Z", "MDTF_envvar" : "lev_coord"}, "time" : {"axis" : "T", "MDTF_envvar" : "time_coord"} }} self.variables = {'CF': dict()} self.units = {'CF': dict()} for filename in config_files: d = util.read_json(filename) for conv in util.coerce_to_iter(d['convention_name']): if verbose > 0: print('XXX found ', conv) if conv in self.variables: print("ERROR: convention "+conv+" defined in "+filename+" already exists") raise ConventionError self.axes[conv] = d.get('axes', dict()) self.variables[conv] = util.MultiMap(d.get('var_names', dict())) self.units[conv] = util.MultiMap(d.get('units', dict()))
def _build_data_dicts(self): self.data_keys = defaultdict(list) self.data_pods = util.MultiMap() self.data_files = util.MultiMap() for pod in self.iter_pods(): for var in pod.iter_vars_and_alts(): key = self.dataset_key(var) self.data_pods[key].update(set([pod])) self.data_keys[key].append(var) self.data_files[key].update(var._remote_data)
def get_lookup(self, source, dest): """Find the appropriate lookup table to convert values in *source* (keys) to values in *dest* (values), generating it if necessary. Args: source (str): the CV category to use for the keys. dest (str): the CV category to use for the values. Returns: :class:`util.MultiMap` providing a dict-like lookup interface, ie dest_value = d[source_key]. """ if (source, dest) in self._lookups: return self._lookups[(source, dest)] elif (dest, source) in self._lookups: return self._lookups[(dest, source)].inverse() elif source in self._contents: k = list(self._contents[source])[0] if dest not in self._contents[source][k]: raise KeyError(f"Can't find {dest} in attributes for {source}.") mm = util.MultiMap() for k in self._contents[source]: mm[k].update( util.to_iter(self._contents[source][k][dest], set) ) self._lookups[(source, dest)] = mm return mm elif dest in self._contents: return self._lookups[(dest, source)].inverse() else: raise KeyError(f"Neither {source} or {dest} in CV table list.")
def test_multimap_remove(self): temp = util.MultiMap({'a': 1, 'b': 2, 'c': 1}) temp['c'].add(2) temp['c'].remove(1) temp_inv = temp.inverse() self.assertIn(2, temp_inv) self.assertItemsEqual(temp_inv[2], set(['b', 'c'])) self.assertIn(1, temp_inv) self.assertItemsEqual(temp_inv[1], set(['a']))
def test_multimap_add(self): temp = util.MultiMap({'a': 1, 'b': 2, 'c': 1}) temp['a'].add(3) temp_inv = temp.inverse() self.assertIn(3, temp_inv) self.assertItemsEqual(temp_inv[3], set(['a'])) temp['a'].add(2) temp_inv = temp.inverse() self.assertIn(2, temp_inv) self.assertItemsEqual(temp_inv[2], set(['a', 'b']))
def test_multimap_setitem(self): # test key addition and handling of duplicate values temp = util.MultiMap({'a': 1, 'b': 2}) temp['c'] = 1 temp_inv = temp.inverse() self.assertIn(1, temp_inv) self.assertItemsEqual(temp_inv[1], set(['a', 'c'])) temp['b'] = 3 temp_inv = temp.inverse() self.assertNotIn(2, temp_inv)
def test_multimap_delitem(self): # test item deletion temp = util.MultiMap({'a': 1, 'b': 2}) del temp['b'] temp_inv = temp.inverse() self.assertNotIn(2, temp_inv)
def test_multimap_inverse(self): # test inverse map temp = util.MultiMap({'a': 1, 'b': 2}) temp_inv = temp.inverse() self.assertIn(1, temp_inv) self.assertEqual(temp_inv[2], set(['b']))
def test_multimap_add_new(self): temp = util.MultiMap({'a': 1, 'b': 2, 'c': 1}) temp['x'].add(2) temp_inv = temp.inverse() self.assertIn(2, temp_inv) self.assertCountEqual(temp_inv[2], set(['b', 'x']))