Skip to content

Commit

Permalink
removed timer, get data from volumina stack. Not less hacky. Need for…
Browse files Browse the repository at this point in the history
… caches, storing raw datasources
  • Loading branch information
paulhfu committed Apr 3, 2019
1 parent 737718a commit 47ab62c
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 65 deletions.
6 changes: 6 additions & 0 deletions volumina/patchAccessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ def getPatchesForRect(self,startx,starty,endx,endy):
ex = min(ex, self._cX)
ey = min(ey, self._cY)

# always return at least one index
if sx==ex:
ex = ex + 1
if sy==ey:
ey = ey + 1

nums = []
for y in range(sy,ey):
nums += list(range(y*self._cX+sx, y*self._cX+ex))
Expand Down
4 changes: 2 additions & 2 deletions volumina/positionModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class PositionModel(QObject):

timeChanged = pyqtSignal(int)
channelChanged = pyqtSignal(int)
cursorPositionChanged = pyqtSignal(object, object, object)
cursorPositionChanged = pyqtSignal(object, object)
slicingPositionChanged = pyqtSignal(object, object)
slicingPositionSettled = pyqtSignal(bool)

Expand Down Expand Up @@ -168,7 +168,7 @@ def cursorPos(self, coordinates):
return
oldPos = self._cursorPos
self._cursorPos = coordinates
self.cursorPositionChanged.emit(self.cursorPos, oldPos, self.time)
self.cursorPositionChanged.emit(self.cursorPos, oldPos)

@property
def slicingPos(self):
Expand Down
98 changes: 38 additions & 60 deletions volumina/sliceSelectorHud.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from functools import partial

#PyQt
from PyQt5.QtCore import pyqtSignal, Qt, QPointF, QSize, QTimer
from PyQt5.QtCore import pyqtSignal, Qt, QPointF, QPoint, QRect, QSize
from PyQt5.QtGui import QPen, QPainter, QPixmap, QColor, QFont, QPainterPath, QBrush, QTransform, QIcon

from PyQt5.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QAbstractSpinBox, QCheckBox, QWidget, \
Expand Down Expand Up @@ -415,12 +415,12 @@ def setAxes(self, rotation, swapped):
class QuadStatusBar(QHBoxLayout):
positionChanged = pyqtSignal(int, int, int) # x,y,z

def __init__(self, layerStack, parent=None):
def __init__(self, volumeEditor, parent=None):
QHBoxLayout.__init__(self, parent)
self.setContentsMargins(0,4,0,0)
self.setSpacing(0)
self.timeControlFontSize = 12
self.layerStack = layerStack
self.editor = volumeEditor

def showXYCoordinates(self):
self.zLabel.setHidden(True)
Expand Down Expand Up @@ -462,7 +462,7 @@ def createQuadViewStatusBar(self,
self.zLabel, self.zSpinBox = self._get_pos_widget('Z',
zbackgroundColor,
zforegroundColor)
self.labelWidget, self.pos_info_ticker = self._get_label_widget(labelbackgroundColor, labelforegroundColor)
self.labelWidget = self._get_posMeta_widget(labelbackgroundColor, labelforegroundColor)
self.labelbackgroundColor = labelbackgroundColor

self.xSpinBox.delayedValueChanged.connect( partial(self._handlePositionBoxValueChanged, 'x') )
Expand Down Expand Up @@ -593,10 +593,7 @@ def _get_pos_widget(self, name, backgroundColor, foregroundColor):
spinbox.setStyleSheet(sheet)
return label, spinbox

def _get_label_widget(self, backgroundColor, foregroundColor):
ticker = QTimer()
ticker.setInterval(200)
ticker.setSingleShot(True)
def _get_posMeta_widget(self, backgroundColor, foregroundColor):
ledit = QLineEdit()
ledit.setAlignment(Qt.AlignCenter)
ledit.setMaximumHeight(20)
Expand All @@ -610,58 +607,39 @@ def _get_label_widget(self, backgroundColor, foregroundColor):
f"background-color: {backgroundColor.name()};"
f"border: none")

return ledit, ticker
return ledit

def _set_label_widget(self, x, y, z, t):
def _set_posMeta_widget(self, x, y, z):
"""Updates the label widget according to current mouse cursor position (x,y,z) and selectet time frame (t)"""
# from lazyflow.roi import TinyVector
# from collections import namedtuple

# no need for the color dimension (last element) here.
slicing = [slice(int(i), int(i + 1)) for i in [t, x, y, z]] + [slice(0,1)]
# Roi = namedtuple('Roi', 'start stop')
# roi = Roi(start=TinyVector([int(t),int(y),int(x),int(z)]), stop=TinyVector([int(t+1),int(y+1),int(x+1),int(z+1)]))
label = None
coords = [int(val) for val in [x,y,z]]
imgView = self.editor.posModel.activeView
blockSize = self.editor.imageViews[imgView].scene()._tileProvider.tiling.blockSize
del coords[imgView]
x,y = (val for val in coords)
if imgView == 0:
x,y = (y,x)
try:
def findLayer(layer):
if "Segmentation (Label " in layer.name:
return True
labelings = self.layerStack.findMatchingIndices(findLayer) # this throws exception if no layer found
for lbl in labelings:
try:
fixed = []
# FIXME This is really hacky, need to find another way of retrieving the cached values without the cache blocking the request
for op in self.layerStack[lbl].datasources[0].dataSlot.getRealOperator().opPredictionPipeline.innerOperators[0].prediction_cache_gui._innerOps:
fixed.append(op._opCacheFixer._fixed)
op._opCacheFixer._fixed = False

# Get the whole dataset (debugging purposes)
# whole_set_roi = Roi(start=TinyVector([0, 0, 0, 0]),
# whole_set_slicing = [slice(int(0), int(i)) for i in [2, 1343, 1022, 1]] + [slice(0,1)]
# set_fromRoi = self.layerStack[lbl].datasources[0].dataSlot.get(whole_set_roi).wait()
# set_fromSlice = self.layerStack[lbl].datasources[0].request(whole_set_slicing).wait()
# set_fromVal = self.layerStack[lbl].datasources[0].dataSlot.value

# Equivalent calls to opCacheFixer
# val = self.layerStack[lbl].datasources[0].dataSlot.get(roi).wait()
# val = self.layerStack[lbl].datasources[0].dataSlot(roi.start, roi.stop).wait()
val = self.layerStack[lbl].datasources[0].request(slicing).wait()

# This does not call cached values, hence no need to hack the cache. But it is way to slow
# val = self.layerStack[lbl].datasources[0].dataSlot.value[int(t),int(y),int(x),int(z)]
finally:
if fixed:
for fx, op in zip(fixed, self.layerStack[lbl].datasources[0].dataSlot.getRealOperator().opPredictionPipeline.innerOperators[0].prediction_cache_gui._innerOps):
op._opCacheFixer._fixed = fx
if val == 1: # indicates, that 'sclicing' is labelled with the label 'lbl'
name = self.layerStack[lbl].name
label = name[name.find("(") + 1:name.find(")")]
color = self.layerStack[lbl].tintColor.name()
self.labelWidget.setStyleSheet(f"color: white;"
f"background-color: {color};"
f"border: none")
self.labelWidget.setText(f"{label}")
break
for layer in self.editor.layerStack:
if layer.visible:
layer_id = self.editor.imagepumps[imgView].stackedImageSources._layerToIms[layer]
stack_id = self.editor.imageViews[imgView].scene()._tileProvider._current_stack_id
tile_id = self.editor.imageViews[imgView].scene()._tileProvider.tiling.intersected(QRect(QPoint(x,y), QPoint(x,y)))[0] # There will be just one tile, since we have just a single point

with self.editor.imageViews[imgView].scene()._tileProvider._cache:
image = self.editor.imageViews[imgView].scene()._tileProvider._cache.layer(stack_id, layer_id,
tile_id)
if image is not None:
colorVal = image.pixelColor(x%blockSize,y%blockSize)
if "Segmentation (Label " in layer.name and colorVal.getRgb() != (0,0,0,0):
name = layer.name
label = name[name.find("(") + 1:name.find(")")]
color = layer.tintColor.name()
self.labelWidget.setStyleSheet(f"color: white;"
f"background-color: {color};"
f"border: none")
self.labelWidget.setText(f"{label}")
break
if label is None:
raise ValueError("No matching layer in stack.")
except ValueError as e:
Expand All @@ -672,6 +650,8 @@ def findLayer(layer):

if str(e) != "No matching layer in stack.":
raise
except:
raise

def _registerTimeframeShortcuts(self, enabled=True, remove=True):
""" Register or deregister "," and "." as keyboard shortcuts for scrolling in time """
Expand Down Expand Up @@ -776,13 +756,11 @@ def updateShape5Dcropped(self, shape5DcropMin, shape5Dmax):
self.zSpinBox.setValue(shape5DcropMin[3])
self.timeSlider.setValue(shape5DcropMin[0])

def setMouseCoords(self, x, y, z, t):
def setMouseCoords(self, x, y, z):
self.xSpinBox.setValueWithoutSignal(x)
self.ySpinBox.setValueWithoutSignal(y)
self.zSpinBox.setValueWithoutSignal(z)
if not self.pos_info_ticker.isActive():
self._set_label_widget(x, y, z, t)
self.pos_info_ticker.start()
self._set_posMeta_widget(x, y, z)


if __name__ == "__main__":
Expand Down
6 changes: 3 additions & 3 deletions volumina/volumeEditorWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def onViewFocused():
self.editor.imageViews[0], self.editor.imageViews[1],
self.editor.view3d)
self.quadview.installEventFilter(self)
self.quadViewStatusBar = QuadStatusBar(self.editor.layerStack)
self.quadViewStatusBar = QuadStatusBar(self.editor)
self.quadViewStatusBar.createQuadViewStatusBar(
QColor("#dc143c"),
QColor("white"),
Expand Down Expand Up @@ -439,8 +439,8 @@ def jumpToLastSlice(axis):
v,
None) )

def _updateInfoLabels(self, pos, oldpos, time):
self.quadViewStatusBar.setMouseCoords(*pos, time)
def _updateInfoLabels(self, pos):
self.quadViewStatusBar.setMouseCoords(*pos)

def eventFilter(self, watched, event):
# If the user performs a ctrl+scroll on the splitter itself,
Expand Down

0 comments on commit 47ab62c

Please sign in to comment.