biosignal-device-interface 0.1.11b0__py3-none-any.whl → 0.1.32a1__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.
- biosignal_device_interface/__init__.py +0 -4
- biosignal_device_interface/constants/devices/__init__.py +3 -0
- biosignal_device_interface/constants/devices/core/base_device_constants.py +10 -0
- biosignal_device_interface/constants/devices/otb/otb_constants.py +0 -0
- biosignal_device_interface/constants/devices/otb/otb_quattrocento_constants.py +289 -35
- biosignal_device_interface/constants/devices/otb/otb_quattrocento_light_constants.py +59 -0
- biosignal_device_interface/constants/devices/otb/otb_syncstation_constants.py +233 -0
- biosignal_device_interface/devices/__init__.py +11 -3
- biosignal_device_interface/devices/core/base_device.py +8 -9
- biosignal_device_interface/devices/otb/__init__.py +27 -7
- biosignal_device_interface/devices/otb/otb_muovi.py +9 -10
- biosignal_device_interface/devices/otb/otb_quattrocento.py +215 -118
- biosignal_device_interface/devices/otb/otb_quattrocento_light.py +210 -0
- biosignal_device_interface/devices/otb/otb_syncstation.py +407 -0
- biosignal_device_interface/gui/device_template_widgets/__init__.py +0 -6
- biosignal_device_interface/gui/device_template_widgets/all_devices_widget.py +19 -7
- biosignal_device_interface/gui/device_template_widgets/core/base_device_widget.py +17 -8
- biosignal_device_interface/gui/device_template_widgets/core/base_multiple_devices_widget.py +7 -4
- biosignal_device_interface/gui/device_template_widgets/otb/__init__.py +0 -10
- biosignal_device_interface/gui/device_template_widgets/otb/otb_devices_widget.py +19 -7
- biosignal_device_interface/gui/device_template_widgets/otb/otb_muovi_plus_widget.py +11 -11
- biosignal_device_interface/gui/device_template_widgets/otb/otb_muovi_widget.py +11 -11
- biosignal_device_interface/gui/device_template_widgets/otb/otb_quattrocento_light_widget.py +61 -57
- biosignal_device_interface/gui/device_template_widgets/otb/otb_quattrocento_widget.py +260 -0
- biosignal_device_interface/gui/device_template_widgets/otb/otb_syncstation_widget.py +262 -0
- biosignal_device_interface/gui/plot_widgets/biosignal_plot_widget.py +9 -4
- biosignal_device_interface/gui/ui/otb_quattrocento_template_widget.ui +415 -0
- biosignal_device_interface/gui/ui/otb_syncstation_template_widget.ui +732 -0
- biosignal_device_interface/gui/ui_compiled/otb_quattrocento_template_widget.py +318 -0
- biosignal_device_interface/gui/ui_compiled/otb_syncstation_template_widget.py +495 -0
- biosignal_device_interface-0.1.32a1.dist-info/LICENSE +675 -0
- {biosignal_device_interface-0.1.11b0.dist-info → biosignal_device_interface-0.1.32a1.dist-info}/METADATA +7 -17
- biosignal_device_interface-0.1.32a1.dist-info/RECORD +46 -0
- biosignal_device_interface-0.1.11b0.dist-info/LICENSE +0 -395
- biosignal_device_interface-0.1.11b0.dist-info/RECORD +0 -35
- {biosignal_device_interface-0.1.11b0.dist-info → biosignal_device_interface-0.1.32a1.dist-info}/WHEEL +0 -0
|
@@ -16,9 +16,11 @@ class DeviceType(Enum):
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
_init_ = "value __doc__"
|
|
19
|
+
OTB_QUATTROCENTO = auto(), "OT Bioelettronica Quattrocento"
|
|
19
20
|
OTB_QUATTROCENTO_LIGHT = auto(), "OT Bioelettronica Quattrocento Light"
|
|
20
21
|
OTB_MUOVI = auto(), "OT Bioelettronica Muovi"
|
|
21
22
|
OTB_MUOVI_PLUS = auto(), "OT Bioelettronica Muovi Plus"
|
|
23
|
+
OTB_SYNCSTATION = auto(), "OT Bioelettronica SyncStation"
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class OTBDeviceType(Enum):
|
|
@@ -27,9 +29,13 @@ class OTBDeviceType(Enum):
|
|
|
27
29
|
Add new devices here.
|
|
28
30
|
"""
|
|
29
31
|
|
|
32
|
+
_init_ = "value __doc__"
|
|
33
|
+
|
|
34
|
+
QUATTROCENTO = auto(), "Quattrocento"
|
|
30
35
|
QUATTROCENTO_LIGHT = auto(), "Quattrocento Light"
|
|
31
36
|
MUOVI = auto(), "Muovi"
|
|
32
37
|
MUOVI_PLUS = auto(), "Muovi Plus"
|
|
38
|
+
SYNCSTATION = auto(), "SyncStation"
|
|
33
39
|
|
|
34
40
|
|
|
35
41
|
class DeviceChannelTypes(Enum):
|
|
@@ -42,10 +48,14 @@ class DeviceChannelTypes(Enum):
|
|
|
42
48
|
|
|
43
49
|
############# CONSTANTS #############
|
|
44
50
|
DEVICE_NAME_DICT: dict[DeviceType | OTBDeviceType, str] = {
|
|
51
|
+
DeviceType.OTB_QUATTROCENTO: "Quattrocento",
|
|
52
|
+
OTBDeviceType.QUATTROCENTO: "Quattrocento",
|
|
45
53
|
DeviceType.OTB_QUATTROCENTO_LIGHT: "Quattrocento Light",
|
|
46
54
|
OTBDeviceType.QUATTROCENTO_LIGHT: "Quattrocento Light",
|
|
47
55
|
DeviceType.OTB_MUOVI: "Muovi",
|
|
48
56
|
OTBDeviceType.MUOVI: "Muovi",
|
|
49
57
|
DeviceType.OTB_MUOVI_PLUS: "Muovi Plus",
|
|
50
58
|
OTBDeviceType.MUOVI_PLUS: "Muovi Plus",
|
|
59
|
+
DeviceType.OTB_SYNCSTATION: "SyncStation",
|
|
60
|
+
OTBDeviceType.SYNCSTATION: "SyncStation",
|
|
51
61
|
}
|
|
File without changes
|
|
@@ -1,17 +1,78 @@
|
|
|
1
1
|
from aenum import Enum, auto
|
|
2
2
|
|
|
3
|
+
"""
|
|
4
|
+
Quattrocento constants.
|
|
5
|
+
|
|
6
|
+
Developer: Dominik I. Braun
|
|
7
|
+
Contact: dome.braun@fau.de
|
|
8
|
+
Last Update: 2025-01-14
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# ------- Command Byte Sequences --------
|
|
13
|
+
class QuattrocentoCommandSequence(Enum):
|
|
14
|
+
"""
|
|
15
|
+
Enum class for the different kind of command sequences.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
_init_ = "value __doc__"
|
|
19
|
+
|
|
20
|
+
NONE = auto(), "None"
|
|
21
|
+
ACQ_SETT = auto(), "Acquisition settings command sequence"
|
|
22
|
+
AN_OUT_IN_SEL = auto(), "Select input source and gain for the analog output"
|
|
23
|
+
AN_OUT_CH_SEL = auto(), "Select the channel for the analog output source"
|
|
24
|
+
IN_CONF = auto(), (
|
|
25
|
+
"Configuration command sequence for the eight IN inputs or",
|
|
26
|
+
"configuration for the four MULTIPLE IN inputs",
|
|
27
|
+
)
|
|
28
|
+
CRC = auto(), "Configuration command sequence byte (8 bits)"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# ------------ ACQ_SETT BYTE ------------
|
|
32
|
+
# Bit 7 is fixed to 1.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class QuattrocentoDecimMode(Enum):
|
|
36
|
+
"""
|
|
37
|
+
Enum class for the decimation bit of the Quattrocento device.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
_init_ = "value __doc__"
|
|
41
|
+
|
|
42
|
+
INACTIVE = auto(), (
|
|
43
|
+
"Inactive. No decimation. The required sampling",
|
|
44
|
+
"frequency is obtained by sampling the signals",
|
|
45
|
+
"directly at the desired sampling frequency ",
|
|
46
|
+
)
|
|
47
|
+
ACTIVE = auto(), (
|
|
48
|
+
"Active. Decimation active.",
|
|
49
|
+
"The required sampling frequency is obtained by",
|
|
50
|
+
"sampling all the signals at 10240 Hz and then",
|
|
51
|
+
"sending one sample out of 2, 5 or 20, to obtain",
|
|
52
|
+
"the desired number of sample per second.",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class QuattrocentoRecordingMode(Enum):
|
|
57
|
+
"""
|
|
58
|
+
Enum class for the recording bit.
|
|
59
|
+
|
|
60
|
+
If the Trigger OUT has to be used to synchronize the acquisition with
|
|
61
|
+
other instruments, the recording has to be started when the trigger
|
|
62
|
+
channel has a transition. In other words it is the quattrocento that
|
|
63
|
+
generate a signal indicating to the computer when the data has to be
|
|
64
|
+
recorded.
|
|
65
|
+
"""
|
|
3
66
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
CONNECTION_RESPONSE = b"OTBioLab"
|
|
67
|
+
_init_ = "value __doc__"
|
|
68
|
+
|
|
69
|
+
STOP = auto(), "Stop"
|
|
70
|
+
START = auto(), "Start"
|
|
9
71
|
|
|
10
72
|
|
|
11
|
-
|
|
12
|
-
class QuattrocentoLightSamplingFrequency(Enum):
|
|
73
|
+
class QuattrocentoSamplingFrequencyMode(Enum):
|
|
13
74
|
"""
|
|
14
|
-
Enum class for the sampling frequencies of the Quattrocento
|
|
75
|
+
Enum class for the sampling frequencies of the Quattrocento device (2 bits).
|
|
15
76
|
"""
|
|
16
77
|
|
|
17
78
|
_init_ = "value __doc__"
|
|
@@ -22,38 +83,231 @@ class QuattrocentoLightSamplingFrequency(Enum):
|
|
|
22
83
|
ULTRA = auto(), "10240 Hz"
|
|
23
84
|
|
|
24
85
|
|
|
25
|
-
class
|
|
86
|
+
class QuattrocentoNumberOfChannelsMode(Enum):
|
|
26
87
|
"""
|
|
27
|
-
Enum class for the
|
|
88
|
+
Enum class for the number of channels of the Quattrocento device (2 bits).
|
|
28
89
|
"""
|
|
29
90
|
|
|
30
91
|
_init_ = "value __doc__"
|
|
31
92
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
SIXTEEN = auto(), "16 Hz"
|
|
37
|
-
THIRTYTWO = auto(), "32 Hz"
|
|
93
|
+
LOW = auto(), "IN1, IN2 and MULTIPLE_IN1 are active."
|
|
94
|
+
MEDIUM = auto(), "IN1-IN4, MULTIPLE_IN1, MULTIPLE_IN2 are active."
|
|
95
|
+
HIGH = auto(), "IN1-IN6, MULTIPLE_IN1-MULTIPLE_IN2 are active."
|
|
96
|
+
ULTRA = auto(), "IN1-IN8, MULTIPLE_IN1-MULTIPLE_IN4 are active."
|
|
38
97
|
|
|
39
98
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
""
|
|
99
|
+
class QuattrocentoAcquisitionMode(Enum):
|
|
100
|
+
"""
|
|
101
|
+
Enum class for the acquisition bit.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
_init_ = "value __doc__"
|
|
105
|
+
|
|
106
|
+
INACTIVE = auto(), "Inactive. Data sampling and transfer is not active"
|
|
107
|
+
ACTIVE = auto(), "Active. Data sampling and transfer is active"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class QuattrocentoAcqSettByte:
|
|
111
|
+
"""
|
|
112
|
+
Class for the acquisition settings byte of the Quattrocento device.
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
def __init__(self):
|
|
116
|
+
self._decimation_mode: QuattrocentoDecimMode = None
|
|
117
|
+
self._recording_mode: QuattrocentoRecordingMode = None
|
|
118
|
+
self._sampling_frequency_mode: QuattrocentoSamplingFrequencyMode = None
|
|
119
|
+
self._sampling_frequency: int = None
|
|
120
|
+
self._number_of_channels_mode: QuattrocentoNumberOfChannelsMode = None
|
|
121
|
+
self._number_of_channels: int = None
|
|
122
|
+
self._acquisition_mode: QuattrocentoAcquisitionMode = (
|
|
123
|
+
QuattrocentoAcquisitionMode
|
|
124
|
+
).INACTIVE
|
|
125
|
+
|
|
126
|
+
def update(
|
|
127
|
+
self,
|
|
128
|
+
decimation_mode: QuattrocentoDecimMode,
|
|
129
|
+
recording_mode: QuattrocentoRecordingMode,
|
|
130
|
+
sampling_frequency_mode: QuattrocentoSamplingFrequencyMode,
|
|
131
|
+
number_of_channels_mode: QuattrocentoNumberOfChannelsMode,
|
|
132
|
+
):
|
|
133
|
+
self._decimation_mode = decimation_mode
|
|
134
|
+
self._recording_mode = recording_mode
|
|
135
|
+
self._sampling_frequency_mode = sampling_frequency_mode
|
|
136
|
+
self._number_of_channels_mode = number_of_channels_mode
|
|
137
|
+
|
|
138
|
+
self._configure()
|
|
139
|
+
|
|
140
|
+
def _configure(self):
|
|
141
|
+
self._set_sampling_frequency()
|
|
142
|
+
self._set_number_of_channels()
|
|
143
|
+
|
|
144
|
+
def _set_sampling_frequency(self) -> None:
|
|
145
|
+
mode = self._sampling_frequency_mode
|
|
146
|
+
match mode:
|
|
147
|
+
case QuattrocentoSamplingFrequencyMode.LOW:
|
|
148
|
+
self._sampling_frequency = 512
|
|
149
|
+
case QuattrocentoSamplingFrequencyMode.MEDIUM:
|
|
150
|
+
self._sampling_frequency = 2048
|
|
151
|
+
case QuattrocentoSamplingFrequencyMode.HIGH:
|
|
152
|
+
self._sampling_frequency = 5120
|
|
153
|
+
case QuattrocentoSamplingFrequencyMode.ULTRA:
|
|
154
|
+
self._sampling_frequency = 10240
|
|
155
|
+
case _:
|
|
156
|
+
raise ValueError("Invalid sampling frequency mode.")
|
|
157
|
+
|
|
158
|
+
def _set_number_of_channels(self) -> None:
|
|
159
|
+
mode = self._number_of_channels_mode
|
|
160
|
+
match mode:
|
|
161
|
+
case QuattrocentoNumberOfChannelsMode.LOW:
|
|
162
|
+
self._number_of_channels = 120
|
|
163
|
+
case QuattrocentoNumberOfChannelsMode.MEDIUM:
|
|
164
|
+
self._number_of_channels = 216
|
|
165
|
+
case QuattrocentoNumberOfChannelsMode.HIGH:
|
|
166
|
+
self._number_of_channels = 312
|
|
167
|
+
case QuattrocentoNumberOfChannelsMode.ULTRA:
|
|
168
|
+
self._number_of_channels = 408
|
|
169
|
+
case _:
|
|
170
|
+
raise ValueError("Invalid number of channels mode.")
|
|
171
|
+
|
|
172
|
+
def get_sampling_frequency(self) -> int:
|
|
173
|
+
return self._sampling_frequency
|
|
174
|
+
|
|
175
|
+
def get_number_of_channels(self) -> int:
|
|
176
|
+
return self._number_of_channels
|
|
177
|
+
|
|
178
|
+
def __int__(self):
|
|
179
|
+
acq_sett_byte = 1 << 7
|
|
180
|
+
acq_sett_byte += (self._decimation_mode.value - 1) << 6
|
|
181
|
+
acq_sett_byte += (self._recording_mode.value - 1) << 5
|
|
182
|
+
acq_sett_byte += (self._sampling_frequency_mode.value - 1) << 3
|
|
183
|
+
acq_sett_byte += (self._number_of_channels_mode.value - 1) << 1
|
|
184
|
+
acq_sett_byte += self._acquisition_mode.value - 1
|
|
185
|
+
|
|
186
|
+
return int(acq_sett_byte)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# ---------- AN_OUT_IN_SEL BYTE ----------
|
|
190
|
+
# Bit 7 and bit 6 are fixed to 0.
|
|
191
|
+
# TODO:
|
|
192
|
+
|
|
193
|
+
# ---------- AN_OUT_CH_SEL BYTE ----------
|
|
194
|
+
# Bit 7 and bit 6 are fixed to 0.
|
|
195
|
+
# TODO:
|
|
196
|
+
|
|
197
|
+
# -- INX_CONF0 and MULTIPLE_INX_CONF0 BYTE --
|
|
198
|
+
# Bit 7 is fixed to 0.
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class QuattrocentoMuscleSelectionMode(Enum):
|
|
202
|
+
"""
|
|
203
|
+
Enum class for the muscle selection mode of the
|
|
204
|
+
Quattrocento device (5 bits).
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class QuattrocentoSensorSelectionMode(Enum):
|
|
209
|
+
"""
|
|
210
|
+
Enum class for the sensor selection mode of the
|
|
211
|
+
Quattrocento device (5 bits).
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
# TODO: "Implement"
|
|
215
|
+
...
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class QuattrocentoSideMode(Enum):
|
|
219
|
+
""""""
|
|
220
|
+
|
|
221
|
+
_init_ = "value __doc__"
|
|
222
|
+
UNDEFINED = auto(), "Undefined"
|
|
223
|
+
LEFT = auto(), "Left"
|
|
224
|
+
RIGHT = auto(), "Right"
|
|
225
|
+
NONE = auto(), "None"
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
# ---------- INX_CONF2 BYTE ----------
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class QuattrocentoHighPassFilterMode(Enum):
|
|
232
|
+
"""
|
|
233
|
+
Enum class for the high-pass filter of INPUT INX or MULTIPLE INX (2 bits).
|
|
234
|
+
"""
|
|
235
|
+
|
|
236
|
+
_init_ = "value __doc__"
|
|
237
|
+
|
|
238
|
+
NONE = auto(), "No high-pass filter"
|
|
239
|
+
LOW = auto(), "High-pass filter at 0.7 Hz"
|
|
240
|
+
MEDIUM = auto(), "High-pass filter at 10 Hz"
|
|
241
|
+
HIGH = auto(), "High-pass filter at 100 Hz"
|
|
242
|
+
ULTRA = auto(), "High-pass filter at 200 Hz"
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class QuattrocentoLowPassFilterMode(Enum):
|
|
246
|
+
"""
|
|
247
|
+
Enum class for the low-pass filter of INPUT INX or MULTIPLE INX (2 bits).
|
|
248
|
+
0 -> LOW: 130 Hz
|
|
249
|
+
1 -> MEDIUM: 500 Hz
|
|
250
|
+
2 -> HIGH: 900 Hz
|
|
251
|
+
3 -> ULTRA: 4400 Hz
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
_init_ = "value __doc__"
|
|
255
|
+
|
|
256
|
+
LOW = auto(), "Low-pass filter at 130 Hz"
|
|
257
|
+
MEDIUM = auto(), "Low-pass filter at 500 Hz"
|
|
258
|
+
HIGH = auto(), "Low-pass filter at 900 Hz"
|
|
259
|
+
ULTRA = auto(), "Low-pass filter at 4400 Hz"
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class QuattrocentoDetectionMode(Enum):
|
|
263
|
+
"""
|
|
264
|
+
Enum class for the detection mode of the Quattrocento device (2 bits).
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
_init_ = "value __doc_"
|
|
268
|
+
|
|
269
|
+
NONE = auto(), "No detection"
|
|
270
|
+
MONOPOLAR = auto(), "Monopolar detection"
|
|
271
|
+
BIPOLAR = auto(), "Bipolar detection"
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class QuattrocentoINXConf2Byte:
|
|
275
|
+
"""
|
|
276
|
+
Class for the INX_CONF2 byte of the Quattrocento device.
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
def __init__(self):
|
|
280
|
+
self._muscle_selection_mode: QuattrocentoMuscleSelectionMode = None
|
|
281
|
+
self._sensor_selection_mode: QuattrocentoSensorSelectionMode = None
|
|
282
|
+
self._side_mode: QuattrocentoSideMode = QuattrocentoSideMode.UNDEFINED
|
|
283
|
+
self._high_pass_filter: QuattrocentoHighPassFilterMode = None
|
|
284
|
+
self._low_pass_filter: QuattrocentoLowPassFilterMode = None
|
|
285
|
+
self._detection_mode: QuattrocentoDetectionMode = None
|
|
286
|
+
|
|
287
|
+
def update(
|
|
288
|
+
self,
|
|
289
|
+
high_pass_filter: QuattrocentoHighPassFilterMode,
|
|
290
|
+
low_pass_filter: QuattrocentoLowPassFilterMode,
|
|
291
|
+
detection_mode: QuattrocentoDetectionMode,
|
|
292
|
+
):
|
|
293
|
+
self._high_pass_filter = high_pass_filter
|
|
294
|
+
self._low_pass_filter = low_pass_filter
|
|
295
|
+
self._detection_mode = detection_mode
|
|
296
|
+
|
|
297
|
+
def __int__(self):
|
|
298
|
+
input_conf_byte_1 = 0 # TODO: Muscle
|
|
299
|
+
input_conf_byte_2 = 0 # TODO: Sensor + Adapter
|
|
300
|
+
input_conf_byte_3 = (self._side_mode.value - 1) << 6
|
|
301
|
+
input_conf_byte_3 += (self._high_pass_filter.value - 1) << 4
|
|
302
|
+
input_conf_byte_3 += (self._low_pass_filter.value - 1) << 2
|
|
303
|
+
input_conf_byte_3 += self._detection_mode.value - 1
|
|
304
|
+
|
|
305
|
+
return int(
|
|
306
|
+
(input_conf_byte_1 << 16) + (input_conf_byte_2 << 8) + input_conf_byte_3
|
|
307
|
+
)
|
|
308
|
+
|
|
49
309
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
QuattrocentoLightStreamingFrequency.TWO: 2,
|
|
55
|
-
QuattrocentoLightStreamingFrequency.FOUR: 4,
|
|
56
|
-
QuattrocentoLightStreamingFrequency.EIGHT: 8,
|
|
57
|
-
QuattrocentoLightStreamingFrequency.SIXTEEN: 16,
|
|
58
|
-
QuattrocentoLightStreamingFrequency.THIRTYTWO: 32,
|
|
59
|
-
}
|
|
310
|
+
QUATTROCENTO_AUXILIARY_CHANNELS: int = 16
|
|
311
|
+
QUATTROCENTO_SUPPLEMENTARY_CHANNELS: int = 8
|
|
312
|
+
QUATTROCENTO_SAMPLES_PER_FRAME: int = 64
|
|
313
|
+
QUATTROCENTO_BYTES_PER_SAMPLE: int = 2
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from aenum import Enum, auto
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Quattrocento Light constants
|
|
5
|
+
############# COMMANDS #############
|
|
6
|
+
COMMAND_START_STREAMING = b"startTX"
|
|
7
|
+
COMMAND_STOP_STREAMING = b"stopTX"
|
|
8
|
+
CONNECTION_RESPONSE = b"OTBioLab"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
############# QUATTROCENTO LIGHT #############
|
|
12
|
+
class QuattrocentoLightSamplingFrequency(Enum):
|
|
13
|
+
"""
|
|
14
|
+
Enum class for the sampling frequencies of the Quattrocento Light device.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
_init_ = "value __doc__"
|
|
18
|
+
|
|
19
|
+
LOW = auto(), "512 Hz"
|
|
20
|
+
MEDIUM = auto(), "2048 Hz"
|
|
21
|
+
HIGH = auto(), "5120 Hz"
|
|
22
|
+
ULTRA = auto(), "10240 Hz"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class QuattrocentoLightStreamingFrequency(Enum):
|
|
26
|
+
"""
|
|
27
|
+
Enum class for the streaming frequencies of the Quattrocento Light device.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
_init_ = "value __doc__"
|
|
31
|
+
|
|
32
|
+
ONE = auto(), "1 Hz"
|
|
33
|
+
TWO = auto(), "2 Hz"
|
|
34
|
+
FOUR = auto(), "4 Hz"
|
|
35
|
+
EIGHT = auto(), "8 Hz"
|
|
36
|
+
SIXTEEN = auto(), "16 Hz"
|
|
37
|
+
THIRTYTWO = auto(), "32 Hz"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
QUATTROCENTO_SAMPLING_FREQUENCY_DICT: dict[QuattrocentoLightSamplingFrequency, int] = {
|
|
41
|
+
QuattrocentoLightSamplingFrequency.LOW: 512,
|
|
42
|
+
QuattrocentoLightSamplingFrequency.MEDIUM: 2048,
|
|
43
|
+
QuattrocentoLightSamplingFrequency.HIGH: 5120,
|
|
44
|
+
QuattrocentoLightSamplingFrequency.ULTRA: 10240,
|
|
45
|
+
}
|
|
46
|
+
"""
|
|
47
|
+
Dictionary to get sampling frequency for each mode.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
QUATTROCENTO_LIGHT_STREAMING_FREQUENCY_DICT: dict[
|
|
51
|
+
QuattrocentoLightStreamingFrequency, int
|
|
52
|
+
] = {
|
|
53
|
+
QuattrocentoLightStreamingFrequency.ONE: 1,
|
|
54
|
+
QuattrocentoLightStreamingFrequency.TWO: 2,
|
|
55
|
+
QuattrocentoLightStreamingFrequency.FOUR: 4,
|
|
56
|
+
QuattrocentoLightStreamingFrequency.EIGHT: 8,
|
|
57
|
+
QuattrocentoLightStreamingFrequency.SIXTEEN: 16,
|
|
58
|
+
QuattrocentoLightStreamingFrequency.THIRTYTWO: 32,
|
|
59
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Device class for real-time interfacing the OTB Syncstation device.
|
|
3
|
+
Developer: Dominik I. Braun
|
|
4
|
+
Contact: dome.braun@fau.de
|
|
5
|
+
Last Update: 2025-01-09
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, Union
|
|
9
|
+
from aenum import Enum, auto
|
|
10
|
+
from biosignal_device_interface.constants.devices.core.base_device_constants import (
|
|
11
|
+
DeviceType,
|
|
12
|
+
DeviceChannelTypes,
|
|
13
|
+
)
|
|
14
|
+
from biosignal_device_interface.constants.devices.otb.otb_muovi_constants import (
|
|
15
|
+
MUOVI_AVAILABLE_CHANNELS_DICT,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SyncStationRecOnMode(Enum):
|
|
20
|
+
"""
|
|
21
|
+
Enum class for the recording on mode of the SyncStation device.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
_init_ = "value __doc__"
|
|
25
|
+
|
|
26
|
+
OFF = auto(), (
|
|
27
|
+
"The PC is not recording the received signals from SyncStation."
|
|
28
|
+
"If the Timestapms.log is closed if it was previously opened."
|
|
29
|
+
)
|
|
30
|
+
ON = auto(), (
|
|
31
|
+
"The PC is recording the signals received by the SyncStation."
|
|
32
|
+
"When triggered, this bit reset the internal timer for the"
|
|
33
|
+
"ramp counter sent on the Accessory Ch2 and start the log of"
|
|
34
|
+
"the timestamps on the internal timestamps.log file"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SyncStationWorkingMode(Enum):
|
|
39
|
+
"""
|
|
40
|
+
Enum class for the sampling frequency mode of the SyncStation device.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
_init_ = "value __doc__"
|
|
44
|
+
|
|
45
|
+
NONE = 0, "No working mode set."
|
|
46
|
+
EEG = auto(), "EEG Mode Fsamp 500 Hz, DC coupled, 24 bit resolution."
|
|
47
|
+
EMG = (
|
|
48
|
+
auto(),
|
|
49
|
+
"EMG Mode Fsamp 2000 Hz, high pass filter at 10 Hz*, 16 bit resolution",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class SyncStationDetectionMode(Enum):
|
|
54
|
+
"""
|
|
55
|
+
Enum class for the detection mode of the SyncStation device.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
_init_ = "value __doc__"
|
|
59
|
+
|
|
60
|
+
NONE = 0, "No detection mode set."
|
|
61
|
+
MONOPOLAR_GAIN_HIGH = auto(), (
|
|
62
|
+
"Monopolar Mode. High gain. 32 monopolar bioelectrical signals + 6 accessory signals. "
|
|
63
|
+
"Resolution is 286.1 nV and range +/-9.375 mV."
|
|
64
|
+
)
|
|
65
|
+
MONOPOLAR_GAIN_LOW = auto(), (
|
|
66
|
+
"Monopolar Mode. Low gain. 32 monopolar bioelectrical signals + 6 accessory signals. "
|
|
67
|
+
"Resolution is 572.2nV and range +/-18.75 mV."
|
|
68
|
+
)
|
|
69
|
+
IMPEDANCE_CHECK = auto(), "Impedance Check on all 32 + 6 channels."
|
|
70
|
+
TEST = auto(), "Ramps on all 32 + 6 channels."
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class SyncStationProbeConfigMode(Enum):
|
|
74
|
+
"""
|
|
75
|
+
Enum class for the probe configuration mode of the SyncStation device.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
_init_ = "value __doc__"
|
|
79
|
+
|
|
80
|
+
NONE = 0, "No probe configuration mode set."
|
|
81
|
+
MUOVI_PROBE_ONE = auto(), "Probe configuration mode for Muovi probe one."
|
|
82
|
+
MUOVI_PROBE_TWO = auto(), "Probe configuration mode for Muovi probe two."
|
|
83
|
+
MUOVI_PROBE_THREE = auto(), "Probe configuration mode for Muovi probe three."
|
|
84
|
+
MUOVI_PROBE_FOUR = auto(), "Probe configuration mode for Muovi probe four."
|
|
85
|
+
MUOVI_PLUS_PROBE_ONE = auto(), "Probe configuration mode for Muovi Plus probe one."
|
|
86
|
+
MUOVI_PLUS_PROBE_TWO = auto(), "Probe configuration mode for Muovi Plus probe two."
|
|
87
|
+
DUE_PLUS_PROBE_ONE = (
|
|
88
|
+
auto(),
|
|
89
|
+
"Probe configuration mode for Due Plus probe one.",
|
|
90
|
+
)
|
|
91
|
+
DUE_PLUS_PROBE_TWO = (
|
|
92
|
+
auto(),
|
|
93
|
+
"Probe configuration mode for Due Plus probe two.",
|
|
94
|
+
)
|
|
95
|
+
DUE_PLUS_PROBE_THREE = (
|
|
96
|
+
auto(),
|
|
97
|
+
"Probe configuration mode for Due Plus probe three.",
|
|
98
|
+
)
|
|
99
|
+
DUE_PLUS_PROBE_FOUR = (
|
|
100
|
+
auto(),
|
|
101
|
+
"Probe configuration mode for Due Plus probe four.",
|
|
102
|
+
)
|
|
103
|
+
DUE_PLUS_PROBE_FIVE = (
|
|
104
|
+
auto(),
|
|
105
|
+
"Probe configuration mode for Due Plus probe five.",
|
|
106
|
+
)
|
|
107
|
+
DUE_PLUS_PROBE_SIX = (
|
|
108
|
+
auto(),
|
|
109
|
+
"Probe configuration mode for Due Plus probe six.",
|
|
110
|
+
)
|
|
111
|
+
DUE_PLUS_PROBE_SEVEN = (
|
|
112
|
+
auto(),
|
|
113
|
+
"Probe configuration mode for Due Plus probe seven.",
|
|
114
|
+
)
|
|
115
|
+
DUE_PLUS_PROBE_EIGHT = (
|
|
116
|
+
auto(),
|
|
117
|
+
"Probe configuration mode for Due Plus probe eight.",
|
|
118
|
+
)
|
|
119
|
+
DUE_PLUS_PROBE_NINE = (
|
|
120
|
+
auto(),
|
|
121
|
+
"Probe configuration mode for Due Plus probe nine.",
|
|
122
|
+
)
|
|
123
|
+
DUE_PLUS_PROBE_TEN = (
|
|
124
|
+
auto(),
|
|
125
|
+
"Probe configuration mode for Due Plus probe ten.",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# DICTS
|
|
130
|
+
|
|
131
|
+
SYNCSTATION_CHARACTERISTICS_DICT: Dict[str, int] = {
|
|
132
|
+
DeviceChannelTypes.ALL: 6,
|
|
133
|
+
"bytes_per_sample": 2,
|
|
134
|
+
"channel_information": {
|
|
135
|
+
SyncStationWorkingMode.EEG: {
|
|
136
|
+
"sampling_frequency": 500,
|
|
137
|
+
"bytes_per_sample": 3,
|
|
138
|
+
"frame_size": 5,
|
|
139
|
+
},
|
|
140
|
+
SyncStationWorkingMode.EMG: {
|
|
141
|
+
"sampling_frequency": 2000,
|
|
142
|
+
"bytes_per_sample": 2,
|
|
143
|
+
"frame_size": 10,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
"number_of_packages": 32,
|
|
147
|
+
"package_size": 1460,
|
|
148
|
+
"FPS": 50,
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# TODO: Load information from Device Constants directly!
|
|
152
|
+
PROBE_CHARACTERISTICS_DICT: Dict[
|
|
153
|
+
SyncStationProbeConfigMode, Dict[str, Union[str, int]]
|
|
154
|
+
] = {
|
|
155
|
+
SyncStationProbeConfigMode.MUOVI_PROBE_ONE: MUOVI_AVAILABLE_CHANNELS_DICT[
|
|
156
|
+
DeviceType.OTB_MUOVI
|
|
157
|
+
],
|
|
158
|
+
SyncStationProbeConfigMode.MUOVI_PROBE_TWO: MUOVI_AVAILABLE_CHANNELS_DICT[
|
|
159
|
+
DeviceType.OTB_MUOVI
|
|
160
|
+
],
|
|
161
|
+
SyncStationProbeConfigMode.MUOVI_PROBE_THREE: MUOVI_AVAILABLE_CHANNELS_DICT[
|
|
162
|
+
DeviceType.OTB_MUOVI
|
|
163
|
+
],
|
|
164
|
+
SyncStationProbeConfigMode.MUOVI_PROBE_FOUR: MUOVI_AVAILABLE_CHANNELS_DICT[
|
|
165
|
+
DeviceType.OTB_MUOVI
|
|
166
|
+
],
|
|
167
|
+
SyncStationProbeConfigMode.MUOVI_PLUS_PROBE_ONE: MUOVI_AVAILABLE_CHANNELS_DICT[
|
|
168
|
+
DeviceType.OTB_MUOVI_PLUS
|
|
169
|
+
],
|
|
170
|
+
SyncStationProbeConfigMode.MUOVI_PLUS_PROBE_TWO: MUOVI_AVAILABLE_CHANNELS_DICT[
|
|
171
|
+
DeviceType.OTB_MUOVI_PLUS
|
|
172
|
+
],
|
|
173
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_ONE: {
|
|
174
|
+
DeviceChannelTypes.ALL: 8,
|
|
175
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
176
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
177
|
+
},
|
|
178
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_TWO: {
|
|
179
|
+
DeviceChannelTypes.ALL: 8,
|
|
180
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
181
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
182
|
+
},
|
|
183
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_THREE: {
|
|
184
|
+
DeviceChannelTypes.ALL: 8,
|
|
185
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
186
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
187
|
+
},
|
|
188
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_FOUR: {
|
|
189
|
+
DeviceChannelTypes.ALL: 8,
|
|
190
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
191
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
192
|
+
},
|
|
193
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_FIVE: {
|
|
194
|
+
DeviceChannelTypes.ALL: 8,
|
|
195
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
196
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
197
|
+
},
|
|
198
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_SIX: {
|
|
199
|
+
DeviceChannelTypes.ALL: 8,
|
|
200
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
201
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
202
|
+
},
|
|
203
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_SEVEN: {
|
|
204
|
+
DeviceChannelTypes.ALL: 8,
|
|
205
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
206
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
207
|
+
},
|
|
208
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_EIGHT: {
|
|
209
|
+
DeviceChannelTypes.ALL: 8,
|
|
210
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
211
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
212
|
+
},
|
|
213
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_NINE: {
|
|
214
|
+
DeviceChannelTypes.ALL: 8,
|
|
215
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
216
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
217
|
+
},
|
|
218
|
+
SyncStationProbeConfigMode.DUE_PLUS_PROBE_TEN: {
|
|
219
|
+
DeviceChannelTypes.ALL: 8,
|
|
220
|
+
DeviceChannelTypes.BIOSIGNAL: 2,
|
|
221
|
+
DeviceChannelTypes.AUXILIARY: 6,
|
|
222
|
+
},
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
SYNCSTATION_CONVERSION_FACTOR_DICT: dict[SyncStationDetectionMode, int] = {
|
|
226
|
+
SyncStationDetectionMode.MONOPOLAR_GAIN_HIGH: 572.2e-6,
|
|
227
|
+
SyncStationDetectionMode.MONOPOLAR_GAIN_LOW: 286.1e-6,
|
|
228
|
+
}
|
|
229
|
+
"""
|
|
230
|
+
Dictionary to get the gain of the Muovi detection mode. \\
|
|
231
|
+
The keys are the detection modes of the Muovi device. \\
|
|
232
|
+
The values are the gain of the detection mode in V.
|
|
233
|
+
"""
|