From c84d4d520fd94e94a4e1df42c75fd2e051ecf139 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Thu, 21 May 2015 10:48:12 +0100 Subject: [PATCH] Various bugfixes to AtlasPanel - it now supports reference images. --- fsl/data/atlases.py | 2 +- fsl/data/strings.py | 5 +- fsl/fslview/controls/atlasinfopanel.py | 67 +++++++++++++++++++------- fsl/fslview/controls/atlaspanel.py | 25 ++++++---- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/fsl/data/atlases.py b/fsl/data/atlases.py index 32e633f7e..b9ddf49d5 100644 --- a/fsl/data/atlases.py +++ b/fsl/data/atlases.py @@ -297,6 +297,6 @@ class ProbabilisticAtlas(Atlas): voxelLoc[0] >= self.shape[0] or \ voxelLoc[1] >= self.shape[1] or \ voxelLoc[2] >= self.shape[2]: - return np.nan + return [] return self.data[voxelLoc[0], voxelLoc[1], voxelLoc[2], :] diff --git a/fsl/data/strings.py b/fsl/data/strings.py index 87552843d..ee69c6d36 100644 --- a/fsl/data/strings.py +++ b/fsl/data/strings.py @@ -38,10 +38,9 @@ messages = TypeDict({ 'installing the colour map', 'AtlasInfoPanel.notMNISpace' : 'Atlas lookup can only be performed on ' - 'images registered to MNI152 space', + 'images oriented to MNI152 space', - 'AtlasInfoPanel.nonVolumetric' : 'Atlas lookup can only be performed on ' - 'volumetric images', + 'AtlasInfoPanel.noReference' : 'No reference image available', 'AtlasInfoPanel.chooseAnAtlas' : 'Choose an atlas!', 'AtlasInfoPanel.atlasDisabled' : 'Atlases are not available', diff --git a/fsl/fslview/controls/atlasinfopanel.py b/fsl/fslview/controls/atlasinfopanel.py index 8619812b2..749da973c 100644 --- a/fsl/fslview/controls/atlasinfopanel.py +++ b/fsl/fslview/controls/atlasinfopanel.py @@ -14,7 +14,6 @@ import pwidgets.elistbox as elistbox import fsl.fslview.panel as fslpanel import fsl.data.atlases as atlases -import fsl.data.image as fslimage import fsl.data.strings as strings import fsl.data.constants as constants import fsl.utils.transform as transform @@ -88,14 +87,20 @@ class AtlasInfoPanel(fslpanel.FSLViewPanel): self.__infoPanel.Bind(wxhtml.EVT_HTML_LINK_CLICKED, self.__infoPanelLinkClicked) - displayCtx.addListener('location', - self._name, - self.__locationChanged) - displayCtx.addListener('selectedOverlay', - self._name, - self.__locationChanged) - - self.__locationChanged() + overlayList.addListener('overlays', + self._name, + self.__selectedOverlayChanged) + displayCtx .addListener('selectedOverlay', + self._name, + self.__selectedOverlayChanged) + displayCtx .addListener('overlayOrder', + self._name, + self.__selectedOverlayChanged) + displayCtx .addListener('location', + self._name, + self.__locationChanged) + + self.__selectedOverlayChanged() self.Layout() self.SetMinSize(self.__sizer.GetMinSize()) @@ -107,8 +112,10 @@ class AtlasInfoPanel(fslpanel.FSLViewPanel): """ fslpanel.FSLViewPanel.destroy(self) - self._displayCtx.removeListener('location', self._name) - self._displayCtx.removeListener('selectedOverlay', self._name) + self._overlayList.removeListener('overlays', self._name) + self._displayCtx .removeListener('location', self._name) + self._displayCtx .removeListener('selectedOverlay', self._name) + self._displayCtx .removeListener('overlayOrder', self._name) def enableAtlasInfo(self, atlasID): @@ -139,17 +146,43 @@ class AtlasInfoPanel(fslpanel.FSLViewPanel): self.__atlasPanel.toggleOverlay(atlasID, labelIndex, summary) + def __selectedOverlayChanged(self, *a): + """ + """ + + if len(self._overlayList) == 0: + self.__locationChanged() + return + + selOverlay = self._displayCtx.getSelectedOverlay() + + for ovl in self._overlayList: + + opts = self._displayCtx.getDisplay(ovl).getDisplayOpts() + + if ovl == selOverlay: + opts.addGlobalListener( self._name, + self.__locationChanged, + overwrite=True) + else: + opts.removeGlobalListener(self._name) + + self.__locationChanged() + + def __locationChanged(self, *a): overlay = self._displayCtx.getSelectedOverlay() + opts = self._displayCtx.getDisplay(overlay).getDisplayOpts() + overlay = opts.getReferenceImage() text = self.__infoPanel if len(atlases.listAtlases()) == 0: text.SetPage(strings.messages['AtlasInfoPanel.atlasDisabled']) return - if not isinstance(overlay, fslimage.Image): - text.SetPage(strings.messages['AtlasInfoPanel.nonVolumetric']) + if overlay is None: + text.SetPage(strings.messages['AtlasInfoPanel.noReference']) return if overlay.getXFormCode() != constants.NIFTI_XFORM_MNI_152: @@ -159,11 +192,11 @@ class AtlasInfoPanel(fslpanel.FSLViewPanel): if len(self.__enabledAtlases) == 0: text.SetPage(strings.messages['AtlasInfoPanel.chooseAnAtlas']) return - - display = self._displayCtx.getDisplay(overlay) + + opts = self._displayCtx.getDisplay(overlay).getDisplayOpts() loc = self._displayCtx.location loc = transform.transform( - [loc], display.getTransform('display', 'world'))[0] + [loc], opts.getTransform('display', 'world'))[0] lines = [] titleTemplate = '<b>{}</b> (<a href="summary {} {}">Show/Hide</a>)' @@ -172,7 +205,7 @@ class AtlasInfoPanel(fslpanel.FSLViewPanel): for atlasID in self.__enabledAtlases: - atlas = self.enabledAtlases[atlasID] + atlas = self.__enabledAtlases[atlasID] lines.append(titleTemplate.format(atlas.desc.name, atlasID, None)) diff --git a/fsl/fslview/controls/atlaspanel.py b/fsl/fslview/controls/atlaspanel.py index 5a8be8989..ad6a6e56c 100644 --- a/fsl/fslview/controls/atlaspanel.py +++ b/fsl/fslview/controls/atlaspanel.py @@ -151,7 +151,7 @@ class AtlasPanel(fslpanel.FSLViewPanel): if overlay is not None: self.clearAtlas(atlasID, summary) self._overlayList.remove(overlay) - self.overlayPanel.setOverlayState( + self.__overlayPanel.setOverlayState( atlasID, labelIdx, summary, False) log.debug('Removed overlay {}'.format(overlayName)) return @@ -201,9 +201,12 @@ class AtlasPanel(fslpanel.FSLViewPanel): else: display.getDisplayOpts().cmap = 'hot' else: # The Harvard-Oxford atlases have special colour maps - if atlasID == 'HarvardOxford-Cortical': cmap = 'cortical' - elif atlasID == 'HarvardOxford-Subcortical': cmap = 'subcortical' - else: cmap = 'random' + if atlasID == 'HarvardOxford-Cortical': + cmap = 'MGH Cortical' + elif atlasID == 'HarvardOxford-Subcortical': + cmap = 'MGH Sub-cortical' + else: + cmap = 'Random' display.getDisplayOpts().cmap = cmap @@ -212,15 +215,17 @@ class AtlasPanel(fslpanel.FSLViewPanel): atlasDesc = atlases.getAtlasDescription(atlasID) label = atlasDesc.labels[labelIdx] + overlay = self._displayCtx.getSelectedOverlay() + opts = self._displayCtx.getDisplay(overlay).getDisplayOpts() + overlay = opts.getReferenceImage() - overlay = self._displayCtx.getSelectedOverlay() - display = self._displayCtx.getDisplay(overlay) - - if not isinstance(overlay, fslimage.Image): - raise RuntimeError('Non-volumetric types not supported yet') + if overlay is None: + log.warn('No reference image available - cannot locate region') + + opts = self._displayCtx.getDisplay(overlay).getDisplayOpts() worldLoc = (label.x, label.y, label.z) dispLoc = transform.transform( - [worldLoc], display.getTransform('world', 'display'))[0] + [worldLoc], opts.getTransform('world', 'display'))[0] self._displayCtx.location.xyz = dispLoc -- GitLab