Skip to content
Snippets Groups Projects
Commit a91e32e7 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Slice spacing/zrange values are hopefully set to sensible things when Z

axis/display space change.
parent b12abd5c
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,7 @@ import fsl.fsleyes.gl.slicecanvas as slicecanvas
import fsl.fsleyes.gl.resources as glresources
import fsl.fsleyes.gl.routines as glroutines
import fsl.fsleyes.gl.textures as textures
import fsl.data.image as fslimage
log = logging.getLogger(__name__)
......@@ -71,6 +72,7 @@ class LightBoxCanvas(slicecanvas.SliceCanvas):
canvasToWorld
worldToCanvas
getTotalRows
calcSliceSpacing
"""
......@@ -232,6 +234,54 @@ class LightBoxCanvas(slicecanvas.SliceCanvas):
"""Returns the total number of rows that may be displayed. """
return self._totalRows
def calcSliceSpacing(self, overlay):
"""Calculates and returns a Z-axis slice spacing value suitable
for the given overlay.
"""
displayCtx = self.displayCtx
opts = displayCtx.getOpts(overlay)
overlay = displayCtx.getReferenceImage(overlay)
zmin, zmax = opts.bounds.getLimits(self.zax)
# If the overlay does not have a
# reference NIFTI1 image, choose
# an arbitrary slice spacing.
if overlay is None: return (zmax - zmin) / 50.0
# Otherwise return a spacing
# appropriate for the current
# display space
if opts.transform == 'id': return 1
elif opts.transform == 'pixdim': return overlay.pixdim[self.zax]
elif opts.transform == 'affine': return min(overlay.pixdim[:3])
# This overlay is being displayed with a
# custrom transformation matrix - check
# to see what display space we're in
displaySpace = displayCtx.displaySpace
if isinstance(displaySpace, fslimage.Nifti1):
return self.calcSliceSpacing(displaySpace)
else:
return min(overlay.pixdim[:3])
def _zAxisChanged(self, *a):
"""Overrides :meth:`.SliceCanvas._zAxisChanged`. Calls that
method, and then resets the :attr:`sliceSpacing` and :attr:`zrange`
properties to sensible values.
"""
slicecanvas.SliceCanvas._zAxisChanged(self, *a)
overlay = self.displayCtx.getSelectedOverlay()
if overlay is None:
return
self.sliceSpacing = self.calcSliceSpacing(overlay)
self.zrange.x = self.displayCtx.bounds.getRange(self.zax)
def _topRowChanged(self, *a):
"""Called when the :attr:`topRow` property changes. Adjusts display
......@@ -346,7 +396,7 @@ class LightBoxCanvas(slicecanvas.SliceCanvas):
height == 0:
return
self._nslices = int(np.floor(zlen / self.sliceSpacing))
self._nslices = int(np.ceil(zlen / self.sliceSpacing))
self._totalRows = int(np.ceil(self._nslices / float(self.ncols)))
if self._nslices == 0 or self._totalRows == 0:
......@@ -418,47 +468,29 @@ class LightBoxCanvas(slicecanvas.SliceCanvas):
self.setConstraint('zrange', 'minDistance', 0)
self.zrange.x = (0, 0)
self.sliceSpacing = 0
else:
return
# Get the new Z range from the
# display context bounding box.
#
# And calculate the minimum possible
# slice spacing - the smallest pixdim
# across all overlays in the list.
newZRange = self.displayCtx.bounds.getRange(self.zax)
newZGap = sys.float_info.max
for overlay in self.overlayList:
# Get the new Z range from the
# display context bounding box.
#
# And calculate the minimum possible
# slice spacing - the smallest pixdim
# across all overlays in the list.
newZRange = self.displayCtx.bounds.getRange(self.zax)
newZGap = sys.float_info.max
overlay = self.displayCtx.getReferenceImage(overlay)
if overlay is None:
continue
opts = self.displayCtx.getOpts(overlay)
if opts.transform == 'id':
zgap = 1
elif opts.transform == 'pixdim':
zgap = overlay.pixdim[self.zax]
else:
zgap = min(overlay.pixdim[:3])
if zgap < newZGap:
newZGap = zgap
# If there were no volumetric overlays
# in the overlay list, choose an arbitrary
# default slice spacing
if newZGap == sys.float_info.max:
newZGap = (newZRange[1] - newZRange[0]) / 50.0
# Update the zrange and slice
# spacing constraints
self.zrange.setLimits(0, *newZRange)
self.setConstraint('zrange', 'minDistance', newZGap)
self.setConstraint('sliceSpacing', 'minval', newZGap)
for overlay in self.overlayList:
zgap = self.calcSliceSpacing(overlay)
if zgap < newZGap:
newZGap = zgap
# Update the zrange and slice
# spacing constraints
self.zrange.setLimits(0, *newZRange)
self.setConstraint('zrange', 'minDistance', newZGap)
self.setConstraint('sliceSpacing', 'minval', newZGap)
def _overlayBoundsChanged(self, *a):
......
......@@ -261,11 +261,16 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
self._name,
self.__transformChanged)
# If the current zrange is [0, 0] we'll
# assume that it needs to be initialised.
sceneOpts = self.getSceneOptions()
if sceneOpts.zrange == [0.0, 0.0]:
sceneOpts.zrange = self._displayCtx.bounds.getRange(sceneOpts.zax)
# If the current zrange is [0, 0]
# we'll assume that the spacing/
# zrange need to be initialised.
lbCanvas = self.__lbCanvas
opts = self.getSceneOptions()
if opts.zrange == [0.0, 0.0]:
opts.sliceSpacing = lbCanvas.calcSliceSpacing(selectedOverlay)
opts.zrange = self._displayCtx.bounds.getRange(opts.zax)
def __transformChanged(self, *a):
......@@ -288,15 +293,12 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
loBounds = opts.bounds.getLo()
hiBounds = opts.bounds.getHi()
if opts.transform == 'id':
sceneOpts.sliceSpacing = 1
elif opts.transform == 'pixdim':
sceneOpts.sliceSpacing = overlay.pixdim[sceneOpts.zax]
else:
sceneOpts.sliceSpacing = min(overlay.pixdim[sceneOpts.zax])
sceneOpts.zrange.x = (loBounds[sceneOpts.zax],
hiBounds[sceneOpts.zax])
# Reset the spacing/zrange. Not
# sure if this is the best idea,
# but it's here for the time being.
sceneOpts.sliceSpacing = self.__lbCanvas.calcSliceSpacing(overlay)
sceneOpts.zrange.x = (loBounds[sceneOpts.zax],
hiBounds[sceneOpts.zax])
self.__onResize()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment