py-neuromodulation 0.0.3__py3-none-any.whl → 0.0.4__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.
- py_neuromodulation/ConnectivityDecoding/Automated Anatomical Labeling 3 (Rolls 2020).nii +0 -0
- py_neuromodulation/ConnectivityDecoding/_get_grid_hull.m +34 -0
- py_neuromodulation/ConnectivityDecoding/_get_grid_whole_brain.py +106 -0
- py_neuromodulation/ConnectivityDecoding/_helper_write_connectome.py +119 -0
- py_neuromodulation/ConnectivityDecoding/mni_coords_cortical_surface.mat +0 -0
- py_neuromodulation/ConnectivityDecoding/mni_coords_whole_brain.mat +0 -0
- py_neuromodulation/ConnectivityDecoding/rmap_func_all.nii +0 -0
- py_neuromodulation/ConnectivityDecoding/rmap_struc.nii +0 -0
- py_neuromodulation/data/README +6 -0
- py_neuromodulation/data/dataset_description.json +8 -0
- py_neuromodulation/data/participants.json +32 -0
- py_neuromodulation/data/participants.tsv +2 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +5 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +11 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +11 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.eeg +0 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.json +18 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +35 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +13 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +2 -0
- py_neuromodulation/grid_cortex.tsv +40 -0
- py_neuromodulation/grid_subcortex.tsv +1429 -0
- py_neuromodulation/nm_settings.json +338 -0
- py_neuromodulation/nm_stream_offline.py +7 -6
- py_neuromodulation/plots/STN_surf.mat +0 -0
- py_neuromodulation/plots/Vertices.mat +0 -0
- py_neuromodulation/plots/faces.mat +0 -0
- py_neuromodulation/plots/grid.mat +0 -0
- {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info}/METADATA +182 -182
- py_neuromodulation-0.0.4.dist-info/RECORD +72 -0
- {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info}/WHEEL +1 -2
- docs/build/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -68
- docs/build/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -233
- docs/build/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
- docs/build/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -97
- docs/build/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
- docs/build/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -192
- docs/build/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
- docs/build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -68
- docs/build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -239
- docs/build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
- docs/build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -97
- docs/build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
- docs/build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -192
- docs/build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
- docs/source/_build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -76
- docs/source/_build/html/_downloads/0d0d0a76e8f648d5d3cbc47da6351932/plot_real_time_demo.py +0 -97
- docs/source/_build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -240
- docs/source/_build/html/_downloads/5d73cadc59a8805c47e3b84063afc157/plot_example_BIDS.py +0 -233
- docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py +0 -63
- docs/source/_build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
- docs/source/_build/html/_downloads/839e5b319379f7fd9e867deb00fd797f/plot_example_gridPointProjection.py +0 -210
- docs/source/_build/html/_downloads/ae8be19afe5e559f011fc9b138968ba0/plot_first_demo.py +0 -192
- docs/source/_build/html/_downloads/b8b06cacc17969d3725a0b6f1d7741c5/plot_example_sharpwave_analysis.py +0 -219
- docs/source/_build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -121
- docs/source/_build/html/_downloads/c31a86c0b68cb4167d968091ace8080d/plot_example_add_feature.py +0 -68
- docs/source/_build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
- docs/source/_build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -189
- docs/source/_build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
- docs/source/auto_examples/plot_0_first_demo.py +0 -189
- docs/source/auto_examples/plot_1_example_BIDS.py +0 -240
- docs/source/auto_examples/plot_2_example_add_feature.py +0 -76
- docs/source/auto_examples/plot_3_example_sharpwave_analysis.py +0 -219
- docs/source/auto_examples/plot_4_example_gridPointProjection.py +0 -210
- docs/source/auto_examples/plot_5_example_rmap_computing.py +0 -64
- docs/source/auto_examples/plot_6_real_time_demo.py +0 -121
- docs/source/conf.py +0 -105
- examples/plot_0_first_demo.py +0 -189
- examples/plot_1_example_BIDS.py +0 -240
- examples/plot_2_example_add_feature.py +0 -76
- examples/plot_3_example_sharpwave_analysis.py +0 -219
- examples/plot_4_example_gridPointProjection.py +0 -210
- examples/plot_5_example_rmap_computing.py +0 -64
- examples/plot_6_real_time_demo.py +0 -121
- packages/realtime_decoding/build/lib/realtime_decoding/__init__.py +0 -4
- packages/realtime_decoding/build/lib/realtime_decoding/decoder.py +0 -104
- packages/realtime_decoding/build/lib/realtime_decoding/features.py +0 -163
- packages/realtime_decoding/build/lib/realtime_decoding/helpers.py +0 -15
- packages/realtime_decoding/build/lib/realtime_decoding/run_decoding.py +0 -345
- packages/realtime_decoding/build/lib/realtime_decoding/trainer.py +0 -54
- packages/tmsi/build/lib/TMSiFileFormats/__init__.py +0 -37
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/__init__.py +0 -36
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/lsl_stream_writer.py +0 -200
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_file_writer.py +0 -496
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_to_edf_converter.py +0 -236
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/xdf_file_writer.py +0 -977
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/__init__.py +0 -35
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/edf_reader.py +0 -116
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/poly5reader.py +0 -294
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/xdf_reader.py +0 -229
- packages/tmsi/build/lib/TMSiFileFormats/file_writer.py +0 -102
- packages/tmsi/build/lib/TMSiPlotters/__init__.py +0 -2
- packages/tmsi/build/lib/TMSiPlotters/gui/__init__.py +0 -39
- packages/tmsi/build/lib/TMSiPlotters/gui/_plotter_gui.py +0 -234
- packages/tmsi/build/lib/TMSiPlotters/gui/plotting_gui.py +0 -440
- packages/tmsi/build/lib/TMSiPlotters/plotters/__init__.py +0 -44
- packages/tmsi/build/lib/TMSiPlotters/plotters/hd_emg_plotter.py +0 -446
- packages/tmsi/build/lib/TMSiPlotters/plotters/impedance_plotter.py +0 -589
- packages/tmsi/build/lib/TMSiPlotters/plotters/signal_plotter.py +0 -1326
- packages/tmsi/build/lib/TMSiSDK/__init__.py +0 -54
- packages/tmsi/build/lib/TMSiSDK/device.py +0 -588
- packages/tmsi/build/lib/TMSiSDK/devices/__init__.py +0 -34
- packages/tmsi/build/lib/TMSiSDK/devices/saga/TMSi_Device_API.py +0 -1764
- packages/tmsi/build/lib/TMSiSDK/devices/saga/__init__.py +0 -34
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_device.py +0 -1366
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_types.py +0 -520
- packages/tmsi/build/lib/TMSiSDK/devices/saga/xml_saga_config.py +0 -165
- packages/tmsi/build/lib/TMSiSDK/error.py +0 -95
- packages/tmsi/build/lib/TMSiSDK/sample_data.py +0 -63
- packages/tmsi/build/lib/TMSiSDK/sample_data_server.py +0 -99
- packages/tmsi/build/lib/TMSiSDK/settings.py +0 -45
- packages/tmsi/build/lib/TMSiSDK/tmsi_device.py +0 -111
- packages/tmsi/build/lib/__init__.py +0 -4
- packages/tmsi/build/lib/apex_sdk/__init__.py +0 -34
- packages/tmsi/build/lib/apex_sdk/device/__init__.py +0 -41
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API.py +0 -1009
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_enums.py +0 -239
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_structures.py +0 -668
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_device.py +0 -1611
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_dongle.py +0 -38
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_event_reader.py +0 -57
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_channel.py +0 -44
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_config.py +0 -150
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_const.py +0 -36
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_impedance_channel.py +0 -48
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_info.py +0 -108
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/dongle_info.py +0 -39
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/download_measurement.py +0 -77
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/eeg_measurement.py +0 -150
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/impedance_measurement.py +0 -129
- packages/tmsi/build/lib/apex_sdk/device/threads/conversion_thread.py +0 -59
- packages/tmsi/build/lib/apex_sdk/device/threads/sampling_thread.py +0 -57
- packages/tmsi/build/lib/apex_sdk/device/tmsi_channel.py +0 -83
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device.py +0 -201
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device_enums.py +0 -103
- packages/tmsi/build/lib/apex_sdk/device/tmsi_dongle.py +0 -43
- packages/tmsi/build/lib/apex_sdk/device/tmsi_event_reader.py +0 -50
- packages/tmsi/build/lib/apex_sdk/device/tmsi_measurement.py +0 -118
- packages/tmsi/build/lib/apex_sdk/sample_data_server/__init__.py +0 -33
- packages/tmsi/build/lib/apex_sdk/sample_data_server/event_data.py +0 -44
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data.py +0 -50
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data_server.py +0 -136
- packages/tmsi/build/lib/apex_sdk/tmsi_errors/error.py +0 -126
- packages/tmsi/build/lib/apex_sdk/tmsi_sdk.py +0 -113
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/apex/apex_structure_generator.py +0 -134
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/decorators.py +0 -60
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/logger_filter.py +0 -42
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/singleton.py +0 -42
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/support_functions.py +0 -72
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/tmsi_logger.py +0 -98
- py_neuromodulation-0.0.3.dist-info/RECORD +0 -188
- py_neuromodulation-0.0.3.dist-info/top_level.txt +0 -5
- tests/__init__.py +0 -0
- tests/conftest.py +0 -117
- tests/test_all_examples.py +0 -10
- tests/test_all_features.py +0 -63
- tests/test_bispectra.py +0 -70
- tests/test_bursts.py +0 -105
- tests/test_feature_sampling_rates.py +0 -143
- tests/test_fooof.py +0 -16
- tests/test_initalization_offline_stream.py +0 -41
- tests/test_multiprocessing.py +0 -58
- tests/test_nan_values.py +0 -29
- tests/test_nm_filter.py +0 -95
- tests/test_nm_resample.py +0 -63
- tests/test_normalization_settings.py +0 -146
- tests/test_notch_filter.py +0 -31
- tests/test_osc_features.py +0 -424
- tests/test_preprocessing_filter.py +0 -151
- tests/test_rereference.py +0 -171
- tests/test_sampling.py +0 -57
- tests/test_settings_change_after_init.py +0 -76
- tests/test_sharpwave.py +0 -165
- tests/test_target_channel_add.py +0 -100
- tests/test_timing.py +0 -80
- {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
(c) 2022 Twente Medical Systems International B.V., Oldenzaal The Netherlands
|
|
3
|
-
|
|
4
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
you may not use this file except in compliance with the License.
|
|
6
|
-
You may obtain a copy of the License at
|
|
7
|
-
|
|
8
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
|
|
16
|
-
####### # # ##### #
|
|
17
|
-
# ## ## #
|
|
18
|
-
# # # # # # #
|
|
19
|
-
# # # # ##### #
|
|
20
|
-
# # # # #
|
|
21
|
-
# # # # #
|
|
22
|
-
# # # ##### #
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @file ${__init__.py}
|
|
26
|
-
* @brief Initialisation of the TMSiFileFormats directory classes.
|
|
27
|
-
*
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"""
|
|
32
|
-
from . import (
|
|
33
|
-
file_formats,
|
|
34
|
-
file_readers,
|
|
35
|
-
file_writer,
|
|
36
|
-
)
|
|
37
|
-
from .file_writer import FileWriter, FileFormat
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
(c) 2022 Twente Medical Systems International B.V., Oldenzaal The Netherlands
|
|
3
|
-
|
|
4
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
you may not use this file except in compliance with the License.
|
|
6
|
-
You may obtain a copy of the License at
|
|
7
|
-
|
|
8
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
|
|
16
|
-
####### # # ##### #
|
|
17
|
-
# ## ## #
|
|
18
|
-
# # # # # # #
|
|
19
|
-
# # # # ##### #
|
|
20
|
-
# # # # #
|
|
21
|
-
# # # # #
|
|
22
|
-
# # # ##### #
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @file ${__init__.py}
|
|
26
|
-
* @brief Initialisation of the file_formats directory classes.
|
|
27
|
-
*
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
from .lsl_stream_writer import LSLWriter
|
|
34
|
-
from .poly5_file_writer import Poly5Writer
|
|
35
|
-
from .xdf_file_writer import XdfWriter
|
|
36
|
-
from .poly5_to_edf_converter import Poly5_to_EDF_Converter
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Copyright 2021 John Veillette (https://gitlab.com/john-veillette)
|
|
3
|
-
(c) 2022 Twente Medical Systems International B.V., Oldenzaal The Netherlands
|
|
4
|
-
|
|
5
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
you may not use this file except in compliance with the License.
|
|
7
|
-
You may obtain a copy of the License at
|
|
8
|
-
|
|
9
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
|
|
11
|
-
Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
See the License for the specific language governing permissions and
|
|
15
|
-
limitations under the License.
|
|
16
|
-
|
|
17
|
-
####### # # ##### #
|
|
18
|
-
# ## ## #
|
|
19
|
-
# # # # # # #
|
|
20
|
-
# # # # ##### #
|
|
21
|
-
# # # # #
|
|
22
|
-
# # # # #
|
|
23
|
-
# # # ##### #
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @file ${lsl_stream_writer.py}
|
|
27
|
-
* @brief Labstreaminglayer Writer
|
|
28
|
-
*
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
import sys
|
|
35
|
-
from datetime import datetime
|
|
36
|
-
import os
|
|
37
|
-
import struct
|
|
38
|
-
import time
|
|
39
|
-
|
|
40
|
-
from TMSiSDK.error import TMSiError, TMSiErrorCode
|
|
41
|
-
from TMSiSDK import sample_data_server
|
|
42
|
-
from pylsl import StreamInfo, StreamOutlet, local_clock
|
|
43
|
-
from TMSiSDK.device import ChannelType
|
|
44
|
-
|
|
45
|
-
from apex_sdk.device.tmsi_device import TMSiDevice
|
|
46
|
-
from apex_sdk.sample_data_server.sample_data_server import (
|
|
47
|
-
SampleDataServer as ApexSampleDataServer,
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class LSLConsumer:
|
|
52
|
-
"""
|
|
53
|
-
Provides the .put() method expected by TMSiSDK.sample_data_server
|
|
54
|
-
|
|
55
|
-
liblsl will handle the data buffer in a seperate thread. Since liblsl can
|
|
56
|
-
bypass the global interpreter lock and python can't, and lsl uses faster
|
|
57
|
-
compiled code, it's better to offload this than to create our own thread.
|
|
58
|
-
"""
|
|
59
|
-
|
|
60
|
-
def __init__(self, lsl_outlet):
|
|
61
|
-
self._outlet = lsl_outlet
|
|
62
|
-
|
|
63
|
-
def put(self, sd):
|
|
64
|
-
"""
|
|
65
|
-
Pushes sample data to pylsl outlet, which handles the data buffer
|
|
66
|
-
|
|
67
|
-
sd (TMSiSDK.sample_data.SampleData): provided by the sample data server
|
|
68
|
-
"""
|
|
69
|
-
try:
|
|
70
|
-
# split into list of arrays for each sampling event
|
|
71
|
-
signals = [
|
|
72
|
-
sd.samples[
|
|
73
|
-
i
|
|
74
|
-
* sd.num_samples_per_sample_set : (i + 1)
|
|
75
|
-
* sd.num_samples_per_sample_set
|
|
76
|
-
]
|
|
77
|
-
for i in range(sd.num_sample_sets)
|
|
78
|
-
]
|
|
79
|
-
# and push to LSL
|
|
80
|
-
self._outlet.push_chunk(signals, local_clock())
|
|
81
|
-
except:
|
|
82
|
-
raise TMSiError(TMSiErrorCode.file_writer_error)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
class LSLWriter:
|
|
86
|
-
"""
|
|
87
|
-
A drop-in replacement for a TSMiSDK filewriter object
|
|
88
|
-
that streams data to labstreaminglayer
|
|
89
|
-
"""
|
|
90
|
-
|
|
91
|
-
def __init__(self, stream_name=""):
|
|
92
|
-
|
|
93
|
-
self._name = stream_name if stream_name else "tmsi"
|
|
94
|
-
self._consumer = None
|
|
95
|
-
self.device = None
|
|
96
|
-
self._date = None
|
|
97
|
-
self._outlet = None
|
|
98
|
-
|
|
99
|
-
def open(self, device):
|
|
100
|
-
"""
|
|
101
|
-
Input is an open TMSiSDK device object
|
|
102
|
-
"""
|
|
103
|
-
|
|
104
|
-
self.device = device
|
|
105
|
-
|
|
106
|
-
if isinstance(device, TMSiDevice):
|
|
107
|
-
self.__open_TMSiDevice()
|
|
108
|
-
return
|
|
109
|
-
|
|
110
|
-
print("LSLWriter-open")
|
|
111
|
-
|
|
112
|
-
try:
|
|
113
|
-
self._date = datetime.now()
|
|
114
|
-
self._sample_rate = device.config.sample_rate
|
|
115
|
-
self._num_channels = len(device.channels)
|
|
116
|
-
|
|
117
|
-
# Calculate nr of sample-sets within one sample-data-block:
|
|
118
|
-
# This is the nr of sample-sets in 150 milli-seconds or when the
|
|
119
|
-
# sample-data-block-size exceeds 64kb the it will become the nr of
|
|
120
|
-
# sample-sets that fit in 64kb
|
|
121
|
-
self._num_sample_sets_per_sample_data_block = int(
|
|
122
|
-
self._sample_rate * 0.15
|
|
123
|
-
)
|
|
124
|
-
size_one_sample_set = len(self.device.channels) * 4
|
|
125
|
-
if (
|
|
126
|
-
self._num_sample_sets_per_sample_data_block
|
|
127
|
-
* size_one_sample_set
|
|
128
|
-
) > 64000:
|
|
129
|
-
self._num_sample_sets_per_sample_data_block = int(
|
|
130
|
-
64000 / size_one_sample_set
|
|
131
|
-
)
|
|
132
|
-
# provide LSL with metadata
|
|
133
|
-
info = StreamInfo(
|
|
134
|
-
self._name,
|
|
135
|
-
"EEG",
|
|
136
|
-
self._num_channels,
|
|
137
|
-
self._sample_rate,
|
|
138
|
-
"float32",
|
|
139
|
-
"tmsi-" + str(self.device.info.dr_serial_number),
|
|
140
|
-
)
|
|
141
|
-
chs_appended = []
|
|
142
|
-
chns = info.desc().append_child("channels")
|
|
143
|
-
for idx, ch in enumerate(self.device.channels): # active channels
|
|
144
|
-
ch_name = ch.name
|
|
145
|
-
if ch_name in chs_appended:
|
|
146
|
-
ch_name = f"{ch_name}_2"
|
|
147
|
-
|
|
148
|
-
chn = chns.append_child("channel")
|
|
149
|
-
chn.append_child_value("label", ch_name)
|
|
150
|
-
chn.append_child_value("index", str(idx))
|
|
151
|
-
chn.append_child_value("unit", ch.unit_name)
|
|
152
|
-
if (
|
|
153
|
-
ch.type.value == ChannelType.UNI.value
|
|
154
|
-
) and not ch._DeviceChannel__name == "CREF":
|
|
155
|
-
chn.append_child_value("type", "EEG")
|
|
156
|
-
else:
|
|
157
|
-
chn.append_child_value(
|
|
158
|
-
"type", str(ch.type).replace("ChannelType.", "")
|
|
159
|
-
)
|
|
160
|
-
chs_appended.append(ch_name)
|
|
161
|
-
info.desc().append_child_value("manufacturer", "TMSi")
|
|
162
|
-
sync = info.desc().append_child("synchronization")
|
|
163
|
-
sync.append_child_value(
|
|
164
|
-
"offset_mean", str(0.0335)
|
|
165
|
-
) # measured while dock/usb connected
|
|
166
|
-
sync.append_child_value(
|
|
167
|
-
"offset_std", str(0.0008)
|
|
168
|
-
) # jitter AFTER jitter correction by pyxdf
|
|
169
|
-
|
|
170
|
-
# start sampling data and pushing to LSL
|
|
171
|
-
self._outlet = StreamOutlet(
|
|
172
|
-
info, self._num_sample_sets_per_sample_data_block
|
|
173
|
-
)
|
|
174
|
-
self._consumer = LSLConsumer(self._outlet)
|
|
175
|
-
sample_data_server.registerConsumer(self.device.id, self._consumer)
|
|
176
|
-
print("LSL STREAM STARTED")
|
|
177
|
-
|
|
178
|
-
except:
|
|
179
|
-
raise TMSiError(TMSiErrorCode.file_writer_error)
|
|
180
|
-
|
|
181
|
-
def __open_TMSiDevice(self):
|
|
182
|
-
print(
|
|
183
|
-
"For APEX, the LSL_stream_writer is not available for this version of the TMSi Python Interface (v4.0.0.0)\n\n"
|
|
184
|
-
)
|
|
185
|
-
raise TMSiError(TMSiErrorCode.api_invalid_command)
|
|
186
|
-
|
|
187
|
-
def close(self):
|
|
188
|
-
|
|
189
|
-
print("LSLWriter-close")
|
|
190
|
-
if isinstance(self.device, TMSiDevice):
|
|
191
|
-
ApexSampleDataServer().unregister_consumer(
|
|
192
|
-
self.device.get_id(), self._consumer
|
|
193
|
-
)
|
|
194
|
-
else:
|
|
195
|
-
sample_data_server.unregisterConsumer(
|
|
196
|
-
self.device.id, self._consumer
|
|
197
|
-
)
|
|
198
|
-
# let garbage collector take care of destroying LSL outlet
|
|
199
|
-
self._consumer = None
|
|
200
|
-
self._outlet = None
|