Skip to content

Commit

Permalink
Updating the MCT Plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
beniroquai committed Nov 28, 2022
1 parent c1ce6f2 commit 43f1e92
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 57 deletions.
44 changes: 25 additions & 19 deletions imswitch/imcontrol/controller/controllers/MCTController.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,38 +323,43 @@ def takeImageIllu(self, illuMode, intensity, timestamp=0):
# precompute steps for xy scan
indexX=0
iy=0

# get current position
currentPositions = self.stages.getPosition()
initialPosition = (currentPositions["X"], currentPositions["Y"])

if self.xyScanEnabled:
xyScanSteps = []
xyScanStepsRelative = []
xyScanStepsAbsolute = []
for ix in np.arange(self.xScanMin, self.xScanMax, self.xScanStep):
xyScanSteps.append([self.xScanStep*(indexX>0), 0])
xyScanStepsAbsolute.append([ix, iy])
for indexX, ix in enumerate(np.arange(self.xScanMin, self.xScanMax, self.xScanStep)):
for iy in np.arange(self.yScanMin, self.yScanMax, self.yScanStep):
if indexX%2 == 0:
xyScanSteps.append([0, self.yScanStep])
xyScanStepsRelative.append([0, self.yScanStep])
xyScanStepsAbsolute.append([ix, iy])
else:
xyScanSteps.append([0, -self.yScanStep])
xyScanStepsAbsolute.append([ix, -iy])
indexX+=1
xyScanStepsRelative.append([0, -self.yScanStep])
xyScanStepsAbsolute.append([ix, -iy-self.yScanStep])
else:
xyScanSteps = [[0,0]]
xyScanStepsRelative = [[0,0]]
xyScanStepsAbsolute = [[0,0]]
self.xScanMin = 0
self.xScanMax = 0
self.yScanMin = 0
self.yScanMax = 0

# initialize xy coordinates
self.stages.move(value=self.xScanMin, axis="X", is_absolute=False, is_blocking=True)
self.stages.move(value=self.yScanMin, axis="Y", is_absolute=False, is_blocking=True)
self.stages.move(value=self.xScanMin+initialPosition[0], axis="X", is_absolute=True, is_blocking=True)
self.stages.move(value=self.yScanMin+initialPosition[1], axis="Y", is_absolute=True, is_blocking=True)

# initialize iterator
imageIndex = 0

# iterate over all xy coordinates iteratively
for ipos, iXYPos in enumerate(xyScanSteps):
for ipos, iXYPos in enumerate(xyScanStepsAbsolute):

# move to xy position is necessary
self.stages.move(value=iXYPos[0], axis="X", is_absolute=False, is_blocking=True)
self.stages.move(value=iXYPos[1], axis="Y", is_absolute=False, is_blocking=True)
self.stages.move(value=iXYPos[0]+initialPosition[0], axis="X", is_absolute=True, is_blocking=True)
self.stages.move(value=iXYPos[1]+initialPosition[1], axis="Y", is_absolute=True, is_blocking=True)

if self.zStackEnabled:
# perform a z-stack
Expand All @@ -373,13 +378,14 @@ def takeImageIllu(self, illuMode, intensity, timestamp=0):
self.stages.move(value=self.zStackStep, axis="Z", is_absolute=False, is_blocking=True)
filePath = self.getSaveFilePath(date=self.MCTDate,
timestamp=timestamp,
filename=f'{self.MCTFilename}_{illuMode}_Z_{stepsCounter}_X_{xyScanStepsAbsolute[ipos][0]}_Y_{xyScanStepsAbsolute[ipos][1]}',
filename=f'{self.MCTFilename}_{illuMode}_i_{imageIndex}_Z_{stepsCounter}_X_{xyScanStepsAbsolute[ipos][0]}_Y_{xyScanStepsAbsolute[ipos][1]}',
extension=fileExtension)
time.sleep(self.tUnshake) # unshake
lastFrame = self.detector.getLatestFrame()
# self.switchOffIllumination()
self._logger.debug(filePath)
tif.imwrite(filePath, lastFrame, append=True)
imageIndex += 1

# store frames for displaying
if illuMode == "Laser1": self.LastStackLaser1.append(lastFrame.copy())
Expand All @@ -394,22 +400,22 @@ def takeImageIllu(self, illuMode, intensity, timestamp=0):
# single file timelapse
filePath = self.getSaveFilePath(date=self.MCTDate,
timestamp=timestamp,
filename=f'{self.MCTFilename}_{illuMode}_X_{xyScanStepsAbsolute[ipos][0]}_Y_{xyScanStepsAbsolute[ipos][1]}',
filename=f'{self.MCTFilename}_{illuMode}_i_{imageIndex}_X_{xyScanStepsAbsolute[ipos][0]}_Y_{xyScanStepsAbsolute[ipos][1]}',
extension=fileExtension)
lastFrame = self.detector.getLatestFrame()
self._logger.debug(filePath)
tif.imwrite(filePath, lastFrame)
imageIndex += 1

# store frames for displaying
if illuMode == "Laser1": self.LastStackLaser1=(lastFrame.copy())
if illuMode == "Laser2": self.LastStackLaser2=(lastFrame.copy())
if illuMode == "Brightfield": self.LastStackLED=(lastFrame.copy())

# initialize xy coordinates
self.stages.move(value=-self.xScanMin, axis="X", is_absolute=False, is_blocking=True)
self.stages.move(value=-self.yScanMin, axis="Y", is_absolute=False, is_blocking=True)
self.stages.move(value=initialPosition[0], axis="X", is_absolute=True, is_blocking=True)
self.stages.move(value=initialPosition[1], axis="Y", is_absolute=True, is_blocking=True)


self.switchOffIllumination()


Expand Down
23 changes: 12 additions & 11 deletions imswitch/imcontrol/controller/controllers/PositionerController.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ def __init__(self, *args, **kwargs):

# Connect CommunicationChannel signals
self._commChannel.sharedAttrs.sigAttributeSet.connect(self.attrChanged)
self._commChannel.sigSetSpeed.connect(lambda speed: self.setSpeedGUI(speed))


# Connect PositionerWidget signals
self._widget.sigStepUpClicked.connect(self.stepUp)
self._widget.sigStepDownClicked.connect(self.stepDown)
self._widget.sigsetSpeedClicked.connect(self.setSpeedGUI)

self._widget.sigStepAbsoluteClicked.connect(self.moveAbsolute)
def closeEvent(self):
self._master.positionersManager.execOnAll(
lambda p: [p.setPosition(0, axis) for axis in p.axes]
Expand All @@ -51,7 +50,10 @@ def move(self, positionerName, axis, dist, isAbsolute=None, isBlocking=False):
""" Moves positioner by dist micrometers in the specified axis. """
if positionerName is None:
positionerName = self._master.positionersManager.getAllDeviceNames()[0]


# get all speed values from the GUI
speed = self._widget.getSpeed(positionerName, axis)
self.setSpeed(positionerName=positionerName, speed=speed, axis=axis)
try:
self._master.positionersManager[positionerName].move(dist, axis, isAbsolute, isBlocking)
except:
Expand All @@ -63,15 +65,14 @@ def setPos(self, positionerName, axis, position):
self._master.positionersManager[positionerName].setPosition(position, axis)
self.updatePosition(positionerName, axis)

def moveAbsolute(self, positionerName, axis):
self.move(positionerName, axis, self._widget.getAbsPosition(positionerName, axis), isAbsolute=True, isBlocking=True)

def stepUp(self, positionerName, axis):
self.move(positionerName, axis, self._widget.getStepSize(positionerName, axis), False, True) # name, axi, stepsiye
self.move(positionerName, axis, self._widget.getStepSize(positionerName, axis), isAbsolute=False, isBlocking=True) # name, axi, stepsize

def stepDown(self, positionerName, axis):
self.move(positionerName, axis, -self._widget.getStepSize(positionerName, axis), False, True)

def setSpeedGUI(self, positionerName, axis):
speed = self._widget.getSpeed(positionerName, axis)
self.setSpeed(positionerName=positionerName, speed=speed, axis=axis)
self.move(positionerName, axis, -self._widget.getStepSize(positionerName, axis), isAbsolute=False, isBlocking=True)

def setSpeed(self, positionerName, axis, speed=(1000,1000,1000)):
self._master.positionersManager[positionerName].setSpeed(speed, axis)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,14 @@ def setPosition(self, value, axis):
def closeEvent(self):
pass

def get_abs(self, axis=1):
abspos = self._motor.get_position(axis=axis)
return abspos

def getPosition(self):
try:
allPositions = self._motor.get_position()
except:
allPositions = [0,0,0,0]

return {"X": allPositions[1], "Y": allPositions[2], "Z": allPositions[3], "A": allPositions[0]}

def home_x(self):
self._motor.home_x()
Expand Down
7 changes: 0 additions & 7 deletions imswitch/imcontrol/view/widgets/LEDMatrixWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,6 @@ def add_matrix_view(self, nLedsX = 8, nLedsY=8):
self.ButtonAllOff = guitools.BetterPushButton("All Off")
gridLayout.addWidget(self.ButtonAllOff, 1, 8, 1, 1)

self.ButtonSubmit = guitools.BetterPushButton("Submit")
gridLayout.addWidget(self.ButtonSubmit, 2, 8, 1, 1)

self.ButtonToggle = guitools.BetterPushButton("Toggle")
gridLayout.addWidget(self.ButtonToggle, 3, 8, 1, 1)


self.slider = guitools.FloatSlider(QtCore.Qt.Horizontal, self, allowScrollChanges=False,
decimals=1)
self.slider.setFocusPolicy(QtCore.Qt.NoFocus)
Expand Down
41 changes: 24 additions & 17 deletions imswitch/imcontrol/view/widgets/PositionerWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ class PositionerWidget(Widget):
""" Widget in control of the piezo movement. """

sigStepUpClicked = QtCore.Signal(str, str) # (positionerName, axis)
sigStepDownClicked = QtCore.Signal(str, str) # (positionerName, axis)
sigsetSpeedClicked = QtCore.Signal(str, str) # (positionerName, axis)
sigStepDownClicked = QtCore.Signal(str, str) # (positionerName, axis)
sigStepAbsoluteClicked = QtCore.Signal(str,str)


def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand All @@ -31,42 +32,48 @@ def addPositioner(self, positionerName, axes, hasSpeed):
self.pars['UpButton' + parNameSuffix] = guitools.BetterPushButton('+')
self.pars['DownButton' + parNameSuffix] = guitools.BetterPushButton('-')
self.pars['StepEdit' + parNameSuffix] = QtWidgets.QLineEdit('1000')
self.pars['StepUnit' + parNameSuffix] = QtWidgets.QLabel(' µm')

self.pars['AbsolutePosEdit' + parNameSuffix] = QtWidgets.QLineEdit('0')
self.pars['AbsolutePosButton' + parNameSuffix] = guitools.BetterPushButton('Go!')

self.grid.addWidget(self.pars['Label' + parNameSuffix], self.numPositioners, 0)
self.grid.addWidget(self.pars['Position' + parNameSuffix], self.numPositioners, 1)
self.grid.addWidget(self.pars['UpButton' + parNameSuffix], self.numPositioners, 2)
self.grid.addWidget(self.pars['DownButton' + parNameSuffix], self.numPositioners, 3)
self.grid.addWidget(QtWidgets.QLabel('Step'), self.numPositioners, 4)
self.grid.addWidget(QtWidgets.QLabel('Rel'), self.numPositioners, 4)
self.grid.addWidget(self.pars['StepEdit' + parNameSuffix], self.numPositioners, 5)
self.grid.addWidget(self.pars['StepUnit' + parNameSuffix], self.numPositioners, 6)

self.grid.addWidget(QtWidgets.QLabel('Abs'), self.numPositioners, 6)

self.grid.addWidget(self.pars['AbsolutePosEdit' + parNameSuffix], self.numPositioners, 7)
self.grid.addWidget(self.pars['AbsolutePosButton' + parNameSuffix], self.numPositioners, 8)

# Connect signals
self.pars['UpButton' + parNameSuffix].clicked.connect(
lambda *args, axis=axis: self.sigStepUpClicked.emit(positionerName, axis)
)
self.pars['DownButton' + parNameSuffix].clicked.connect(
lambda *args, axis=axis: self.sigStepDownClicked.emit(positionerName, axis)
)
self.pars['AbsolutePosButton' + parNameSuffix].clicked.connect(
lambda *args, axis=axis: self.sigStepAbsoluteClicked.emit(positionerName, axis)
)

if hasSpeed:
self.pars['Speed' + parNameSuffix] = QtWidgets.QLabel(f'<strong>{0:.2f} µm/s</strong>')
self.pars['Speed' + parNameSuffix] = QtWidgets.QLabel('Speed:')
self.pars['Speed' + parNameSuffix].setTextFormat(QtCore.Qt.RichText)
self.pars['ButtonSpeedEnter' + parNameSuffix] = guitools.BetterPushButton('Enter')
self.pars['SpeedEdit' + parNameSuffix] = QtWidgets.QLineEdit('1000')
self.pars['SpeedUnit' + parNameSuffix] = QtWidgets.QLabel(' µm/s')
self.grid.addWidget(self.pars['SpeedEdit' + parNameSuffix], self.numPositioners, 10)
self.grid.addWidget(self.pars['SpeedUnit' + parNameSuffix], self.numPositioners, 11)
self.grid.addWidget(self.pars['ButtonSpeedEnter' + parNameSuffix], self.numPositioners, 12)
self.grid.addWidget(self.pars['Speed' + parNameSuffix], self.numPositioners, 7)


self.pars['ButtonSpeedEnter'+ parNameSuffix].clicked.connect(
lambda *args, axis=axis: self.sigsetSpeedClicked.emit(positionerName, axis)
)
self.grid.addWidget(self.pars['Speed' + parNameSuffix], self.numPositioners, 9)
self.grid.addWidget(self.pars['SpeedEdit' + parNameSuffix], self.numPositioners, 10)

self.numPositioners += 1

def getAbsPosition(self, positionerName, axis):
""" Returns the absolute position of the specified positioner axis in
micrometers. """
parNameSuffix = self._getParNameSuffix(positionerName, axis)
return float(self.pars['AbsolutePosEdit' + parNameSuffix].text())

def getStepSize(self, positionerName, axis):
""" Returns the step size of the specified positioner axis in
micrometers. """
Expand Down

0 comments on commit 43f1e92

Please sign in to comment.