本文整理汇总了Python中odemis.model.CancellableThreadPoolExecutor.cancel方法的典型用法代码示例。如果您正苦于以下问题:Python CancellableThreadPoolExecutor.cancel方法的具体用法?Python CancellableThreadPoolExecutor.cancel怎么用?Python CancellableThreadPoolExecutor.cancel使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类odemis.model.CancellableThreadPoolExecutor
的用法示例。
在下文中一共展示了CancellableThreadPoolExecutor.cancel方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: MFF
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
# Read until end of motion
while True:
_, status = self.GetStatus()
if not (status & STA_IN_MOTION):
return
if timeout is not None and (time.time() > start + timeout):
raise IOError("Device still in motion after %g s" % (timeout,))
# Give it a small break
time.sleep(0.05) # 20Hz
@isasync
def moveRel(self, shift):
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(shift)
shift = self._applyInversion(shift)
# TODO move to the +N next position? (and modulo number of axes)
raise NotImplementedError("Relative move on enumerated axis not supported")
@isasync
def moveAbs(self, pos):
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
pos = self._applyInversion(pos)
return self._executor.submit(self._doMovePos, pos.values()[0])
def stop(self, axes=None):
self._executor.cancel()
def _doMovePos(self, pos):
jogp = self._pos_to_jog[pos]
self.MoveJog(jogp)
self._waitNoMotion(10) # by default, a move lasts ~0.5 s
self._updatePosition()
@staticmethod
def _openSerialPort(port):
"""
Opens the given serial port the right way for a Thorlabs APT device.
port (string): the name of the serial port (e.g., /dev/ttyUSB0)
return (serial): the opened serial port
"""
# For debugging purpose
if port == "/dev/fake":
return MFF102Simulator(timeout=1)
ser = serial.Serial(
port=port,
baudrate=115200,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
rtscts=True,
timeout=1 # s
)
# Purge (as recommended in the documentation)
time.sleep(0.05) # 50 ms
ser.flush()
ser.flushInput()
示例2: DPSS
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
class DPSS(model.PowerSupplier):
'''
Implements the PowerSupplier class to regulate the power supply of the
Cobolt DPSS laser, connected via USB.
'''
def __init__(self, name, role, port, light_name, max_power, **kwargs):
'''
port (str): port name. Can be a pattern, in which case it will pick the
first one which responds well
ligth_name (str): the name of the component that is controlled by this
power supplier
max_power (float): maximum power, in W. Will be set at initialisation.
'''
# TODO: allow to pass the serial number, to select the right device
model.PowerSupplier.__init__(self, name, role, **kwargs)
self._light_name = light_name
self._ser_access = threading.Lock()
self._port = self._findDevice(port) # sets ._serial
logging.info("Found Cobolt DPSS device on port %s", self._port)
self._sn = self.GetSerialNumber()
driver_name = driver.getSerialDriver(self._port)
self._swVersion = "serial driver: %s" % (driver_name,)
self._hwVersion = "Cobolt DPSS (s/n: %s)" % (self._sn,)
# Reset sequence
# TODO: do a proper one. For now it's just everything we can throw, so
# that it's a bit easier to debug
self._sendCommand("ilk?")
self._sendCommand("leds?")
self._sendCommand("@cobasky?")
self._sendCommand("cf") # Clear fault
# self._sendCommand("@cob1") # used to force the laser on after interlock opened error
# will take care of executing switch asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
# Dict str -> bool: component name -> turn on/off
self.supplied = model.VigilantAttribute({light_name: False}, readonly=True)
self._updateSupplied()
self.SetOutputPower(max_power)
# Wrapper for the actual firmware functions
def GetSerialNumber(self):
return self._sendCommand("sn?")
def SetOutputPower(self, p):
"""
p (0 < float): power in W
"""
assert 1e-6 < p < 1e6
self._sendCommand("p %.5f" % p)
def SetLaser(self, state):
"""
state (bool): True to turn on
"""
v = 1 if state else 0
self._sendCommand("l%d" % v) # No space, as they are different commands
@isasync
def supply(self, sup):
"""
Change the power supply to the defined state for each component given.
This is an asynchronous method.
sup dict(string-> boolean): name of the component and new state
returns (Future): object to control the supply request
"""
if not sup:
return model.InstantaneousFuture()
self._checkSupply(sup)
return self._executor.submit(self._doSupply, sup)
def _doSupply(self, sup):
"""
supply power
"""
for comp, val in sup.items():
self.SetLaser(val)
self._updateSupplied()
def _updateSupplied(self):
"""
update the supplied VA
"""
res = self._sendCommand("l?")
pwrd = (res == "1")
# it's read-only, so we change it via _value
self.supplied._set_value({self._light_name: pwrd}, force_write=True)
def terminate(self):
if self._executor:
self._executor.cancel()
self._executor.shutdown()
#.........这里部分代码省略.........
示例3: CoupledStage
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
ref = {} # str (axes name) -> boolean (is referenced)
# consider an axis referenced iff it's referenced in every referenceable children
for c in self.children.value:
if not model.hasVA(c, "referenced"):
continue
cref = c.referenced.value
for a in (set(self.axes.keys()) & set(cref.keys())):
ref[a] = ref.get(a, True) and cref[a]
self.referenced._set_value(ref, force_write=True)
def _doMoveAbs(self, pos):
"""
move to the position
"""
f = self._master.moveAbs(pos)
try:
f.result()
finally: # synchronise slave position even if move failed
# TODO: Move simultaneously based on the expected position, and
# only if the final master position is different, move again.
mpos = self._master.position.value
# Move objective lens
f = self._stage_conv.moveAbs({"x": mpos["x"], "y": mpos["y"]})
f.result()
self._updatePosition()
def _doMoveRel(self, shift):
"""
move by the shift
"""
f = self._master.moveRel(shift)
try:
f.result()
finally:
mpos = self._master.position.value
# Move objective lens
f = self._stage_conv.moveAbs({"x": mpos["x"], "y": mpos["y"]})
f.result()
self._updatePosition()
@isasync
def moveRel(self, shift):
if not shift:
shift = {"x": 0, "y": 0}
self._checkMoveRel(shift)
shift = self._applyInversion(shift)
return self._executor.submit(self._doMoveRel, shift)
@isasync
def moveAbs(self, pos):
if not pos:
pos = self.position.value
self._checkMoveAbs(pos)
pos = self._applyInversion(pos)
return self._executor.submit(self._doMoveAbs, pos)
def stop(self, axes=None):
# Empty the queue for the given axes
self._executor.cancel()
self._master.stop(axes)
self._stage_conv.stop(axes)
logging.warning("Stopping all axes: %s", ", ".join(axes or self.axes))
def _doReference(self, axes):
fs = []
for c in self.children.value:
# only do the referencing for the stages that support it
if not model.hasVA(c, "referenced"):
continue
ax = axes & set(c.referenced.value.keys())
fs.append(c.reference(ax))
# wait for all referencing to be over
for f in fs:
f.result()
# Re-synchronize the 2 stages by moving the slave where the master is
mpos = self._master.position.value
f = self._stage_conv.moveAbs({"x": mpos["x"], "y": mpos["y"]})
f.result()
self._updatePosition()
@isasync
def reference(self, axes):
if not axes:
return model.InstantaneousFuture()
self._checkReference(axes)
return self._executor.submit(self._doReference, axes)
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None
示例4: MultiplexActuator
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
# move before we get to the next one => multi-threaded queue? Still need
# to ensure the order (ie, X>AB>X can be executed as X/AB>X or X>AB/X but
# XA>AB>X must be in the order XA>AB/X
futures = []
for child, move in self._moveToChildMove(shift).items():
f = child.moveRel(move, **kwargs)
futures.append(f)
# just wait for all futures to finish
for f in futures:
f.result()
@isasync
def moveAbs(self, pos, **kwargs):
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
pos = self._applyInversion(pos)
if self._executor:
f = self._executor.submit(self._doMoveAbs, pos, **kwargs)
else:
cmv = self._moveToChildMove(pos)
child, move = cmv.popitem()
assert not cmv
f = child.moveAbs(move, **kwargs)
return f
def _doMoveAbs(self, pos, **kwargs):
futures = []
for child, move in self._moveToChildMove(pos).items():
f = child.moveAbs(move, **kwargs)
futures.append(f)
# just wait for all futures to finish
for f in futures:
f.result()
@isasync
def reference(self, axes):
if not axes:
return model.InstantaneousFuture()
self._checkReference(axes)
if self._executor:
f = self._executor.submit(self._doReference, axes)
else:
cmv = self._axesToChildAxes(axes)
child, a = cmv.popitem()
assert not cmv
f = child.reference(a)
return f
reference.__doc__ = model.Actuator.reference.__doc__
def _doReference(self, axes):
child_to_axes = self._axesToChildAxes(axes)
futures = []
for child, a in child_to_axes.items():
f = child.reference(a)
futures.append(f)
# just wait for all futures to finish
for f in futures:
f.result()
def stop(self, axes=None):
"""
stops the motion
axes (iterable or None): list of axes to stop, or None if all should be stopped
"""
# Empty the queue for the given axes
if self._executor:
self._executor.cancel()
all_axes = set(self.axes.keys())
axes = axes or all_axes
unknown_axes = axes - all_axes
if unknown_axes:
logging.error("Attempting to stop unknown axes: %s", ", ".join(unknown_axes))
axes &= all_axes
threads = []
for child, a in self._axesToChildAxes(axes).items():
# it's synchronous, but we want to stop all of them as soon as possible
thread = threading.Thread(name="Stopping axis", target=child.stop, args=(a,))
thread.start()
threads.append(thread)
# wait for completion
for thread in threads:
thread.join(1)
if thread.is_alive():
logging.warning("Stopping child actuator of '%s' is taking more than 1s", self.name)
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None
示例5: ChamberPressure
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
adjusting the chamber pressure. It actually allows the user to evacuate or
vent the chamber and get the current pressure of it.
"""
def __init__(self, name, role, parent, ranges=None, **kwargs):
axes = {"pressure": model.Axis(unit="Pa",
choices={PRESSURE_VENTED: "vented",
PRESSURE_PUMPED: "vacuum"})}
model.Actuator.__init__(self, name, role, parent=parent, axes=axes, **kwargs)
# last official position
if self.GetStatus() == 0:
self._position = PRESSURE_PUMPED
else:
self._position = PRESSURE_VENTED
# RO, as to modify it the client must use .moveRel() or .moveAbs()
self.position = model.VigilantAttribute(
{"pressure": self._position},
unit="Pa", readonly=True)
# Almost the same as position, but gives the current position
self.pressure = model.VigilantAttribute(self._position,
unit="Pa", readonly=True)
# will take care of executing axis move asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
def GetStatus(self):
"""
return int: vacuum status,
-1 error
0 ready for operation
1 pumping in progress
2 venting in progress
3 vacuum off (pumps are switched off, valves are closed)
4 chamber open
"""
with self.parent._acquisition_init_lock:
status = self.parent._device.VacGetStatus() # channel 0, reserved
return status
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None
def _updatePosition(self):
"""
update the position VA and .pressure VA
"""
# it's read-only, so we change it via _value
pos = self.parent._device.VacGetPressure(0)
self.pressure._value = pos
self.pressure.notify(pos)
# .position contains the last known/valid position
# it's read-only, so we change it via _value
self.position._value = {"pressure": self._position}
self.position.notify(self.position.value)
@isasync
def moveRel(self, shift):
self._checkMoveRel(shift)
# convert into an absolute move
pos = {}
for a, v in shift.items:
pos[a] = self.position.value[a] + v
return self.moveAbs(pos)
@isasync
def moveAbs(self, pos):
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
return self._executor.submit(self._changePressure, pos["pressure"])
def _changePressure(self, p):
"""
Synchronous change of the pressure
p (float): target pressure
"""
if p["pressure"] == PRESSURE_VENTED:
self.parent._device.VacVent()
else:
self.parent._device.VacPump()
start = time.time()
while not self.GetStatus() == 0:
if (time.time() - start) >= VACUUM_TIMEOUT:
raise TimeoutError("Vacuum action timed out")
# Update chamber pressure until pumping/venting process is done
self._updatePosition()
self._position = p
self._updatePosition()
def stop(self, axes=None):
self._executor.cancel()
logging.warning("Stopped pressure change")
示例6: PM8742
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
Convert speed in step/s to m/s
axis (1<=int<=4): axis number
sps (int): steps/s
return (float): m/s
"""
return sps * self._stepsize[axis - 1]
def _setSpeed(self, value):
"""
value (dict string-> float): speed for each axis
returns (dict string-> float): the new value
"""
if set(value.keys()) != set(self._axes.keys()):
raise ValueError("Requested speed %s doesn't specify all axes %s" %
(value, self._axes.keys()))
for axis, v in value.items():
rng = self._axes[axis].speed
if not rng[0] < v <= rng[1]:
raise ValueError("Requested speed of %f for axis %s not within %f->%f" %
(v, axis, rng[0], rng[1]))
i = self._name_to_axis[axis]
sps = max(1, int(round(v / self._stepsize[i - 1])))
self.SetVelocity(i, sps)
return value
def _createFuture(self):
"""
Return (CancellableFuture): a future that can be used to manage a move
"""
f = CancellableFuture()
f._moving_lock = threading.Lock() # taken while moving
f._must_stop = threading.Event() # cancel of the current future requested
f._was_stopped = False # if cancel was successful
f.task_canceller = self._cancelCurrentMove
return f
@isasync
def moveRel(self, shift):
self._checkMoveRel(shift)
shift = self._applyInversion(shift)
# Check if the distance is big enough to make sense
for an, v in shift.items():
aid = self._name_to_axis[an]
if abs(v) < self._stepsize[aid - 1]:
# TODO: store and accumulate all the small moves instead of dropping them?
del shift[an]
logging.info("Dropped too small move of %g m < %g m",
abs(v), self._stepsize[aid - 1])
if not shift:
return model.InstantaneousFuture()
f = self._createFuture()
f = self._executor.submitf(f, self._doMoveRel, f, shift)
return f
@isasync
def moveAbs(self, pos):
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
pos = self._applyInversion(pos)
示例7: Stage
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
self._position = {}
rng = [-0.5, 0.5]
axes_def["x"] = model.Axis(unit="m", range=rng)
axes_def["y"] = model.Axis(unit="m", range=rng)
axes_def["z"] = model.Axis(unit="m", range=rng)
# Demand calibrated stage
if parent._device.StgIsCalibrated() !=1:
logging.warning("Stage was not calibrated. We are performing calibration now.")
parent._device.StgCalibrate()
#Wait for stage to be stable after calibration
while parent._device.StgIsBusy() != 0:
# If the stage is busy (movement is in progress), current position is
# updated approximately every 500 ms
time.sleep(0.5)
x, y, z, rot, tilt = parent._device.StgGetPosition()
self._position["x"] = -x * 1e-3
self._position["y"] = -y * 1e-3
self._position["z"] = -z * 1e-3
model.Actuator.__init__(self, name, role, parent=parent, axes=axes_def, **kwargs)
# will take care of executing axis move asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
# RO, as to modify it the client must use .moveRel() or .moveAbs()
self.position = model.VigilantAttribute(
self._applyInversionAbs(self._position),
unit="m", readonly=True)
def _updatePosition(self):
"""
update the position VA
"""
# it's read-only, so we change it via _value
self.position._value = self._applyInversionAbs(self._position)
self.position.notify(self.position.value)
def _doMove(self, pos):
"""
move to the position
"""
# Perform move through Tescan API
# Position from m to mm and inverted
self.parent._device.StgMoveTo(-pos["x"] * 1e3,
- pos["y"] * 1e3,
- pos["z"] * 1e3)
# Obtain the finally reached position after move is performed.
# This is mainly in order to keep the correct position in case the
# move we tried to perform was greater than the maximum possible
# one.
with self.parent._acquisition_init_lock:
x, y, z, rot, tilt = self.parent._device.StgGetPosition()
self._position["x"] = -x * 1e-3
self._position["y"] = -y * 1e-3
self._position["z"] = -z * 1e-3
self._updatePosition()
@isasync
def moveRel(self, shift):
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(shift)
shift = self._applyInversionRel(shift)
for axis, change in shift.items():
self._position[axis] += change
pos = self._position
return self._executor.submit(self._doMove, pos)
@isasync
def moveAbs(self, pos):
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
pos = self._applyInversionAbs(pos)
for axis, new_pos in pos.items():
self._position[axis] = new_pos
pos = self._position
return self._executor.submit(self._doMove, pos)
def stop(self, axes=None):
# Empty the queue for the given axes
self._executor.cancel()
logging.warning("Stopping all axes: %s", ", ".join(self.axes))
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None
示例8: Stage
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
# Wait until the move is over
# Don't check for future._must_stop because anyway the stage will
# stop moving, and so it's nice to wait until we know the stage is
# not moving.
moving = True
tstart = time.time()
while moving:
x, y, z, moving = self.parent.GetStagePosition()
# Take the opportunity to update .position
self._updatePosition({"x": x, "y": y, "z": z})
if time.time() > tstart + timeout:
self.parent.Abort()
logging.error("Timeout after submitting stage move. Aborting move.")
break
# 50 ms is about the time it takes to read the stage status
time.sleep(50e-3)
# If it was cancelled, Abort() has stopped the stage before, and
# we still have waited until the stage stopped moving. Now let
# know the user that the move is not complete.
if future._must_stop.is_set():
raise CancelledError()
except RemconError:
if future._must_stop.is_set():
raise CancelledError()
raise
finally:
future._was_stopped = True
# Update the position, even if the move didn't entirely succeed
self._updatePosition()
def _cancelCurrentMove(self, future):
"""
Cancels the current move (both absolute or relative). Non-blocking.
future (Future): the future to stop. Unused, only one future must be
running at a time.
return (bool): True if it successfully cancelled (stopped) the move.
"""
# The difficulty is to synchronise correctly when:
# * the task is just starting (not finished requesting axes to move)
# * the task is finishing (about to say that it finished successfully)
logging.debug("Cancelling current move")
future._must_stop.set() # tell the thread taking care of the move it's over
self.parent.Abort()
with future._moving_lock:
if not future._was_stopped:
logging.debug("Cancelling failed")
return future._was_stopped
def _createFuture(self):
"""
Return (CancellableFuture): a future that can be used to manage a move
"""
f = CancellableFuture()
f._moving_lock = threading.Lock() # taken while moving
f._must_stop = threading.Event() # cancel of the current future requested
f._was_stopped = False # if cancel was successful
f.task_canceller = self._cancelCurrentMove
return f
@isasync
def moveRel(self, shift):
"""
示例9: Chamber
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
class Chamber(model.Actuator):
"""
Simulated chamber component. Just pretends to be able to change pressure
"""
def __init__(self, name, role, positions, has_pressure=True, **kwargs):
"""
Initialises the component
positions (list of str): each pressure positions supported by the
component (among the allowed ones)
has_pressure (boolean): if True, has a pressure VA with the current
pressure.
"""
# TODO: or just provide .targetPressure (like .targetTemperature) ?
# Or maybe provide .targetPosition: position that would be reached if
# all the requested move were instantly applied?
chp = {}
for p in positions:
try:
chp[PRESSURES[p]] = p
except KeyError:
raise ValueError("Pressure position %s is unknown" % (p,))
axes = {"pressure": model.Axis(unit="Pa", choices=chp)}
model.Actuator.__init__(self, name, role, axes=axes, **kwargs)
# For simulating moves
self._position = PRESSURE_VENTED # last official position
self._goal = PRESSURE_VENTED
self._time_goal = 0 # time the goal was/will be reached
self._time_start = 0 # time the move started
# RO, as to modify it the client must use .moveRel() or .moveAbs()
self.position = model.VigilantAttribute(
{"pressure": self._position},
unit="Pa", readonly=True)
if has_pressure:
# Almost the same as position, but gives the current position
self.pressure = model.VigilantAttribute(self._position,
unit="Pa", readonly=True)
self._press_timer = util.RepeatingTimer(1, self._updatePressure,
"Simulated pressure update")
self._press_timer.start()
else:
self._press_timer = None
# Indicates whether the chamber is opened or not
# Just pretend it's always closed, and allow the user to change that
# for instance via CLI.
self.opened = model.BooleanVA(False)
# will take care of executing axis move asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
def terminate(self):
if self._press_timer:
self._press_timer.cancel()
self._press_timer = None
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None
def _updatePressure(self):
"""
update the pressure VA (called regularly from a thread)
"""
# Compute the current pressure
now = time.time()
if self._time_goal < now: # done
# goal ±5%
pos = self._goal * random.uniform(0.95, 1.05)
else:
# TODO make it logarithmic
ratio = (now - self._time_start) / (self._time_goal - self._time_start)
pos = self._position + (self._goal - self._position) * ratio
# it's read-only, so we change it via _value
self.pressure._value = pos
self.pressure.notify(pos)
def _updatePosition(self):
"""
update the position VA
"""
# .position contains the last known/valid position
# it's read-only, so we change it via _value
self.position._value = {"pressure": self._position}
self.position.notify(self.position.value)
@isasync
def moveRel(self, shift):
self._checkMoveRel(shift)
# convert into an absolute move
pos = {}
for a, v in shift.items:
pos[a] = self.position.value[a] + v
return self.moveAbs(pos)
#.........这里部分代码省略.........
示例10: PowerControlUnit
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
time.sleep(max(0, remaining))
else:
# wait full time
self._last_start[comp] = time.time()
time.sleep(delay)
# Check it really worked
ans = self._sendCommand("PWR? " + str(pin))
if ans != "1":
logging.warning("Failed to turn on component %s", comp)
else:
self._sendCommand("PWR " + str(pin) + " 0")
self._updateSupplied()
def _updateSupplied(self):
"""
update the supplied VA
"""
pins_updated = set(self._pin_map.values()) # to avoid asking for the same pin multiple times
for pin in pins_updated:
ans = self._sendCommand("PWR? " + str(pin))
# Update all components that are connected to the same pin
to_update = [c for c in self.powered if pin == self._pin_map[c]]
for c_update in to_update:
self._supplied[c_update] = (ans == "1")
# it's read-only, so we change it via _value
self.supplied._value = self._supplied
self.supplied.notify(self.supplied.value)
def terminate(self):
if self._executor:
self._executor.cancel()
self._executor.shutdown()
self._executor = None
if self._serial:
with self._ser_access:
self._serial.close()
self._serial = None
if self._file:
self._file.close()
self._file = None
def _getIdentification(self):
return self._sendCommand("*IDN?")
def writeMemory(self, id, address, data):
"""
Write data to EEPROM.
id (str): EEPROM registration number #hex (little-endian format)
address (str): starting address #hex
data (str): data to be written #hex (little-endian format)
"""
self._sendCommand("WMEM %s %s %s" % (id, address, data))
def readMemory(self, id, address, length):
"""
Read data from EEPROM.
id (str): EEPROM registration number #hex (little-endian format)
address (str): starting address #hex
length (int): number of bytes to be read
returns (str): data read back #hex (little-endian format)
"""
示例11: PMTControl
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
class PMTControl(model.PowerSupplier):
'''
This represents the PMT control unit.
At start up the following is set:
* protection is on (=> gain is forced to 0)
* gain = 0
* power up
'''
def __init__(self, name, role, port, prot_time=1e-3, prot_curr=30e-6,
relay_cycle=None, powered=None, **kwargs):
'''
port (str): port name
prot_time (float): protection trip time (in s)
prot_curr (float): protection current threshold (in Amperes)
relay_cycle (None or 0<float): if not None, will power cycle the relay
with the given delay (in s)
powered (list of str or None): set of the HwComponents controlled by the relay
Raise an exception if the device cannot be opened
'''
if powered is None:
powered = []
self.powered = powered
model.PowerSupplier.__init__(self, name, role, **kwargs)
# get protection time (s) and current (A) properties
if not 0 <= prot_time < 1e3:
raise ValueError("prot_time should be a time (in s) but got %s" % (prot_time,))
self._prot_time = prot_time
if not 0 <= prot_curr <= 100e-6:
raise ValueError("prot_curr (%s A) is not between 0 and 100.e-6" % (prot_curr,))
self._prot_curr = prot_curr
# TODO: catch errors and convert to HwError
self._ser_access = threading.Lock()
self._port = self._findDevice(port) # sets ._serial
logging.info("Found PMT Control device on port %s", self._port)
# Get identification of the PMT control device
self._idn = self._getIdentification()
driver_name = driver.getSerialDriver(self._port)
self._swVersion = "serial driver: %s" % (driver_name,)
self._hwVersion = "%s" % (self._idn,)
# Set protection current and time
self._setProtectionCurrent(self._prot_curr)
self._setProtectionTime(self._prot_time)
# gain, powerSupply and protection VAs
self.protection = model.BooleanVA(True, setter=self._setProtection,
getter=self._getProtection)
self._setProtection(True)
gain_rng = (MIN_VOLT, MAX_VOLT)
gain = self._getGain()
self.gain = model.FloatContinuous(gain, gain_rng, unit="V",
setter=self._setGain)
self.powerSupply = model.BooleanVA(True, setter=self._setPowerSupply)
self._setPowerSupply(True)
# will take care of executing supply asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
# relay initialization
if relay_cycle is not None:
logging.info("Power cycling the relay for %f s", relay_cycle)
self.setRelay(False)
time.sleep(relay_cycle)
# Reset if no powered provided
if not powered:
self.setRelay(True)
else:
self._supplied = {}
self.supplied = model.VigilantAttribute(self._supplied, readonly=True)
self._updateSupplied()
def terminate(self):
if self._executor:
self._executor.cancel()
self._executor.shutdown()
self._executor = None
with self._ser_access:
if self._serial:
self._serial.close()
self._serial = None
@isasync
def supply(self, sup):
if not sup:
return model.InstantaneousFuture()
self._checkSupply(sup)
return self._executor.submit(self._doSupply, sup)
def _doSupply(self, sup):
"""
#.........这里部分代码省略.........
示例12: TMCM3110
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
self._swVersion = "%s (serial driver: %s)" % (odemis.__version__, driver_name)
self._hwVersion = "TMCM-%d (firmware %d.%02d)" % (modl, vmaj, vmin)
self.position = model.VigilantAttribute({}, unit="m", readonly=True)
self._updatePosition()
# TODO: add support for changing speed. cf p.68: axis param 4 + p.81 + TMC 429 p.6
self.speed = model.VigilantAttribute({}, unit="m/s", readonly=True)
self._updateSpeed()
if refproc is not None:
# str -> boolean. Indicates whether an axis has already been referenced
axes_ref = dict([(a, False) for a in axes])
self.referenced = model.VigilantAttribute(axes_ref, readonly=True)
if temp:
# One sensor is at the top, one at the bottom of the sample holder.
# The most interesting is the temperature difference, so just
# report both.
self.temperature = model.FloatVA(0, unit=u"°C", readonly=True)
self.temperature1 = model.FloatVA(0, unit=u"°C", readonly=True)
self._temp_timer = util.RepeatingTimer(10, self._updateTemperatureVA,
"TMCM temperature update")
self._updateTemperatureVA() # make sure the temperature is correct
self._temp_timer.start()
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown(wait=True)
self._executor = None
if hasattr(self, "_temp_timer"):
self._temp_timer.cancel()
del self._temp_timer
with self._ser_access:
if self._serial:
self._serial.close()
self._serial = None
def _init_axis(self, axis):
"""
Initialise the given axis with "good" values for our needs (Delphi)
axis (int): axis number
"""
self.SetAxisParam(axis, 4, 1398) # maximum velocity to 1398 == 2 mm/s
self.SetAxisParam(axis, 5, 7) # maximum acc to 7 == 20 mm/s2
self.SetAxisParam(axis, 140, 8) # number of usteps ==2^8 =256 per fullstep
self.SetAxisParam(axis, 6, 15) # maximum RMS-current to 15 == 15/255 x 2.8 = 165mA
self.SetAxisParam(axis, 7, 0) # standby current to 0
self.SetAxisParam(axis, 204, 100) # power off after 100 ms standstill
self.SetAxisParam(axis, 154, 0) # step divider to 0 ==2^0 ==1
self.SetAxisParam(axis, 153, 0) # acc divider to 0 ==2^0 ==1
self.SetAxisParam(axis, 163, 0) # chopper mode
self.SetAxisParam(axis, 162, 2) # Chopper blank time (1 = for low current applications)
self.SetAxisParam(axis, 167, 3) # Chopper off time (2 = minimum)
self.MoveRelPos(axis, 0) # activate parameter with dummy move
if self._refproc == REFPROC_2XFF:
# set up the programs needed for the referencing
# Interrupt: stop the referencing
# The original idea was to mark the current position as 0 ASAP, and then
# later on move back to there. Now, we just stop ASAP, and hope it
示例13: Focus
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
axes_def = {
# Ranges are from the documentation
"z": model.Axis(unit="m", range=(FOCUS_RANGE[0] * 1e-3, FOCUS_RANGE[1] * 1e-3)),
}
model.Actuator.__init__(self, name, role, parent=parent, axes=axes_def, **kwargs)
# will take care of executing axis move asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
# RO, as to modify it the client must use .moveRel() or .moveAbs()
self.position = model.VigilantAttribute({},
unit="m", readonly=True)
self._updatePosition()
# Refresh regularly the position
self._pos_poll = util.RepeatingTimer(5, self._refreshPosition, "Position polling")
self._pos_poll.start()
def _updatePosition(self):
"""
update the position VA
"""
z = self.parent.GetFocus() * 1e-3
self.position._set_value({"z": z}, force_write=True)
def _refreshPosition(self):
"""
Called regularly to update the current position
"""
# We don't use the VA setters, to avoid sending back to the hardware a
# set request
logging.debug("Updating SEM stage position")
try:
self._updatePosition()
except Exception:
logging.exception("Unexpected failure when updating position")
def _doMoveRel(self, foc):
"""
move by foc
foc (float): relative change in mm
"""
try:
foc += self.parent.GetFocus() # mm
self.parent.SetFocus(foc)
finally:
# Update the position, even if the move didn't entirely succeed
self._updatePosition()
def _doMoveAbs(self, foc):
"""
move to pos
foc (float): unit mm
"""
try:
self.parent.SetFocus(foc)
finally:
# Update the position, even if the move didn't entirely succeed
self._updatePosition()
@isasync
def moveRel(self, shift):
"""
shift (dict): shift in m
"""
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(shift)
foc = shift["z"] * 1e3
f = self._executor.submit(self._doMoveRel, foc)
return f
@isasync
def moveAbs(self, pos):
"""
pos (dict): pos in m
"""
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
foc = pos["z"] * 1e3
f = self._executor.submit(self._doMoveAbs, foc)
return f
def stop(self, axes=None):
"""
Stop the last command
"""
# Empty the queue (and already stop the stage if a future is running)
self._executor.cancel()
logging.debug("Stopping all axes: %s", ", ".join(self.axes))
try:
self._updatePosition()
except Exception:
logging.exception("Unexpected failure when updating position")
示例14: SpectraPro
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
#.........这里部分代码省略.........
def _doSetWavelengthAbs(self, pos):
"""
Change the wavelength to a value
"""
with self._ser_access:
self._setCalibratedWavelength(pos)
self._updatePosition()
def _doSetGrating(self, g, wl=None):
"""
Setter for the grating VA.
g (1<=int<=3): the new grating
wl (None or float): wavelength to set afterwards. If None, will put the
same wavelength as before the change of grating.
returns the actual new grating
Warning: synchronous until the grating is finished (up to 20s)
"""
try:
with self._ser_access:
if wl is None:
wl = self.position.value["wavelength"]
self.SetGrating(g)
self._setCalibratedWavelength(wl)
except Exception:
logging.exception("Failed to change grating to %d", g)
raise
self._updatePosition()
def stop(self, axes=None):
"""
stops the motion
Warning: Only not yet-executed moves can be cancelled, this hardware
doesn't support stopping while a move is going on.
"""
self._executor.cancel()
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None
if self._serial:
self._serial.close()
self._serial = None
def getPixelToWavelength(self, npixels, pxs):
"""
Return the lookup table pixel number of the CCD -> wavelength observed.
npixels (1 <= int): number of pixels on the CCD (horizontally), after
binning.
pxs (0 < float): pixel size in m (after binning)
return (list of floats): pixel number -> wavelength in m
"""
centerpixel = (npixels - 1) / 2
cw = self.position.value["wavelength"] # m
gid = self.position.value["grating"]
gl = self._getGrooveDensity(gid)
ca, sa, fl, ia, da = self._calib[gid]
# Formula based on the Winspec documentation:
# "Equations used in WinSpec Wavelength Calibration", p. 257 of the manual
# ftp://ftp.piacton.com/Public/Manuals/Princeton%20Instruments/WinSpec%202.6%20Spectroscopy%20Software%20User%20Manual.pdf
# Converted to code by Benjamin Brenny (from AMOLF)
示例15: EbeamFocus
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import cancel [as 别名]
class EbeamFocus(model.Actuator):
"""
This is an extension of the model.Actuator class. It provides functions for
adjusting the ebeam focus by changing the working distance i.e. the distance
between the end of the objective and the surface of the observed specimen
"""
def __init__(self, name, role, parent, axes, ranges=None, **kwargs):
assert len(axes) > 0
if ranges is None:
ranges = {}
axes_def = {}
self._position = {}
# Just z axis
a = axes[0]
# The maximum, obviously, is not 1 meter. We do not actually care
# about the range since Tescan API will adjust the value set if the
# required one is out of limits.
rng = [0, 1]
axes_def[a] = model.Axis(unit="m", range=rng)
# start at the centre
self._position[a] = parent._device.GetWD() * 1e-3
model.Actuator.__init__(self, name, role, parent=parent, axes=axes_def, **kwargs)
# RO, as to modify it the client must use .moveRel() or .moveAbs()
self.position = model.VigilantAttribute(
self._applyInversionAbs(self._position),
unit="m", readonly=True)
# will take care of executing axis move asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
def _updatePosition(self):
"""
update the position VA
"""
# it's read-only, so we change it via _value
self.position._value = self._applyInversionAbs(self._position)
self.position.notify(self.position.value)
def _doMove(self, pos):
"""
move to the position
"""
# Perform move through Tescan API
# Position from m to mm and inverted
self.parent._device.SetWD(self._position["z"] * 1e03)
# Obtain the finally reached position after move is performed.
with self.parent._acquisition_init_lock:
wd = self.parent._device.GetWD()
self._position["z"] = wd * 1e-3
# Changing WD results to change in fov
self.parent._scanner.updateHorizontalFOV()
self._updatePosition()
@isasync
def moveRel(self, shift):
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(shift)
shift = self._applyInversionRel(shift)
for axis, change in shift.items():
self._position[axis] += change
pos = self._position
return self._executor.submit(self._doMove, pos)
@isasync
def moveAbs(self, pos):
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
pos = self._applyInversionAbs(pos)
for axis, new_pos in pos.items():
self._position[axis] = new_pos
pos = self._position
return self._executor.submit(self._doMove, pos)
def stop(self, axes=None):
# Empty the queue for the given axes
self._executor.cancel()
logging.warning("Stopping all axes: %s", ", ".join(self.axes))
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None