Skip to content

Commit a4b631f

Browse files
zaberstage: Refactor zaber stage code into modern driver layout, add a mock class.
Prepare for implementing actual device interaction using new zaber API.
1 parent d1a0b99 commit a4b631f

File tree

8 files changed

+318
-205
lines changed

8 files changed

+318
-205
lines changed

β€ŽZaberStageController.pyβ€Ž

Lines changed: 0 additions & 205 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#####################################################################
2+
# #
3+
# /labscript_devices/ZaberStageController/__init__.py #
4+
# #
5+
# Copyright 2019, Monash University and contributors #
6+
# #
7+
# This file is part of labscript_devices, in the labscript suite #
8+
# (see http://labscriptsuite.org), and is licensed under the #
9+
# Simplified BSD License. See the license.txt file in the root of #
10+
# the project for the full license. #
11+
# #
12+
#####################################################################
13+
14+
#TODO: check Python version high enough for zaber API
15+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#####################################################################
2+
# #
3+
# /labscript_devices/ZaberStageController/blacs_tabs.py #
4+
# #
5+
# Copyright 2019, Monash University and contributors #
6+
# #
7+
# This file is part of labscript_devices, in the labscript suite #
8+
# (see http://labscriptsuite.org), and is licensed under the #
9+
# Simplified BSD License. See the license.txt file in the root of #
10+
# the project for the full license. #
11+
# #
12+
#####################################################################
13+
14+
from blacs.device_base_class import DeviceTab
15+
from .utils import get_stage_number
16+
17+
class ZaberStageControllerTab(DeviceTab):
18+
def initialise_GUI(self):
19+
# Capabilities
20+
self.base_units = 'steps'
21+
self.base_min = 0
22+
self.base_step = 100
23+
self.base_decimals = 0
24+
25+
device = self.settings['connection_table'].find_by_name(self.device_name)
26+
self.com_port = device.BLACS_connection
27+
self.mock = device.properties['mock']
28+
29+
# Create the AO output objects
30+
ao_prop = {}
31+
for stage in device.child_list.values():
32+
connection = stage.parent_port
33+
base_min, base_max = stage.properties['limits']
34+
ao_prop[connection] = {
35+
'base_unit': self.base_units,
36+
'min': base_min,
37+
'max': base_max,
38+
'step': self.base_step,
39+
'decimals': self.base_decimals,
40+
}
41+
# Sort by stage number:
42+
ao_prop = {c: ao_prop[c] for c in sorted(ao_prop, key=get_stage_number)}
43+
# Create the output objects
44+
self.create_analog_outputs(ao_prop)
45+
# Create widgets for output objects
46+
_, ao_widgets, _ = self.auto_create_widgets()
47+
# and auto place the widgets in the UI
48+
self.auto_place_widgets(("Zaber Stages", ao_widgets))
49+
50+
# Set the capabilities of this device
51+
self.supports_remote_value_check(False) # TODO: Implement this if supported by hardware
52+
self.supports_smart_programming(False) #TODO: Implement smart programming
53+
54+
def initialise_workers(self):
55+
# Create and set the primary worker
56+
self.create_worker(
57+
"main_worker",
58+
"labscript_devices.ZaberStageController.blacs_workers.ZaberWorker",
59+
{'com_port': self.com_port, 'mock': self.mock},
60+
)
61+
self.primary_worker = "main_worker"
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#####################################################################
2+
# #
3+
# /labscript_devices/ZaberStageController/blacs_workers.py #
4+
# #
5+
# Copyright 2019, Monash University and contributors #
6+
# #
7+
# This file is part of labscript_devices, in the labscript suite #
8+
# (see http://labscriptsuite.org), and is licensed under the #
9+
# Simplified BSD License. See the license.txt file in the root of #
10+
# the project for the full license. #
11+
# #
12+
#####################################################################
13+
14+
from blacs.tab_base_classes import Worker
15+
from labscript_utils import dedent
16+
import labscript_utils.h5_lock, h5py
17+
18+
from .utils import get_stage_number
19+
20+
class MockZaberInterface(object):
21+
def __init__(self, port):
22+
pass
23+
24+
def move(self, stage_number, position):
25+
print(f"Mock move stage {stage_number} to position {position}")
26+
27+
def close(self):
28+
print(f"mock close")
29+
30+
31+
zaber = None
32+
33+
class ZaberInterface(object):
34+
def __init__(self, com_port):
35+
global zaber
36+
try:
37+
import zaber.serial as zaber
38+
except ImportError:
39+
msg = """Could not import zaber.serial module. Please ensure it is
40+
installed. It is installable via pip with 'pip install zaber.serial'"""
41+
raise ImportError(dedent(msg))
42+
43+
self.port = zaber.AsciiSerial(com_port)
44+
45+
def move(self, stage_number, position):
46+
pass
47+
48+
def close(self):
49+
pass
50+
51+
52+
53+
class ZaberWorker(Worker):
54+
def init(self):
55+
if self.mock:
56+
self.controller = MockZaberInterface(self.com_port)
57+
else:
58+
self.controller = ZaberInterface(self.com_port)
59+
60+
def program_manual(self, values):
61+
#print "***************programming static*******************"
62+
#self.stages.move_absolute(settings)
63+
for connection, value in values.items():
64+
stage_number = get_stage_number(connection)
65+
self.controller.move(stage_number, value)
66+
67+
#TODO: return actual position of the zaber stage. Are they readable? Check API
68+
return values
69+
70+
# TODO: home stage function?
71+
72+
def transition_to_buffered(self, device_name, h5file, initial_values, fresh):
73+
with h5py.File(h5file) as hdf5_file:
74+
group = hdf5_file['/devices/' + device_name]
75+
if 'static_values' in group:
76+
data = group['static_values']
77+
values = {name: data[0][name] for name in data.dtype.names}
78+
else:
79+
values = {}
80+
81+
return self.program_manual(values)
82+
83+
def transition_to_manual(self):
84+
return True
85+
86+
def abort_buffered(self):
87+
return True
88+
89+
def abort_transition_to_buffered(self):
90+
return True
91+
92+
def shutdown(self):
93+
self.controller.close()

0 commit comments

Comments
Β (0)