2525device(microscope.filterwheels.aurox.Clarity,
2626 {'camera': 'microscope.Cameras.cameramodule.SomeCamera',
2727 'camera.someSetting': value})
28+
29+ Deconvolving data requires:
30+ * availability of clarity_process and cv2
31+ * successful completion of a calibration step
32+ + set_mode(Modes.calibrate)
33+ + trigger the camera to generate an image
34+ + when the camera returns the image, calibration is complete
2835"""
2936import functools
3037import hid
3138import logging
3239import microscope .devices
3340import typing
34- from enum import Enum
41+ from enum import IntEnum
3542
3643_logger = logging .getLogger (__name__ )
3744
45+ Mode = IntEnum ("Mode" , "difference, raw, calibrate" )
46+
3847## Clarity constants. These may differ across products, so mangle names.
3948# USB IDs
4049_Clarity__VENDORID = 0x1F0A
@@ -97,6 +106,7 @@ class Clarity(microscope.devices.ControllerDevice, microscope.devices.FilterWhee
97106 __GETSERIAL : 4 ,
98107 __FULLSTAT : 10 }
99108
109+
100110 def __init__ (self , camera = None , ** kwargs ) -> None :
101111 # Extract kwargs for camera device.
102112 cam_kw_keys = [k for k in kwargs if k .startswith ("camera." )]
@@ -121,20 +131,43 @@ def __init__(self, camera=None, **kwargs) -> None:
121131 except :
122132 _logger .warn ("Could not import clarity_process module: no processing available." )
123133 self ._processor = None
134+ self ._mode = Mode .raw
124135 self .add_setting ("sectioning" , "enum" ,
125136 self .get_slide_position ,
126137 lambda val : self .set_slide_position (val ),
127138 self ._slide_to_sectioning )
139+ self .add_setting ("mode" , "enum" ,
140+ lambda : self ._mode ,
141+ self .set_mode ,
142+ Mode )
128143
129144 def _c_process_data (self , data ):
130- # TODO
131- _logger .info ("Clarity processed data." )
132- return data
145+ if self ._mode == Mode .raw :
146+ return data
147+ elif self ._mode == Mode .difference :
148+ if self ._processor is None :
149+ raise Exception ("Not calibrated yet - can not process image" )
150+ return self ._processor .process (data )
151+ elif self ._mode == Mode .calibrate :
152+ # This will introduce a significant delay, but returning the
153+ # image indicates that the calibration step is complete.
154+ self ._processor = clarity_process .ClarityProcessor (data )
155+ return data
156+ else :
157+ raise Exception ("Unrecognised mode: %s" , self ._mode )
133158
134159 @property
135160 def devices (self ) -> typing .Mapping [str , microscope .devices .Device ]:
136161 return self ._devices
137162
163+ def set_mode (self , mode : Mode ) -> None :
164+ """Set the operation mode"""
165+ if mode == Mode .calibrate :
166+ self ._set_calibration (True )
167+ else :
168+ self ._set_calibration (False )
169+ self ._mode = mode
170+
138171 def _send_command (self , command , param = 0 , max_length = 16 , timeout_ms = 100 ):
139172 """Send a command to the Clarity and return its response"""
140173 if not self ._hid :
@@ -200,7 +233,9 @@ def _on_enable(self):
200233 def _on_disable (self ):
201234 self ._send_command (__SETONOFF , __SLEEP )
202235
203- def set_calibration (self , state ):
236+ 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.
204239 if state :
205240 result = self ._send_command (__SETCAL , __CALON )
206241 else :
0 commit comments