-
Notifications
You must be signed in to change notification settings - Fork 2
/
metainfo.py
86 lines (68 loc) · 2.9 KB
/
metainfo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import yaml, re, csv
class Metainfo(object):
def describe_variable(self, variable):
"""Text description of a variable."""
raise NotImplementedError()
def get_unit(self, variable):
"""Canonical unit for variable."""
raise NotImplementedError()
def get_tags(self, variable):
"""Return a list of tags for each variable."""
return NotImplementedError()
class UniformMetainfo(Metainfo):
def __init__(self, description, unit):
self.description = description
self.unit = unit
def describe_variable(self, variable):
"""Text description of a variable."""
return self.description
def get_unit(self, variable):
"""Canonical unit for variable."""
return self.unit
class StoredMetainfo(Metainfo):
VARFINDER = re.compile(r'^(?P<desc>[^\[]+)\s+(?P<unit>\[([^\]]+)\])')
def __init__(self, catalog):
self.catalog = catalog
def describe_variable(self, variable):
"""Text description of a variable."""
return self.catalog.get(variable, dict(description="Missing information")).get('description', None)
def get_unit(self, variable):
"""Canonical unit for variable."""
return self.catalog.get(variable, dict(unit="unknown")).get('unit', "unknown")
@staticmethod
def load(filepath):
catalog = yaml.load(file(filepath, 'r'))
for variable in catalog:
catalog[variable] = StoredMetainfo.parse(catalog[variable])
return StoredMetainfo(catalog)
@staticmethod
def load_csv(filepath, varcol, desccol=None, unitcol=None):
catalog = {}
with open(filepath, 'r') as fp:
reader = csv.reader(fp)
header = reader.next()
for row in reader:
rowinfo = {}
if desccol is not None and len(row) > header.index(desccol):
rowinfo['description'] = row[header.index(desccol)]
if unitcol is not None and len(row) > header.index(unitcol):
rowinfo['unit'] = row[header.index(unitcol)]
catalog[row[header.index(varcol)]] = rowinfo
return StoredMetainfo(catalog)
@staticmethod
def parse(defn):
matchstr = re.search(StoredMetainfo.VARFINDER, defn)
if matchstr is None:
return dict(description=clean(defn))
return dict(description=matchstr.group('desc').strip(), unit=matchstr.group('unit').strip(' []'))
class FunctionalMetainfo(Metainfo):
def __init__(self, get_description, get_unitstr):
"""
get_description: get_description(variable) returns the description of that variable.
"""
self.get_description = get_description
self.get_unitstr = get_unitstr
def describe_variable(self, variable):
return self.get_description(variable)
def get_unit(self, variable):
return self.get_unitstr(variable)