def generateActions(self): table = actionTable.ActionTable() curTime = 0 vStart, vLessThan, vSteps = self.vRange dv = float(vLessThan - vStart) / float(vSteps) dt = decimal.Decimal(self.settlingTime) for step in range(vSteps): # Move to next polarization rotator voltage. vTarget = vStart + step * dv table.addAction(curTime, self.lineHandler, vTarget) curTime += dt # Image the sample. for cameras, lightTimePairs in self.exposureSettings: curTime = self.expose(curTime, cameras, lightTimePairs, table) # Advance the time very slightly so that all exposures # are strictly ordered. curTime += decimal.Decimal('.001') # Hold the rotator angle constant during the exposure. table.addAction(curTime, self.lineHandler, vTarget) # Advance time slightly so all actions are sorted (e.g. we # don't try to change angle and phase in the same timestep). curTime += dt return table
def generateActions(self): table = actionTable.ActionTable() curTime = 0 prevAltitude = None numZSlices = int(math.ceil(self.zHeight / self.sliceHeight)) if self.zHeight > 1e-6: # Non-2D experiment; tack on an extra image to hit the top of # the volume. numZSlices += 1 for zIndex in range(numZSlices): # Move to the next position, then wait for the stage to # stabilize. zTarget = self.zStart + self.sliceHeight * zIndex motionTime, stabilizationTime = 0, 0 if prevAltitude is not None: motionTime, stabilizationTime = self.zPositioner.getMovementTime(prevAltitude, zTarget) motionTime *= 1000 stabilizationTime *= 1000 curTime += motionTime table.addAction(curTime, self.zPositioner, zTarget) curTime += stabilizationTime prevAltitude = zTarget # Image the sample. for cameras, lightTimePairs in self.exposureSettings: curTime = self.expose(curTime, cameras, lightTimePairs, table) # Advance the time very slightly so that all exposures # are strictly ordered. curTime += decimal.Decimal('1e-10') # Hold the Z motion flat during the exposure. table.addAction(curTime, self.zPositioner, zTarget) # Move back to the start so we're ready for the next rep. motionTime, stabilizationTime = self.zPositioner.getMovementTime( self.zHeight, 0) motionTime *= 1000 stabilizationTime *= 1000 curTime += motionTime table.addAction(curTime, self.zPositioner, self.zStart) # Hold flat for the stabilization time, and any time needed for # the cameras to be ready. Only needed if we're doing multiple # reps, so we can proceed immediately to the next one. cameraReadyTime = 0 if self.numReps > 1: for cameras, lightTimePairs in self.exposureSettings: for camera in cameras: cameraReadyTime = max(cameraReadyTime, self.getTimeWhenCameraCanExpose(table, camera)) table.addAction(max(curTime + stabilizationTime, cameraReadyTime), self.zPositioner, self.zStart) return table
def generateActions(self, multiplier, activeCameras): table = actionTable.ActionTable() curTime = 0 for cameras, lightTimePairs in self.exposureSettings: usedCams = activeCameras.intersection(cameras) if usedCams: settings = [] for light, time in lightTimePairs: # We can't actually have a zero exposure time. exposureTime = max(time * multiplier, decimal.Decimal('.1')) settings.append((light, exposureTime)) for i in range(self.numExposures): curTime = self.expose(curTime, usedCams, settings, table) return table
def generateActions(self, exposureTime): table = actionTable.ActionTable() curTime = 0 allCams = set(self.cameras) for cameras, lightTimePairs in self.exposureSettings: usedCams = allCams.intersection(cameras) if usedCams: settings = [] for light, time in lightTimePairs: # We can't actually have a zero exposure time, so use # 1ns as a minimum. exposureTime = max(exposureTime, decimal.Decimal('.000001')) settings.append((light, exposureTime)) for i in range(self.numExposures): curTime = self.expose(curTime, usedCams, settings, table) return table
def generateActions(self): table = actionTable.ActionTable() curTime = 0 for cameras, lightTimePairs in self.exposureSettings: # Start the stage at the bottom. table.addAction(curTime, self.zPositioner, 0) # Ensure our exposure is at least as long as the time needed to # move through the sample. motionTime, stabilizationTime = self.zPositioner.getMovementTime( 0, self.zHeight) # Image the sample. curTime = self.expose(curTime, cameras, lightTimePairs, table) # End the exposure with the stage at the top. table.addAction(curTime, self.zPositioner, self.zHeight) curTime += stabilizationTime # Move back to the start so we're ready for the next set of cameras # or the next rep. motionTime, stabilizationTime = self.zPositioner.getMovementTime( self.zHeight, 0) curTime += motionTime table.addAction(curTime, self.zPositioner, 0) # Hold flat for the stabilization time, and any time needed for # the cameras to be ready. Only needed if we're doing multiple # reps, so we can proceed immediately to the next one. cameraReadyTime = 0 if self.numReps > 1: for cameras, lightTimePairs in self.exposureSettings: for camera in cameras: cameraReadyTime = max( cameraReadyTime, self.getTimeWhenCameraCanExpose(table, camera)) table.addAction( max(curTime + stabilizationTime, cameraReadyTime), self.zPositioner, 0) return table
def generateActions(self): table = actionTable.ActionTable() curTime = 0 prevAngle, prevZ, prevPhase = None, None, None # Set initial angle and phase, if relevant. We assume the SLM (if any) # is already showing the correct pattern for the first image set. # Increment the time slightly after each "motion" so that actions are well-ordered. if self.angleHandler is not None: theta = self.angleHandler.indexedPosition(0) table.addAction(curTime, self.angleHandler, theta) curTime += decimal.Decimal('1e-6') if self.phaseHandler is not None: table.addAction(curTime, self.phaseHandler, 0) curTime += decimal.Decimal('1') table.addAction(curTime, self.zPositioner, self.zStart) curTime += decimal.Decimal('1') if self.slmHandler is not None: # Add a first trigger of the SLM to get first new image. table.addAction(curTime, self.slmHandler, 0) # Wait a few ms for any necessary SLM triggers. curTime = decimal.Decimal('5e-3') for angle, phase, z in self.genSIPositions(): delayBeforeImaging = 0 # Figure out which positions changed. They need to be held flat # up until the move, then spend some amount of time moving, # then have some time to stabilize. Or, if we have an SLM, then we # need to trigger it and then wait for it to stabilize. # Ensure we truly are doing this after all exposure events are done. curTime = max( curTime, table.getFirstAndLastActionTimes()[1] + decimal.Decimal('1e-6')) if angle != prevAngle and prevAngle is not None: if self.angleHandler is not None: theta = self.angleHandler.indexedPosition(angle) motionTime, stabilizationTime = self.angleHandler.getMovementTime( prevAngle, theta) # Move to the next position. table.addAction(curTime + motionTime, self.angleHandler, theta) delayBeforeImaging = max(delayBeforeImaging, motionTime + stabilizationTime) # Advance time slightly so all actions are sorted (e.g. we # don't try to change angle and phase in the same timestep). curTime += decimal.Decimal('.001') if phase != prevPhase and prevPhase is not None: if self.phaseHandler is not None: motionTime, stabilizationTime = self.phaseHandler.getMovementTime( prevPhase, phase) # Hold flat. table.addAction(curTime, self.phaseHandler, prevPhase) # Move to the next position. table.addAction(curTime + motionTime, self.phaseHandler, phase) delayBeforeImaging = max(delayBeforeImaging, motionTime + stabilizationTime) # Advance time slightly so all actions are sorted (e.g. we # don't try to change angle and phase in the same timestep). curTime += decimal.Decimal('.001') if z != prevZ: if prevZ is not None: motionTime, stabilizationTime = self.zPositioner.getMovementTime( prevZ, z) # Hold flat. table.addAction(curTime, self.zPositioner, prevZ) # Move to the next position. table.addAction(curTime + motionTime, self.zPositioner, z) delayBeforeImaging = max(delayBeforeImaging, motionTime + stabilizationTime) # Advance time slightly so all actions are sorted (e.g. we # don't try to change angle and phase in the same timestep). curTime += decimal.Decimal('.001') prevAngle = angle prevPhase = phase prevZ = z curTime += delayBeforeImaging # Image the sample. # expose handles the SLM triggers. This may result in an additional # short delay before exposure, but is the best way to support SIM # in a series of exposures at different wavelengths, with the SIM # pattern optimised for each wavelength. for cameras, lightTimePairs in self.exposureSettings: curTime = self.expose(curTime, cameras, lightTimePairs, angle, phase, table) # Hold Z, angle, and phase steady through to the end, then ramp down # to 0 to prep for the next experiment. table.addAction(curTime, self.zPositioner, prevZ) motionTime, stabilizationTime = self.zPositioner.getMovementTime( self.zHeight, self.zStart) table.addAction(curTime + motionTime, self.zPositioner, self.zStart) finalWaitTime = motionTime + stabilizationTime # Ramp down Z table.addAction(curTime + finalWaitTime, self.zPositioner, self.zStart) if self.angleHandler is not None: # Ramp down angle theta = self.angleHandler.indexedPosition(0) motionTime, stabilizationTime = self.angleHandler.getMovementTime( prevAngle, theta) table.addAction(curTime + motionTime, self.angleHandler, theta) finalWaitTime = max(finalWaitTime, motionTime + stabilizationTime) if self.phaseHandler is not None: # Ramp down phase table.addAction(curTime, self.phaseHandler, prevPhase) motionTime, stabilizationTime = self.phaseHandler.getMovementTime( prevPhase, 0) table.addAction(curTime + motionTime, self.phaseHandler, 0) finalWaitTime = max(finalWaitTime, motionTime + stabilizationTime) if self.polarizerHandler is not None: # Return to idle voltage. table.addAction(curTime, self.polarizerHandler, (0, 'default')) finalWaitTime = finalWaitTime + decimal.Decimal(1e-6) # Set SLM back to 0th image ready for next measurement in timelapse or multi-site. if self.slmHandler is not None: # Toggle the slmHandler's digital line handler to advance one frame. table.addToggle(curTime, self.slmHandler) return table