本文整理汇总了Python中odemis.model.CancellableThreadPoolExecutor.submit方法的典型用法代码示例。如果您正苦于以下问题:Python CancellableThreadPoolExecutor.submit方法的具体用法?Python CancellableThreadPoolExecutor.submit怎么用?Python CancellableThreadPoolExecutor.submit使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类odemis.model.CancellableThreadPoolExecutor
的用法示例。
在下文中一共展示了CancellableThreadPoolExecutor.submit方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: SpectraPro
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
#.........这里部分代码省略.........
# conversion (for displaying in .position)
self._wl = (gid, self.GetWavelength(), wl)
# high-level methods (interface)
def _updatePosition(self):
"""
update the position VA
Note: it should not be called while holding _ser_access
"""
with self._ser_access:
pos = {"wavelength": self._getCalibratedWavelength(),
"grating": self.GetGrating()
}
# it's read-only, so we change it via _value
self.position._value = pos
self.position.notify(self.position.value)
@isasync
def moveRel(self, shift):
"""
Move the stage the defined values in m for each axis given.
shift dict(string-> float): name of the axis and shift in m
returns (Future): future that control the asynchronous move
"""
self._checkMoveRel(shift)
for axis in shift:
if axis == "wavelength":
# cannot convert it directly to an absolute move, because
# several in a row must mean they accumulate. So we queue a
# special task. That also means the range check is delayed until
# the actual position is known.
return self._executor.submit(self._doSetWavelengthRel, shift[axis])
@isasync
def moveAbs(self, pos):
"""
Move the stage the defined values in m for each axis given.
pos dict(string-> float): name of the axis and new position in m
returns (Future): future that control the asynchronous move
"""
self._checkMoveAbs(pos)
# If grating needs to be changed, change it first, then the wavelength
if "grating" in pos:
g = pos["grating"]
wl = pos.get("wavelength")
return self._executor.submit(self._doSetGrating, g, wl)
elif "wavelength" in pos:
wl = pos["wavelength"]
return self._executor.submit(self._doSetWavelengthAbs, wl)
else: # nothing to do
return model.InstantaneousFuture()
def _doSetWavelengthRel(self, shift):
"""
Change the wavelength by a value
"""
with self._ser_access:
pos = self.position.value["wavelength"] + shift
# it's only now that we can check the absolute position is wrong
minp, maxp = self.axes["wavelength"].range
if not minp <= pos <= maxp:
raise ValueError("Position %f of axis '%s' not within range %f→%f" %
(pos, "wavelength", minp, maxp))
示例2: FW102c
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
#.........这里部分代码省略.........
finally:
self._serial.timeout = prev_timeout
logging.debug("Move to pos %d finished", pos)
# What we don't need:
# speed?\r1\r>
# trig?\r0\r>
# sensors?\r0\r>
def _doMoveBand(self, pos):
"""
move to the position and updates the metadata and position once it's over
"""
self.SetPosition(pos)
self._updatePosition()
# high-level methods (interface)
def _updatePosition(self):
"""
update the position VA
Note: it should not be called while holding _ser_access
"""
pos = {"band": self.GetPosition()}
# it's read-only, so we change it via _value
self.position._value = pos
self.position.notify(self.position.value)
@isasync
def moveRel(self, shift):
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(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)
return self._executor.submit(self._doMoveBand, pos["band"])
def stop(self, axes=None):
self._executor.cancel()
def selfTest(self):
"""
check as much as possible that it works without actually moving the motor
return (boolean): False if it detects any problem
"""
try:
pos = self.GetPosition()
maxpos = self.GetMaxPosition()
if 1 <= pos <= maxpos:
return True
except Exception:
logging.exception("Selftest failed")
return False
@classmethod
def scan(cls, port=None):
"""
port (string): name of the serial port. If None, all the serial ports are tried
returns (list of 2-tuple): name, args (port)
Note: it's obviously not advised to call this function if a device is already under use
"""
if port:
ports = [port]
else:
if os.name == "nt":
ports = ["COM" + str(n) for n in range(15)]
else:
ports = glob.glob('/dev/ttyS?*') + glob.glob('/dev/ttyUSB?*')
logging.info("Serial ports scanning for Thorlabs filter wheel in progress...")
found = [] # (list of 2-tuple): name, kwargs
for p in ports:
try:
logging.debug("Trying port %s", p)
dev = cls(None, None, p, bands=None, _scan=True)
except (serial.SerialException, IOError):
# not possible to use this port? next one!
continue
# Get some more info
try:
maxpos = dev.GetMaxPosition()
except Exception:
continue
else:
# create fake band argument
bands = {}
for i in range(1, maxpos + 1):
bands[i] = (i * 100e-9, (i + 1) * 100e-9)
found.append((dev._idn, {"port": p, "bands": bands}))
return found
示例3: MFF
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
#.........这里部分代码省略.........
timeout (0 < float): maximum time to wait for the end of the motion
"""
start = time.time()
# 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)
示例4: DPSS
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [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()
#.........这里部分代码省略.........
示例5: MultiplexActuator
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
#.........这里部分代码省略.........
def _moveToChildMove(self, mv):
child_to_move = collections.defaultdict(dict) # child -> moveRel argument
for axis, distance in mv.items():
child, child_axis = self._axis_to_child[axis]
child_to_move[child].update({child_axis: distance})
logging.debug("Moving axis %s (-> %s) by %g", axis, child_axis, distance)
return child_to_move
def _axesToChildAxes(self, axes):
child_to_axes = collections.defaultdict(set) # child -> set(str): axes
for axis in axes:
child, child_axis = self._axis_to_child[axis]
child_to_axes[child].add(child_axis)
logging.debug("Interpreting axis %s (-> %s)", axis, child_to_axes)
return child_to_axes
@isasync
def moveRel(self, shift, **kwargs):
"""
Move the stage the defined values in m for each axis given.
shift dict(string-> float): name of the axis and shift in m
**kwargs: Mostly there to support "update" argument (but currently works
only if there is only one child)
"""
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(shift)
shift = self._applyInversion(shift)
if self._executor:
f = self._executor.submit(self._doMoveRel, shift, **kwargs)
else:
cmv = self._moveToChildMove(shift)
child, move = cmv.popitem()
assert not cmv
f = child.moveRel(move, **kwargs)
return f
def _doMoveRel(self, shift, **kwargs):
# TODO: updates don't work because we still wait for the end of the
# 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:
示例6: FixedPositionsActuator
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
#.........这里部分代码省略.........
real_pos = self._position[self._axis]
nearest = util.find_closest(real_pos, self._positions.keys())
if not util.almost_equal(real_pos, nearest):
logging.warning("Reporting axis %s @ %s (known position), while physical axis %s @ %s",
self._axis, nearest, self._caxis, real_pos)
pos = {self._axis: nearest}
logging.debug("reporting position %s", pos)
self.position._set_value(pos, force_write=True)
def _updateReferenced(self):
"""
update the referenced VA
"""
# .referenced is copied to detect changes to it on next update
self.referenced._set_value(self._referenced.copy(), force_write=True)
@isasync
def moveRel(self, shift):
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(shift)
raise NotImplementedError("Relative move on fixed positions axis not supported")
@isasync
def moveAbs(self, pos):
"""
Move the actuator to the defined position in m for each axis given.
pos dict(string-> float): name of the axis and position in m
"""
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
pos = self._applyInversion(pos)
f = self._executor.submit(self._doMoveAbs, pos)
return f
def _doMoveAbs(self, pos):
axis, distance = pos.items()[0]
logging.debug("Moving axis %s (-> %s) to %g", self._axis, self._caxis, distance)
if self._cycle is None:
move = {self._caxis: distance}
self._child.moveAbs(move).result()
else:
# Optimize by moving through the closest way
cur_pos = self._child.position.value[self._caxis]
vector1 = distance - cur_pos
mod1 = vector1 % self._cycle
vector2 = cur_pos - distance
mod2 = vector2 % self._cycle
if abs(mod1) < abs(mod2):
self._move_sum += mod1
if self._move_sum >= self._cycle:
# Once we are about to complete a full cycle, reference again
# to get rid of accumulated error
self._move_sum = 0
# move to the reference switch
move_to_ref = (self._cycle - cur_pos) % self._cycle + self._offset
self._child.moveRel({self._caxis: move_to_ref}).result()
self._child.reference({self._caxis}).result()
move = {self._caxis: distance}
else:
move = {self._caxis: mod1}
else:
move = {self._caxis:-mod2}
示例7: ChamberPressure
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
class ChamberPressure(model.Actuator):
"""
This is an extension of the model.Actuator class. It provides functions for
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()
#.........这里部分代码省略.........
示例8: CoupledStage
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [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
示例9: Stage
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
class Stage(model.Actuator):
"""
This is an extension of the model.Actuator class. It provides functions for
moving the Tescan stage and updating the position.
"""
def __init__(self, name, role, parent, **kwargs):
"""
axes (set of string): names of the axes
"""
axes_def = {}
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)
#.........这里部分代码省略.........
示例10: EbeamFocus
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [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
示例11: PowerControlUnit
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
class PowerControlUnit(model.PowerSupplier):
'''
Implements the PowerSupplier class to regulate the power supply of the
components connected to the Power Control Unit board. It also takes care of
communication with the PCU firmware.
'''
def __init__(self, name, role, port, pin_map=None, delay=None, init=None, ids=None, **kwargs):
'''
port (str): port name
pin_map (dict of str -> int): names of the components
and the pin where the component is connected.
delay (dict str -> float): time to wait for each component after it is
turned on.
init (dict str -> boolean): turn on/off the corresponding component upon
initialization.
ids (list str): EEPROM ids expected to be detected during initialization.
Raise an exception if the device cannot be opened
'''
if pin_map:
self.powered = pin_map.keys()
else:
self.powered = []
model.PowerSupplier.__init__(self, name, role, **kwargs)
# TODO: catch errors and convert to HwError
self._ser_access = threading.Lock()
self._file = None
self._port = self._findDevice(port) # sets ._serial and ._file
logging.info("Found Power Control device on port %s", self._port)
# Get identification of the Power control device
self._idn = self._getIdentification()
driver_name = driver.getSerialDriver(self._port)
self._swVersion = "serial driver: %s" % (driver_name,)
self._hwVersion = "%s" % (self._idn,)
pin_map = pin_map or {}
self._pin_map = pin_map
delay = delay or {}
# fill the missing pairs with 0 values
self._delay = dict.fromkeys(pin_map, 0)
self._delay.update(delay)
self._last_start = dict.fromkeys(self._delay, time.time())
# will take care of executing switch asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
self._supplied = {}
self.supplied = model.VigilantAttribute(self._supplied, readonly=True)
self._updateSupplied()
init = init or {}
# Remove all None's from the dict, so it can be passed as-is to _doSupply()
for k, v in init.items():
if v is None:
del init[k]
try:
self._doSupply(init, apply_delay=False)
except IOError as ex:
# This is in particular to handle some cases where the device resets
# when turning on the power. One or more trials and the
logging.exception("Failure during turning on initial power.")
raise HwError("Device error when initialising power: %s. "
"Try again or contact support if the problem persists." %
(ex,))
self.memoryIDs = model.VigilantAttribute(None, readonly=True, getter=self._getIdentities)
if ids:
mem_ids = self.memoryIDs.value
for eid in ids:
if eid not in mem_ids:
raise HwError("EEPROM id %s was not detected. Make sure "
"all EEPROM components are connected." % (eid,))
@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, apply_delay=True):
"""
supply power
apply_delay (bool): If true, wait the amount of time requested in delay
after turning on the power
"""
for comp, val in sup.items():
#.........这里部分代码省略.........
示例12: PMTControl
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [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):
"""
#.........这里部分代码省略.........
示例13: TMCM3110
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
#.........这里部分代码省略.........
self.temperature._value = t0
self.temperature.notify(t0)
self.temperature1._value = t1
self.temperature1.notify(t1)
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._applyInversionRel(shift)
# Check if the distance is big enough to make sense
for an, v in shift.items():
aid = self._axes_names.index(an)
if abs(v) < self._ustepsize[aid]:
# TODO: store and accumulate all the small moves instead of dropping them?
del shift[an]
logging.info("Dropped too small move of %f m", abs(v))
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._applyInversionRel(pos)
f = self._createFuture()
f = self._executor.submitf(f, self._doMoveAbs, f, pos)
return f
moveAbs.__doc__ = model.Actuator.moveAbs.__doc__
@isasync
def reference(self, axes):
if not axes:
return model.InstantaneousFuture()
self._checkReference(axes)
f = self._executor.submit(self._doReference, axes)
return f
reference.__doc__ = model.Actuator.reference.__doc__
def stop(self, axes=None):
self._executor.cancel()
def _doMoveRel(self, future, pos):
"""
Blocking and cancellable relative move
future (Future): the future it handles
pos (dict str -> float): axis name -> relative target position
示例14: Focus
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
class Focus(model.Actuator):
"""
This is an extension of the model.Actuator class. It provides functions for
moving the SEM focus (as it's considered an axis in Odemis)
"""
def __init__(self, name, role, parent, **kwargs):
"""
axes (set of string): names of the axes
"""
self.parent = parent
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
#.........这里部分代码省略.........
示例15: AntiBacklashActuator
# 需要导入模块: from odemis.model import CancellableThreadPoolExecutor [as 别名]
# 或者: from odemis.model.CancellableThreadPoolExecutor import submit [as 别名]
#.........这里部分代码省略.........
self._child = children.values()[0]
self._backlash = backlash
axes_def = self._child.axes
# look for axes in backlash not existing in the child
missing = set(backlash.keys()) - set(axes_def.keys())
if missing:
raise ValueError("Child actuator doesn't have the axes %s", missing)
model.Actuator.__init__(self, name, role, axes=axes_def,
children=children, **kwargs)
# will take care of executing axis moves asynchronously
self._executor = CancellableThreadPoolExecutor(max_workers=1) # one task at a time
# Duplicate VAs which are just identical
# TODO: shall we "hide" the antibacklash move by not updating position
# while doing this move?
self.position = self._child.position
if (hasattr(self._child, "referenced") and
isinstance(self._child.referenced, model.VigilantAttributeBase)):
self.referenced = self._child.referenced
if (hasattr(self._child, "speed") and
isinstance(self._child.speed, model.VigilantAttributeBase)):
self.speed = self._child.speed
def terminate(self):
if self._executor:
self.stop()
self._executor.shutdown()
self._executor = None
def _doMoveRel(self, shift):
# move with the backlash subtracted
sub_shift = {}
sub_backlash = {} # same as backlash but only contains the axes moved
for a, v in shift.items():
if a not in self._backlash:
sub_shift[a] = v
else:
# optimisation: if move goes in the same direction as backlash
# correction, then no need to do the correction
# TODO: only do this if backlash correction has already been applied once?
if v * self._backlash[a] >= 0:
sub_shift[a] = v
else:
sub_shift[a] = v - self._backlash[a]
sub_backlash[a] = self._backlash[a]
f = self._child.moveRel(sub_shift)
f.result()
# backlash move
f = self._child.moveRel(sub_backlash)
f.result()
def _doMoveAbs(self, pos):
sub_pos = {}
fpos = {} # same as pos but only contains the axes moved due to backlash
for a, v in pos.items():
if a not in self._backlash:
sub_pos[a] = v
else:
shift = v - self.position.value[a]
if shift * self._backlash[a] >= 0:
sub_pos[a] = v
else:
sub_pos[a] = v - self._backlash[a]
fpos[a] = pos[a]
f = self._child.moveAbs(sub_pos)
f.result()
# backlash move
f = self._child.moveAbs(fpos)
return f
@isasync
def moveRel(self, shift):
if not shift:
return model.InstantaneousFuture()
self._checkMoveRel(shift)
return self._executor.submit(self._doMoveRel, shift)
@isasync
def moveAbs(self, pos):
if not pos:
return model.InstantaneousFuture()
self._checkMoveAbs(pos)
return self._executor.submit(self._doMoveAbs, pos)
def stop(self, axes=None):
self._child.stop()
@isasync
def reference(self, axes):
f = self._child.reference(axes)
return f