Skip to content

Commit

Permalink
Handle TypeError in Live Viewer due to slow FITS files (#2476)
Browse files Browse the repository at this point in the history
  • Loading branch information
samtygier-stfc authored Jan 28, 2025
2 parents 9469b60 + 3437739 commit c3be194
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 22 deletions.
3 changes: 2 additions & 1 deletion mantidimaging/eyes_tests/live_viewer_window_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
from mantidimaging.core.operations.loader import load_filter_packages
from mantidimaging.gui.windows.live_viewer.model import Image_Data
from mantidimaging.gui.windows.live_viewer.presenter import ImageLoadFailError
from mantidimaging.test_helpers.unit_test_helper import FakeFSTestCase
from pathlib import Path
from mantidimaging.eyes_tests.base_eyes import BaseEyesTest
Expand Down Expand Up @@ -73,7 +74,7 @@ def test_live_view_opens_with_data(self, _mock_time, _mock_image_watcher, mock_l
def test_live_view_opens_with_bad_data(self, _mock_time, _mock_image_watcher, mock_load_image):
file_list = self._make_simple_dir(self.live_directory)
image_list = [Image_Data(path) for path in file_list]
mock_load_image.side_effect = ValueError
mock_load_image.side_effect = ImageLoadFailError(file_list[0], source_error=ValueError)
self.imaging.show_live_viewer(self.live_directory)
self.imaging.live_viewer_list[-1].presenter.model._handle_image_changed_in_list(image_list)
self.check_target(widget=self.imaging.live_viewer_list[-1])
Expand Down
7 changes: 1 addition & 6 deletions mantidimaging/gui/windows/live_viewer/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,7 @@ def load_image(self, image: Image_Data) -> np.ndarray:
if image in self.cache_dict.keys():
return self.cache_dict[image]
else:
try:
image_array = self.loading_func(image.image_path)
except ValueError as error:
message = f"{type(error).__name__} reading image: {image.image_path}: {error}"
LOG.error(message)
raise ValueError from error
image_array = self.loading_func(image.image_path)
self._add_to_cache(image, image_array)
return image_array

Expand Down
51 changes: 36 additions & 15 deletions mantidimaging/gui/windows/live_viewer/presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
from collections.abc import Callable
from logging import getLogger
import numpy as np
import tifffile
from PyQt5.QtCore import pyqtSignal, QObject, QThread, QTimer
from astropy.io import fits

from imagecodecs._deflate import DeflateError
from tifffile import tifffile
from tifffile.tifffile import TiffFileError

from mantidimaging.gui.mvp_base import BasePresenter
from mantidimaging.gui.windows.live_viewer.model import LiveViewerWindowModel, Image_Data
Expand All @@ -25,6 +26,20 @@
logger = getLogger(__name__)


class ImageLoadFailError(Exception):
"""
Exception raised when an image is not loaded correctly
"""

def __init__(self, image_path: Path, source_error, message: str = '') -> None:
error_name = type(source_error).__name__
if message == '':
self.message = f"{error_name} :Could not load image f{image_path}, Exception: {source_error} "
else:
self.message = message
super().__init__(message)


class Worker(QObject):
finished = pyqtSignal()

Expand Down Expand Up @@ -101,9 +116,8 @@ def update_image_list(self, images_list: list[Image_Data]) -> None:
try:
image_data = self.model.image_cache.load_image(images_list[-1])
self.model.add_mean(images_list[-1], image_data)
except (OSError, KeyError, ValueError, DeflateError) as error:
message = f"{type(error).__name__} reading image: {images_list[-1].image_path}: {error}"
logger.error(message)
except ImageLoadFailError as error:
logger.error(error.message)
self.update_intensity(self.model.mean)
self.view.set_image_range((0, len(images_list) - 1))
self.view.set_image_index(len(images_list) - 1)
Expand All @@ -126,11 +140,10 @@ def display_image(self, image_data_obj: Image_Data) -> None:
"""
try:
image_data = self.model.image_cache.load_image(image_data_obj)
except (OSError, KeyError, ValueError, DeflateError) as error:
message = f"{type(error).__name__} reading image: {image_data_obj.image_path}: {error}"
logger.error(message)
except ImageLoadFailError as error:
logger.error(error.message)
self.view.remove_image()
self.view.live_viewer.show_error(message)
self.view.live_viewer.show_error(error.message)
return
image_data = self.perform_operations(image_data)
if image_data.size == 0:
Expand All @@ -149,15 +162,23 @@ def load_image_from_path(image_path: Path) -> np.ndarray:
and returns as an ndarray
"""
if image_path.suffix.lower() in [".tif", ".tiff"]:
with tifffile.TiffFile(image_path) as tif:
image_data = tif.asarray()
return image_data
try:
with tifffile.TiffFile(image_path) as tif:
image_data = tif.asarray()
return image_data
except (OSError, KeyError, ValueError, TiffFileError, DeflateError) as err:
raise ImageLoadFailError(image_path, err) from err
elif image_path.suffix.lower() == ".fits":
with fits.open(image_path) as fits_hdul:
image_data = fits_hdul[0].data
return image_data
try:
with fits.open(image_path) as fits_hdul:
image_data = fits_hdul[0].data
return image_data
except (OSError, TypeError, ValueError) as err:
raise ImageLoadFailError(image_path, err) from err
else:
raise ValueError(f"Unsupported file type: {image_path.suffix}")
raise ImageLoadFailError(image_path,
source_error=FileNotFoundError,
message=f"Unsupported file type: {image_path.suffix}")

def update_image_modified(self, image_path: Path) -> None:
"""
Expand Down

0 comments on commit c3be194

Please sign in to comment.