Skip to content

Commit 8fc4f9a

Browse files
committed
use bald objects
1 parent eca8da6 commit 8fc4f9a

File tree

8 files changed

+218
-84
lines changed

8 files changed

+218
-84
lines changed

lib/bald/__init__.py

Lines changed: 144 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def check_uri(self, uri):
3737

3838

3939
class Subject(object):
40-
def __init__(self, attrs=None, prefixes=None, aliases=None):
40+
def __init__(self, attrs=None, prefixes=None, aliases=None,
41+
rdftype='bald__Subject'):
4142
"""
4243
A subject of metadata statements.
4344
@@ -50,13 +51,35 @@ def __init__(self, attrs=None, prefixes=None, aliases=None):
5051
if aliases is None:
5152
aliases = {}
5253
self.attrs = attrs
54+
if 'rdf__type' not in attrs:
55+
attrs['rdf__type'] = rdftype
56+
elif rdftype not in attrs['rdf__type']:
57+
if isinstance(attrs['rdf__type'], list):
58+
attrs['rdf__type'].append(rdftype)
59+
elif isinstance(attrs['rdf__type'], set):
60+
attrs['rdf__type'].add(rdftype)
61+
else:
62+
attrs['rdf__type'] = set((attrs['rdf__type'], rdftype))
63+
5364
self.aliases = aliases
5465
self._prefixes = prefixes
5566
self._prefix_suffix = re.compile('(^(?:(?!__).)*)__((?!.*__).*$)')
5667
_http_p = 'http[s]?://.*'
5768
self._http_uri = re.compile('{}'.format(_http_p))
5869
self._http_uri_prefix = re.compile('{}/|#'.format(_http_p))
5970

71+
def __str__(self):
72+
return '{}: {}'.format(type(self), self.attrs)
73+
74+
def __repr__(self):
75+
return str(self)
76+
77+
def __getattr__(self, attr):
78+
if attr not in self.attrs:
79+
msg = '{} object has no attribute {}'.format(type(self), attr)
80+
raise AttributeError(msg)
81+
return self.attrs[attr]
82+
6083
def prefixes(self):
6184
prefixes = {}
6285
for key, value in self._prefixes.iteritems():
@@ -80,7 +103,30 @@ def unpack_uri(self, astring):
80103
result = self.aliases[astring]
81104
return result
82105

106+
def graph(self):
107+
graph = rdflib.Graph()
108+
109+
return graph
110+
111+
class Array(Subject):
112+
def __init__(self, attrs=None, prefixes=None, aliases=None,
113+
shape=None):
114+
self.shape = shape
115+
rdftype = 'bald__Array'
116+
super(Array, self).__init__(attrs, prefixes, aliases, rdftype)
83117

118+
@property
119+
def array_references(self):
120+
return self.attrs.get('bald__references', [])
121+
#return []
122+
123+
class Container(Subject):
124+
def __init__(self, attrs=None, prefixes=None, aliases=None,
125+
shape=None):
126+
rdftype = 'bald__Container'
127+
super(Container, self).__init__(attrs, prefixes, aliases, rdftype)
128+
129+
84130
@contextlib.contextmanager
85131
def load(afilepath):
86132
if afilepath.endswith('.hdf'):
@@ -108,78 +154,136 @@ def load(afilepath):
108154
finally:
109155
f.close()
110156

111-
112-
def validate_netcdf(afilepath):
157+
def load_netcdf(afilepath):
113158
"""
114-
Validate a file with respect to binarry-array-linked-data.
159+
Validate a file with respect to binary-array-linked-data.
115160
Returns a :class:`bald.validation.Validation`
116161
"""
117162

118163
with load(afilepath) as fhandle:
119-
sval = bv.StoredValidation()
120-
prefix_group = fhandle[fhandle.bald__isPrefixedBy] if hasattr(fhandle, 'bald__isPrefixedBy') else {}
164+
prefix_group = (fhandle[fhandle.bald__isPrefixedBy] if
165+
hasattr(fhandle, 'bald__isPrefixedBy') else {})
121166
prefixes = {}
122167
if prefix_group:
123-
prefixes = dict([(prefix, getattr(prefix_group, prefix)) for prefix in prefix_group.ncattrs()])
168+
prefixes = (dict([(prefix, getattr(prefix_group, prefix)) for
169+
prefix in prefix_group.ncattrs()]))
124170
else:
125171
for k in fhandle.ncattrs():
126172
if k.endswith('__'):
127173
prefixes[k] = getattr(fhandle, k)
128-
alias_group = fhandle[fhandle.bald__isAliasedBy] if hasattr(fhandle, 'bald__isAliasedBy') else {}
174+
alias_group = (fhandle[fhandle.bald__isAliasedBy]
175+
if hasattr(fhandle, 'bald__isAliasedBy') else {})
129176
aliases = {}
130177
if alias_group:
131-
aliases = dict([(alias, getattr(alias_group, alias)) for alias in alias_group.ncattrs()])
178+
aliases = (dict([(alias, getattr(alias_group, alias))
179+
for alias in alias_group.ncattrs()]))
132180

133181
attrs = {}
134182
for k in fhandle.ncattrs():
135183
attrs[k] = getattr(fhandle, k)
136-
root_container = Subject(attrs, prefixes=prefixes, aliases=aliases)
137-
root_val = bv.ContainerValidation(subject=root_container,
138-
fhandle=fhandle)
139-
sval.stored_exceptions += root_val.exceptions()
184+
# It would be nice to use the URI of the file if it is known.
185+
attrs['@id'] = 'root'
186+
root_container = Container(attrs, prefixes=prefixes,
187+
aliases=aliases)
188+
root_container.attrs['bald__contains'] = []
189+
140190
for name in fhandle.variables:
141-
sattrs = fhandle.__dict__.copy()
142-
sattrs.update(fhandle.variables[name].__dict__.copy())
143-
var = Subject(sattrs, prefixes=prefixes, aliases=aliases)
144-
var_val = bv.ArrayValidation(name, fhandle.variables[name], fhandle=fhandle,
145-
subject=var)
146-
sval.stored_exceptions += var_val.exceptions()
191+
192+
sattrs = fhandle.variables[name].__dict__.copy()
193+
sattrs['@id'] = '/{}'.format(name)
194+
195+
if 'bald__references' in fhandle.variables[name].ncattrs():
196+
child_dset = fhandle.variables[fhandle.variables[name].bald__references]
197+
cattrs = child_dset.__dict__.copy()
198+
cattrs['@id'] = '/{}'.format(child_dset.name)
199+
carray = Array(cattrs, prefixes, aliases, child_dset.shape)
200+
sattrs['bald__references'] = [carray]
201+
202+
var = Array(sattrs, prefixes=prefixes, aliases=aliases,
203+
shape=fhandle.variables[name].shape)
204+
root_container.attrs['bald__contains'].append(var)
147205

148-
return sval
206+
207+
return root_container
208+
209+
210+
def validate_netcdf(afilepath):
211+
"""
212+
Validate a file with respect to binary-array-linked-data.
213+
Returns a :class:`bald.validation.Validation`
214+
215+
"""
216+
root_container = load_netcdf(afilepath)
217+
return validate(root_container)
149218

150219

151220
def validate_hdf5(afilepath):
152221
"""
153-
Validate a file with respect ot binarry-array-linked-data.
222+
Validate a file with respect to binary-array-linked-data.
223+
Returns a :class:`bald.validation.Validation`
224+
225+
"""
226+
root_container = load_hdf5(afilepath)
227+
return validate(root_container)
228+
229+
def validate(root_container):
230+
"""
231+
Validate a Container with respect to binary-array-linked-data.
154232
Returns a :class:`bald.validation.Validation`
233+
155234
"""
235+
sval = bv.StoredValidation()
236+
237+
root_val = bv.ContainerValidation(subject=root_container)
238+
sval.stored_exceptions += root_val.exceptions()
239+
for subject in root_container.attrs.get('bald__contains', []):
240+
241+
# a dataset's attribute collection inherits from and
242+
# specialises it's container's attrbiute collection
243+
# this only helps with prefixes, afaik, hence:
244+
# #
245+
array_val = bv.ArrayValidation(subject)
246+
sval.stored_exceptions += array_val.exceptions()
247+
248+
return sval
156249

250+
def load_hdf5(afilepath):
157251
with load(afilepath) as fhandle:
158-
sval = bv.StoredValidation()
252+
# unused?
159253
cache = {}
160254
prefix_group = fhandle.attrs.get('bald__isPrefixedBy')
161255
prefixes = {}
162256
if prefix_group:
163-
prefixes = fhandle[prefix_group].attrs
257+
prefixes = dict(fhandle[prefix_group].attrs)
164258
alias_group = fhandle.attrs.get('bald__isAliasedBy')
165259
aliases = {}
166260
if alias_group:
167-
aliases = dict(fhandle[alias_group].attrs.iteritems())
168-
root_container = Subject(fhandle.attrs, prefixes=prefixes, aliases=aliases)
169-
root_val = bv.ContainerValidation(subject=root_container,
170-
fhandle=fhandle)
171-
sval.stored_exceptions += root_val.exceptions()
261+
aliases = dict(fhandle[alias_group].attrs)
262+
attrs = dict(fhandle.attrs)
263+
attrs['@id'] = 'root'
264+
root_container = Container(attrs, prefixes=prefixes, aliases=aliases)
265+
266+
root_container.attrs['bald__contains'] = []
267+
172268
# iterate through the datasets
173269
for name, dataset in fhandle.items():
174-
# a dataset's attribute collection inherits from and
175-
# specialises it's container's attrbiute collection
176-
# this only helps with prefixes, afaik, hence:
177-
# #
178-
sattrs = dict(fhandle.attrs).copy()
179-
sattrs.update(dataset.attrs)
180-
dset = Subject(sattrs, prefixes, aliases)
181-
dset_val = bv.ArrayValidation(name, dataset, fhandle=fhandle,
182-
subject=dset)
183-
sval.stored_exceptions += dset_val.exceptions()
184-
185-
return sval
270+
if hasattr(dataset, 'shape'):
271+
sattrs = dict(dataset.attrs)
272+
sattrs['@id'] = dataset.name
273+
ref = sattrs.get('bald__references', '')
274+
if ref:
275+
ref_dset = fhandle[ref]
276+
child_dset = fhandle[ref_dset.attrs.get('bald__array',
277+
None)]
278+
if child_dset:
279+
cattrs = dict(child_dset.attrs)
280+
cattrs['@id'] = child_dset.name
281+
carray = Array(cattrs, prefixes, aliases,
282+
child_dset.shape)
283+
sattrs['bald__references'] = [carray]
284+
dset = Array(sattrs, prefixes, aliases, dataset.shape)
285+
root_container.attrs['bald__contains'].append(dset)
286+
287+
return root_container
288+
289+

lib/bald/tests/__init__.pyc

-879 Bytes
Binary file not shown.

lib/bald/tests/integration/CDL/ereefs-gbr4_ncld.cdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ dimensions:
33
i = 600 ;
44
j = 180 ;
55
k = 47 ;
6-
time = 50521 ;
6+
time = 5 ;
77
variables:
88
double zc(k) ;
99
zc:axis = "Z" ;

lib/bald/tests/integration/test_aliases.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ def test_invalid_uri(self):
5555
validation = bald.validate_hdf5(tfile)
5656
exns = validation.exceptions()
5757
expected = ['http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
58-
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).',
59-
'http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
60-
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).',
61-
'http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
62-
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).',
63-
'http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
6458
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).']
6559
self.assertTrue((not validation.is_valid()) and exns == expected,
6660
msg='{} != {}'.format(exns, expected))

lib/bald/tests/integration/test_cdl.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,18 @@ def test_process_chain(self):
3535
subprocess.check_call(['ncgen', '-o', tfile, cdl_file])
3636
validation = bald.validate_netcdf(tfile)
3737
exns = validation.exceptions()
38-
self.assertTrue(validation.is_valid(), msg='{} != []'.format(exns))
38+
self.assertTrue(validation.is_valid(), msg='{} != []'.format(exns))
3939

4040
def test_ereef(self):
4141
with self.temp_filename('.nc') as tfile:
4242
cdl_file = os.path.join(self.cdl_path, 'ereefs-gbr4_ncld.cdl')
4343
subprocess.check_call(['ncgen', '-o', tfile, cdl_file])
4444
validation = bald.validate_netcdf(tfile)
4545
exns = validation.exceptions()
46-
#self.assertTrue(validation.is_valid(), msg='{} != []'.format(exns))
47-
self.assertFalse(validation.is_valid(), msg='AssertionError: [\'http://qudt.org/vocab/unit#Meter is not resolving as a resource (404).\', \'http://qudt.org/vocab/unit#MeterPerSecond is not resolving as a resource (404).\', \'http://qudt.org/vocab/unit#MeterPerSecond is not resolving as a resource (404).\', \'http://qudt.org/vocab/unit#DegreeCelsius is not resolving as a resource (404).\']. Also {} != []'.format(exns))
48-
46+
xs = '{} is not resolving as a resource (404).'
47+
expected = [xs.format('http://qudt.org/vocab/unit#Meter'),
48+
xs.format('http://qudt.org/vocab/unit#MeterPerSecond'),
49+
xs.format('http://qudt.org/vocab/unit#MeterPerSecond'),
50+
xs.format('http://qudt.org/vocab/unit#DegreeCelsius')]
51+
self.assertTrue(not validation.is_valid() and exns == expected,
52+
msg='{} \n!= \n{}'.format(exns, expected))
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
import subprocess
3+
import unittest
4+
5+
import netCDF4
6+
import numpy as np
7+
8+
import bald
9+
from bald.tests import BaldTestCase
10+
11+
class Test(BaldTestCase):
12+
def setUp(self):
13+
self.cdl_path = os.path.join(os.path.dirname(__file__), 'CDL')
14+
15+
def test_array_reference(self):
16+
with self.temp_filename('.nc') as tfile:
17+
cdl_file = os.path.join(self.cdl_path, 'array_reference.cdl')
18+
subprocess.check_call(['ncgen', '-o', tfile, cdl_file])
19+
root_container = bald.load_netcdf(tfile)
20+
21+
print root_container
22+
23+
24+
# def test_alias(self):
25+
# with self.temp_filename('.nc') as tfile:
26+
# cdl_file = os.path.join(self.cdl_path, 'array_alias.cdl')
27+
# subprocess.check_call(['ncgen', '-o', tfile, cdl_file])

lib/bald/tests/integration/test_validation.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ def test_invalid_uri(self):
4747
validation = bald.validate_hdf5(tfile)
4848
exns = validation.exceptions()
4949
expected = ['http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
50-
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).',
51-
'http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
52-
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).',
53-
'http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
54-
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).',
55-
'http://binary-array-ld.net/latest/turtle is not resolving as a resource (404).',
5650
'http://binary-array-ld.net/latest/walnut is not resolving as a resource (404).']
5751
self.assertTrue((not validation.is_valid()) and exns == expected,
5852
msg='{} != {}'.format(exns, expected))

0 commit comments

Comments
 (0)