Skip to content

Commit 47ab62c

Browse files
committed
removed timer, get data from volumina stack. Not less hacky. Need for caches, storing raw datasources
1 parent 737718a commit 47ab62c

File tree

4 files changed

+49
-65
lines changed

4 files changed

+49
-65
lines changed

volumina/patchAccessor.py

+6
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ def getPatchesForRect(self,startx,starty,endx,endy):
105105
ex = min(ex, self._cX)
106106
ey = min(ey, self._cY)
107107

108+
# always return at least one index
109+
if sx==ex:
110+
ex = ex + 1
111+
if sy==ey:
112+
ey = ey + 1
113+
108114
nums = []
109115
for y in range(sy,ey):
110116
nums += list(range(y*self._cX+sx, y*self._cX+ex))

volumina/positionModel.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class PositionModel(QObject):
4040

4141
timeChanged = pyqtSignal(int)
4242
channelChanged = pyqtSignal(int)
43-
cursorPositionChanged = pyqtSignal(object, object, object)
43+
cursorPositionChanged = pyqtSignal(object, object)
4444
slicingPositionChanged = pyqtSignal(object, object)
4545
slicingPositionSettled = pyqtSignal(bool)
4646

@@ -168,7 +168,7 @@ def cursorPos(self, coordinates):
168168
return
169169
oldPos = self._cursorPos
170170
self._cursorPos = coordinates
171-
self.cursorPositionChanged.emit(self.cursorPos, oldPos, self.time)
171+
self.cursorPositionChanged.emit(self.cursorPos, oldPos)
172172

173173
@property
174174
def slicingPos(self):

volumina/sliceSelectorHud.py

+38-60
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from functools import partial
2626

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

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

418-
def __init__(self, layerStack, parent=None):
418+
def __init__(self, volumeEditor, parent=None):
419419
QHBoxLayout.__init__(self, parent)
420420
self.setContentsMargins(0,4,0,0)
421421
self.setSpacing(0)
422422
self.timeControlFontSize = 12
423-
self.layerStack = layerStack
423+
self.editor = volumeEditor
424424

425425
def showXYCoordinates(self):
426426
self.zLabel.setHidden(True)
@@ -462,7 +462,7 @@ def createQuadViewStatusBar(self,
462462
self.zLabel, self.zSpinBox = self._get_pos_widget('Z',
463463
zbackgroundColor,
464464
zforegroundColor)
465-
self.labelWidget, self.pos_info_ticker = self._get_label_widget(labelbackgroundColor, labelforegroundColor)
465+
self.labelWidget = self._get_posMeta_widget(labelbackgroundColor, labelforegroundColor)
466466
self.labelbackgroundColor = labelbackgroundColor
467467

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

596-
def _get_label_widget(self, backgroundColor, foregroundColor):
597-
ticker = QTimer()
598-
ticker.setInterval(200)
599-
ticker.setSingleShot(True)
596+
def _get_posMeta_widget(self, backgroundColor, foregroundColor):
600597
ledit = QLineEdit()
601598
ledit.setAlignment(Qt.AlignCenter)
602599
ledit.setMaximumHeight(20)
@@ -610,58 +607,39 @@ def _get_label_widget(self, backgroundColor, foregroundColor):
610607
f"background-color: {backgroundColor.name()};"
611608
f"border: none")
612609

613-
return ledit, ticker
610+
return ledit
614611

615-
def _set_label_widget(self, x, y, z, t):
612+
def _set_posMeta_widget(self, x, y, z):
616613
"""Updates the label widget according to current mouse cursor position (x,y,z) and selectet time frame (t)"""
617-
# from lazyflow.roi import TinyVector
618-
# from collections import namedtuple
619-
620-
# no need for the color dimension (last element) here.
621-
slicing = [slice(int(i), int(i + 1)) for i in [t, x, y, z]] + [slice(0,1)]
622-
# Roi = namedtuple('Roi', 'start stop')
623-
# 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)]))
624614
label = None
615+
coords = [int(val) for val in [x,y,z]]
616+
imgView = self.editor.posModel.activeView
617+
blockSize = self.editor.imageViews[imgView].scene()._tileProvider.tiling.blockSize
618+
del coords[imgView]
619+
x,y = (val for val in coords)
620+
if imgView == 0:
621+
x,y = (y,x)
625622
try:
626-
def findLayer(layer):
627-
if "Segmentation (Label " in layer.name:
628-
return True
629-
labelings = self.layerStack.findMatchingIndices(findLayer) # this throws exception if no layer found
630-
for lbl in labelings:
631-
try:
632-
fixed = []
633-
# FIXME This is really hacky, need to find another way of retrieving the cached values without the cache blocking the request
634-
for op in self.layerStack[lbl].datasources[0].dataSlot.getRealOperator().opPredictionPipeline.innerOperators[0].prediction_cache_gui._innerOps:
635-
fixed.append(op._opCacheFixer._fixed)
636-
op._opCacheFixer._fixed = False
637-
638-
# Get the whole dataset (debugging purposes)
639-
# whole_set_roi = Roi(start=TinyVector([0, 0, 0, 0]),
640-
# whole_set_slicing = [slice(int(0), int(i)) for i in [2, 1343, 1022, 1]] + [slice(0,1)]
641-
# set_fromRoi = self.layerStack[lbl].datasources[0].dataSlot.get(whole_set_roi).wait()
642-
# set_fromSlice = self.layerStack[lbl].datasources[0].request(whole_set_slicing).wait()
643-
# set_fromVal = self.layerStack[lbl].datasources[0].dataSlot.value
644-
645-
# Equivalent calls to opCacheFixer
646-
# val = self.layerStack[lbl].datasources[0].dataSlot.get(roi).wait()
647-
# val = self.layerStack[lbl].datasources[0].dataSlot(roi.start, roi.stop).wait()
648-
val = self.layerStack[lbl].datasources[0].request(slicing).wait()
649-
650-
# This does not call cached values, hence no need to hack the cache. But it is way to slow
651-
# val = self.layerStack[lbl].datasources[0].dataSlot.value[int(t),int(y),int(x),int(z)]
652-
finally:
653-
if fixed:
654-
for fx, op in zip(fixed, self.layerStack[lbl].datasources[0].dataSlot.getRealOperator().opPredictionPipeline.innerOperators[0].prediction_cache_gui._innerOps):
655-
op._opCacheFixer._fixed = fx
656-
if val == 1: # indicates, that 'sclicing' is labelled with the label 'lbl'
657-
name = self.layerStack[lbl].name
658-
label = name[name.find("(") + 1:name.find(")")]
659-
color = self.layerStack[lbl].tintColor.name()
660-
self.labelWidget.setStyleSheet(f"color: white;"
661-
f"background-color: {color};"
662-
f"border: none")
663-
self.labelWidget.setText(f"{label}")
664-
break
623+
for layer in self.editor.layerStack:
624+
if layer.visible:
625+
layer_id = self.editor.imagepumps[imgView].stackedImageSources._layerToIms[layer]
626+
stack_id = self.editor.imageViews[imgView].scene()._tileProvider._current_stack_id
627+
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
628+
629+
with self.editor.imageViews[imgView].scene()._tileProvider._cache:
630+
image = self.editor.imageViews[imgView].scene()._tileProvider._cache.layer(stack_id, layer_id,
631+
tile_id)
632+
if image is not None:
633+
colorVal = image.pixelColor(x%blockSize,y%blockSize)
634+
if "Segmentation (Label " in layer.name and colorVal.getRgb() != (0,0,0,0):
635+
name = layer.name
636+
label = name[name.find("(") + 1:name.find(")")]
637+
color = layer.tintColor.name()
638+
self.labelWidget.setStyleSheet(f"color: white;"
639+
f"background-color: {color};"
640+
f"border: none")
641+
self.labelWidget.setText(f"{label}")
642+
break
665643
if label is None:
666644
raise ValueError("No matching layer in stack.")
667645
except ValueError as e:
@@ -672,6 +650,8 @@ def findLayer(layer):
672650

673651
if str(e) != "No matching layer in stack.":
674652
raise
653+
except:
654+
raise
675655

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

779-
def setMouseCoords(self, x, y, z, t):
759+
def setMouseCoords(self, x, y, z):
780760
self.xSpinBox.setValueWithoutSignal(x)
781761
self.ySpinBox.setValueWithoutSignal(y)
782762
self.zSpinBox.setValueWithoutSignal(z)
783-
if not self.pos_info_ticker.isActive():
784-
self._set_label_widget(x, y, z, t)
785-
self.pos_info_ticker.start()
763+
self._set_posMeta_widget(x, y, z)
786764

787765

788766
if __name__ == "__main__":

volumina/volumeEditorWidget.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def onViewFocused():
144144
self.editor.imageViews[0], self.editor.imageViews[1],
145145
self.editor.view3d)
146146
self.quadview.installEventFilter(self)
147-
self.quadViewStatusBar = QuadStatusBar(self.editor.layerStack)
147+
self.quadViewStatusBar = QuadStatusBar(self.editor)
148148
self.quadViewStatusBar.createQuadViewStatusBar(
149149
QColor("#dc143c"),
150150
QColor("white"),
@@ -439,8 +439,8 @@ def jumpToLastSlice(axis):
439439
v,
440440
None) )
441441

442-
def _updateInfoLabels(self, pos, oldpos, time):
443-
self.quadViewStatusBar.setMouseCoords(*pos, time)
442+
def _updateInfoLabels(self, pos):
443+
self.quadViewStatusBar.setMouseCoords(*pos)
444444

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

0 commit comments

Comments
 (0)