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