Skip to content

Commit cb3c0c0

Browse files
authored
Merge pull request nexpy#264 from rayosborn:skip-self-copy-uncopied-data
Skip self-copy when reading uncopied lazy-loaded field
2 parents 17b4b6d + 768bed9 commit cb3c0c0

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

src/nexusformat/nexus/tree.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3286,7 +3286,16 @@ def _get_uncopied_data(self, idx=None):
32863286
return f.readvalue(_path, idx=idx)
32873287
else:
32883288
if self.nxfilemode == 'rw':
3289-
f.copy(_path, self.nxpath)
3289+
# Skip the copy if the field already lives at the
3290+
# destination path. This happens when a file-backed
3291+
# field is deep-copied into a new container that
3292+
# ends up at the same on-disk location (e.g. the
3293+
# PlotDialog wraps a field in an in-memory NXdata
3294+
# whose nxpath collides with the source). HDF5
3295+
# otherwise raises 'destination object already
3296+
# exists' here.
3297+
if _path != self.nxpath:
3298+
f.copy(_path, self.nxpath)
32903299
else:
32913300
self._create_memfile()
32923301
f.copy(_path, self._memfile, name='data')

tests/test_files.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import os
22

3+
import numpy as np
34
import pytest
4-
from nexusformat.nexus.tree import (NXdata, NXentry, NXFile, NXroot, nxload,
5-
nxopen)
5+
from nexusformat.nexus.tree import (NXdata, NXentry, NXfield, NXFile, NXroot,
6+
nxload, nxopen)
67

78

89
def test_file_creation(tmpdir):
@@ -80,3 +81,29 @@ def test_file_context_manager(tmpdir, field1, field2):
8081
assert "entry/data/f2" in w2
8182
assert "signal" in w2["entry/data"].attrs
8283
assert "axes" in w2["entry/data"].attrs
84+
85+
86+
def test_read_lazy_field_on_copy(tmpdir):
87+
88+
filename = os.path.join(tmpdir, "file.nxs")
89+
shape = (2000, 2000)
90+
root = NXroot(NXentry(NXdata(
91+
NXfield(np.zeros(shape, dtype=np.int64), name="signal"),
92+
name="data")))
93+
root["entry/data/signal_mask"] = NXfield(np.zeros(shape, dtype=bool))
94+
root["entry/data/signal"].attrs["mask"] = "signal_mask"
95+
root.save(filename, mode="w")
96+
del root
97+
98+
root = nxload(filename, "rw")
99+
src = root["entry/data"]
100+
wrapper = NXdata(src["signal_mask"], name=src.nxname)
101+
wrapper.nxgroup = src.nxgroup
102+
field = wrapper.nxsignal
103+
assert field._uncopied_data is not None
104+
assert field._uncopied_data[1] == field.nxpath
105+
106+
arr = field[()]
107+
assert arr.shape == shape
108+
assert arr.dtype == bool
109+
assert field._uncopied_data is None

0 commit comments

Comments
 (0)