Skip to content

Commit

Permalink
add phasics zip tif group file format
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmueller committed Oct 18, 2017
1 parent c283a42 commit 8bb88e6
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 19 deletions.
4 changes: 2 additions & 2 deletions qpformat/file_formats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from .dataset import DataSet
# from .group_hdf5_qpimage import GroupHdf5Qpimage
# from .group_zip_tif_phasics import GroupZipTifPhasics
from .group_zip_tif_phasics import GroupZipTifPhasics
from .single_hdf5_qimage import SingleHdf5Qpimage
from .single_tif_phasics import SingleTifPhasics

Expand Down Expand Up @@ -88,7 +88,7 @@ class UnknownFileFormatError(BaseException):

# the order is important for
formats = [GroupFolder,
# GroupZipTifPhasics,
GroupZipTifPhasics,
# GroupHdf5Qpimage,
SingleHdf5Qpimage,
SingleTifPhasics,
Expand Down
81 changes: 81 additions & 0 deletions qpformat/file_formats/group_zip_tif_phasics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import io
import functools
import zipfile

from .dataset import DataSet
from .single_tif_phasics import SingleTifPhasics


class GroupZipTifPhasics(DataSet):
def __init__(self, *args, **kwargs):
super(GroupZipTifPhasics, self).__init__(*args, **kwargs)
self._files = None
self._dataset = None

def __len__(self):
return len(self.files)

def _get_dataset(self, idx):
if self._dataset is None:
self._dataset = [None] * len(self)
if self._dataset[idx] is None:
# Use ``zipfile.ZipFile.open`` to return an open file
zf = zipfile.ZipFile(self.path)
pt = zf.open(self.files[idx])
fd = io.BytesIO(pt.read())
self._dataset[idx] = SingleTifPhasics(path=fd,
meta_data=self.meta_data)
assert len(self._dataset[idx]) == 1, "unknown phasics tif file"
return self._dataset[idx]

@staticmethod
@functools.lru_cache(maxsize=32)
def _index_files(path):
"""Search zip file for SID PHA files"""
with zipfile.ZipFile(path) as zf:
names = sorted(zf.namelist())
names = [nn for nn in names if nn.endswith(".tif")]
names = [nn for nn in names if nn.startswith("SID PHA")]
phasefiles = []
for name in names:
with zf.open(name) as pt:
fd = io.BytesIO(pt.read())
if SingleTifPhasics.verify(fd):
phasefiles.append(name)
return phasefiles

@property
def files(self):
if self._files is None:
self._files = GroupZipTifPhasics._index_files(self.path)
return self._files

def get_qpimage_raw(self, idx=0):
"""Return QPImage without background correction"""
ds = self._get_dataset(idx)
return ds.get_qpimage_raw(idx=0)

def get_time(self, idx=0):
ds = self._get_dataset(idx)
return ds.get_time(idx=0)

@staticmethod
def verify(path):
"""Verify phasics zip tif file format"""
valid = False
try:
zf = zipfile.ZipFile(path)
except:
pass
else:
names = sorted(zf.namelist())
names = [nn for nn in names if nn.endswith(".tif")]
names = [nn for nn in names if nn.startswith("SID PHA")]
for name in names:
with zf.open(name) as pt:
fd = io.BytesIO(pt.read())
if SingleTifPhasics.verify(fd):
valid = True
break
zf.close()
return valid
41 changes: 24 additions & 17 deletions qpformat/file_formats/single_tif_phasics.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, path, meta_data={}):
Parameters
----------
path: str
path to the experimental data file.
path to the experimental data file or an open file object
meta_data: dict
dictionary containing meta data.
see :py:class:`qpimage.VALID_META_KEYS`.
Expand Down Expand Up @@ -55,12 +55,20 @@ def __init__(self, path, meta_data={}):
def __len__(self):
return 1

@staticmethod
def _get_tif(path):
if not isinstance(path, str):
# Seek open file zero to avoid error in tifffile:
# "ValueError: invalid TIFF file"
path.seek(0)
return tifffile.TiffFile(path)

def get_qpimage_raw(self, idx=0):
"""Return QPImage without background correction"""
if idx != 0:
raise ValueError("Single file format, only one entry (`idx!=0`)!")
# Load experimental data
with tifffile.TiffFile(self.path) as tf:
with SingleTifPhasics._get_tif(self.path) as tf:
# page 0 contains intensity
# page 1 contains phase in nm
# page 2 contains phase in wavelengths
Expand Down Expand Up @@ -114,7 +122,7 @@ def get_time(self, idx=0):

@staticmethod
def _get_meta_data(path, section, name):
with tifffile.TiffFile(path) as tf:
with SingleTifPhasics._get_tif(path) as tf:
meta = str(tf.pages[0].tags["61238"].value)

meta = meta.strip("'b")
Expand Down Expand Up @@ -142,18 +150,17 @@ def verify(path):
Returns `True` if the file format matches.
"""
valid = False
if path.endswith(".tif"):
try:
tf = tifffile.TiffFile(path)
except:
pass
else:
if (len(tf) == 3 and
"61243" in tf.pages[0].tags and
"61242" in tf.pages[0].tags and
"61238" in tf.pages[0].tags and
"max_sample_value" in tf.pages[0].tags and
(tf.pages[0].tags["61242"].value !=
tf.pages[1].tags["61242"].value)):
valid = True
try:
tf = SingleTifPhasics._get_tif(path)
except:
pass
else:
if (len(tf) == 3 and
"61243" in tf.pages[0].tags and
"61242" in tf.pages[0].tags and
"61238" in tf.pages[0].tags and
"max_sample_value" in tf.pages[0].tags and
(tf.pages[0].tags["61242"].value !=
tf.pages[1].tags["61242"].value)):
valid = True
return valid
Binary file added tests/data/group_phasics.zip
Binary file not shown.
44 changes: 44 additions & 0 deletions tests/test_group_zip_tif_phasics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
The test file "group_phasics.zip" was created from an original
Phasics zip file. The "ConfigStack.txt" was adapted to reflect
only three measured images. All data files that are not relevant
for qpformat are included as empty files to reflect the original
zip file structure. The "SID PHA*.tif" files were created with
the script given in the doc string of "test_single_tif_phasics.py".
"""
from os.path import abspath, dirname, join
import sys

import numpy as np

# Add parent directory to beginning of path variable
sys.path.insert(0, dirname(dirname(abspath(__file__))))
import qpformat # noqa: E402


def test_load_data():
path = join(dirname(abspath(__file__)), "data/group_phasics.zip")
ds = qpformat.load_data(path)
assert ds.path == path
assert "GroupZipTifPhasics" in ds.__repr__()


def test_data_content():
path = join(dirname(abspath(__file__)), "data/group_phasics.zip")
ds = qpformat.load_data(path)
assert len(ds) == 3
assert ds.get_time(0) == 1461949418.29027
assert ds.get_time(1) == 1461949418.62727
assert ds.get_time(2) == 1461949419.11427
qpi = ds.get_qpimage(0)
assert qpi.meta["wavelength"] == 550e-9
assert np.allclose(qpi.amp.max(), 183.96992660669972)
assert np.allclose(qpi.pha.max() - qpi.pha.min(), 0.189023369599572)


if __name__ == "__main__":
# Run all tests
loc = locals()
for key in list(loc.keys()):
if key.startswith("test_") and hasattr(loc[key], "__call__"):
loc[key]()

0 comments on commit 8bb88e6

Please sign in to comment.