horiba-sdk 0.3.3__py3-none-any.whl → 0.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- horiba_sdk/__init__.py +5 -3
- horiba_sdk/communication/websocket_communicator.py +2 -2
- horiba_sdk/core/__init__.py +0 -0
- horiba_sdk/core/acquisition_format.py +20 -0
- horiba_sdk/core/clean_count_mode.py +13 -0
- horiba_sdk/core/timer_resolution.py +14 -0
- horiba_sdk/core/x_axis_conversion_type.py +18 -0
- horiba_sdk/devices/ccd_discovery.py +10 -12
- horiba_sdk/devices/device_manager.py +24 -10
- horiba_sdk/devices/fake_responses/ccd.json +261 -12
- horiba_sdk/devices/fake_responses/monochromator.json +38 -10
- horiba_sdk/devices/monochromator_discovery.py +16 -9
- horiba_sdk/devices/single_devices/abstract_device.py +46 -1
- horiba_sdk/devices/single_devices/ccd.py +388 -143
- horiba_sdk/devices/single_devices/monochromator.py +87 -71
- horiba_sdk/sync/communication/abstract_communicator.py +2 -3
- horiba_sdk/sync/communication/websocket_communicator.py +38 -18
- horiba_sdk/sync/devices/device_discovery.py +13 -37
- horiba_sdk/sync/devices/device_manager.py +14 -10
- horiba_sdk/sync/devices/fake_icl_server.py +9 -6
- horiba_sdk/sync/devices/single_devices/abstract_device.py +11 -7
- horiba_sdk/sync/devices/single_devices/ccd.py +517 -62
- horiba_sdk/sync/devices/single_devices/monochromator.py +288 -25
- {horiba_sdk-0.3.3.dist-info → horiba_sdk-0.5.2.dist-info}/METADATA +166 -92
- {horiba_sdk-0.3.3.dist-info → horiba_sdk-0.5.2.dist-info}/RECORD +27 -22
- {horiba_sdk-0.3.3.dist-info → horiba_sdk-0.5.2.dist-info}/LICENSE +0 -0
- {horiba_sdk-0.3.3.dist-info → horiba_sdk-0.5.2.dist-info}/WHEEL +0 -0
@@ -1,8 +1,8 @@
|
|
1
|
+
from enum import Enum
|
1
2
|
from types import TracebackType
|
2
|
-
from typing import Optional, final
|
3
|
+
from typing import Any, Optional, final
|
3
4
|
|
4
5
|
from loguru import logger
|
5
|
-
from numericalunits import nm
|
6
6
|
from overrides import override
|
7
7
|
|
8
8
|
from horiba_sdk.communication import Response
|
@@ -19,6 +19,78 @@ class Monochromator(AbstractDevice):
|
|
19
19
|
should be used to access the detected Monochromators on the system.
|
20
20
|
"""
|
21
21
|
|
22
|
+
@final
|
23
|
+
class Shutter(Enum):
|
24
|
+
"""Shutters installed in the monochromator."""
|
25
|
+
|
26
|
+
FIRST = 0
|
27
|
+
SECOND = 1
|
28
|
+
|
29
|
+
@final
|
30
|
+
class ShutterPosition(Enum):
|
31
|
+
"""Position of the shutter."""
|
32
|
+
|
33
|
+
CLOSED = 0
|
34
|
+
OPENED = 1
|
35
|
+
|
36
|
+
@final
|
37
|
+
class Grating(Enum):
|
38
|
+
"""Gratings installed in the monochromator"""
|
39
|
+
|
40
|
+
FIRST = 0
|
41
|
+
SECOND = 1
|
42
|
+
THIRD = 2
|
43
|
+
|
44
|
+
@final
|
45
|
+
class FilterWheel(Enum):
|
46
|
+
"""Filter wheels installed in the monochromator.
|
47
|
+
|
48
|
+
.. note:: the filter wheel is an optional module
|
49
|
+
|
50
|
+
"""
|
51
|
+
|
52
|
+
# TODO: clarify naming of filter wheel
|
53
|
+
FIRST = 0
|
54
|
+
SECOND = 1
|
55
|
+
|
56
|
+
@final
|
57
|
+
class FilterWheelPosition(Enum):
|
58
|
+
"""Positions of the filter wheel installed in the monochromator.
|
59
|
+
|
60
|
+
.. note:: the filter wheel is an optional module
|
61
|
+
|
62
|
+
"""
|
63
|
+
|
64
|
+
# TODO: clarify naming of filter wheel positions
|
65
|
+
RED = 0
|
66
|
+
GREEN = 1
|
67
|
+
BLUE = 2
|
68
|
+
YELLOW = 3
|
69
|
+
|
70
|
+
@final
|
71
|
+
class Mirror(Enum):
|
72
|
+
"""Mirrors installed in the monochromator"""
|
73
|
+
|
74
|
+
ENTRANCE = 0
|
75
|
+
EXIT = 1
|
76
|
+
|
77
|
+
@final
|
78
|
+
class MirrorPosition(Enum):
|
79
|
+
"""Possible positions of the mirrors"""
|
80
|
+
|
81
|
+
AXIAL = 0
|
82
|
+
LATERAL = 1
|
83
|
+
|
84
|
+
@final
|
85
|
+
class Slit(Enum):
|
86
|
+
"""Slits available on the monochromator."""
|
87
|
+
|
88
|
+
# TODO: clarify how the slits are called
|
89
|
+
A = 0
|
90
|
+
B = 1
|
91
|
+
C = 2
|
92
|
+
D = 3
|
93
|
+
|
22
94
|
def __init__(self, device_id: int, communicator: AbstractCommunicator, error_db: AbstractErrorDB) -> None:
|
23
95
|
super().__init__(device_id, communicator, error_db)
|
24
96
|
|
@@ -46,7 +118,7 @@ class Monochromator(AbstractDevice):
|
|
46
118
|
Exception: When an error occured on the device side
|
47
119
|
"""
|
48
120
|
super().open()
|
49
|
-
super()._execute_command('mono_open', {'index': self._id}
|
121
|
+
super()._execute_command('mono_open', {'index': self._id})
|
50
122
|
|
51
123
|
@override
|
52
124
|
def close(self) -> None:
|
@@ -66,7 +138,6 @@ class Monochromator(AbstractDevice):
|
|
66
138
|
response: Response = super()._execute_command('mono_isOpen', {'index': self._id})
|
67
139
|
return bool(response.results['open'])
|
68
140
|
|
69
|
-
@property
|
70
141
|
def is_busy(self) -> bool:
|
71
142
|
"""Checks if the monochromator is busy.
|
72
143
|
|
@@ -76,7 +147,7 @@ class Monochromator(AbstractDevice):
|
|
76
147
|
response: Response = super()._execute_command('mono_isBusy', {'index': self._id})
|
77
148
|
return bool(response.results['busy'])
|
78
149
|
|
79
|
-
def
|
150
|
+
def initialize(self) -> None:
|
80
151
|
"""Starts the monochromator initialization process called "homing".
|
81
152
|
|
82
153
|
Use :func:`Monochromator.is_busy()` to know if the operation is still taking place.
|
@@ -86,65 +157,257 @@ class Monochromator(AbstractDevice):
|
|
86
157
|
"""
|
87
158
|
super()._execute_command('mono_init', {'index': self._id})
|
88
159
|
|
89
|
-
|
90
|
-
|
160
|
+
def is_initialized(self) -> bool:
|
161
|
+
"""This command returns true when the mono is initialized. Otherwise, it returns false.
|
162
|
+
Note: This command may also return false when the mono is busy with another command.
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
bool: If the monochromator is initialized or not
|
166
|
+
|
167
|
+
Raises:
|
168
|
+
Exception: When an error occurred on the device side
|
169
|
+
"""
|
170
|
+
response: Response = super()._execute_command('mono_isInitialized', {'index': self._id})
|
171
|
+
return bool(response.results['initialized'])
|
172
|
+
|
173
|
+
def configuration(self) -> dict[str, Any]:
|
174
|
+
"""Returns the configuration of the monochromator.
|
175
|
+
|
176
|
+
Returns:
|
177
|
+
str: configuration of the monochromator
|
178
|
+
"""
|
179
|
+
response: Response = super()._execute_command('mono_getConfig', {'index': self._id, 'compact': False})
|
180
|
+
return response.results['configuration']
|
181
|
+
|
182
|
+
def get_current_wavelength(self) -> float:
|
91
183
|
"""Current wavelength of the monochromator's position in nm.
|
92
184
|
|
185
|
+
Returns:
|
186
|
+
float: The current wavelength in nm
|
187
|
+
|
93
188
|
Raises:
|
94
189
|
Exception: When an error occured on the device side
|
95
190
|
"""
|
96
191
|
response = super()._execute_command('mono_getPosition', {'index': self._id})
|
97
|
-
return float(response.results['wavelength'])
|
192
|
+
return float(response.results['wavelength'])
|
98
193
|
|
99
|
-
def
|
194
|
+
def calibrate_wavelength(self, wavelength: float) -> None:
|
100
195
|
"""This command sets the wavelength value of the current grating position of the monochromator.
|
101
196
|
|
102
197
|
.. warning:: This could potentially uncalibrate the monochromator and report an incorrect wavelength compared to
|
103
198
|
the actual output wavelength.
|
104
199
|
|
105
200
|
Args:
|
106
|
-
wavelength (
|
201
|
+
wavelength (float): wavelength in nm
|
107
202
|
|
108
203
|
Raises:
|
109
204
|
Exception: When an error occured on the device side
|
110
205
|
"""
|
111
206
|
super()._execute_command('mono_setPosition', {'index': self._id, 'wavelength': wavelength})
|
112
207
|
|
113
|
-
def
|
208
|
+
def move_to_target_wavelength(self, wavelength_nm: float) -> None:
|
114
209
|
"""Orders the monochromator to move to the requested wavelength.
|
115
210
|
|
116
211
|
Use :func:`Monochromator.is_busy()` to know if the operation is still taking place.
|
117
212
|
|
118
213
|
Args:
|
119
|
-
|
214
|
+
wavelength_nm (float): wavelength in nm
|
120
215
|
|
121
216
|
Raises:
|
122
217
|
Exception: When an error occured on the device side
|
123
218
|
"""
|
124
|
-
super()._execute_command('mono_moveToPosition', {'index': self._id, 'wavelength':
|
219
|
+
super()._execute_command('mono_moveToPosition', {'index': self._id, 'wavelength': wavelength_nm}, 180)
|
220
|
+
|
221
|
+
def get_turret_grating(self) -> Grating:
|
222
|
+
"""Current grating of the turret.
|
125
223
|
|
126
|
-
|
127
|
-
|
128
|
-
|
224
|
+
.. note:: Prior to the initialization of the grating turret, this value may not reflect the actual position
|
225
|
+
of the turret. To read the current position of the grating turret, please run
|
226
|
+
:func:`Monochromator.home()` prior to running this command.
|
129
227
|
|
130
228
|
Returns:
|
131
|
-
|
229
|
+
Grating: current grating of turret. See :class:`Monochromator.Grating` for possible values.
|
132
230
|
|
133
231
|
Raises:
|
134
|
-
Exception: When an error
|
232
|
+
Exception: When an error occurred on the device side
|
135
233
|
"""
|
136
234
|
response: Response = super()._execute_command('mono_getGratingPosition', {'index': self._id})
|
137
|
-
return
|
235
|
+
return self.Grating(response.results['position'])
|
138
236
|
|
139
|
-
def
|
140
|
-
"""
|
237
|
+
def set_turret_grating(self, grating: Grating) -> None:
|
238
|
+
"""Select turret grating
|
141
239
|
|
142
|
-
..
|
240
|
+
.. note:: Note: The turret sensor does not re-read the position each time it is moved, therefore the position
|
241
|
+
may not be accurate prior to initialization. See note for get_turret_grating().
|
143
242
|
|
144
243
|
Args:
|
145
|
-
|
244
|
+
grating (Grating): new grating of the turret. See :class:`Monochromator.Grating` for possible values.
|
146
245
|
|
147
246
|
Raises:
|
148
|
-
Exception: When an error
|
247
|
+
Exception: When an error occurred on the device side
|
248
|
+
"""
|
249
|
+
super()._execute_command('mono_moveGrating', {'index': self._id, 'position': grating.value})
|
250
|
+
|
251
|
+
def get_filter_wheel_position(self, filter_wheel: FilterWheel) -> FilterWheelPosition:
|
252
|
+
"""Current position of the filter wheel.
|
253
|
+
|
254
|
+
Returns:
|
255
|
+
FilterWheelPosition: current position of the filter wheel. See :class:`Monochromator.FilterWheelPosition`
|
256
|
+
for possible values.
|
257
|
+
|
258
|
+
Raises:
|
259
|
+
Exception: When an error occurred on the device side
|
260
|
+
"""
|
261
|
+
response: Response = super()._execute_command(
|
262
|
+
'mono_getFilterWheelPosition', {'index': self._id, 'type': filter_wheel.value}
|
263
|
+
)
|
264
|
+
return self.FilterWheelPosition(response.results['position'])
|
265
|
+
|
266
|
+
def set_filter_wheel_position(self, filter_wheel: FilterWheel, position: FilterWheelPosition) -> None:
|
267
|
+
"""Sets the current position of the filter wheel.
|
268
|
+
|
269
|
+
Returns:
|
270
|
+
FilterWheelPosition: current position of the filter wheel. See :class:`Monochromator.FilterWheelPosition`,
|
271
|
+
for possible values.
|
272
|
+
|
273
|
+
Raises:
|
274
|
+
Exception: When an error occurred on the device side
|
275
|
+
"""
|
276
|
+
super()._execute_command(
|
277
|
+
'mono_moveFilterWheel', {'index': self._id, 'locationId': filter_wheel.value, 'position': position.value}
|
278
|
+
)
|
279
|
+
|
280
|
+
def get_mirror_position(self, mirror: Mirror) -> MirrorPosition:
|
281
|
+
"""Position of the selected mirror.
|
282
|
+
|
283
|
+
.. todo:: Get more information about possible values and explain elements contained in monochromator at top
|
284
|
+
of this class.
|
285
|
+
|
286
|
+
Args:
|
287
|
+
mirror (Mirror): desired mirror to get the position from.
|
288
|
+
|
289
|
+
Returns:
|
290
|
+
MirrorPosition: current mirror position. See :class:`Monochromator.MirrorPosition` for possible values
|
291
|
+
|
292
|
+
Raises:
|
293
|
+
Exception: When an error occurred on the device side
|
294
|
+
"""
|
295
|
+
response: Response = super()._execute_command(
|
296
|
+
'mono_getMirrorPosition', {'index': self._id, 'locationId': mirror.value}
|
297
|
+
)
|
298
|
+
return self.MirrorPosition(response.results['position'])
|
299
|
+
|
300
|
+
def set_mirror_position(self, mirror: Mirror, position: MirrorPosition) -> None:
|
301
|
+
"""Sets the position of the selected mirror.
|
302
|
+
|
303
|
+
.. todo:: Get more information about possible values and explain elements contained in monochromator at top
|
304
|
+
of this class.
|
305
|
+
|
306
|
+
Args:
|
307
|
+
mirror (Mirror): desired mirror to set the position.
|
308
|
+
position (MirrorPosition): position to set. See :class:`Monochromator.MirrorPosition` for possible values
|
309
|
+
|
310
|
+
Raises:
|
311
|
+
Exception: When an error occurred on the device side
|
312
|
+
"""
|
313
|
+
super()._execute_command(
|
314
|
+
'mono_moveMirror', {'index': self._id, 'locationId': mirror.value, 'position': position.value}
|
315
|
+
)
|
316
|
+
|
317
|
+
def get_slit_position_in_mm(self, slit: Slit) -> float:
|
318
|
+
"""Returns the position in millimeters [mm] of the selected slit.
|
319
|
+
|
320
|
+
Args:
|
321
|
+
slit (Slit): desired slit to get the position from. See :class:`Monochromator.Slit` for possible
|
322
|
+
|
323
|
+
Returns:
|
324
|
+
float: position in mm
|
325
|
+
|
326
|
+
Raises:
|
327
|
+
Exception: When an error occurred on the device side
|
328
|
+
"""
|
329
|
+
|
330
|
+
response: Response = super()._execute_command(
|
331
|
+
'mono_getSlitPositionInMM', {'index': self._id, 'locationId': slit.value}
|
332
|
+
)
|
333
|
+
return float(response.results['position'])
|
334
|
+
|
335
|
+
def set_slit_position(self, slit: Slit, position_in_mm: float) -> None:
|
336
|
+
"""Sets the position of the selected slit.
|
337
|
+
|
338
|
+
Args:
|
339
|
+
slit (Slit): desired slit to set the position. See :class:`Monochromator.Slit` for possible values.
|
340
|
+
position_in_mm (float): position to set in millimeters [mm].
|
341
|
+
|
342
|
+
Raises:
|
343
|
+
Exception: When an error occurred on the device side
|
344
|
+
"""
|
345
|
+
super()._execute_command(
|
346
|
+
'mono_moveSlitMM', {'index': self._id, 'locationId': slit.value, 'position': position_in_mm}
|
347
|
+
)
|
348
|
+
|
349
|
+
def get_slit_step_position(self, slit: Slit) -> int:
|
350
|
+
"""Returns the position of the specified slit in steps.
|
351
|
+
|
352
|
+
Args:
|
353
|
+
slit (Slit): desired slit to get the position from. See :class:`Monochromator.Slit` for possible
|
354
|
+
Returns:
|
355
|
+
int: step position.
|
356
|
+
|
357
|
+
Raises:
|
358
|
+
Exception: When an error occurred on the device side
|
359
|
+
"""
|
360
|
+
|
361
|
+
response: Response = super()._execute_command(
|
362
|
+
'mono_getSlitStepPosition', {'index': self._id, 'locationId': slit.value}
|
363
|
+
)
|
364
|
+
return int(response.results['position'])
|
365
|
+
|
366
|
+
def set_slit_step_position(self, slit: Slit, step_position: int) -> None:
|
367
|
+
"""Moves the specified slit to the position in steps.
|
368
|
+
|
369
|
+
Args:
|
370
|
+
slit (Slit): desired slit to set the step position. See :class:`Monochromator.Slit` for possible values.
|
371
|
+
step_position (int): the step position.
|
372
|
+
|
373
|
+
Raises:
|
374
|
+
Exception: When an error occurred on the device side
|
375
|
+
"""
|
376
|
+
super()._execute_command(
|
377
|
+
'mono_moveSlit', {'index': self._id, 'locationId': slit.value, 'position': step_position}
|
378
|
+
)
|
379
|
+
|
380
|
+
def open_shutter(self) -> None:
|
381
|
+
"""Opens the shutter.
|
382
|
+
|
383
|
+
Raises:
|
384
|
+
Exception: When an error occurred on the device side
|
385
|
+
"""
|
386
|
+
super()._execute_command('mono_shutterOpen', {'index': self._id})
|
387
|
+
|
388
|
+
def close_shutter(self) -> None:
|
389
|
+
"""Closes the shutter.
|
390
|
+
|
391
|
+
Raises:
|
392
|
+
Exception: When an error occurred on the device side
|
393
|
+
"""
|
394
|
+
super()._execute_command('mono_shutterClose', {'index': self._id})
|
395
|
+
|
396
|
+
def get_shutter_position(self, shutter: Shutter) -> ShutterPosition:
|
397
|
+
"""Returns the shutter position.
|
398
|
+
|
399
|
+
Returns:
|
400
|
+
ShutterPosition: OPEN or CLOSED
|
401
|
+
|
402
|
+
Raises:
|
403
|
+
Exception: When an error occurred on the device side
|
149
404
|
"""
|
150
|
-
super()._execute_command('
|
405
|
+
response: Response = super()._execute_command('mono_getShutterStatus', {'index': self._id})
|
406
|
+
# TODO: How many shutters are there?
|
407
|
+
if shutter == self.Shutter.FIRST:
|
408
|
+
return self.ShutterPosition(response.results['shutter 1'])
|
409
|
+
elif shutter == self.Shutter.SECOND:
|
410
|
+
return self.ShutterPosition(response.results['shutter 2'])
|
411
|
+
else:
|
412
|
+
logger.error(f'shutter {shutter} not implemented')
|
413
|
+
raise Exception('shutter not implemented')
|