Skip to content

Commit b785a0f

Browse files
committed
coordinate variable referencing
1 parent 4cd66ae commit b785a0f

File tree

3 files changed

+42
-58
lines changed

3 files changed

+42
-58
lines changed

lib/bald/__init__.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ def load_netcdf(afilepath, uri=None):
576576
fhandle.variables[name].dimensions[0] == name):
577577
sattrs['bald__array'] = name
578578
sattrs['rdf__type'] = 'bald__Reference'
579-
579+
580580
if fhandle.variables[name].shape:
581581
sattrs['bald__shape'] = fhandle.variables[name].shape
582582
var = Array(identity, sattrs, prefixes=prefixes, aliases=aliases)
@@ -604,8 +604,26 @@ def load_netcdf(afilepath, uri=None):
604604
if 'bald__Reference' not in var.rdf__type:
605605
for dim in fhandle.variables[name].dimensions:
606606
if file_variables.get(dim):
607+
cv_shape = fhandle.variables[dim].shape
608+
var_shape = fhandle.variables[name].shape
607609
refset = var.attrs.get('bald__references', set())
608-
refset.add(file_variables.get(dim))
610+
# Only the dimension defining the last dimension will
611+
# broadcase correctly
612+
if var_shape[-1] == cv_shape[0]:
613+
refset.add(file_variables.get(dim))
614+
# Else, define a bald:childBroadcast
615+
else:
616+
identity = '{}_{}_ref'.format(name, dim)
617+
rattrs = {}
618+
rattrs['rdf__type'] = 'bald__Reference'
619+
reshape = [1 for adim in var_shape]
620+
621+
cvi = fhandle.variables[name].dimensions.index(dim)
622+
reshape[cvi] = fhandle.variables[dim].size
623+
rattrs['bald__childBroadcast'] = tuple(reshape)
624+
rattrs['bald__array'] = set((file_variables.get(dim),))
625+
ref_node = Subject(identity, rattrs, prefixes=prefixes, aliases=aliases)
626+
refset.add(ref_node)
609627
var.attrs['bald__references'] = refset
610628

611629

lib/bald/tests/integration/test_cdl.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,39 +39,16 @@ def test_ereefs_gbr4_ncld(self):
3939
exns = validation.exceptions()
4040
exns.sort()
4141
expected = ['http://qudt.org/vocab/unit#Meter is not resolving as a resource (404).',
42-
'p declares a child of c but the arrays do not conform to the bald array reference rules',
4342
'http://qudt.org/vocab/unit#MeterPerSecond is not resolving as a resource (404).',
44-
'p declares a child of c but the arrays do not conform to the bald array reference rules',
4543
'http://qudt.org/vocab/unit#MeterPerSecond is not resolving as a resource (404).',
46-
'p declares a child of c but the arrays do not conform to the bald array reference rules',
47-
'p declares a child of c but the arrays do not conform to the bald array reference rules',
48-
'http://qudt.org/vocab/unit#DegreeCelsius is not resolving as a resource (404).',
49-
'p declares a child of c but the arrays do not conform to the bald array reference rules',
50-
'p declares a child of c but the arrays do not conform to the bald array reference rules',
51-
'p declares a child of c but the arrays do not conform to the bald array reference rules']
44+
'http://qudt.org/vocab/unit#DegreeCelsius is not resolving as a resource (404).']
5245
expected.sort()
5346
self.assertTrue(not validation.is_valid() and exns == expected,
5447
msg='{} \n!= \n{}'.format(exns, expected))
5548

5649
setattr(Test, 'test_ereefs_gbr4_ncld', test_ereefs_gbr4_ncld)
5750

5851

59-
def test_multi_array_reference(self):
60-
"""Override multi_array test with currently accepted failures"""
61-
with self.temp_filename('.nc') as tfile:
62-
cdl_file = os.path.join(self.cdl_path, 'multi_array_reference.cdl')
63-
subprocess.check_call(['ncgen', '-o', tfile, cdl_file])
64-
validation = bald.validate_netcdf(tfile)
65-
exns = validation.exceptions()
66-
exns.sort()
67-
expected = ['p declares a child of c but the arrays do not conform to the bald array reference rules',
68-
'p declares a child of c but the arrays do not conform to the bald array reference rules']
69-
self.assertTrue(not validation.is_valid() and exns == expected,
70-
msg='{} \n!= \n{}'.format(exns, expected))
71-
72-
73-
setattr(Test, 'test_multi_array_reference', test_multi_array_reference)
74-
7552
def test_ProcessChain0300(self):
7653
"""Override multi_array test with currently accepted failures"""
7754
self.assertTrue(True)

lib/bald/validation.py

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ def valid_array_reference(parray, carray, broadcast_shape=None):
2929
result = True
3030
# try numpy broadcast
3131
try:
32+
if broadcast_shape is not None and carray is not None:
33+
if carray.shape != broadcast_shape:
34+
carray = carray.reshape(broadcast_shape)
3235
_ = np.broadcast(parray, carray)
3336
except ValueError:
3437
result = False
@@ -165,46 +168,32 @@ def _extra_exceptions(self, exceptions):
165168

166169
def check_array_references(self, exceptions):
167170

168-
# if this Array has a bald__references
169-
# # not implemented yet: and it's a singleton
170-
# if refs:
171-
# # then it must have a bald_array
172-
# ref_dset = self.fhandle[self.subject.attrs.get('bald__references')]
173-
# child_dset = None
174-
# if (hasattr(ref_dset, 'attrs')):
175-
# child_dset = self.fhandle[ref_dset.attrs.get('bald__array', None)]
176-
# elif 'bald__array' in ref_dset.ncattrs():
177-
# child_dset = self.fhandle[ref_dset.bald__array]
178-
# else:
179-
# exceptions.append('A bald__Reference must link to '
180-
# 'one and only one bald__Array')
181-
# # and we impose bald broadcasting rules on it
171+
# If this Array has a bald__references
172+
# we impose bald broadcasting rules on it
182173
parray = None
183174
if hasattr(self.array, 'bald__shape') and self.array.bald__shape:
184175
parray = np.zeros(self.array.bald__shape)
185176
for bald_array in self.array.array_references:
177+
broadcast_shape = None
186178
parraysubj = self.array.identity
187179
carray = None
188180
if hasattr(bald_array, 'bald__shape') and bald_array.bald__shape:
189181
carray = np.zeros(bald_array.bald__shape)
190-
carraysubj = bald_array.identity
191-
if not valid_array_reference(parray, carray):
192-
msg = ('{} declares a child of {} but the arrays '
193-
'do not conform to the bald array reference '
194-
'rules')
195-
msg = msg.format(parraysubj, carraysubj)
196-
exceptions.append(msg)
197-
if parray is None and carray is not None:
198-
msg = ('{} declares a child of {} but the parent array '
199-
'is not an extensive array')
200-
msg = msg.format(parraysubj, carraysubj)
201-
exceptions.append(msg)
202-
if carray is None and parray is not None:
203-
msg = ('{} declares a child of {} but the child array '
204-
'is not an extensive array')
205-
msg = msg.format(parraysubj, carraysubj)
206-
exceptions.append(msg)
207-
182+
elif hasattr(bald_array, 'bald__array'):
183+
if len(bald_array.bald__array) == 1:
184+
array_ref = bald_array.bald__array.copy().pop()
185+
if hasattr(array_ref, 'bald__shape'):
186+
carray = np.zeros(bald_array.bald__array.copy().pop().bald__shape)
187+
188+
if hasattr(bald_array, 'bald__childBroadcast'):
189+
broadcast_shape = bald_array.bald__childBroadcast
190+
carraysubj = bald_array.identity
191+
if not valid_array_reference(parray, carray, broadcast_shape):
192+
msg = ('{} declares a child of {} but the arrays '
193+
'do not conform to the bald array reference '
194+
'rules')
195+
msg = msg.format(parraysubj, carraysubj)
196+
exceptions.append(msg)
208197
return exceptions
209198

210199

0 commit comments

Comments
 (0)