Skip to content

Commit

Permalink
fix: identifier not always set for generated instances of QPImage
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmueller committed Oct 17, 2018
1 parent 31d3297 commit 4e795c3
Show file tree
Hide file tree
Showing 21 changed files with 181 additions and 47 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
0.4.3
- fix: "identifier" not always set for generated instances of QPImage
0.4.2
- fix: implement `get_name` method for SeriesFolder format
- enh: start identifier/name indexing at 1 instead of 0
Expand Down
4 changes: 3 additions & 1 deletion qpformat/file_formats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ def get_name(self, idx):
def get_qpimage_raw(self, idx):
"""Return QPImage without background correction"""
ds = self._get_dataset(idx)
return ds.get_qpimage_raw()
qpi = ds.get_qpimage_raw()
qpi["identifier"] = self.get_identifier(idx)
return qpi

def get_time(self, idx):
ds = self._get_dataset(idx)
Expand Down
31 changes: 21 additions & 10 deletions qpformat/file_formats/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import copy
import functools
import hashlib
import io
import pathlib

import numpy as np
Expand Down Expand Up @@ -31,12 +32,13 @@ class SeriesData(object):
def __init__(self, path, meta_data={}, holo_kw={}, as_type="float32"):
#: Enforced dtype via keyword arguments
self.as_type = as_type
if isinstance(path, (str, pathlib.Path)):
#: pathlib.Path to data file or BytesIO
self.path = pathlib.Path(path).resolve()
else:
# _io.BytesIO
if isinstance(path, io.IOBase):
# io.IOBase
self.path = path
else:
#: pathlib.Path to data file or io.IOBase
self.path = pathlib.Path(path).resolve()

# check for valid metadata keys
for key in meta_data:
if key not in qpimage.meta.DATA_KEYS:
Expand Down Expand Up @@ -113,8 +115,11 @@ def _compute_bgid(self, bg=None):
def _identifier_data(self):
data = []
# data
with self.path.open("rb") as fd:
data.append(fd.read(50 * 1024))
if isinstance(self.path, io.IOBase):
data.append(self.path.read(50 * 1024))
else:
with self.path.open("rb") as fd:
data.append(fd.read(50 * 1024))
data += self._identifier_meta()
return hash_obj(data)

Expand Down Expand Up @@ -161,6 +166,10 @@ def get_qpimage(self, idx):
"""Return background-corrected QPImage of data at index `idx`"""
# raw data
qpi = self.get_qpimage_raw(idx)
if "identifier" not in qpi:
msg = "`get_qpimage_raw` does not set 'identifier' " \
+ "in class '{}'!".format(self.__class__)
raise KeyError(msg)
# bg data
if self._bgdata:
if len(self._bgdata) == 1:
Expand All @@ -176,13 +185,15 @@ def get_qpimage(self, idx):
# `self._bgdata` is a QPImage
bg = self._bgdata[bgidx]
qpi.set_bg_data(bg_data=bg)
# set identifier
qpi["identifier"] = self.get_identifier(idx)
return qpi

@abc.abstractmethod
def get_qpimage_raw(self, idx):
"""Return QPImage without background correction"""
"""Return QPImage without background correction
Note that this method must always return a QPImage instance with
the "identifier" metadata key set!
"""

def get_time(self, idx):
"""Return time of data at index `idx`
Expand Down
2 changes: 2 additions & 0 deletions qpformat/file_formats/series_hdf5_hyperspy.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ def get_qpimage_raw(self, idx=0):
meta_data=meta_data,
holo_kw=self.holo_kw,
h5dtype=self.as_type)
# set identifier
qpi["identifier"] = self.get_identifier(idx)
return qpi

@staticmethod
Expand Down
5 changes: 4 additions & 1 deletion qpformat/file_formats/series_zip_tif_holo.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ def files(self):
def get_qpimage_raw(self, idx):
"""Return QPImage without background correction"""
ds = self._get_dataset(idx)
return ds.get_qpimage_raw()
qpi = ds.get_qpimage_raw()
# set identifier
qpi["identifier"] = self.get_identifier(idx)
return qpi

@staticmethod
def verify(path):
Expand Down
5 changes: 4 additions & 1 deletion qpformat/file_formats/series_zip_tif_phasics.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ def files(self):
def get_qpimage_raw(self, idx):
"""Return QPImage without background correction"""
ds = self._get_dataset(idx)
return ds.get_qpimage_raw()
qpi = ds.get_qpimage_raw()
# get identifier
qpi["identifier"] = self.get_identifier(idx)
return qpi

def get_time(self, idx):
# Obtain the time from the tif meta data
Expand Down
2 changes: 2 additions & 0 deletions qpformat/file_formats/single_hdf5_qpimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ def get_qpimage_raw(self, idx=0):
# Force meta data
for key in self.meta_data:
qpi[key] = self.meta_data[key]
# set identifier
qpi["identifier"] = self.get_identifier(idx)
return qpi

@staticmethod
Expand Down
2 changes: 2 additions & 0 deletions qpformat/file_formats/single_npy_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def get_qpimage_raw(self, idx=0):
which_data=self.storage_type,
meta_data=meta_data,
h5dtype=self.as_type)
# get identifier
qpi["identifier"] = self.get_identifier(idx)
return qpi

@staticmethod
Expand Down
2 changes: 2 additions & 0 deletions qpformat/file_formats/single_tif_holo.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def get_qpimage_raw(self, idx=0):
meta_data=meta_data,
holo_kw=self.holo_kw,
h5dtype=self.as_type)
# get identifier
qpi["identifier"] = self.get_identifier(idx)
return qpi

@staticmethod
Expand Down
2 changes: 2 additions & 0 deletions qpformat/file_formats/single_tif_phasics.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ def get_qpimage_raw(self, idx=0):
which_data="phase,intensity",
meta_data=meta_data,
h5dtype=self.as_type)
# set identifier
qpi["identifier"] = self.get_identifier()
return qpi

def get_time(self, idx=0):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
install_requires=["h5py>=2.7.0",
"nrefocus>=0.1.5",
"numpy>=1.12.0",
"qpimage>=0.4.0",
"qpimage>=0.4.3",
"scikit-image>=0.11.0",
"scipy>=0.18.0",
],
Expand Down
4 changes: 1 addition & 3 deletions tests/test_series_folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,8 @@ def test_load_data():
# data should be the same
qpi0 = ds.get_qpimage(0)
qpi1 = ds.get_qpimage(1)
assert qpi0 != qpi1
assert qpi0 == qpi1
assert qpi0["identifier"] != qpi1["identifier"]
qpi0["identifier"] = ""
qpi1["identifier"] = ""
assert qpi0 == qpi1
assert ds.get_qpimage_raw(0) == ds.get_qpimage_raw(1)
assert ds.get_qpimage(0).shape == (50, 50)
Expand Down
10 changes: 10 additions & 0 deletions tests/test_series_hdf5_hyperspy.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ def test_basic():
shutil.rmtree(path=tdir, ignore_errors=True)


def test_returned_identifier():
tdir, hspyf = make_hyperspy()
ds = qpformat.load_data(hspyf)
qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw
shutil.rmtree(path=tdir, ignore_errors=True)


def test_wrong_format():
path = datapath / "single_qpimage.h5"
ds = qpformat.load_data(path, fmt="SeriesHdf5HyperSpy")
Expand Down
42 changes: 34 additions & 8 deletions tests/test_series_hdf5_qpimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ def test_identifier():
def test_load_data():
path = datapath / "single_qpimage.h5"
tf = tempfile.mktemp(suffix=".h5", prefix="qpformat_test_")
qpi = qpimage.QPImage(h5file=path, h5mode="r")
qpi1 = qpimage.QPImage(h5file=path, h5mode="r").copy()
qpi2 = qpi1.copy()
qpi1["identifier"] = "test100"
qpi2["identifier"] = "test200"
# generate qpseries hdf5 file
with qpimage.QPSeries(qpimage_list=[qpi, qpi],
with qpimage.QPSeries(qpimage_list=[qpi1, qpi2],
h5file=tf,
h5mode="a"):
pass
Expand All @@ -52,13 +55,12 @@ def test_load_data():
assert ds.path == pathlib.Path(tf)
assert ds.get_time(1) == 0
assert "SeriesHdf5Qpimage" in ds.__repr__()
# individual identifiers are not extracted anymore as of
# qpformat version 0.3.4
qpd = ds.get_qpimage(1)
assert qpd != qpi
assert qpd.shape == qpi.shape
assert np.allclose(qpd.amp, qpi.amp)
assert np.allclose(qpd.pha, qpi.pha)
assert qpd["identifier"] != qpi1["identifier"]
assert qpd == qpi1
assert qpd.shape == qpi1.shape
assert np.allclose(qpd.amp, qpi1.amp)
assert np.allclose(qpd.pha, qpi1.pha)

# cleanup
try:
Expand Down Expand Up @@ -126,6 +128,30 @@ def test_meta_override():
pass


def test_returned_identifier():
path = datapath / "single_qpimage.h5"
tf = tempfile.mktemp(suffix=".h5", prefix="qpformat_test_")
qpi = qpimage.QPImage(h5file=path, h5mode="r")
# generate qpseries hdf5 file
with qpimage.QPSeries(qpimage_list=[qpi, qpi],
h5file=tf,
h5mode="a"):
pass

ds = qpformat.load_data(tf)

qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw

# cleanup
try:
os.remove(tf)
except OSError:
pass


if __name__ == "__main__":
# Run all tests
loc = locals()
Expand Down
14 changes: 14 additions & 0 deletions tests/test_series_zip_tif_holo.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ def test_load_data():
pass


def test_returned_identifier():
path = setup_test_zip()
ds = qpformat.load_data(path)
qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw

try:
path.unlink()
except OSError:
pass


if __name__ == "__main__":
# Run all tests
loc = locals()
Expand Down
9 changes: 9 additions & 0 deletions tests/test_series_zip_tif_phasics.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ def test_data_content():
assert np.allclose(qpi.pha.max() - qpi.pha.min(), 0.18902349472045898)


def test_returned_identifier():
path = datapath / "series_phasics.zip"
ds = qpformat.load_data(path)
qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw


if __name__ == "__main__":
# Run all tests
loc = locals()
Expand Down
17 changes: 13 additions & 4 deletions tests/test_single_hdf5_qpimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ def test_load_data():
assert ds.path == path.resolve()
assert ds.get_time() == 0
assert "SingleHdf5Qpimage" in ds.__repr__()
# individual identifiers are not extracted anymore as of
# qpformat version 0.3.4
qpd = ds.get_qpimage()
qpi = qpimage.QPImage(h5file=path, h5mode="r")
assert qpd != qpi
qpi = qpimage.QPImage(h5file=path, h5mode="r").copy()
qpi["identifier"] = "test"
assert qpd["identifier"] != qpi["identifier"]
assert qpd == qpi
assert qpd.shape == qpi.shape
assert np.allclose(qpd.amp, qpi.amp)
assert np.allclose(qpd.pha, qpi.pha)
Expand Down Expand Up @@ -98,6 +98,15 @@ def test_meta_override():
pass


def test_returned_identifier():
path = datapath / "single_qpimage.h5"
ds = qpformat.load_data(path)
qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw


if __name__ == "__main__":
# Run all tests
loc = locals()
Expand Down
19 changes: 19 additions & 0 deletions tests/test_single_npy_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,25 @@ def test_load_field():
pass


def test_returned_identifier():
# generate test data
tf = pathlib.Path(tempfile.mktemp(suffix=".npy", prefix="qpformat_test_"))
phase = np.ones((20, 20), dtype=float)
phase *= np.linspace(0, .3, 20).reshape(-1, 1)
np.save(tf, phase)

ds = qpformat.load_data(tf, as_type="float64")
qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw

try:
tf.unlink()
except OSError:
pass


if __name__ == "__main__":
# Run all tests
loc = locals()
Expand Down
9 changes: 9 additions & 0 deletions tests/test_single_tif_holo.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ def test_load_data():
assert qpi.shape == (238, 267)


def test_returned_identifier():
path = datapath / "single_holo.tif"
ds = qpformat.load_data(path)
qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw


if __name__ == "__main__":
# Run all tests
loc = locals()
Expand Down
9 changes: 9 additions & 0 deletions tests/test_single_tif_phasics.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ def test_data_content():
assert np.allclose(qpi.pha.max() - qpi.pha.min(), 4.168394088745117)


def test_returned_identifier():
path = datapath / "single_phasics.tif"
ds = qpformat.load_data(path)
qpi = ds.get_qpimage(0)
assert "identifier" in qpi
qpiraw = ds.get_qpimage_raw(0)
assert "identifier" in qpiraw


if __name__ == "__main__":
# Run all tests
loc = locals()
Expand Down

0 comments on commit 4e795c3

Please sign in to comment.