horiba-sdk 0.3.2__py3-none-any.whl → 0.4.0__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 +0 -4
- horiba_sdk/core/__init__.py +0 -0
- horiba_sdk/core/acquisition_format.py +10 -0
- horiba_sdk/core/clean_count_mode.py +11 -0
- horiba_sdk/core/timer_resolution.py +12 -0
- horiba_sdk/core/x_axis_conversion_type.py +13 -0
- horiba_sdk/devices/ccd_discovery.py +10 -12
- horiba_sdk/devices/device_manager.py +13 -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 +8 -0
- horiba_sdk/devices/single_devices/ccd.py +359 -153
- horiba_sdk/devices/single_devices/monochromator.py +73 -70
- horiba_sdk/sync/communication/abstract_communicator.py +2 -3
- horiba_sdk/sync/communication/websocket_communicator.py +37 -17
- horiba_sdk/sync/devices/device_discovery.py +13 -37
- horiba_sdk/sync/devices/device_manager.py +13 -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 +479 -62
- horiba_sdk/sync/devices/single_devices/monochromator.py +274 -24
- {horiba_sdk-0.3.2.dist-info → horiba_sdk-0.4.0.dist-info}/METADATA +120 -18
- {horiba_sdk-0.3.2.dist-info → horiba_sdk-0.4.0.dist-info}/RECORD +26 -21
- {horiba_sdk-0.3.2.dist-info → horiba_sdk-0.4.0.dist-info}/LICENSE +0 -0
- {horiba_sdk-0.3.2.dist-info → horiba_sdk-0.4.0.dist-info}/WHEEL +0 -0
@@ -1,14 +1,15 @@
|
|
1
|
-
from enum import Enum
|
2
1
|
from types import TracebackType
|
3
|
-
from typing import Any, Optional, final
|
2
|
+
from typing import Any, List, Optional, final
|
4
3
|
|
5
|
-
import pint
|
6
4
|
from loguru import logger
|
7
5
|
from overrides import override
|
8
6
|
|
9
|
-
from horiba_sdk import ureg
|
10
7
|
from horiba_sdk.communication import AbstractCommunicator, Response
|
8
|
+
from horiba_sdk.core.acquisition_format import AcquisitionFormat
|
9
|
+
from horiba_sdk.core.clean_count_mode import CleanCountMode
|
11
10
|
from horiba_sdk.core.resolution import Resolution
|
11
|
+
from horiba_sdk.core.timer_resolution import TimerResolution
|
12
|
+
from horiba_sdk.core.x_axis_conversion_type import XAxisConversionType
|
12
13
|
from horiba_sdk.icl_error import AbstractErrorDB
|
13
14
|
|
14
15
|
from .abstract_device import AbstractDevice
|
@@ -22,40 +23,6 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
22
23
|
should be used to access the detected CCDs on the system.
|
23
24
|
"""
|
24
25
|
|
25
|
-
@final
|
26
|
-
class Gain(Enum):
|
27
|
-
HIGH_LIGHT = 0
|
28
|
-
BEST_DYNAMIC_RANGE = 1
|
29
|
-
HIGH_SENSITIVITY = 2
|
30
|
-
|
31
|
-
@final
|
32
|
-
class Speed(Enum):
|
33
|
-
SLOW_45_kHz = 0
|
34
|
-
MEDIUM_1_MHz = 1
|
35
|
-
FAST_1_MHz_Ultra = 2
|
36
|
-
|
37
|
-
@final
|
38
|
-
class AcquisitionFormat(Enum):
|
39
|
-
SPECTRA = 0
|
40
|
-
IMAGE = 1
|
41
|
-
CROP = 2
|
42
|
-
FAST_KINETICS = 3
|
43
|
-
|
44
|
-
@final
|
45
|
-
class CleanCountMode(Enum):
|
46
|
-
Mode1 = 238
|
47
|
-
|
48
|
-
@final
|
49
|
-
class XAxisConversionType(Enum):
|
50
|
-
"""
|
51
|
-
Enumeration of possible XAxisConversionTypes
|
52
|
-
None = 0, CCD-Firmware = 1, ICL ini settings file = 2
|
53
|
-
"""
|
54
|
-
|
55
|
-
NONE = 0
|
56
|
-
FROM_CCD_FIRMWARE = 1
|
57
|
-
FROM_ICL_SETTINGS_INI = 2
|
58
|
-
|
59
26
|
def __init__(self, device_id: int, communicator: AbstractCommunicator, error_db: AbstractErrorDB) -> None:
|
60
27
|
super().__init__(device_id, communicator, error_db)
|
61
28
|
|
@@ -82,6 +49,7 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
82
49
|
"""
|
83
50
|
await super().open()
|
84
51
|
await super()._execute_command('ccd_open', {'index': self._id})
|
52
|
+
self._config: dict[str, Any] = await self.get_configuration()
|
85
53
|
|
86
54
|
@override
|
87
55
|
async def close(self) -> None:
|
@@ -121,131 +89,135 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
121
89
|
Exception: When an error occurred on the device side
|
122
90
|
"""
|
123
91
|
response: Response = await super()._execute_command('ccd_getConfig', {'index': self._id})
|
124
|
-
return response.results
|
92
|
+
return response.results['configuration']
|
125
93
|
|
126
|
-
async def
|
127
|
-
"""Returns the
|
94
|
+
async def get_gain_token(self) -> int:
|
95
|
+
"""Returns the current gain token.
|
128
96
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
Raises:
|
133
|
-
Exception: When an error occurred on the device side
|
134
|
-
"""
|
135
|
-
response: Response = await super()._execute_command('ccd_getNumberOfAvgs', {'index': self._id})
|
136
|
-
return int(response.results['count'])
|
137
|
-
|
138
|
-
async def set_number_of_averages(self, number_of_averages: int) -> None:
|
139
|
-
"""Sets the number of averages of the CCD
|
140
|
-
|
141
|
-
Args:
|
142
|
-
number_of_averages (int): Number of averages
|
143
|
-
|
144
|
-
Raises:
|
145
|
-
Exception: When an error occurred on the device side
|
146
|
-
"""
|
147
|
-
await super()._execute_command('ccd_setNumberOfAvgs', {'index': self._id, 'count': number_of_averages})
|
148
|
-
|
149
|
-
async def get_gain(self) -> str:
|
150
|
-
"""Returns the gain of the CCD
|
97
|
+
.. note:: The CCD can have different sensors installed, which can have different gain values. This is why only
|
98
|
+
the token to the gain is returned. You need to first check what gain values are available for the CCD using the
|
99
|
+
get_configuration function. Please see the according "Gain and Speed" documentation.
|
151
100
|
|
152
101
|
Returns:
|
153
|
-
|
102
|
+
int: Gain token of the ccd
|
154
103
|
|
155
104
|
Raises:
|
156
105
|
Exception: When an error occurred on the device side
|
157
106
|
"""
|
158
107
|
response: Response = await super()._execute_command('ccd_getGain', {'index': self._id})
|
159
|
-
|
108
|
+
gain: int = int(response.results['token'])
|
109
|
+
return gain
|
110
|
+
|
111
|
+
async def set_gain(self, gain_token: int) -> None:
|
112
|
+
"""Sets the gain of the CCD.
|
160
113
|
|
161
|
-
|
162
|
-
|
114
|
+
.. note:: The CCD can have different sensors installed, which can have different gain values. Therefore you need
|
115
|
+
to first check what gain values are available for the CCD using the get_configuration function. Please see the
|
116
|
+
according "Gain and Speed" documentation.
|
163
117
|
|
164
118
|
Args:
|
165
|
-
|
119
|
+
gain_token (int): Token of the desired gain
|
166
120
|
|
167
121
|
Raises:
|
168
122
|
Exception: When an error occurred on the device side
|
169
123
|
"""
|
170
|
-
await super()._execute_command('ccd_setGain', {'index': self._id, 'token':
|
124
|
+
await super()._execute_command('ccd_setGain', {'index': self._id, 'token': gain_token})
|
171
125
|
|
172
|
-
async def
|
173
|
-
"""Returns the speed
|
126
|
+
async def get_speed_token(self) -> int:
|
127
|
+
"""Returns the speed token.
|
128
|
+
|
129
|
+
.. note:: The CCD can have different sensors installed, which can have different speed values. This is why only
|
130
|
+
the token to the speed is returned. You need to first check what speed values are available for the CCD using
|
131
|
+
the get_configuration function. Please see the according "Gain and Speed" documentation.
|
174
132
|
|
175
133
|
Returns:
|
176
|
-
|
134
|
+
int: Speed token of the CCD.
|
177
135
|
|
178
136
|
Raises:
|
179
137
|
Exception: When an error occurred on the device side
|
180
138
|
"""
|
181
139
|
response: Response = await super()._execute_command('ccd_getSpeed', {'index': self._id})
|
182
|
-
|
140
|
+
speed_token: int = int(response.results['token'])
|
141
|
+
return speed_token
|
183
142
|
|
184
|
-
async def set_speed(self,
|
143
|
+
async def set_speed(self, speed_token: int) -> None:
|
185
144
|
"""Sets the speed of the CCD
|
186
145
|
|
146
|
+
.. note:: The CCD can have different sensors installed, which can have different speed values. Therefore you
|
147
|
+
need to first check what speed values are available for the CCD using the get_configuration function. Please
|
148
|
+
see the according "Gain and Speed" documentation.
|
149
|
+
|
187
150
|
Args:
|
188
|
-
|
151
|
+
speed_token (int): Token of the desired speed.
|
189
152
|
|
190
153
|
Raises:
|
191
154
|
Exception: When an error occurred on the device side
|
192
155
|
"""
|
193
|
-
await super()._execute_command('ccd_setSpeed', {'index': self._id, 'token':
|
156
|
+
await super()._execute_command('ccd_setSpeed', {'index': self._id, 'token': speed_token})
|
194
157
|
|
195
|
-
async def
|
158
|
+
async def get_fit_parameters(self) -> list[int]:
|
196
159
|
"""Returns the fit parameters of the CCD
|
197
160
|
|
198
161
|
Returns:
|
199
|
-
|
162
|
+
List[int]: Fit parameters
|
200
163
|
|
201
164
|
Raises:
|
202
165
|
Exception: When an error occurred on the device side
|
203
166
|
"""
|
204
167
|
response: Response = await super()._execute_command('ccd_getFitParams', {'index': self._id})
|
205
|
-
|
168
|
+
fit_params: list[int] = response.results['fitParameters']
|
169
|
+
return fit_params
|
206
170
|
|
207
|
-
async def
|
171
|
+
async def set_fit_parameters(self, fit_params: list[int]) -> None:
|
208
172
|
"""Sets the fit parameters of the CCD
|
209
173
|
|
210
174
|
Args:
|
211
|
-
fit_params (
|
175
|
+
fit_params (List[int]): Fit parameters
|
212
176
|
|
213
177
|
Raises:
|
214
178
|
Exception: When an error occurred on the device side
|
215
179
|
"""
|
216
|
-
|
180
|
+
fit_params_str: str = ','.join(map(str, fit_params))
|
181
|
+
await super()._execute_command('ccd_setFitParams', {'index': self._id, 'params': fit_params_str})
|
217
182
|
|
218
|
-
async def get_timer_resolution(self) ->
|
219
|
-
"""Returns the timer resolution of the CCD
|
183
|
+
async def get_timer_resolution(self) -> TimerResolution:
|
184
|
+
"""Returns the timer resolution of the CCD in microseconds [μs]
|
220
185
|
|
221
186
|
Returns:
|
222
|
-
int: Timer resolution
|
187
|
+
int: Timer resolution in microseconds [μs]
|
223
188
|
|
224
189
|
Raises:
|
225
190
|
Exception: When an error occurred on the device side
|
226
191
|
"""
|
227
192
|
response: Response = await super()._execute_command('ccd_getTimerResolution', {'index': self._id})
|
228
|
-
|
193
|
+
timer_resolution: int = int(response.results['resolutionToken'])
|
194
|
+
return TimerResolution(timer_resolution)
|
229
195
|
|
230
|
-
async def set_timer_resolution(self, timer_resolution:
|
196
|
+
async def set_timer_resolution(self, timer_resolution: TimerResolution) -> None:
|
231
197
|
"""Sets the timer resolution of the CCD
|
232
198
|
|
199
|
+
.. note:: The timer resolution value of 1 microsecond is not supported by all CCDs.
|
200
|
+
|
233
201
|
Args:
|
234
202
|
timer_resolution (int): Timer resolution
|
235
203
|
|
236
204
|
Raises:
|
237
205
|
Exception: When an error occurred on the device side
|
238
206
|
"""
|
239
|
-
await super()._execute_command(
|
207
|
+
await super()._execute_command(
|
208
|
+
'ccd_setTimerResolution', {'index': self._id, 'resolutionToken': timer_resolution.value}
|
209
|
+
)
|
240
210
|
|
241
211
|
async def set_acquisition_format(self, number_of_rois: int, acquisition_format: AcquisitionFormat) -> None:
|
242
|
-
"""Sets the acquisition format and the number of ROIs (Regions of Interest) or areas.
|
243
|
-
|
244
|
-
|
212
|
+
"""Sets the acquisition format and the number of ROIs (Regions of Interest) or areas.
|
213
|
+
|
214
|
+
After using this command to set the number of ROIs and format, the set_region_of_interest function
|
215
|
+
should be used to define each ROI. Note: The Crop and Fast Kinetics acquisition formats are not
|
216
|
+
supported by every CCD.
|
245
217
|
|
246
218
|
Args:
|
247
|
-
acquisition_format (AcquisitionFormat): Acquisition format
|
248
219
|
number_of_rois (int): Number of regions of interest
|
220
|
+
acquisition_format (AcquisitionFormat): Acquisition format
|
249
221
|
|
250
222
|
Raises:
|
251
223
|
Exception: When an error occurred on the device side
|
@@ -254,6 +226,45 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
254
226
|
'ccd_setAcqFormat', {'index': self._id, 'format': acquisition_format.value, 'numberOfRois': number_of_rois}
|
255
227
|
)
|
256
228
|
|
229
|
+
async def set_region_of_interest(
|
230
|
+
self,
|
231
|
+
roi_index: int = 1,
|
232
|
+
x_origin: int = 0,
|
233
|
+
y_origin: int = 0,
|
234
|
+
x_size: int = 1024,
|
235
|
+
y_size: int = 256,
|
236
|
+
x_bin: int = 1,
|
237
|
+
y_bin: int = 256,
|
238
|
+
) -> None:
|
239
|
+
"""Sets the region of interest of the CCD
|
240
|
+
an example json command looks like this:
|
241
|
+
|
242
|
+
Args:
|
243
|
+
roi_index (int, optional): One based index of the region of interest. Defaults to 1.
|
244
|
+
x_origin (int, optional): X origin of the region of interest. Defaults to 0.
|
245
|
+
y_origin (int, optional): Y origin of the region of interest. Defaults to 0.
|
246
|
+
x_size (int, optional): X size of the region of interest. Defaults to 1024.
|
247
|
+
y_size (int, optional): Y size of the region of interest. Defaults to 256.
|
248
|
+
x_bin (int, optional): X bin of the region of interest. Defaults to 1.
|
249
|
+
y_bin (int, optional): Y bin of the region of interest. Defaults to 256.
|
250
|
+
|
251
|
+
Raises:
|
252
|
+
Exception: When an error occurred on the device side
|
253
|
+
"""
|
254
|
+
await super()._execute_command(
|
255
|
+
'ccd_setRoi',
|
256
|
+
{
|
257
|
+
'index': self._id,
|
258
|
+
'roiIndex': roi_index,
|
259
|
+
'xOrigin': x_origin,
|
260
|
+
'yOrigin': y_origin,
|
261
|
+
'xSize': x_size,
|
262
|
+
'ySize': y_size,
|
263
|
+
'xBin': x_bin,
|
264
|
+
'yBin': y_bin,
|
265
|
+
},
|
266
|
+
)
|
267
|
+
|
257
268
|
async def set_x_axis_conversion_type(self, conversion_type: XAxisConversionType) -> None:
|
258
269
|
"""Sets the X-axis pixel conversion type to be used when retrieving the acquisition data with the
|
259
270
|
ccd_getAcquisitionData command.
|
@@ -274,13 +285,15 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
274
285
|
2 = Mono Wavelength parameters contained in the icl_settings.ini file
|
275
286
|
"""
|
276
287
|
response: Response = await super()._execute_command('ccd_getXAxisConversionType', {'index': self._id})
|
277
|
-
return
|
288
|
+
return XAxisConversionType(response.results['type'])
|
278
289
|
|
279
290
|
async def set_acquisition_count(self, count: int) -> None:
|
280
|
-
"""Sets the number of
|
281
|
-
|
291
|
+
"""Sets the number of acquisition measurements to be performed sequentially by the hardware.
|
292
|
+
|
293
|
+
A count > 1 is commonly referred to as "MultiAcq".
|
294
|
+
|
282
295
|
Args:
|
283
|
-
count (int): The number of
|
296
|
+
count (int): The number of acquisition measurements.
|
284
297
|
"""
|
285
298
|
await super()._execute_command('ccd_setAcqCount', {'index': self._id, 'count': count})
|
286
299
|
|
@@ -291,11 +304,18 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
291
304
|
response: Response = await super()._execute_command('ccd_getAcqCount', {'index': self._id})
|
292
305
|
return int(response.results['count'])
|
293
306
|
|
294
|
-
async def get_clean_count(self) ->
|
295
|
-
"""Gets the
|
307
|
+
async def get_clean_count(self) -> tuple[int, CleanCountMode]:
|
308
|
+
"""Gets the number of cleans to be performed prior to measurement.
|
309
|
+
|
310
|
+
Returns:
|
311
|
+
Tuple[int, CleanCountMode]:
|
312
|
+
count: Number of cleans,
|
313
|
+
mode: Specifies how the cleans will be performed.
|
314
|
+
"""
|
296
315
|
response: Response = await super()._execute_command('ccd_getCleanCount', {'index': self._id})
|
297
|
-
|
298
|
-
|
316
|
+
count: int = int(response.results['count'])
|
317
|
+
mode: CleanCountMode = CleanCountMode(response.results['mode'])
|
318
|
+
return count, mode
|
299
319
|
|
300
320
|
async def set_clean_count(self, count: int, mode: CleanCountMode) -> None:
|
301
321
|
"""Sets the clean count mode of the CCD and the according mode
|
@@ -305,8 +325,8 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
305
325
|
"""
|
306
326
|
await super()._execute_command('ccd_setCleanCount', {'index': self._id, 'count': count, 'mode': mode.value})
|
307
327
|
|
308
|
-
async def
|
309
|
-
"""Returns the size of the data of the CCD
|
328
|
+
async def get_acquisition_data_size(self) -> int:
|
329
|
+
"""Returns the size of the acquisition data of the CCD
|
310
330
|
|
311
331
|
Returns:
|
312
332
|
int: Size of the data
|
@@ -317,17 +337,17 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
317
337
|
response: Response = await super()._execute_command('ccd_getDataSize', {'index': self._id})
|
318
338
|
return int(response.results['size'])
|
319
339
|
|
320
|
-
async def get_temperature(self) ->
|
340
|
+
async def get_temperature(self) -> float:
|
321
341
|
"""Chip temperature of the CCD.
|
322
342
|
|
323
343
|
Returns:
|
324
|
-
|
344
|
+
float: chip's temperature in degree Celsius
|
325
345
|
|
326
346
|
Raises:
|
327
347
|
Exception: When an error occurred on the device side
|
328
348
|
"""
|
329
349
|
response: Response = await super()._execute_command('ccd_getChipTemperature', {'index': self._id})
|
330
|
-
return
|
350
|
+
return float(response.results['temperature'])
|
331
351
|
|
332
352
|
async def get_chip_size(self) -> Resolution:
|
333
353
|
"""Chip resolution of the CCD.
|
@@ -356,16 +376,176 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
356
376
|
exposure = int(response.results['time'])
|
357
377
|
return exposure
|
358
378
|
|
359
|
-
async def set_exposure_time(self,
|
360
|
-
"""Sets the exposure time in
|
379
|
+
async def set_exposure_time(self, exposure_time: int) -> None:
|
380
|
+
"""Sets the exposure time in timer resolution units (1us or 1000us)
|
381
|
+
|
382
|
+
Examples:
|
383
|
+
- If exposure_time is set to 50, and the timer resolution value is 1000, the CCD exposure time
|
384
|
+
(integration time) = 50 milliseconds.
|
385
|
+
- If exposure_time is set to 50, and the timer resolution value is 1, the CCD exposure time
|
386
|
+
(integration time) = 50 microseconds.
|
361
387
|
|
362
388
|
Args:
|
363
|
-
|
389
|
+
exposure_time (int): Exposure time in timer resolution units (1us or 1000us)
|
364
390
|
Raises:
|
365
391
|
Exception: When an error occurred on the device side
|
366
392
|
"""
|
367
393
|
|
368
|
-
await super()._execute_command('ccd_setExposureTime', {'index': self._id, 'time':
|
394
|
+
await super()._execute_command('ccd_setExposureTime', {'index': self._id, 'time': exposure_time})
|
395
|
+
|
396
|
+
async def get_trigger_input(self) -> tuple[bool, int, int, int]:
|
397
|
+
"""This command is used to get the current setting of the input trigger.
|
398
|
+
|
399
|
+
The address, event, and signalType parameters are used to define the input trigger based on the
|
400
|
+
supported options of that particular CCD.
|
401
|
+
|
402
|
+
The supported trigger options are retrieved using the get_configuration function, and begin with the
|
403
|
+
“Triggers” string contained in the configuration.
|
404
|
+
|
405
|
+
Returns:
|
406
|
+
Tuple[bool, int, int, int]:
|
407
|
+
enabled: Specifies if the signal is enabled (e.g. False = Disabled),
|
408
|
+
address: used to specify where the trigger is located. (e.g. 0 = Trigger Input).
|
409
|
+
Note: Value of -1 indicates that the input trigger is disabled,
|
410
|
+
event: used to specify when the trigger event should occur. (e.g. 0 = Once - Start All)
|
411
|
+
Note: Value of -1 indicates that the input trigger is disabled,
|
412
|
+
signal type: used to specify how the signal will cause the input trigger. (e.g. 0 = TTL Falling Edge)
|
413
|
+
Note: Value of -1 indicates that the input trigger is disabled,
|
414
|
+
|
415
|
+
Raises:
|
416
|
+
Exception: When an error occurred on the device side
|
417
|
+
"""
|
418
|
+
response: Response = await super()._execute_command('ccd_getTriggerIn', {'index': self._id})
|
419
|
+
address = int(response.results['address'])
|
420
|
+
event = int(response.results['event'])
|
421
|
+
signal_type = int(response.results['signalType'])
|
422
|
+
enabled = address > -1 and event > -1 and signal_type > -1
|
423
|
+
return enabled, address, event, signal_type
|
424
|
+
|
425
|
+
async def set_trigger_input(self, enabled: bool, address: int, event: int, signal_type: int) -> None:
|
426
|
+
"""This command is used to enable or disable the trigger input.
|
427
|
+
|
428
|
+
When enabling the trigger input, the address, event, and signalType parameters are used to define
|
429
|
+
the input trigger based on the supported options of that particular CCD.
|
430
|
+
|
431
|
+
The supported trigger options are retrieved using the get_configuration function, and begin with the
|
432
|
+
“Triggers” string contained in the configuration.
|
433
|
+
|
434
|
+
Args:
|
435
|
+
enabled (bool): Enable or disable the trigger input. Note: When disabling the input trigger,
|
436
|
+
the address, event, and signalType parameters are ignored.
|
437
|
+
address (int): Used to specify where the trigger is located. (e.g. 0 = Trigger Input)
|
438
|
+
event (int): Used to specify when the trigger event should occur. (e.g. 0 = Once - Start All)
|
439
|
+
signal_type (int): Used to specify how the signal will cause the input trigger. (e.g. 0 = TTL Falling Edge)
|
440
|
+
|
441
|
+
Raises:
|
442
|
+
Exception: When an error occurred on the device side
|
443
|
+
"""
|
444
|
+
if not enabled:
|
445
|
+
address = -1
|
446
|
+
event = -1
|
447
|
+
signal_type = -1
|
448
|
+
|
449
|
+
await super()._execute_command(
|
450
|
+
'ccd_setTriggerIn',
|
451
|
+
{'index': self._id, 'enable': enabled, 'address': address, 'event': event, 'signalType': signal_type},
|
452
|
+
)
|
453
|
+
return
|
454
|
+
|
455
|
+
found_triggers = [trigger for trigger in self._config['triggers'] if trigger['token'] == address]
|
456
|
+
if not found_triggers:
|
457
|
+
raise Exception(f'Trigger address {address} not found in the configuration')
|
458
|
+
|
459
|
+
found_events = [
|
460
|
+
trigger_event for trigger_event in found_triggers[0]['events'] if trigger_event['token'] == event
|
461
|
+
]
|
462
|
+
if not found_events:
|
463
|
+
raise Exception(f'Trigger event {event} not found in the configuration')
|
464
|
+
|
465
|
+
found_signal_types = [signal for signal in found_events[0]['types'] if signal['token'] == signal_type]
|
466
|
+
if not found_signal_types:
|
467
|
+
raise Exception(f'Trigger signal type {signal_type} not found in the configuration')
|
468
|
+
|
469
|
+
await super()._execute_command(
|
470
|
+
'ccd_setTriggerIn',
|
471
|
+
{'index': self._id, 'enable': enabled, 'address': address, 'event': event, 'signalType': signal_type},
|
472
|
+
)
|
473
|
+
|
474
|
+
async def get_signal_output(self) -> tuple[bool, int, int, int]:
|
475
|
+
"""This command is used to get the current setting of the signal output.
|
476
|
+
|
477
|
+
The address, event, and signalType parameters are used to define the signal based on the supported
|
478
|
+
options of that particular CCD.
|
479
|
+
|
480
|
+
The supported signal options are retrieved using the get_configuration command, and begin with the
|
481
|
+
“Signals” string contained in the configuration.
|
482
|
+
|
483
|
+
Returns:
|
484
|
+
Tuple[bool, int, int, int]:
|
485
|
+
enabled: Specifies if the signal is enabled (e.g. False = Disabled),
|
486
|
+
address: Used to specify where the signal is located (e.g. 0 = Signal Output),
|
487
|
+
Note: Value of -1 indicates that the signal output is disabled,
|
488
|
+
event: Used to specify when the signal event should occur. (e.g. 3 = Shutter Open)
|
489
|
+
Note: Value of -1 indicates that the signal output is disabled,
|
490
|
+
signal type: how the signal will cause the event. (e.g. 0 = TTL Active High)
|
491
|
+
Note: Value of -1 indicates that the signal output is disabled,
|
492
|
+
|
493
|
+
Raises:
|
494
|
+
Exception: When an error occurred on the device side
|
495
|
+
"""
|
496
|
+
response: Response = await super()._execute_command('ccd_getSignalOut', {'index': self._id})
|
497
|
+
address = int(response.results['address'])
|
498
|
+
event = int(response.results['event'])
|
499
|
+
signal_type = int(response.results['signalType'])
|
500
|
+
enabled = address > -1 and event > -1 and signal_type > -1
|
501
|
+
return enabled, address, event, signal_type
|
502
|
+
|
503
|
+
async def set_signal_output(self, enabled: bool, address: int, event: int, signal_type: int) -> None:
|
504
|
+
"""This command is used to enable or disable the signal output.
|
505
|
+
|
506
|
+
When enabling the signal output, the address, event, and signalType parameters are used to
|
507
|
+
define the signal based on the supported options of that particular CCD.
|
508
|
+
|
509
|
+
The supported signal options are retrieved using the ccd_getConfig command, and begin with the
|
510
|
+
“Signals” string contained in the configuration.
|
511
|
+
|
512
|
+
Args:
|
513
|
+
enabled (bool): Enable or disable the signal output. Note: When disabling the signal output,
|
514
|
+
the address, event, and signal_type parameters are ignored.
|
515
|
+
address (int): Used to specify where the signal is located (e.g. 0 = Signal Output)
|
516
|
+
event (int): Used to specify when the signal event should occur. (e.g. 3 = Shutter Open)
|
517
|
+
signal_type (int): How the signal will cause the event. (e.g. 0 = TTL Active High)
|
518
|
+
|
519
|
+
"""
|
520
|
+
if not enabled:
|
521
|
+
address = -1
|
522
|
+
event = -1
|
523
|
+
signal_type = -1
|
524
|
+
|
525
|
+
await super()._execute_command(
|
526
|
+
'ccd_setSignalOut',
|
527
|
+
{'index': self._id, 'enable': enabled, 'address': address, 'event': event, 'signalType': signal_type},
|
528
|
+
)
|
529
|
+
return
|
530
|
+
|
531
|
+
found_triggers = [trigger for trigger in self._config['signals'] if trigger['token'] == address]
|
532
|
+
if not found_triggers:
|
533
|
+
raise Exception(f'Signal address {address} not found in the configuration')
|
534
|
+
|
535
|
+
found_events = [
|
536
|
+
trigger_event for trigger_event in found_triggers[0]['events'] if trigger_event['token'] == event
|
537
|
+
]
|
538
|
+
if not found_events:
|
539
|
+
raise Exception(f'Signal event {event} not found in the configuration')
|
540
|
+
|
541
|
+
found_signal_types = [signal for signal in found_events[0]['types'] if signal['token'] == signal_type]
|
542
|
+
if not found_signal_types:
|
543
|
+
raise Exception(f'Signal type {signal_type} not found in the configuration')
|
544
|
+
|
545
|
+
await super()._execute_command(
|
546
|
+
'ccd_setSignalOut',
|
547
|
+
{'index': self._id, 'enable': enabled, 'address': address, 'event': event, 'signalType': signal_type},
|
548
|
+
)
|
369
549
|
|
370
550
|
async def get_acquisition_ready(self) -> bool:
|
371
551
|
"""Returns true if the CCD is ready to acquire
|
@@ -379,65 +559,91 @@ class ChargeCoupledDevice(AbstractDevice):
|
|
379
559
|
return bool(response.results['ready'])
|
380
560
|
|
381
561
|
async def set_acquisition_start(self, open_shutter: bool) -> None:
|
382
|
-
"""Starts
|
562
|
+
"""Starts an acquisition that has been set up according to the previously defined acquisition parameters.
|
563
|
+
|
564
|
+
Note: To specify the acquisiton parameters please see set_region_of_interest, set_x_axis_conversion_type.
|
565
|
+
If there are no acquisition parameters set at the time of acquisition it may result in no data being generated.
|
383
566
|
|
384
567
|
Args:
|
385
|
-
open_shutter (bool): Whether the shutter of the camera should be open
|
568
|
+
open_shutter (bool): Whether the shutter of the camera should be open during the acquisition.
|
386
569
|
Raises:
|
387
570
|
Exception: When an error occurred on the device side
|
388
571
|
"""
|
389
572
|
await super()._execute_command('ccd_setAcquisitionStart', {'index': self._id, 'openShutter': open_shutter})
|
390
573
|
|
391
|
-
async def
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
) ->
|
401
|
-
"""
|
402
|
-
|
574
|
+
async def get_acquisition_busy(self) -> bool:
|
575
|
+
"""Returns true if the CCD is busy with the acquisition"""
|
576
|
+
response: Response = await super()._execute_command('ccd_getAcquisitionBusy', {'index': self._id})
|
577
|
+
return bool(response.results['isBusy'])
|
578
|
+
|
579
|
+
async def set_acquisition_abort(self, reset_port: bool = True) -> None:
|
580
|
+
"""Stops the acquisition of the CCD"""
|
581
|
+
await super()._execute_command('ccd_setAcquisitionAbort', {'index': self._id, 'resetPort': reset_port})
|
582
|
+
|
583
|
+
async def get_acquisition_data(self) -> dict[Any, Any]:
|
584
|
+
"""Retrieves data from the last acquisition.
|
585
|
+
|
586
|
+
The acquisition description string consists of the following information:
|
587
|
+
- acqIndex: Acquisition number
|
588
|
+
- roiIndex: Region of Interest number
|
589
|
+
- xOrigin: ROI’s X Origin
|
590
|
+
- yOrigin: ROI’s Y Origin
|
591
|
+
- xSize: ROI’s X Size
|
592
|
+
- ySize: ROI’s Y Size
|
593
|
+
- xBinning: ROI’s X Bin
|
594
|
+
- yBinning: ROI’s Y Bin
|
595
|
+
- Timestamp: This is a timestamp that relates to the time when the all the programmed acquisitions have
|
596
|
+
completed. The data from all programmed acquisitions are retrieve from the CCD after all
|
597
|
+
acquisitions have completed, therefore the same timestamp is used for all acquisitions.
|
598
|
+
"""
|
599
|
+
response: Response = await super()._execute_command('ccd_getAcquisitionData', {'index': self._id})
|
600
|
+
return response.results['acquisition']
|
601
|
+
|
602
|
+
async def set_center_wavelength(self, center_wavelength: float) -> None:
|
603
|
+
"""Sets the center wavelength value to be used in the grating equation.
|
604
|
+
|
605
|
+
Used when X axis conversion is XAxisConversionType.FROM_ICL_SETTINGS_INI
|
403
606
|
|
404
607
|
Args:
|
405
|
-
|
406
|
-
x_origin (int, optional): X origin of the region of interest. Defaults to 0.
|
407
|
-
y_origin (int, optional): Y origin of the region of interest. Defaults to 0.
|
408
|
-
x_size (int, optional): X size of the region of interest. Defaults to 1024.
|
409
|
-
y_size (int, optional): Y size of the region of interest. Defaults to 256.
|
410
|
-
x_bin (int, optional): X bin of the region of interest. Defaults to 1.
|
411
|
-
y_bin (int, optional): Y bin of the region of interest. Defaults to 256.
|
608
|
+
center_wavelength (float): Center wavelength
|
412
609
|
|
413
610
|
Raises:
|
414
611
|
Exception: When an error occurred on the device side
|
415
612
|
"""
|
416
613
|
await super()._execute_command(
|
417
|
-
'
|
418
|
-
{
|
419
|
-
'index': self._id,
|
420
|
-
'roiIndex': roi_index,
|
421
|
-
'xOrigin': x_origin,
|
422
|
-
'yOrigin': y_origin,
|
423
|
-
'xSize': x_size,
|
424
|
-
'ySize': y_size,
|
425
|
-
'xBin': x_bin,
|
426
|
-
'yBin': y_bin,
|
427
|
-
},
|
614
|
+
'ccd_setCenterWavelength',
|
615
|
+
{'index': self._id, 'wavelength': center_wavelength},
|
428
616
|
)
|
429
617
|
|
430
|
-
async def
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
return response.results
|
618
|
+
async def range_mode_center_wavelengths(
|
619
|
+
self, monochromator_index: int, start_wavelength: float, end_wavelength: float, pixel_overlap: int
|
620
|
+
) -> List[float]:
|
621
|
+
"""Finds the center wavelength positions based on the input range and pixel overlap.
|
435
622
|
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
623
|
+
The following commands are prerequisites and should be called prior to using this command:
|
624
|
+
- :func:`ChargeCoupledDevice.set_x`,
|
625
|
+
- :func:`ChargeCoupledDevice.ccd_setAcqFormat`,
|
626
|
+
- :func:`ChargeCoupledDevice.ccd_setRoi`
|
440
627
|
|
441
|
-
|
442
|
-
|
443
|
-
|
628
|
+
Args:
|
629
|
+
monochromator_index (int): Index of the monochromator that is connected to the setup
|
630
|
+
start_wavelength (float): Start wavelength
|
631
|
+
end_wavelength (float): End wavelength
|
632
|
+
pixel_overlap (int): Overlap size in pixels between the scans.
|
633
|
+
|
634
|
+
Returns:
|
635
|
+
List[float]: List of center wavelength positions to cover the desired range.
|
636
|
+
Raises:
|
637
|
+
Exception: When an error occurred on the device side
|
638
|
+
"""
|
639
|
+
response: Response = await super()._execute_command(
|
640
|
+
'ccd_calculateRangeModePositions',
|
641
|
+
{
|
642
|
+
'index': self._id,
|
643
|
+
'monoIndex': monochromator_index,
|
644
|
+
'start': start_wavelength,
|
645
|
+
'end': end_wavelength,
|
646
|
+
'overlap': pixel_overlap,
|
647
|
+
},
|
648
|
+
)
|
649
|
+
return response.results['centerWavelengths']
|