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.
Files changed (27) hide show
  1. horiba_sdk/__init__.py +5 -3
  2. horiba_sdk/communication/websocket_communicator.py +2 -2
  3. horiba_sdk/core/__init__.py +0 -0
  4. horiba_sdk/core/acquisition_format.py +20 -0
  5. horiba_sdk/core/clean_count_mode.py +13 -0
  6. horiba_sdk/core/timer_resolution.py +14 -0
  7. horiba_sdk/core/x_axis_conversion_type.py +18 -0
  8. horiba_sdk/devices/ccd_discovery.py +10 -12
  9. horiba_sdk/devices/device_manager.py +24 -10
  10. horiba_sdk/devices/fake_responses/ccd.json +261 -12
  11. horiba_sdk/devices/fake_responses/monochromator.json +38 -10
  12. horiba_sdk/devices/monochromator_discovery.py +16 -9
  13. horiba_sdk/devices/single_devices/abstract_device.py +46 -1
  14. horiba_sdk/devices/single_devices/ccd.py +388 -143
  15. horiba_sdk/devices/single_devices/monochromator.py +87 -71
  16. horiba_sdk/sync/communication/abstract_communicator.py +2 -3
  17. horiba_sdk/sync/communication/websocket_communicator.py +38 -18
  18. horiba_sdk/sync/devices/device_discovery.py +13 -37
  19. horiba_sdk/sync/devices/device_manager.py +14 -10
  20. horiba_sdk/sync/devices/fake_icl_server.py +9 -6
  21. horiba_sdk/sync/devices/single_devices/abstract_device.py +11 -7
  22. horiba_sdk/sync/devices/single_devices/ccd.py +517 -62
  23. horiba_sdk/sync/devices/single_devices/monochromator.py +288 -25
  24. {horiba_sdk-0.3.3.dist-info → horiba_sdk-0.5.2.dist-info}/METADATA +166 -92
  25. {horiba_sdk-0.3.3.dist-info → horiba_sdk-0.5.2.dist-info}/RECORD +27 -22
  26. {horiba_sdk-0.3.3.dist-info → horiba_sdk-0.5.2.dist-info}/LICENSE +0 -0
  27. {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}, 0.5)
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 home(self) -> None:
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
- @property
90
- def wavelength(self) -> nm:
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']) * nm
192
+ return float(response.results['wavelength'])
98
193
 
99
- def set_current_wavelength(self, wavelength: int) -> None:
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 (nm): 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 move_to_wavelength(self, wavelength: nm) -> None:
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
- wavelength (nm): wavelength
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': wavelength / nm})
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
- @property
127
- def turret_grating_position(self) -> int:
128
- """Grating turret position.
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
- int: current grating turret position
229
+ Grating: current grating of turret. See :class:`Monochromator.Grating` for possible values.
132
230
 
133
231
  Raises:
134
- Exception: When an error occured on the device side
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 int(response.results['position'])
235
+ return self.Grating(response.results['position'])
138
236
 
139
- def move_turret_to_grating(self, position: int) -> None:
140
- """Move turret to grating position
237
+ def set_turret_grating(self, grating: Grating) -> None:
238
+ """Select turret grating
141
239
 
142
- .. todo:: Get more information about how it works and clarify veracity of returned data
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
- position (int): new grating position
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 occured on the device side
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('mono_getPosition', {'index': self._id, 'position': position})
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')