BioImager  4.9.0
A .NET microscopy imaging application based on Bio library. Supports various microscopes by using imported libraries & GUI automation. Supports XInput game controllers to move stage, take images, run ImageJ macros on images or Bio C# scripts.
Loading...
Searching...
No Matches
devices.py
1#!/usr/bin/env python3
2
3
20
21import logging
22import time
23from enum import IntEnum
24
25import microscope.abc
26
27# These classes were originally in testsuite but have been moved to
28# their own subpackage, these imports are for backwards compatibility.
29from microscope.simulators import (
30 SimulatedCamera,
31 SimulatedController as TestController,
32 SimulatedDeformableMirror as TestDeformableMirror,
33 SimulatedFilterWheel as TestFilterWheel,
34 SimulatedLightSource,
35 SimulatedStage as TestStage,
36)
37
38
39_logger = logging.getLogger(__name__)
40
41
42class CamEnum(IntEnum):
43 A = 1
44 B = 2
45 C = 3
46 D = 4
47
48
50 # This adds a series of weird settings to the base simulated
51 # camera which are only useful to test settings in cockpit.
52 def __init__(self, **kwargs) -> None:
53 super().__init__(**kwargs)
54 # Enum-setting tests
55 self._intEnum = CamEnum.A
56 self.add_setting(
57 "intEnum",
58 "enum",
59 lambda: self._intEnum,
60 lambda val: setattr(self, "_intEnum", val),
61 CamEnum,
62 )
63 self._dictEnum = 0
64 self.add_setting(
65 "dictEnum",
66 "enum",
67 lambda: self._dictEnum,
68 lambda val: setattr(self, "_dictEnum", val),
69 {0: "A", 8: "B", 13: "C", 22: "D"},
70 )
71 self._listEnum = 0
72 self.add_setting(
73 "listEnum",
74 "enum",
75 lambda: self._listEnum,
76 lambda val: setattr(self, "_listEnum", val),
77 ["A", "B", "C", "D"],
78 )
79 self._tupleEnum = 0
80 self.add_setting(
81 "tupleEnum",
82 "enum",
83 lambda: self._tupleEnum,
84 lambda val: setattr(self, "_tupleEnum", val),
85 ("A", "B", "C", "D"),
86 )
87
88
90 # Deprecated, kept for backwards compatibility.
91 pass
92
93
94class DummySLM(microscope.abc.Device):
95 # This only exists to test cockpit. There is no corresponding
96 # device type in microscope yet.
97 def __init__(self, **kwargs):
98 super().__init__(**kwargs)
99 self.sim_diffraction_angle = 0.0
100 self.sequence_params = []
101 self.sequence_index = 0
102
103 def _do_shutdown(self) -> None:
104 pass
105
106 def set_sim_diffraction_angle(self, theta):
107 _logger.info("set_sim_diffraction_angle %f", theta)
108 self.sim_diffraction_angle = theta
109
110 def get_sim_diffraction_angle(self):
111 return self.sim_diffraction_angle
112
113 def run(self):
114 self.enabled = True
115 _logger.info("run")
116 return
117
118 def stop(self):
119 self.enabled = False
120 _logger.info("stop")
121 return
122
123 def get_sim_sequence(self):
124 return self.sequence_params
125
126 def set_sim_sequence(self, seq):
127 _logger.info("set_sim_sequence")
128 self.sequence_params = seq
129 return
130
131 def get_sequence_index(self):
132 return self.sequence_index
133
134
136 # This only exists to test cockpit. There is no corresponding
137 # device type in microscope yet.
138 def __init__(self, **kwargs):
139 super().__init__(**kwargs)
140 self._digi = 0
141 self._ana = [0, 0, 0, 0]
142 self._client = None
143 self._actions = []
144
145 def _do_shutdown(self) -> None:
146 pass
147
148 def Abort(self):
149 _logger.info("Abort")
150
151 def WriteDigital(self, value):
152 _logger.info("WriteDigital: %s", bin(value))
153 self._digi = value
154
155 def MoveAbsolute(self, aline, pos):
156 _logger.info("MoveAbsoluteADU: line %d, value %d", aline, pos)
157 self._ana[aline] = pos
158
159 def arcl(self, mask, pairs):
160 _logger.info("arcl: %s, %s", mask, pairs)
161
162 def profileSet(self, pstr, digitals, *analogs):
163 _logger.info("profileSet ...")
164 _logger.info("... ", pstr)
165 _logger.info("... ", digitals)
166 _logger.info("... ", analogs)
167
168 def DownloadProfile(self):
169 _logger.info("DownloadProfile")
170
171 def InitProfile(self, numReps):
172 _logger.info("InitProfile")
173
174 def trigCollect(self, *args, **kwargs):
175 _logger.info("trigCollect: ... ")
176 _logger.info(args)
177 _logger.info(kwargs)
178
179 def ReadPosition(self, aline):
180 _logger.info(
181 "ReadPosition : line %d, value %d", aline, self._ana[aline]
182 )
183 return self._ana[aline]
184
185 def ReadDigital(self):
186 _logger.info("ReadDigital: %s", bin(self._digi))
187 return self._digi
188
189 def PrepareActions(self, actions, numReps=1):
190 _logger.info("PrepareActions")
191 self._actions = actions
192 self._repeats = numReps
193
194 def RunActions(self):
195 _logger.info("RunActions ...")
196 for i in range(self._repeats):
197 for a in self._actions:
198 _logger.info(a)
199 time.sleep(a[0] / 1000.0)
200 if self._client:
201 self._client.receiveData("DSP done")
202 _logger.info("... RunActions done.")
203
204 def receiveClient(self, *args, **kwargs):
205 # XXX: maybe this should be on its own mixin instead of on DataDevice
206 return microscope.abc.DataDevice.receiveClient(self, *args, **kwargs)
207
208 def set_client(self, *args, **kwargs):
209 # XXX: maybe this should be on its own mixin instead of on DataDevice
210 return microscope.abc.DataDevice.set_client(self, *args, **kwargs)
211
212
215):
216 """Simple device with a UID after having been initialized.
217
218 Floating devices are devices where we can't specify which one to
219 get, we can only construct it and after initialisation check its
220 UID. In this class for test units we can check which UID to get.
221
222 """
223
224 def __init__(self, uid: str, **kwargs) -> None:
225 super().__init__(**kwargs)
226 self._initialized = False
227 self._uid = uid
229
230 def initialize(self) -> None:
231 super().initialize()
232 self._initialized = True
233
234 def get_index(self) -> int:
235 """Expose private _index for testing purposes."""
236 return self._index
237
238 def get_id(self) -> str:
239 if self._initialized:
240 return self._uid
241 else:
243 "uid is not available until after initialisation"
244 )
245
246 def _do_shutdown(self) -> None:
247 pass
None set_client(self, new_client)
Definition abc.py:749
None receiveClient(self, str client_uri)
Definition abc.py:785
None add_setting(self, name, dtype, get_func, set_func, values, typing.Optional[typing.Callable[[], bool]] readonly=None)
Definition abc.py:407
None initialize(self)
Definition abc.py:339