Skip to content

Commit

Permalink
fix+docs: add metadata checks, cleanup identifier usage, add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmueller committed Jul 30, 2018
1 parent 404a314 commit e8ffbef
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 49 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
0.3.4
- fix: qpimage file formats: override identifiers (clean solution)
- fix: add check for valid meta_data keys
- docs: document attributes of SeriesData
0.3.3
- fix: qpimage file formats: identifiers were not unique, but simply
copied from the input hdf5 file
Expand Down
11 changes: 11 additions & 0 deletions qpformat/file_formats/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,24 @@ class SeriesData(object):
is_series = True

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
self.path = path
# check for valid metadata keys
for key in meta_data:
if key not in qpimage.meta.DATA_KEYS:
msg = "Invalid metadata key `{}`!".format(key) \
+ "Valid keys: {}".format(sorted(qpimage.meta.DATA_KEYS))
raise ValueError(msg)
#: Enforced metadata via keyword arguments
self.meta_data = copy.copy(meta_data)
#: Hologram retrieval; keyword arguments for
#: :func:`qpimage.holo.get_field`.
self.holo_kw = holo_kw
self._bgdata = []
#: Unique string that identifies the background data that
Expand Down
26 changes: 3 additions & 23 deletions qpformat/file_formats/series_hdf5_qpimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,6 @@ def __len__(self):
def _qpseries(self):
return qpimage.QPSeries(h5file=self.path, h5mode="r")

@property
def identifier(self):
# Qpformat generates a new identifier that also depends on the given
# keyword arguments. Thus, the identifiers of source and modified
# dataset must not be identical.
with self._qpseries() as qps:
identifier = qps.identifier
if identifier is None:
identifier = ""
else:
identifier += "_"
identifier += super(SeriesHdf5Qpimage, self).identifier
return identifier

def get_identifier(self, idx):
"""Return an identifier for the data at index `idx`"""
with self._qpseries() as qps:
if "identifier" in qps[idx]:
identifier = qps[idx]["identifier"]
else:
identifier = super(SeriesHdf5Qpimage, self).get_identifier(idx)
return identifier

def get_qpimage(self, idx):
"""Return background-corrected QPImage of data at index `idx`"""
if self._bgdata:
Expand All @@ -55,6 +32,8 @@ def get_qpimage(self, idx):
# 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

def get_qpimage_raw(self, idx):
Expand All @@ -66,6 +45,7 @@ def get_qpimage_raw(self, idx):
# Force meta data
for key in self.meta_data:
qpi[key] = self.meta_data[key]
qpi["identifier"] = self.get_identifier(idx)
return qpi

@staticmethod
Expand Down
19 changes: 2 additions & 17 deletions qpformat/file_formats/single_hdf5_qpimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,6 @@ class SingleHdf5Qpimage(SingleData):
"""
storage_type = "phase,amplitude"

@property
def identifier(self):
# Qpformat generates a new identifier that also depends on the given
# keyword arguments. Thus, the identifiers of source and modified
# dataset must not be identical.
with qpimage.QPImage(h5file=self.path, h5mode="r") as qpi:
if "identifier" in qpi:
identifier = qpi["identifier"]
else:
identifier = ""
identifier += "_"
identifier += super(SingleHdf5Qpimage, self).identifier
return identifier

def get_identifier(self, idx=0):
return self.identifier

def get_qpimage(self, idx=0):
"""Return background-corrected QPImage"""
if self._bgdata:
Expand All @@ -44,6 +27,8 @@ def get_qpimage(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

def get_qpimage_raw(self, idx=0):
Expand Down
3 changes: 0 additions & 3 deletions tests/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ def test_save():
ds2 = qpformat.load_data(path=save_path)

assert ds.identifier is not None
# Qpformat generates a new identifier that also depends on the given
# keyword arguments. Thus, the identifiers are not identical.
assert ds.identifier in ds2.identifier
assert len(ds) == len(ds2)
assert np.all(ds.get_qpimage(0).pha == ds2.get_qpimage(0).pha)

Expand Down
15 changes: 13 additions & 2 deletions tests/test_series_hdf5_qpimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import pathlib
import tempfile

import numpy as np

import qpimage
import qpformat

Expand All @@ -22,8 +24,10 @@ def test_identifier():
pass

ds = qpformat.load_data(tf)
# individual identifiers are not extracted anymore as of
# qpformat version 0.3.4
assert ds.get_identifier(0) != "an important string"
assert ds.get_identifier(1) == "an important string"
assert ds.get_identifier(1) != "an important string"
assert ds.identifier in ds.get_identifier(0)

# cleanup
Expand All @@ -48,7 +52,14 @@ def test_load_data():
assert ds.path == pathlib.Path(tf)
assert ds.get_time(1) == 0
assert "SeriesHdf5Qpimage" in ds.__repr__()
assert ds.get_qpimage(1) == qpi
# 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)

# cleanup
try:
os.remove(tf)
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 @@ -2,6 +2,8 @@
import pathlib
import tempfile

import numpy as np

import qpimage
import qpformat

Expand All @@ -20,9 +22,9 @@ def test_identifier():
ds2 = qpformat.load_data(tf)

assert ds1.identifier != ds2.identifier
# Qpformat generates a new identifier that also depends on the given
# keyword arguments. Thus, the identifiers are not identical.
assert "an extremely important string" in ds2.identifier
# individual identifiers are not extracted anymore as of
# qpformat version 0.3.4
assert "an extremely important string" not in ds2.identifier
assert ds1.identifier == ds1.get_identifier()
assert ds2.identifier == ds2.get_identifier()

Expand All @@ -39,7 +41,14 @@ def test_load_data():
assert ds.path == path.resolve()
assert ds.get_time() == 0
assert "SingleHdf5Qpimage" in ds.__repr__()
assert ds.get_qpimage() == qpimage.QPImage(h5file=path, h5mode="r")
# 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
assert qpd.shape == qpi.shape
assert np.allclose(qpd.amp, qpi.amp)
assert np.allclose(qpd.pha, qpi.pha)


def test_meta_override():
Expand Down

0 comments on commit e8ffbef

Please sign in to comment.