Skip to content

Commit 8bf3607

Browse files
committed
Fix deep copies of virtual fields
1 parent 3234acc commit 8bf3607

1 file changed

Lines changed: 27 additions & 14 deletions

File tree

src/nexusformat/nexus/tree.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,6 +2086,7 @@ class NXroot, but if the NeXus tree was defined interactively,
20862086
_vpath = None
20872087
_vfiles = None
20882088
_vshape = None
2089+
_vidx = None
20892090
_proxy = None
20902091

20912092
def __init__(self, *args, **kwargs):
@@ -3338,6 +3339,7 @@ def serialize(self):
33383339
'vpath': self._vpath,
33393340
'vfiles': self._vfiles,
33403341
'vshape': self._vshape,
3342+
'vidx': self._vidx,
33413343
'h5opts': self._h5opts,
33423344
'entries': None,
33433345
'attrs': {k: v._value for k, v in self.attrs.items()}}
@@ -3368,6 +3370,7 @@ def deserialize(cls, serialized_field):
33683370
obj._vpath = serialized_field['vpath']
33693371
obj._vfiles = serialized_field['vfiles']
33703372
obj._vshape = serialized_field['vshape']
3373+
obj._vidx = serialized_field['vidx']
33713374
return obj
33723375

33733376
def __iter__(self):
@@ -4545,19 +4548,21 @@ def __init__(self, target, files, name='unknown', shape=None, idx=None,
45454548
shape = target.shape
45464549
dtype = target.dtype
45474550
target = target.nxfilepath
4551+
elif shape is None:
4552+
raise NeXusError('The shape has not been specified')
4553+
self._vshape = shape
4554+
self._vidx = idx
45484555
self._vpath = target
45494556
if abspath:
45504557
self._vfiles = [Path(f).resolve() for f in files]
45514558
else:
45524559
self._vfiles = files
45534560
if idx:
4554-
self._vshape = (len(self._vfiles),) + slice_shape(idx, shape)
4555-
elif shape:
4556-
self._vshape = (len(self._vfiles),) + shape
4561+
shape = (len(self._vfiles),) + slice_shape(idx, self._vshape)
45574562
else:
4558-
self._vshape = None
4559-
super().__init__(name=name, shape=self._vshape, dtype=dtype,
4560-
group=group, attrs=attrs, **kwargs)
4563+
shape = (len(self._vfiles),) + self._vshape
4564+
super().__init__(name=name, shape=shape, dtype=dtype, group=group,
4565+
attrs=attrs, **kwargs)
45614566
if create_vds and shape and dtype:
45624567
self._create_virtual_data(shape, idx=idx)
45634568

@@ -4567,34 +4572,42 @@ def _create_virtual_data(self, shape, idx=None):
45674572
45684573
Parameters
45694574
----------
4575+
files : list of str
4576+
Paths to the source files.
4577+
path : str
4578+
Path to the field within each source file.
45704579
shape : tuple
4571-
Shape of the fields in the source files.
4580+
Shape of the virtual field in the source files.
45724581
idx : tuple, optional
45734582
Slice indices of the source fields, by default None.
45744583
"""
4575-
maxshape = (None,) + self._vshape[1:]
4576-
if idx is None:
4577-
idx = (None,) * len(self._vshape[1:])
4578-
layout = h5.VirtualLayout(shape=self._vshape, dtype=self.dtype,
4584+
maxshape = (None,) + shape[1:]
4585+
layout = h5.VirtualLayout(shape=shape, dtype=self.dtype,
45794586
maxshape=maxshape)
4587+
if idx is None:
4588+
idx = Ellipsis
45804589
for i, f in enumerate(self._vfiles):
4581-
vsource = h5.VirtualSource(f, self._vpath, shape=shape)
4590+
vsource = h5.VirtualSource(f, self._vpath, shape=self._vshape)
45824591
layout[i] = vsource[idx]
45834592
self._create_memfile()
45844593
self._memfile.create_virtual_dataset('data', layout)
45854594

45864595
def __deepcopy__(self, memo={}):
45874596
"""Return a deep copy of the virtual field and attributes."""
45884597
obj = self
4589-
dpcpy = obj.__class__(self._vpath, self._vfiles)
4598+
dpcpy = obj.__class__(self._vpath, self._vfiles, shape=self._vshape,
4599+
idx=self._vidx, dtype=self.dtype,
4600+
create_vds=False)
45904601
memo[id(self)] = dpcpy
45914602
dpcpy._name = copy(self.nxname)
45924603
dpcpy._dtype = copy(obj.dtype)
45934604
dpcpy._shape = copy(obj.shape)
45944605
dpcpy._vshape = copy(obj._vshape)
4606+
dpcpy._vidx = copy(obj._vidx)
45954607
dpcpy._vpath = copy(obj._vpath)
45964608
dpcpy._vfiles = copy(obj._vfiles)
4597-
dpcpy._create_virtual_data()
4609+
shape = (len(obj._vfiles),) + slice_shape(obj._vidx, obj._vshape)
4610+
dpcpy._create_virtual_data(shape=shape, idx=obj._vidx)
45984611
dpcpy._h5opts = copy(obj._h5opts)
45994612
dpcpy._changed = True
46004613
dpcpy._uncopied_data = None

0 commit comments

Comments
 (0)