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