horiba-sdk 0.3.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 +19 -0
- horiba_sdk/communication/__init__.py +44 -0
- horiba_sdk/communication/abstract_communicator.py +59 -0
- horiba_sdk/communication/communication_exception.py +19 -0
- horiba_sdk/communication/messages.py +87 -0
- horiba_sdk/communication/websocket_communicator.py +213 -0
- horiba_sdk/core/resolution.py +45 -0
- horiba_sdk/devices/__init__.py +11 -0
- horiba_sdk/devices/abstract_device_discovery.py +7 -0
- horiba_sdk/devices/abstract_device_manager.py +68 -0
- horiba_sdk/devices/ccd_discovery.py +57 -0
- horiba_sdk/devices/device_manager.py +250 -0
- horiba_sdk/devices/fake_device_manager.py +133 -0
- horiba_sdk/devices/fake_icl_server.py +56 -0
- horiba_sdk/devices/fake_responses/ccd.json +168 -0
- horiba_sdk/devices/fake_responses/icl.json +29 -0
- horiba_sdk/devices/fake_responses/monochromator.json +187 -0
- horiba_sdk/devices/monochromator_discovery.py +48 -0
- horiba_sdk/devices/single_devices/__init__.py +5 -0
- horiba_sdk/devices/single_devices/abstract_device.py +79 -0
- horiba_sdk/devices/single_devices/ccd.py +443 -0
- horiba_sdk/devices/single_devices/monochromator.py +395 -0
- horiba_sdk/icl_error/__init__.py +34 -0
- horiba_sdk/icl_error/abstract_error.py +65 -0
- horiba_sdk/icl_error/abstract_error_db.py +25 -0
- horiba_sdk/icl_error/error_list.json +265 -0
- horiba_sdk/icl_error/icl_error.py +30 -0
- horiba_sdk/icl_error/icl_error_db.py +81 -0
- horiba_sdk/sync/__init__.py +0 -0
- horiba_sdk/sync/communication/__init__.py +7 -0
- horiba_sdk/sync/communication/abstract_communicator.py +48 -0
- horiba_sdk/sync/communication/test_client.py +16 -0
- horiba_sdk/sync/communication/websocket_communicator.py +212 -0
- horiba_sdk/sync/devices/__init__.py +15 -0
- horiba_sdk/sync/devices/abstract_device_discovery.py +17 -0
- horiba_sdk/sync/devices/abstract_device_manager.py +68 -0
- horiba_sdk/sync/devices/device_discovery.py +82 -0
- horiba_sdk/sync/devices/device_manager.py +209 -0
- horiba_sdk/sync/devices/fake_device_manager.py +91 -0
- horiba_sdk/sync/devices/fake_icl_server.py +79 -0
- horiba_sdk/sync/devices/single_devices/__init__.py +5 -0
- horiba_sdk/sync/devices/single_devices/abstract_device.py +83 -0
- horiba_sdk/sync/devices/single_devices/ccd.py +219 -0
- horiba_sdk/sync/devices/single_devices/monochromator.py +150 -0
- horiba_sdk-0.3.2.dist-info/LICENSE +20 -0
- horiba_sdk-0.3.2.dist-info/METADATA +438 -0
- horiba_sdk-0.3.2.dist-info/RECORD +48 -0
- horiba_sdk-0.3.2.dist-info/WHEEL +4 -0
@@ -0,0 +1,443 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
from types import TracebackType
|
3
|
+
from typing import Any, Optional, final
|
4
|
+
|
5
|
+
import pint
|
6
|
+
from loguru import logger
|
7
|
+
from overrides import override
|
8
|
+
|
9
|
+
from horiba_sdk import ureg
|
10
|
+
from horiba_sdk.communication import AbstractCommunicator, Response
|
11
|
+
from horiba_sdk.core.resolution import Resolution
|
12
|
+
from horiba_sdk.icl_error import AbstractErrorDB
|
13
|
+
|
14
|
+
from .abstract_device import AbstractDevice
|
15
|
+
|
16
|
+
|
17
|
+
@final
|
18
|
+
class ChargeCoupledDevice(AbstractDevice):
|
19
|
+
"""Charge Coupled Device
|
20
|
+
|
21
|
+
This class should not be instanced by the end user. Instead, the :class:`horiba_sdk.devices.DeviceManager`
|
22
|
+
should be used to access the detected CCDs on the system.
|
23
|
+
"""
|
24
|
+
|
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
|
+
def __init__(self, device_id: int, communicator: AbstractCommunicator, error_db: AbstractErrorDB) -> None:
|
60
|
+
super().__init__(device_id, communicator, error_db)
|
61
|
+
|
62
|
+
async def __aenter__(self) -> 'ChargeCoupledDevice':
|
63
|
+
await self.open()
|
64
|
+
return self
|
65
|
+
|
66
|
+
async def __aexit__(
|
67
|
+
self, exc_type: type[BaseException], exc_value: BaseException, traceback: Optional[TracebackType]
|
68
|
+
) -> None:
|
69
|
+
is_open = await self.is_open()
|
70
|
+
if not is_open:
|
71
|
+
logger.debug('CCD is already closed')
|
72
|
+
return
|
73
|
+
|
74
|
+
await self.close()
|
75
|
+
|
76
|
+
@override
|
77
|
+
async def open(self) -> None:
|
78
|
+
"""Opens the connection to the Charge Coupled Device
|
79
|
+
|
80
|
+
Raises:
|
81
|
+
Exception: When an error occurred on the device side
|
82
|
+
"""
|
83
|
+
await super().open()
|
84
|
+
await super()._execute_command('ccd_open', {'index': self._id})
|
85
|
+
|
86
|
+
@override
|
87
|
+
async def close(self) -> None:
|
88
|
+
"""Closes the connection to the ChargeCoupledDevice
|
89
|
+
|
90
|
+
Raises:
|
91
|
+
Exception: When an error occurred on the device side
|
92
|
+
"""
|
93
|
+
await super()._execute_command('ccd_close', {'index': self._id})
|
94
|
+
|
95
|
+
async def is_open(self) -> bool:
|
96
|
+
"""Checks if the connection to the charge coupled device is open.
|
97
|
+
|
98
|
+
Raises:
|
99
|
+
Exception: When an error occurred on the device side
|
100
|
+
"""
|
101
|
+
response: Response = await super()._execute_command('ccd_isOpen', {'index': self._id})
|
102
|
+
return bool(response.results['open'])
|
103
|
+
|
104
|
+
async def restart(self) -> None:
|
105
|
+
"""Restarts the charge coupled device
|
106
|
+
This command only works if the camera has been opened before.
|
107
|
+
The connection to the camera stays open after the restart.
|
108
|
+
|
109
|
+
Raises:
|
110
|
+
Exception: When an error occurred on the device side
|
111
|
+
"""
|
112
|
+
await super()._execute_command('ccd_restart', {'index': self._id})
|
113
|
+
|
114
|
+
async def get_configuration(self) -> dict[str, Any]:
|
115
|
+
"""Returns the configuration of the CCD
|
116
|
+
|
117
|
+
Returns:
|
118
|
+
dict[str, Any]: Configuration of the CCD
|
119
|
+
|
120
|
+
Raises:
|
121
|
+
Exception: When an error occurred on the device side
|
122
|
+
"""
|
123
|
+
response: Response = await super()._execute_command('ccd_getConfig', {'index': self._id})
|
124
|
+
return response.results
|
125
|
+
|
126
|
+
async def get_number_of_averages(self) -> int:
|
127
|
+
"""Returns the number of averages of the CCD
|
128
|
+
|
129
|
+
Returns:
|
130
|
+
int: Number of averages
|
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
|
151
|
+
|
152
|
+
Returns:
|
153
|
+
str: Gain
|
154
|
+
|
155
|
+
Raises:
|
156
|
+
Exception: When an error occurred on the device side
|
157
|
+
"""
|
158
|
+
response: Response = await super()._execute_command('ccd_getGain', {'index': self._id})
|
159
|
+
return str(response.results['info'])
|
160
|
+
|
161
|
+
async def set_gain(self, gain: Gain) -> None:
|
162
|
+
"""Sets the gain of the CCD
|
163
|
+
|
164
|
+
Args:
|
165
|
+
gain (Gain): Gain
|
166
|
+
|
167
|
+
Raises:
|
168
|
+
Exception: When an error occurred on the device side
|
169
|
+
"""
|
170
|
+
await super()._execute_command('ccd_setGain', {'index': self._id, 'token': gain.value})
|
171
|
+
|
172
|
+
async def get_speed(self) -> str:
|
173
|
+
"""Returns the speed of the CCD
|
174
|
+
|
175
|
+
Returns:
|
176
|
+
str: Speed
|
177
|
+
|
178
|
+
Raises:
|
179
|
+
Exception: When an error occurred on the device side
|
180
|
+
"""
|
181
|
+
response: Response = await super()._execute_command('ccd_getSpeed', {'index': self._id})
|
182
|
+
return str(response.results['info'])
|
183
|
+
|
184
|
+
async def set_speed(self, speed: Speed) -> None:
|
185
|
+
"""Sets the speed of the CCD
|
186
|
+
|
187
|
+
Args:
|
188
|
+
speed (Speed): Speed
|
189
|
+
|
190
|
+
Raises:
|
191
|
+
Exception: When an error occurred on the device side
|
192
|
+
"""
|
193
|
+
await super()._execute_command('ccd_setSpeed', {'index': self._id, 'token': speed.value})
|
194
|
+
|
195
|
+
async def get_fit_params(self) -> str:
|
196
|
+
"""Returns the fit parameters of the CCD
|
197
|
+
|
198
|
+
Returns:
|
199
|
+
str: Fit parameters
|
200
|
+
|
201
|
+
Raises:
|
202
|
+
Exception: When an error occurred on the device side
|
203
|
+
"""
|
204
|
+
response: Response = await super()._execute_command('ccd_getFitParams', {'index': self._id})
|
205
|
+
return str(response.results['params'])
|
206
|
+
|
207
|
+
async def set_fit_params(self, fit_params: str) -> None:
|
208
|
+
"""Sets the fit parameters of the CCD
|
209
|
+
|
210
|
+
Args:
|
211
|
+
fit_params (str): Fit parameters
|
212
|
+
|
213
|
+
Raises:
|
214
|
+
Exception: When an error occurred on the device side
|
215
|
+
"""
|
216
|
+
await super()._execute_command('ccd_setFitParams', {'index': self._id, 'params': fit_params})
|
217
|
+
|
218
|
+
async def get_timer_resolution(self) -> int:
|
219
|
+
"""Returns the timer resolution of the CCD
|
220
|
+
|
221
|
+
Returns:
|
222
|
+
int: Timer resolution
|
223
|
+
|
224
|
+
Raises:
|
225
|
+
Exception: When an error occurred on the device side
|
226
|
+
"""
|
227
|
+
response: Response = await super()._execute_command('ccd_getTimerResolution', {'index': self._id})
|
228
|
+
return int(response.results['resolution'])
|
229
|
+
|
230
|
+
async def set_timer_resolution(self, timer_resolution: int) -> None:
|
231
|
+
"""Sets the timer resolution of the CCD
|
232
|
+
|
233
|
+
Args:
|
234
|
+
timer_resolution (int): Timer resolution
|
235
|
+
|
236
|
+
Raises:
|
237
|
+
Exception: When an error occurred on the device side
|
238
|
+
"""
|
239
|
+
await super()._execute_command('ccd_setTimerResolution', {'index': self._id, 'resolution': timer_resolution})
|
240
|
+
|
241
|
+
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. After using this command
|
243
|
+
to set the number of ROIs and format, the ccd_setRoi command should be used to define each ROI.
|
244
|
+
Note: The Crop (2) and Fast Kinetics (3) acquisition formats are not supported by every CCD.
|
245
|
+
|
246
|
+
Args:
|
247
|
+
acquisition_format (AcquisitionFormat): Acquisition format
|
248
|
+
number_of_rois (int): Number of regions of interest
|
249
|
+
|
250
|
+
Raises:
|
251
|
+
Exception: When an error occurred on the device side
|
252
|
+
"""
|
253
|
+
await super()._execute_command(
|
254
|
+
'ccd_setAcqFormat', {'index': self._id, 'format': acquisition_format.value, 'numberOfRois': number_of_rois}
|
255
|
+
)
|
256
|
+
|
257
|
+
async def set_x_axis_conversion_type(self, conversion_type: XAxisConversionType) -> None:
|
258
|
+
"""Sets the X-axis pixel conversion type to be used when retrieving the acquisition data with the
|
259
|
+
ccd_getAcquisitionData command.
|
260
|
+
0 = None (default)
|
261
|
+
1 = CCD FIT parameters contained in the CCD firmware
|
262
|
+
2 = Mono Wavelength parameters contained in the icl_settings.ini file
|
263
|
+
|
264
|
+
Args:
|
265
|
+
conversion_type (XAxisConversionType): Conversion type Integer. The X-axis pixel conversion type to be used.
|
266
|
+
|
267
|
+
"""
|
268
|
+
await super()._execute_command('ccd_setXAxisConversionType', {'index': self._id, 'type': conversion_type.value})
|
269
|
+
|
270
|
+
async def get_x_axis_conversion_type(self) -> XAxisConversionType:
|
271
|
+
"""Gets the conversion type of the x axis.
|
272
|
+
0 = None (default)
|
273
|
+
1 = CCD FIT parameters contained in the CCD firmware
|
274
|
+
2 = Mono Wavelength parameters contained in the icl_settings.ini file
|
275
|
+
"""
|
276
|
+
response: Response = await super()._execute_command('ccd_getXAxisConversionType', {'index': self._id})
|
277
|
+
return self.XAxisConversionType(self.XAxisConversionType(response.results['type']))
|
278
|
+
|
279
|
+
async def set_acquisition_count(self, count: int) -> None:
|
280
|
+
"""Sets the number of acquisitions to be performed. The acquisition count is used to perform multiple
|
281
|
+
acquisitions in a row.
|
282
|
+
Args:
|
283
|
+
count (int): The number of acquisitions to be performed.
|
284
|
+
"""
|
285
|
+
await super()._execute_command('ccd_setAcqCount', {'index': self._id, 'count': count})
|
286
|
+
|
287
|
+
async def get_acquisition_count(self) -> int:
|
288
|
+
"""Gets the number of acquisitions to be performed. The acquisition count is used to perform multiple
|
289
|
+
acquisitions in a row.
|
290
|
+
"""
|
291
|
+
response: Response = await super()._execute_command('ccd_getAcqCount', {'index': self._id})
|
292
|
+
return int(response.results['count'])
|
293
|
+
|
294
|
+
async def get_clean_count(self) -> str:
|
295
|
+
"""Gets the clean count mode of the CCD and the according mode"""
|
296
|
+
response: Response = await super()._execute_command('ccd_getCleanCount', {'index': self._id})
|
297
|
+
answer: str = 'count: ' + str(response.results['count']) + ' ' + 'mode: ' + str(response.results['mode'])
|
298
|
+
return answer
|
299
|
+
|
300
|
+
async def set_clean_count(self, count: int, mode: CleanCountMode) -> None:
|
301
|
+
"""Sets the clean count mode of the CCD and the according mode
|
302
|
+
Args:
|
303
|
+
count (int): The number of acquisitions to be performed.
|
304
|
+
mode (CleanCountMode): The mode of the clean count
|
305
|
+
"""
|
306
|
+
await super()._execute_command('ccd_setCleanCount', {'index': self._id, 'count': count, 'mode': mode.value})
|
307
|
+
|
308
|
+
async def get_data_size(self) -> int:
|
309
|
+
"""Returns the size of the data of the CCD
|
310
|
+
|
311
|
+
Returns:
|
312
|
+
int: Size of the data
|
313
|
+
|
314
|
+
Raises:
|
315
|
+
Exception: When an error occurred on the device side
|
316
|
+
"""
|
317
|
+
response: Response = await super()._execute_command('ccd_getDataSize', {'index': self._id})
|
318
|
+
return int(response.results['size'])
|
319
|
+
|
320
|
+
async def get_temperature(self) -> pint.Quantity:
|
321
|
+
"""Chip temperature of the CCD.
|
322
|
+
|
323
|
+
Returns:
|
324
|
+
pint.Quantity: chip's temperature in degree Celsius
|
325
|
+
|
326
|
+
Raises:
|
327
|
+
Exception: When an error occurred on the device side
|
328
|
+
"""
|
329
|
+
response: Response = await super()._execute_command('ccd_getChipTemperature', {'index': self._id})
|
330
|
+
return ureg.Quantity(response.results['temperature'], ureg.degC) # type: ignore
|
331
|
+
|
332
|
+
async def get_chip_size(self) -> Resolution:
|
333
|
+
"""Chip resolution of the CCD.
|
334
|
+
|
335
|
+
Returns:
|
336
|
+
Resolution: chip resolution (width, height)
|
337
|
+
|
338
|
+
Raises:
|
339
|
+
Exception: When an error occurred on the device side
|
340
|
+
"""
|
341
|
+
response: Response = await super()._execute_command('ccd_getChipSize', {'index': self._id})
|
342
|
+
width: int = response.results['x']
|
343
|
+
height: int = response.results['y']
|
344
|
+
resolution: Resolution = Resolution(width, height)
|
345
|
+
return resolution
|
346
|
+
|
347
|
+
async def get_exposure_time(self) -> int:
|
348
|
+
"""Returns the exposure time in ms
|
349
|
+
|
350
|
+
Returns:
|
351
|
+
pint.Quantity: Exposure time in ms
|
352
|
+
Raises:
|
353
|
+
Exception: When an error occurred on the device side
|
354
|
+
"""
|
355
|
+
response: Response = await super()._execute_command('ccd_getExposureTime', {'index': self._id})
|
356
|
+
exposure = int(response.results['time'])
|
357
|
+
return exposure
|
358
|
+
|
359
|
+
async def set_exposure_time(self, exposure_time_ms: int) -> None:
|
360
|
+
"""Sets the exposure time in ms
|
361
|
+
|
362
|
+
Args:
|
363
|
+
exposure_time_ms (int): Exposure time in ms
|
364
|
+
Raises:
|
365
|
+
Exception: When an error occurred on the device side
|
366
|
+
"""
|
367
|
+
|
368
|
+
await super()._execute_command('ccd_setExposureTime', {'index': self._id, 'time': exposure_time_ms})
|
369
|
+
|
370
|
+
async def get_acquisition_ready(self) -> bool:
|
371
|
+
"""Returns true if the CCD is ready to acquire
|
372
|
+
|
373
|
+
Returns:
|
374
|
+
bool: True if the CCD is ready to acquire
|
375
|
+
Raises:
|
376
|
+
Exception: When an error occurred on the device side
|
377
|
+
"""
|
378
|
+
response: Response = await super()._execute_command('ccd_getAcquisitionReady', {'index': self._id})
|
379
|
+
return bool(response.results['ready'])
|
380
|
+
|
381
|
+
async def set_acquisition_start(self, open_shutter: bool) -> None:
|
382
|
+
"""Starts the acquisition of the CCD
|
383
|
+
|
384
|
+
Args:
|
385
|
+
open_shutter (bool): Whether the shutter of the camera should be open
|
386
|
+
Raises:
|
387
|
+
Exception: When an error occurred on the device side
|
388
|
+
"""
|
389
|
+
await super()._execute_command('ccd_setAcquisitionStart', {'index': self._id, 'openShutter': open_shutter})
|
390
|
+
|
391
|
+
async def set_region_of_interest(
|
392
|
+
self,
|
393
|
+
roi_index: int = 1,
|
394
|
+
x_origin: int = 0,
|
395
|
+
y_origin: int = 0,
|
396
|
+
x_size: int = 1024,
|
397
|
+
y_size: int = 256,
|
398
|
+
x_bin: int = 1,
|
399
|
+
y_bin: int = 256,
|
400
|
+
) -> None:
|
401
|
+
"""Sets the region of interest of the CCD
|
402
|
+
an example json command looks like this:
|
403
|
+
|
404
|
+
Args:
|
405
|
+
roi_index (int, optional): Index of the region of interest. Defaults to 1.
|
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.
|
412
|
+
|
413
|
+
Raises:
|
414
|
+
Exception: When an error occurred on the device side
|
415
|
+
"""
|
416
|
+
await super()._execute_command(
|
417
|
+
'ccd_setRoi',
|
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
|
+
},
|
428
|
+
)
|
429
|
+
|
430
|
+
async def get_acquisition_data(self) -> dict[Any, Any]:
|
431
|
+
"""Returns the acquisition data of the CCD
|
432
|
+
nina: atm this returns data still formatted for telnet communication, not formatted as json"""
|
433
|
+
response: Response = await super()._execute_command('ccd_getAcquisitionData', {'index': self._id})
|
434
|
+
return response.results
|
435
|
+
|
436
|
+
async def get_acquisition_busy(self) -> bool:
|
437
|
+
"""Returns true if the CCD is busy with the acquisition"""
|
438
|
+
response: Response = await super()._execute_command('ccd_getAcquisitionBusy', {'index': self._id})
|
439
|
+
return bool(response.results['isBusy'])
|
440
|
+
|
441
|
+
async def set_acquisition_abort(self) -> None:
|
442
|
+
"""Stops the acquisition of the CCD"""
|
443
|
+
await super()._execute_command('ccd_setAcquisitionAbort', {'index': self._id})
|