Skip to content

Commit

Permalink
Merge pull request hyperspy#206 from ericpre/fix_hspy_empty_array
Browse files Browse the repository at this point in the history
Fix saving hspy file with empty array
  • Loading branch information
jlaehne authored Dec 19, 2023
2 parents 5585f0f + 8048530 commit 94f9aa9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 12 deletions.
7 changes: 4 additions & 3 deletions rsciio/_hierarchical.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ def get_signal_chunks(shape, dtype, signal_axes=None, target_size=1e6):
The target number of bytes for one chunk
"""
typesize = np.dtype(dtype).itemsize
if signal_axes is None:
return h5py._hl.filters.guess_chunk(shape, None, typesize)
if shape == (0,) or signal_axes is None:
# enable autochunking from h5py
return True

# largely based on the guess_chunk in h5py
bytes_per_signal = np.prod([shape[i] for i in signal_axes]) * typesize
Expand Down Expand Up @@ -839,8 +840,8 @@ def write_signal(

def dict2group(self, dictionary, group, **kwds):
"Recursive writer of dicts and signals"

for key, value in dictionary.items():
_logger.debug("Saving item: {}".format(key))
if isinstance(value, dict):
self.dict2group(value, group.require_group(key), **kwds)
elif isinstance(value, (np.ndarray, self.Dataset, da.Array)):
Expand Down
31 changes: 22 additions & 9 deletions rsciio/hspy/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ def __init__(self, file, signal, expg, **kwds):
self.Dataset = h5py.Dataset
self.Group = h5py.Group
self.unicode_kwds = {"dtype": h5py.special_dtype(vlen=str)}
self.ragged_kwds = {"dtype": h5py.special_dtype(vlen=signal["data"][0].dtype)}
if len(signal["data"]) > 0:
self.ragged_kwds = {
"dtype": h5py.special_dtype(vlen=signal["data"][0].dtype)
}

@staticmethod
def _store_data(data, dset, group, key, chunks, show_progressbar=True):
Expand Down Expand Up @@ -98,7 +101,8 @@ def _store_data(data, dset, group, key, chunks, show_progressbar=True):
)
# for performance reason, we write the data later, with all data
# at the same time in a single `da.store` call
elif data_.flags.c_contiguous:
# "write_direct" doesn't play well with empty array
elif data_.flags.c_contiguous and data_.shape != (0,):
dset_.write_direct(data_)
else:
dset_[:] = data_
Expand Down Expand Up @@ -148,9 +152,14 @@ def file_reader(filename, lazy=False, **kwds):
f = h5py.File(filename, mode=mode, **kwds)

reader = HyperspyReader(f)
exp_dict_list = reader.read(lazy=lazy)
if not lazy:
f.close()
# Use try, except, finally to close file when an error is raised
try:
exp_dict_list = reader.read(lazy=lazy)
except BaseException as err:
raise err
finally:
if not lazy:
f.close()

return exp_dict_list

Expand Down Expand Up @@ -244,10 +253,14 @@ def file_writer(
show_progressbar=show_progressbar,
**kwds,
)
writer.write()

if close_file:
f.close()
# Use try, except, finally to close file when an error is raised
try:
writer.write()
except BaseException as err:
raise err
finally:
if close_file:
f.close()


file_writer.__doc__ %= (
Expand Down
28 changes: 28 additions & 0 deletions rsciio/tests/test_hspy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1069,3 +1069,31 @@ def test_more_recent_version_warning(tmp_path):
with pytest.warns(UserWarning):
s2 = hs.load(filename)
np.testing.assert_allclose(s.data, s2.data)


@zspy_marker
def test_save_metadata_empty_array(tmp_path, file):
filename = tmp_path / "test.hspy"

s = hs.signals.Signal1D(np.arange(100 * 1024).reshape(100, 1024))
s.metadata.set_item("Sample.xray_lines", np.array([]))

s.save(filename)
s2 = hs.load(filename)

np.testing.assert_allclose(
s.metadata.Sample.xray_lines, s2.metadata.Sample.xray_lines
)
np.testing.assert_allclose(s.data, s2.data)


@zspy_marker
def test_save_empty_signal(tmp_path, file):
filename = tmp_path / "test.hspy"

s = hs.signals.Signal1D([])

s.save(filename)
s2 = hs.load(filename)

np.testing.assert_allclose(s.data, s2.data)
1 change: 1 addition & 0 deletions upcoming_changes/206.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix saving ``hspy`` file with empty array (signal or metadata) and fix closing ``hspy`` file when a error occurs during reading or writing.

0 comments on commit 94f9aa9

Please sign in to comment.