Skip to content

Commit 3cd6bd5

Browse files
committed
Changes to enable client to start calibration.
1 parent 01b9394 commit 3cd6bd5

File tree

1 file changed

+35
-19
lines changed

1 file changed

+35
-19
lines changed

microscope/filterwheels/aurox.py

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@
3333
+ trigger the camera to generate an image
3434
+ when the camera returns the image, calibration is complete
3535
"""
36-
import functools
3736
import hid
3837
import logging
3938
import microscope.devices
40-
import typing
39+
from typing import Mapping
4140
from enum import IntEnum
4241

4342
_logger = logging.getLogger(__name__)
@@ -116,32 +115,42 @@ def __init__(self, camera=None, **kwargs) -> None:
116115
del kwargs[key]
117116
super().__init__(**kwargs)
118117
from threading import Lock
118+
# A comms lock.
119119
self._lock = Lock()
120+
# The hid connection object
120121
self._hid = None
121-
self._devices = {}
122122
if camera is None:
123123
self._cam = None
124-
_logger.warn("No camera specified.")
124+
_logger.warning("No camera specified.")
125125
else:
126126
self._cam = camera(**cam_kwargs)
127127
self._cam.pipeline.append(self._c_process_data)
128-
self._devices['camera'] = self._cam
128+
# Is processing available?
129+
self._can_process = False
129130
try:
130131
from clarity_process import ClarityProcessor
132+
self._can_process = True
131133
except:
132-
_logger.warn("Could not import clarity_process module: no processing available.")
134+
_logger.warning("Could not import clarity_process module: no processing available.")
135+
# Data processor object, created after calibration
133136
self._processor = None
137+
# Acquisition mode
134138
self._mode = Mode.raw
139+
# Add device settings
135140
self.add_setting("sectioning", "enum",
136141
self.get_slide_position,
137142
lambda val: self.set_slide_position(val),
138143
self._slide_to_sectioning)
139144
self.add_setting("mode", "enum",
140-
lambda: self._mode,
145+
lambda: self._mode.name,
141146
self.set_mode,
142147
Mode)
143148

144149
def _c_process_data(self, data):
150+
"""A function to insert into the camera's processing pipeline.
151+
152+
Depending on the mode, this function will pass through, perform
153+
calibration, or deconvolve the camera data."""
145154
if self._mode == Mode.raw:
146155
return data
147156
elif self._mode == Mode.difference:
@@ -157,11 +166,14 @@ def _c_process_data(self, data):
157166
raise Exception("Unrecognised mode: %s", self._mode)
158167

159168
@property
160-
def devices(self) -> typing.Mapping[str, microscope.devices.Device]:
161-
return self._devices
169+
def devices(self) -> Mapping[str, microscope.devices.Device]:
170+
"""Devices property, required by ControllerDevice interface."""
171+
return {'camera': self._cam}
162172

163173
def set_mode(self, mode: Mode) -> None:
164174
"""Set the operation mode"""
175+
if mode in [Mode.calibrate, Mode.difference] and not self._can_process:
176+
raise Exception ("Processing not available")
165177
if mode == Mode.calibrate:
166178
self._set_calibration(True)
167179
else:
@@ -171,7 +183,10 @@ def set_mode(self, mode: Mode) -> None:
171183
def _send_command(self, command, param=0, max_length=16, timeout_ms=100):
172184
"""Send a command to the Clarity and return its response"""
173185
if not self._hid:
174-
self.open()
186+
try:
187+
self.open()
188+
except:
189+
raise Exception("Connection error")
175190
with self._lock:
176191
# The device expects a list of 16 integers
177192
buffer = [0x00] * max_length # The 0th element must be 0.
@@ -225,17 +240,13 @@ def get_id(self):
225240
return self._send_command(__GETSERIAL)
226241

227242
def _on_enable(self):
228-
if not self.is_connected:
229-
self.open()
230243
self._send_command(__SETONOFF, __RUN)
231244
return self._send_command(__GETONOFF) == __RUN
232245

233246
def _on_disable(self):
234247
self._send_command(__SETONOFF, __SLEEP)
235248

236249
def _set_calibration(self, state):
237-
# TODO: cockpit will need changes for new calibration method and to
238-
# remove references to set_calibration, which is now a private method.
239250
if state:
240251
result = self._send_command(__SETCAL, __CALON)
241252
else:
@@ -262,12 +273,17 @@ def get_slides(self):
262273
return (self._slide_to_sectioning)
263274

264275
def get_status(self):
265-
# Fetch 10 bytes VERSION[3],ONOFF,SHUTTER,SLIDE,FILT,CAL,??,??
266-
result = self._send_command(__FULLSTAT)
267-
if result is None:
268-
return
269276
# A status dict to populate and return
270-
status = {}
277+
status = dict.fromkeys(['connected','on','door open','slide',
278+
'filter','calibration','busy', 'mode'])
279+
status['mode'] = self._mode.name
280+
# Fetch 10 bytes VERSION[3],ONOFF,SHUTTER,SLIDE,FILT,CAL,??,??
281+
try:
282+
result = self._send_command(__FULLSTAT)
283+
status['connected'] = True
284+
except:
285+
status['connected'] = False
286+
return status
271287
# A list to track states, any one of which mean the device is busy.
272288
busy = []
273289
# Disk running

0 commit comments

Comments
 (0)