Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Registered image selector fixes #64

Merged
merged 4 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 52 additions & 25 deletions magmap/gui/visualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ class Visualization(HasTraits):
# File selection

_filename = File # file browser
_ignore_filename = False # ignore file update trigger
_channel_names = Instance(TraitsList)
_channel = List # selected channels, 0-based

Expand Down Expand Up @@ -792,10 +791,11 @@ def __init__(self):
self._drawn_offset = self._curr_offset()

# setup interface for image
self._ignore_filename = False # ignore file update trigger
self._reset_filename = True # reset when updating loaded image
if config.filename:
# show image filename in file selector without triggering update
self._ignore_filename = True
self._filename = config.filename
self.update_filename(config.filename, True, False)

# create figs after applying Matplotlib style and theme
rc_params = None
Expand Down Expand Up @@ -829,6 +829,10 @@ def __init__(self):
self._imgadj_max_ignore_update = False

# set up rest of registered images during image setup

# dictionary of registered image suffix without ext to suffix with
# ext of a matching existing file
self._reg_img_names: OrderedDict[str, str] = OrderedDict()
self._main_img_names_avail = TraitsList()
self._main_img_names = TraitsList()
self._labels_img_names = TraitsList()
Expand Down Expand Up @@ -1541,23 +1545,25 @@ def _setup_for_image(self):
else [config.roi_size])

# find matching registered images to populate dropdowns
main_img_names_avail = []
self._reg_img_names = OrderedDict()
for reg_name in config.RegNames:
# check for potential registered image files
reg_path = sitk_io.read_sitk(sitk_io.reg_out_path(
config.filename, reg_name.value), dryrun=True)[1]
if reg_path:
# add to list of available suffixes
main_img_names_avail.append(
f"{os.path.splitext(reg_name.value)[0]}"
f"{os.path.splitext(reg_path)[1]}")
self._labels_img_names.selections = list(main_img_names_avail)
# add to list of available suffixes, storing the found
# extension to load directly and save to same ext
name = libmag.get_filename_without_ext(reg_name.value)
self._reg_img_names[name] = (
f"{name}{libmag.splitext(reg_path)[1]}")
self._labels_img_names.selections = list(self._reg_img_names.keys())
self._labels_img_names.selections.insert(0, "")

# set any registered names based on loaded images, defaulting to
# image5d and no labels
main_suffixes = [self._MAIN_IMG_NAME_DEFAULT]
labels_suffix = self._labels_img_names.selections[0]
main_img_names_avail = list(self._reg_img_names.keys())
if config.reg_suffixes:
# use registered suffixes without ext, using first suffix
# of each type
Expand All @@ -1566,15 +1572,17 @@ def _setup_for_image(self):
if not libmag.is_seq(suffixes):
suffixes = [suffixes]
for suffix in suffixes:
if suffix in main_img_names_avail:
suffix_stem = libmag.get_filename_without_ext(suffix)
if suffix_stem in main_img_names_avail:
# move from available to selected suffixes lists
main_suffixes.append(suffix)
main_img_names_avail.remove(suffix)
main_suffixes.append(suffix_stem)
main_img_names_avail.remove(suffix_stem)
suffix = config.reg_suffixes[config.RegSuffixes.ANNOTATION]
if suffix:
suffix = libmag.get_if_within(suffix, 0, "")
if suffix in self._labels_img_names.selections:
labels_suffix = suffix
suffix_stem = libmag.get_filename_without_ext(
libmag.get_if_within(suffix, 0, ""))
if suffix_stem in self._labels_img_names.selections:
labels_suffix = suffix_stem

# show main image lists in two dropdowns, where selecting a suffix
# from one list immediately moves it to the other
Expand Down Expand Up @@ -1610,15 +1618,26 @@ def _setup_for_image(self):
self._rois_selections.selections = list(self._rois_dict.keys())
self.rois_check_list = _ROI_DEFAULT

def update_filename(self, filename):
def update_filename(
self, filename: str, ignore: bool = False, reset: bool = True):
"""Update main image filename, triggering image load.

Args:
filename (str): Path to image file to load.
filename: Path to image file to load.
ignore: Set to :attr:`_ignore_filename` flag; deafults to False.
True to av
reset: Set the :attr:`_reset_filename` flag; defaults to False.
True to reset additional image parameters such as registered
image suffixes.

"""
# reset path so that new path triggers an image load
# if old and new filename are the same, no update will be triggered,
# so need to set to non-image first
self._filename = ""

# update filename, triggering Trait change
self._reset_filename = reset
self._ignore_filename = ignore
self._filename = filename

def open_image(self, filename, new_window=True):
Expand Down Expand Up @@ -1653,10 +1672,17 @@ def _image_path_updated(self):
will not be loaded for now.
"""
if self._ignore_filename or not self._filename:
# ignore if only updating widget value, without triggering load
# avoid triggering file load, eg if only updating widget value;
# reset flags
self._ignore_filename = False
self._reset_filename = True
return


if self._reset_filename:
# reset registered suffixes
config.reg_suffixes = dict.fromkeys(config.RegSuffixes, None)
self._reset_filename = True

# load image if possible without allowing import, deconstructing
# filename from the selected imported image
filename, offset, size, reg_suffixes = importer.deconstruct_img_name(
Expand Down Expand Up @@ -1694,21 +1720,22 @@ def _reload_images(self):
if len(atlas_suffixes) == 1:
# reduce to str if only one element
atlas_suffixes = atlas_suffixes[0]
reg_suffixes[config.RegSuffixes.ATLAS] = atlas_suffixes
reg_suffixes[config.RegSuffixes.ATLAS] = self._reg_img_names.get(
atlas_suffixes)

if self._labels_img_names.selections.index(self._labels_img_name) != 0:
# add if not the empty first selection
reg_suffixes[config.RegSuffixes.ANNOTATION] = self._labels_img_name
reg_suffixes[
config.RegSuffixes.ANNOTATION] = self._reg_img_names.get(
self._labels_img_name)
config.reg_suffixes.update(reg_suffixes)

if self._labels_ref_path:
# set up labels
cli.setup_labels([self._labels_ref_path])

# re-setup image
filename = self._filename
self._filename = ""
self._filename = filename
self.update_filename(self._filename, reset=False)

@on_trait_change("_channel")
def update_channel(self):
Expand Down
2 changes: 1 addition & 1 deletion magmap/io/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ def deconstruct_img_name(np_filename, sep="_", keep_subimg=False):
suffix = suffix.value
suffix_noext = libmag.get_filename_without_ext(suffix)
suffixi = np_filename.rfind(suffix_noext)
if suffixi != -1 and os.path.splitext(np_filename)[0].endswith(
if suffixi != -1 and libmag.splitext(np_filename)[0].endswith(
suffix_noext):
# strip suffix and any ending separator to get base path
filename = np_filename[:suffixi]
Expand Down
7 changes: 3 additions & 4 deletions magmap/io/libmag.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,8 @@ def match_ext(path, path_to_match):
return path_to_match


def get_filename_without_ext(path):
"""Get filename without extension with support for extensions with
multiple periods through :meth:`splitext`.
def get_filename_without_ext(path: str) -> str:
"""Wrapper to :meth:`splitext` for getting only the filename.

Args:
path: Full path.
Expand All @@ -252,7 +251,7 @@ def get_filename_without_ext(path):
no extension exists.
"""
name = os.path.basename(path)
name_split = os.path.splitext(name)
name_split = splitext(name)
if len(name_split) > 1: return name_split[0]
return name

Expand Down