From 4932427663b5b1ad6b34c78c13c6b59aa82b2817 Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Wed, 26 Jan 2022 22:25:42 +0100 Subject: [PATCH] display sequence will now allow the loading of sequences with missing frames Sequences with missing frames are not uncommon in the raw images that were collected at soleil. I beleive that these missing frames are caused by the sequence captures that are stopped, resting in missing frames at the end compared to what was planned.... fixes #10 --- Makefile | 2 +- src/lipase/catalog.py | 27 ++++++++++++++++++++++++--- src/lipase/imagej/__init__.py | 23 ++++++++++++++++------- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 88acda0..029b6f0 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ TEMP_PATH:=$(shell echo ~/work/lipase/tmp) TESTS_OUTPUT_DATA_PATH:=$(TEMP_PATH) LIB_SRC_FILES=$(shell find ./src/lipase -name "*.py") PLUGINS_SRC_FILES=$(shell find ./src/ij-plugins -name "*.py") -LIPASE_VERSION=1.10 +LIPASE_VERSION=1.11 BUILD_ROOT_PATH:=$(TEMP_PATH)/build PACKAGE_FILE_PATH=$(BUILD_ROOT_PATH)/lipase-$(LIPASE_VERSION).zip diff --git a/src/lipase/catalog.py b/src/lipase/catalog.py index 705da33..ecc6e69 100644 --- a/src/lipase/catalog.py +++ b/src/lipase/catalog.py @@ -28,6 +28,19 @@ class DacMetadata(object): return channels[channel_index]["Name"] +class MissingImageFile(Exception): + + def __init__(self, sequence_id, frame_index, slice_index, channel_index): + self.sequence_id = sequence_id + self.frame_index= frame_index + self.slice_index = slice_index + self.channel_index = channel_index + super(MissingImageFile, self).__init__(self, 'missing image file') + + def __str__(self): + return 'the image file for sequence "%s" frame %d, slice %d and channel %d is missing' % (self.sequence_id, self.frame_index, self.slice_index, self.channel_index) + + class Sequence(object): """A sequence of images stored in micro manager format """ @@ -121,7 +134,10 @@ class Sequence(object): ''' assert frame_index < self.num_frames assert channel_index < self.num_channels - frame_info = self.mmm['FrameKey-%d-%d-%d' % (frame_index, channel_index, slice_index)] + try: + frame_info = self.mmm['FrameKey-%d-%d-%d' % (frame_index, channel_index, slice_index)] + except KeyError as e: + raise MissingImageFile(sequence_id=self.id, frame_index=frame_index, slice_index=slice_index, channel_index=channel_index) rel_file_path = frame_info['FileName'] return os.path.join(self.get_root_path(), rel_file_path) @@ -192,8 +208,13 @@ class Sequence(object): for frame_index in selected_frames: for slice_index in selected_slices: for channel_index in selected_channel_indices: - image = IImageEngine.get_instance().load_image(self.get_image_file_path(channel_index=channel_index, frame_index=frame_index, slice_index=slice_index)) - stack.set_image(image=image, channel_index=channel_index, frame_index=frame_index, slice_index=slice_index) + try: + image_file_path = self.get_image_file_path(channel_index=channel_index, frame_index=frame_index, slice_index=slice_index) + image = IImageEngine.get_instance().load_image(image_file_path) + stack.set_image(image=image, channel_index=channel_index, frame_index=frame_index, slice_index=slice_index) + except MissingImageFile as e: + logger.warn('%s. As a result, the hyperstack will be black at this frame' % str(e)) + # logger.warn('the image file for sequence "%s" frame %d, slice %d and channel %d is missing. As a result, the hyperstack will be black at this frame' % (self.id, frame_index, slice_index, channel_index)) return stack def find_dirs_containing_file(file_name, root_dir): diff --git a/src/lipase/imagej/__init__.py b/src/lipase/imagej/__init__.py index 2bcde53..594595d 100644 --- a/src/lipase/imagej/__init__.py +++ b/src/lipase/imagej/__init__.py @@ -1,15 +1,20 @@ +import os from ij import IJ, ImagePlus # pylint: disable=import-error import re - +from .. import logger +from ..catalog import MissingImageFile def open_sequence_as_hyperstack(sequence): hyperstack = IJ.createHyperStack(sequence.id, sequence.width, sequence.height, sequence.num_channels, sequence.num_slices, sequence.num_frames, sequence.num_bits_per_pixels) for channel_index in range(sequence.num_channels): for frame_index in range(sequence.num_frames): slice_index = 0 - src_image_file_path = sequence.get_image_file_path(channel_index=channel_index, frame_index=frame_index) - # print(src_image_file_path) - src_image = IJ.openImage(src_image_file_path) + try: + src_image_file_path = sequence.get_image_file_path(channel_index=channel_index, frame_index=frame_index) + src_image = IJ.openImage(src_image_file_path) + except MissingImageFile as e: + logger.warn('%s. As a result, the hyperstack will be black at this frame' % str(e)) + #logger.warn('the image file for frame %d and channel %d is missing. As a result, the hyperstack will be black at this frame' % (frame_index, channel_index)) # print(src_image.getProperties()) hyperstack.setPositionWithoutUpdate(channel_index + 1, slice_index + 1, frame_index + 1) hyperstack.setProcessor(src_image.getProcessor()) @@ -23,9 +28,13 @@ def open_sequence_as_stack(sequence, channel_id): hyperstack = IJ.createHyperStack(sequence.id, sequence.width, sequence.height, 1, sequence.num_slices, sequence.num_frames, sequence.num_bits_per_pixels) for frame_index in range(sequence.num_frames): slice_index = 0 - src_image_file_path = sequence.get_image_file_path(channel_index=channel_index, frame_index=frame_index) - # print(src_image_file_path) - src_image = IJ.openImage(src_image_file_path) + try: + src_image_file_path = sequence.get_image_file_path(channel_index=channel_index, frame_index=frame_index) + # print(src_image_file_path) + src_image = IJ.openImage(src_image_file_path) + except MissingImageFile as e: + logger.warn('%s. As a result, the hyperstack will be black at this frame' % str(e)) + # logger.warn('the image file for frame %d and channel %d is missing. As a result, the hyperstack will be black at this frame' % (frame_index, channel_index)) # print(src_image.getProperties()) hyperstack.setPositionWithoutUpdate(channel_index + 1, slice_index + 1, frame_index + 1) hyperstack.setProcessor(src_image.getProcessor())