Skip to content

Commit

Permalink
Handle bmlab exceptions (#42)
Browse files Browse the repository at this point in the history
* Handle bmlab exceptions

* Update bmlab version requirement

* Make Exception a BaseException
  • Loading branch information
raimund-schluessler authored May 13, 2022
1 parent f5110cc commit 4d2fa35
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 38 deletions.
3 changes: 2 additions & 1 deletion impose/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ def _initialize_from_path(self, path):
if not self.path.exists():
raise FileNotFoundError(
errno.ENOENT,
f"File does not exist: '{self.path}'",
f"Failed loading {self.path}, because the following file is "
+ f" missing: \n\n{self.path}",
self.path
)
# extract the data and metadata
Expand Down
90 changes: 60 additions & 30 deletions impose/formats/fmt_bm_bmlab.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from collections import OrderedDict

from bmlab.session import Session, get_valid_source, get_session_file_path
from bmlab.session import Session, get_valid_source, get_session_file_path,\
BmlabInvalidFileError, is_session_file
from bmlab.controllers import EvaluationController
import h5py
import numpy as np
import errno

from ..util import hashfile, hashobj

Expand All @@ -14,7 +16,7 @@ def load_h5(path):
Please see :func:`impose.formats.load` for more information.
"""
if get_valid_source(path) is not None:
try:
# Load data with bmlab
session = Session.get_instance()
session.set_file(path)
Expand All @@ -41,7 +43,22 @@ def load_h5(path):
p1 = get_valid_source(path)
p2 = get_session_file_path(p1)
h1 = hashfile(p1, blocksize=65536, count=1)
h2 = hashfile(p2, blocksize=65536, count=1)
# bmlab can open source data files without
# associated session files, so we need to check
# for this case explicitly.
if is_session_file(p2):
h2 = hashfile(p2, blocksize=65536, count=1)
else:
# The provided data is all-NaN in this case,
# which does not help much for Impose.
# So we raise an error for now. This might change,
# once bmlab can also provide
# brightfield or fluorescence images.
raise FileNotFoundError(
errno.ENOENT,
f"The bmlab session file {p2} is missing.",
p2
)
signature = hashobj((h1, h2))

chan = sorted(channels)
Expand All @@ -53,35 +70,48 @@ def load_h5(path):
"shape": channels[chan[0]].shape,
"signature": signature,
}
else:
# Fall-back to load BrillouinEvaluation exported h5 file
with h5py.File(path, "r") as h5:
# Data
chkeys = sorted(h5.keys())
# find axis order
k0 = chkeys[0]
# sometimes this is str and sometimes bytes
axes = np.string_(h5[k0].attrs["axisOrder"]).decode("utf-8")
xid = axes.index("X")
yid = axes.index("Y")
zid = axes.index("Z")
except BmlabInvalidFileError as err:
try:
# Fall-back to load BrillouinEvaluation exported h5 file
with h5py.File(path, "r") as h5:
# Data
chkeys = sorted(h5.keys())
# find axis order
k0 = chkeys[0]
# sometimes this is str and sometimes bytes
axes = np.string_(h5[k0].attrs["axisOrder"]).decode("utf-8")
xid = axes.index("X")
yid = axes.index("Y")
zid = axes.index("Z")

channels = OrderedDict()
for chan in chkeys:
dslice = h5[chan][:]
if len(dslice.shape) != 3:
raise ValueError(
"Invalid number of dimensions in '{}'. ".format(path)
+ "Please verify the original Brillouin dataset.")
channels[chan] = dslice.transpose(xid, yid, zid)
channels = OrderedDict()
for chan in chkeys:
dslice = h5[chan][:]
if len(dslice.shape) != 3:
raise ValueError(
"Invalid number of dimensions in "
"'{}'. ".format(path)
+ "Please verify the original Brillouin dataset.")
channels[chan] = dslice.transpose(xid, yid, zid)

# Metadata
meta = {
"pixel size x": np.array(h5.attrs["scaleX"]).item(),
"pixel size y": np.array(h5.attrs["scaleY"]).item(),
"pixel size z": np.array(h5.attrs["scaleZ"]).item(),
"shape": channels[chkeys[0]].shape,
}
# Metadata
meta = {
"pixel size x": np.array(h5.attrs["scaleX"]).item(),
"pixel size y": np.array(h5.attrs["scaleY"]).item(),
"pixel size z": np.array(h5.attrs["scaleZ"]).item(),
"shape": channels[chkeys[0]].shape,
}
# If we get a ValueError from loading the legacy Matlab file,
# we pass it on,
# since we then at least know it was supposed to be a Matlab file.
except ValueError as e:
raise e
# We re-raise the exception from bmlab here,
# because the Matlab import is just a legacy option
# and we likely wanted to import a file from BMicro/bmlab
# (which failed).
except BaseException:
raise err

return channels, meta

Expand Down
5 changes: 2 additions & 3 deletions impose/gui/collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ def add_paths(self, paths):
except FileNotFoundError as e:
QtWidgets.QMessageBox.critical(
self,
"Associated data file missing",
f"Failed loading {pp}, because the following file is "
+ f" missing: \n\n{e.filename}"
"Associated data file missing or invalid",
e.strerror
)
self.update_table_paths()

Expand Down
5 changes: 2 additions & 3 deletions impose/gui/colocalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ def add_paths(self, paths):
except FileNotFoundError as e:
QtWidgets.QMessageBox.critical(
self,
"Associated data file missing",
f"Failed loading {pp}, because the following file is "
+ f" missing: \n\n{e.filename}"
"Associated data file missing or invalid",
e.strerror
)
self.update_table_paths()

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
description=description,
long_description=open('README.rst').read() if exists('README.rst') else '',
install_requires=["czifile==2019.7.2", # bc cgohlke and used for signature
"bmlab>=0.1.8",
"bmlab>=0.1.10",
"h5py>=2.10.0",
"numpy>=1.17.0",
"pyqt6>=6.2.0",
Expand Down

0 comments on commit 4d2fa35

Please sign in to comment.