py-neuromodulation 0.0.2__py3-none-any.whl → 0.0.3__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.
- docs/build/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
- docs/build/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +233 -0
- docs/build/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/build/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
- docs/build/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/build/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
- docs/build/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
- docs/build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +239 -0
- docs/build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
- docs/build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
- docs/build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/source/_build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +76 -0
- docs/source/_build/html/_downloads/0d0d0a76e8f648d5d3cbc47da6351932/plot_real_time_demo.py +97 -0
- docs/source/_build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +240 -0
- docs/source/_build/html/_downloads/5d73cadc59a8805c47e3b84063afc157/plot_example_BIDS.py +233 -0
- docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py +63 -0
- docs/source/_build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/source/_build/html/_downloads/839e5b319379f7fd9e867deb00fd797f/plot_example_gridPointProjection.py +210 -0
- docs/source/_build/html/_downloads/ae8be19afe5e559f011fc9b138968ba0/plot_first_demo.py +192 -0
- docs/source/_build/html/_downloads/b8b06cacc17969d3725a0b6f1d7741c5/plot_example_sharpwave_analysis.py +219 -0
- docs/source/_build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +121 -0
- docs/source/_build/html/_downloads/c31a86c0b68cb4167d968091ace8080d/plot_example_add_feature.py +68 -0
- docs/source/_build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/source/_build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +189 -0
- docs/source/_build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/source/auto_examples/plot_0_first_demo.py +189 -0
- docs/source/auto_examples/plot_1_example_BIDS.py +240 -0
- docs/source/auto_examples/plot_2_example_add_feature.py +76 -0
- docs/source/auto_examples/plot_3_example_sharpwave_analysis.py +219 -0
- docs/source/auto_examples/plot_4_example_gridPointProjection.py +210 -0
- docs/source/auto_examples/plot_5_example_rmap_computing.py +64 -0
- docs/source/auto_examples/plot_6_real_time_demo.py +121 -0
- docs/source/conf.py +105 -0
- examples/plot_0_first_demo.py +189 -0
- examples/plot_1_example_BIDS.py +240 -0
- examples/plot_2_example_add_feature.py +76 -0
- examples/plot_3_example_sharpwave_analysis.py +219 -0
- examples/plot_4_example_gridPointProjection.py +210 -0
- examples/plot_5_example_rmap_computing.py +64 -0
- examples/plot_6_real_time_demo.py +121 -0
- packages/realtime_decoding/build/lib/realtime_decoding/__init__.py +4 -0
- packages/realtime_decoding/build/lib/realtime_decoding/decoder.py +104 -0
- packages/realtime_decoding/build/lib/realtime_decoding/features.py +163 -0
- packages/realtime_decoding/build/lib/realtime_decoding/helpers.py +15 -0
- packages/realtime_decoding/build/lib/realtime_decoding/run_decoding.py +345 -0
- packages/realtime_decoding/build/lib/realtime_decoding/trainer.py +54 -0
- packages/tmsi/build/lib/TMSiFileFormats/__init__.py +37 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/__init__.py +36 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/lsl_stream_writer.py +200 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_file_writer.py +496 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_to_edf_converter.py +236 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/xdf_file_writer.py +977 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/__init__.py +35 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/edf_reader.py +116 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/poly5reader.py +294 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/xdf_reader.py +229 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_writer.py +102 -0
- packages/tmsi/build/lib/TMSiPlotters/__init__.py +2 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/__init__.py +39 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/_plotter_gui.py +234 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/plotting_gui.py +440 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/__init__.py +44 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/hd_emg_plotter.py +446 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/impedance_plotter.py +589 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/signal_plotter.py +1326 -0
- packages/tmsi/build/lib/TMSiSDK/__init__.py +54 -0
- packages/tmsi/build/lib/TMSiSDK/device.py +588 -0
- packages/tmsi/build/lib/TMSiSDK/devices/__init__.py +34 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/TMSi_Device_API.py +1764 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/__init__.py +34 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_device.py +1366 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_types.py +520 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/xml_saga_config.py +165 -0
- packages/tmsi/build/lib/TMSiSDK/error.py +95 -0
- packages/tmsi/build/lib/TMSiSDK/sample_data.py +63 -0
- packages/tmsi/build/lib/TMSiSDK/sample_data_server.py +99 -0
- packages/tmsi/build/lib/TMSiSDK/settings.py +45 -0
- packages/tmsi/build/lib/TMSiSDK/tmsi_device.py +111 -0
- packages/tmsi/build/lib/__init__.py +4 -0
- packages/tmsi/build/lib/apex_sdk/__init__.py +34 -0
- packages/tmsi/build/lib/apex_sdk/device/__init__.py +41 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API.py +1009 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_enums.py +239 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_structures.py +668 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_device.py +1611 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_dongle.py +38 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_event_reader.py +57 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_channel.py +44 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_config.py +150 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_const.py +36 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_impedance_channel.py +48 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_info.py +108 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/dongle_info.py +39 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/download_measurement.py +77 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/eeg_measurement.py +150 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/impedance_measurement.py +129 -0
- packages/tmsi/build/lib/apex_sdk/device/threads/conversion_thread.py +59 -0
- packages/tmsi/build/lib/apex_sdk/device/threads/sampling_thread.py +57 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_channel.py +83 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device.py +201 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device_enums.py +103 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_dongle.py +43 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_event_reader.py +50 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_measurement.py +118 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/__init__.py +33 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/event_data.py +44 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data.py +50 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data_server.py +136 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_errors/error.py +126 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_sdk.py +113 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/apex/apex_structure_generator.py +134 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/decorators.py +60 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/logger_filter.py +42 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/singleton.py +42 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/support_functions.py +72 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/tmsi_logger.py +98 -0
- py_neuromodulation/{helper.py → _write_example_dataset_helper.py} +1 -1
- py_neuromodulation/nm_EpochStream.py +2 -3
- py_neuromodulation/nm_IO.py +43 -70
- py_neuromodulation/nm_RMAP.py +308 -11
- py_neuromodulation/nm_analysis.py +1 -1
- py_neuromodulation/nm_artifacts.py +25 -0
- py_neuromodulation/nm_bispectra.py +64 -29
- py_neuromodulation/nm_bursts.py +44 -30
- py_neuromodulation/nm_coherence.py +2 -1
- py_neuromodulation/nm_features.py +4 -2
- py_neuromodulation/nm_filter.py +63 -32
- py_neuromodulation/nm_filter_preprocessing.py +91 -0
- py_neuromodulation/nm_fooof.py +47 -29
- py_neuromodulation/nm_mne_connectivity.py +1 -1
- py_neuromodulation/nm_normalization.py +50 -74
- py_neuromodulation/nm_oscillatory.py +151 -31
- py_neuromodulation/nm_plots.py +13 -10
- py_neuromodulation/nm_rereference.py +10 -8
- py_neuromodulation/nm_run_analysis.py +28 -13
- py_neuromodulation/nm_sharpwaves.py +103 -136
- py_neuromodulation/nm_stats.py +44 -30
- py_neuromodulation/nm_stream_abc.py +18 -10
- py_neuromodulation/nm_stream_offline.py +181 -40
- py_neuromodulation/utils/_logging.py +24 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/METADATA +182 -142
- py_neuromodulation-0.0.3.dist-info/RECORD +188 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/WHEEL +2 -1
- py_neuromodulation-0.0.3.dist-info/top_level.txt +5 -0
- tests/__init__.py +0 -0
- tests/conftest.py +117 -0
- tests/test_all_examples.py +10 -0
- tests/test_all_features.py +63 -0
- tests/test_bispectra.py +70 -0
- tests/test_bursts.py +105 -0
- tests/test_feature_sampling_rates.py +143 -0
- tests/test_fooof.py +16 -0
- tests/test_initalization_offline_stream.py +41 -0
- tests/test_multiprocessing.py +58 -0
- tests/test_nan_values.py +29 -0
- tests/test_nm_filter.py +95 -0
- tests/test_nm_resample.py +63 -0
- tests/test_normalization_settings.py +146 -0
- tests/test_notch_filter.py +31 -0
- tests/test_osc_features.py +424 -0
- tests/test_preprocessing_filter.py +151 -0
- tests/test_rereference.py +171 -0
- tests/test_sampling.py +57 -0
- tests/test_settings_change_after_init.py +76 -0
- tests/test_sharpwave.py +165 -0
- tests/test_target_channel_add.py +100 -0
- tests/test_timing.py +80 -0
- py_neuromodulation/data/README +0 -6
- py_neuromodulation/data/dataset_description.json +0 -8
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/MOV_aligned_features_ch_ECOG_RIGHT_0_all.png +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/all_feature_plt.pdf +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_FEATURES.csv +0 -182
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_LM_ML_RES.p +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SETTINGS.json +0 -273
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SIDECAR.json +0 -6
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_decoding_performance.png +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_nm_channels.csv +0 -11
- py_neuromodulation/data/participants.json +0 -32
- py_neuromodulation/data/participants.tsv +0 -2
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +0 -5
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +0 -11
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +0 -11
- 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 +0 -18
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +0 -35
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +0 -13
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +0 -2
- py_neuromodulation/grid_cortex.tsv +0 -40
- py_neuromodulation/grid_subcortex.tsv +0 -1429
- py_neuromodulation/nm_settings.json +0 -290
- 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/py_neuromodulation.egg-info/PKG-INFO +0 -104
- py_neuromodulation/py_neuromodulation.egg-info/dependency_links.txt +0 -1
- py_neuromodulation/py_neuromodulation.egg-info/requires.txt +0 -26
- py_neuromodulation/py_neuromodulation.egg-info/top_level.txt +0 -1
- py_neuromodulation-0.0.2.dist-info/RECORD +0 -73
- /py_neuromodulation/{py_neuromodulation.egg-info/SOURCES.txt → utils/__init__.py} +0 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
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 error.py
|
|
26
|
+
* @brief
|
|
27
|
+
* TMSi Error interface.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from enum import Enum, unique
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@unique
|
|
37
|
+
class TMSiErrorCode(Enum):
|
|
38
|
+
general_error = 0
|
|
39
|
+
missing_dll = 1
|
|
40
|
+
already_in_use_dll = 2
|
|
41
|
+
device_error = 100
|
|
42
|
+
device_not_connected = 101
|
|
43
|
+
no_devices_found = 102
|
|
44
|
+
api_no_driver = 200
|
|
45
|
+
api_incorrect_argument = 201
|
|
46
|
+
api_invalid_command = 202
|
|
47
|
+
file_writer_error = 300
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class TMSiError(Exception):
|
|
51
|
+
def __init__(self, error_code, dll_error_code=None):
|
|
52
|
+
self.dll_error_code = None
|
|
53
|
+
self.error_code = error_code
|
|
54
|
+
if dll_error_code:
|
|
55
|
+
self.dll_error_code = hex(dll_error_code.value)
|
|
56
|
+
|
|
57
|
+
def __str__(self):
|
|
58
|
+
if self.dll_error_code:
|
|
59
|
+
return "Error code {}: {} \nDLL Error code {}: {}".format(
|
|
60
|
+
self.error_code.value,
|
|
61
|
+
SdkErrorLookupTable(str(self.error_code.value)),
|
|
62
|
+
self.dll_error_code,
|
|
63
|
+
DeviceErrorLookupTable(self.dll_error_code),
|
|
64
|
+
)
|
|
65
|
+
return "Error code {}: {}".format(
|
|
66
|
+
self.error_code.value,
|
|
67
|
+
SdkErrorLookupTable(str(self.error_code.value)),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def DeviceErrorLookupTable(code):
|
|
72
|
+
_lookup_table = {
|
|
73
|
+
"0x0000000": "",
|
|
74
|
+
"0x1010001": "DR reported 'Checksum error in received block'",
|
|
75
|
+
"0x2010001": "DS reported 'Checksum error in received block'",
|
|
76
|
+
"0x1010002": "DR reported 'Unknown command'",
|
|
77
|
+
"0x2010002": "DS reported 'Unknown command'",
|
|
78
|
+
"0x1010003": "DR reported 'Response timeout'",
|
|
79
|
+
"0x2010003": "DS reported 'Response timeout'",
|
|
80
|
+
"0x1010004": "DR reported 'Device busy try again in x msec'",
|
|
81
|
+
"0x2010004": "DS reported 'Device busy try again in x msec'",
|
|
82
|
+
"0x1010005": "DR reported 'Command not supported over current interface'",
|
|
83
|
+
"0x2010005": "DS reported 'Command not supported over current interface'",
|
|
84
|
+
"0x1010006": "DR reported 'Command not possible, device is recording'",
|
|
85
|
+
"0x1010007": "DR reported 'Device not available'",
|
|
86
|
+
"0x2010007": "DS reported 'Device not available'",
|
|
87
|
+
"0x2010008": "DS reported 'Interface not available'",
|
|
88
|
+
"0x2010009": "DS reported 'Command not allowed in current mode'",
|
|
89
|
+
"0x201000A": "DS reported 'Processing error'",
|
|
90
|
+
"0x201000B": "DS reported 'Unknown internal error'",
|
|
91
|
+
"0x1030001": "DR reported 'Command not supported by Channel'",
|
|
92
|
+
"0x1030002": "DR reported 'Illegal start control for ambulant recording",
|
|
93
|
+
"0x201000C": "DS reports that data request does not fit with one Device Api Packet",
|
|
94
|
+
"0x201000D": "DS reports that DR is already opened",
|
|
95
|
+
"0x3001000": "DLL Function is declared, but not yet implemented",
|
|
96
|
+
"0x3001001": "DLL Function called with invalid parameters",
|
|
97
|
+
"0x3001002": "Incorrect checksum of response message",
|
|
98
|
+
"0x3001003": "DLL Function failed because of header failure",
|
|
99
|
+
"0x3001004": "DLL Function failed because an underlying process failed",
|
|
100
|
+
"0x3001005": "DLL Function called with a too small buffer",
|
|
101
|
+
"0x3001006": "DLL Function called with a Handle that's not assigned to a device",
|
|
102
|
+
"0x3002000": "DLL Function failed becasue could not open selected interface",
|
|
103
|
+
"0x3002001": "DLL Function failed because could not close selected interface",
|
|
104
|
+
"0x3002002": "DLL Function failed because could not send command-data",
|
|
105
|
+
"0x3002003": "DLL Function failed because could not receive data",
|
|
106
|
+
"0x3002004": "DLL Function failed because commination timed out",
|
|
107
|
+
"0x3002005": "Lost connection to DS, USB / Ethernet disconnect",
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return _lookup_table[code]
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def SdkErrorLookupTable(code):
|
|
114
|
+
_lookup_table = {
|
|
115
|
+
"0": "general error",
|
|
116
|
+
"1": "missing dll",
|
|
117
|
+
"2": "already in use dll",
|
|
118
|
+
"100": "device error",
|
|
119
|
+
"101": "device not connected",
|
|
120
|
+
"102": "no devices found",
|
|
121
|
+
"200": "api no driver",
|
|
122
|
+
"201": "api incorrect argument",
|
|
123
|
+
"202": "api invalid command",
|
|
124
|
+
"300": "file writer error",
|
|
125
|
+
}
|
|
126
|
+
return _lookup_table[code]
|
|
@@ -0,0 +1,113 @@
|
|
|
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 tmsi_sdk.py
|
|
26
|
+
* @brief
|
|
27
|
+
* Singleton class which handles the discovery of TMSi devices.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from .tmsi_utilities.singleton import Singleton
|
|
34
|
+
from .device.tmsi_device_enums import *
|
|
35
|
+
from .device.devices.apex.apex_device import ApexDevice
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TMSiSDK(metaclass=Singleton):
|
|
39
|
+
"""Singleton class which handles the discovery of TMSi devices"""
|
|
40
|
+
|
|
41
|
+
def __init__(self):
|
|
42
|
+
"""Initializes the object."""
|
|
43
|
+
self.__apex_device_list = []
|
|
44
|
+
self.__apex_dongle_list = []
|
|
45
|
+
self.__saga_device_list = []
|
|
46
|
+
|
|
47
|
+
def discover(
|
|
48
|
+
self,
|
|
49
|
+
dev_type=DeviceType.apex,
|
|
50
|
+
dr_interface=DeviceInterfaceType.usb,
|
|
51
|
+
ds_interface=DeviceInterfaceType.none,
|
|
52
|
+
num_retries=3,
|
|
53
|
+
):
|
|
54
|
+
"""Discovers if there are available devices.
|
|
55
|
+
|
|
56
|
+
:param dev_type: device tipe to search, defaults to DeviceType.apex
|
|
57
|
+
:type dev_type: DeviceType, optional
|
|
58
|
+
:param dr_interface: datarecorder interface, defaults to DeviceInterfaceType.usb
|
|
59
|
+
:type dr_interface: DeviceInterfaceType, optional
|
|
60
|
+
:param ds_interface: dockstation interface (if needed), defaults to DeviceInterfaceType.none
|
|
61
|
+
:type ds_interface: DeviceInterfaceType, optional
|
|
62
|
+
:param num_retries: number of retry if nothing found
|
|
63
|
+
:type num_retries: int, optional
|
|
64
|
+
:return: _description_
|
|
65
|
+
:rtype: tuple[list[TMSiDevice], list[TMSiDongle]]
|
|
66
|
+
"""
|
|
67
|
+
if dev_type == DeviceType.apex:
|
|
68
|
+
ApexDevice.discover(dr_interface, num_retries)
|
|
69
|
+
self.__apex_device_list = ApexDevice.get_device_list(dr_interface)
|
|
70
|
+
self.__apex_dongle_list = ApexDevice.get_dongle_list()
|
|
71
|
+
return (self.__apex_device_list, self.__apex_dongle_list)
|
|
72
|
+
|
|
73
|
+
def get_device_list(self, dev_type=DeviceType.apex):
|
|
74
|
+
"""Gets the list of available devices.
|
|
75
|
+
|
|
76
|
+
:param dev_type: device to get, defaults to DeviceType.apex
|
|
77
|
+
:type dev_type: DeviceType, optional
|
|
78
|
+
:return: list of available devices.
|
|
79
|
+
:rtype: list[TMSiDevice]
|
|
80
|
+
"""
|
|
81
|
+
if dev_type == DeviceType.apex:
|
|
82
|
+
return self.__apex_device_list
|
|
83
|
+
elif dev_type == DeviceType.saga:
|
|
84
|
+
return self.__saga_device_list
|
|
85
|
+
|
|
86
|
+
def get_dongle_list(self, dev_type=DeviceType.apex):
|
|
87
|
+
"""Gets the list of available dongles.
|
|
88
|
+
|
|
89
|
+
:param dev_type: device type dongle to get, defaults to DeviceType.apex
|
|
90
|
+
:type dev_type: DeviceType, optional
|
|
91
|
+
:return: list of available dongles.
|
|
92
|
+
:rtype: list[TMSiDongle]
|
|
93
|
+
"""
|
|
94
|
+
if dev_type == DeviceType.apex:
|
|
95
|
+
return self.__apex_dongle_list
|
|
96
|
+
|
|
97
|
+
def get_driver_version(self, dev_type=DeviceType.apex) -> str:
|
|
98
|
+
"""Gets the driver version
|
|
99
|
+
|
|
100
|
+
:param dev_type: the device type for the drivers, defaults to DeviceType.apex
|
|
101
|
+
:type dev_type: DeviceType, optional
|
|
102
|
+
:return: driver version
|
|
103
|
+
:rtype: str
|
|
104
|
+
"""
|
|
105
|
+
if dev_type == DeviceType.apex:
|
|
106
|
+
version = ApexDevice.get_driver_version()
|
|
107
|
+
dll_version = "".join(
|
|
108
|
+
[chr(i) for i in version.DllVersionString if i != 0]
|
|
109
|
+
)
|
|
110
|
+
usb_version = "".join(
|
|
111
|
+
[chr(i) for i in version.LibUsbVersionString if i != 0]
|
|
112
|
+
)
|
|
113
|
+
return (dll_version, usb_version)
|
|
@@ -0,0 +1,134 @@
|
|
|
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 apex_structure_generator.py
|
|
26
|
+
* @brief
|
|
27
|
+
* Object that creates the structures needed to communicate with APEX.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import datetime
|
|
34
|
+
|
|
35
|
+
from ...device.devices.apex import apex_API_structures as ApexStructures
|
|
36
|
+
from ...device.devices.apex import apex_API_enums as ApexEnums
|
|
37
|
+
from ...device.devices.apex.apex_device import ApexDevice
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ApexStructureGenerator:
|
|
41
|
+
def create_card_record_configuration(
|
|
42
|
+
device: ApexDevice,
|
|
43
|
+
start_control: ApexEnums.ApexStartCardRecording,
|
|
44
|
+
prefix_file_name: str = None,
|
|
45
|
+
start_time: datetime.datetime = None,
|
|
46
|
+
stop_time: datetime.datetime = None,
|
|
47
|
+
pre_measurement_imp=None,
|
|
48
|
+
pre_measeurement_imp_seconds=None,
|
|
49
|
+
user_string_1: str = None,
|
|
50
|
+
user_string_2: str = None,
|
|
51
|
+
) -> ApexStructures.TMSiDevCardRecCfg:
|
|
52
|
+
"""Creates the TMSiDevCardRecCfg structure with provided parameters
|
|
53
|
+
|
|
54
|
+
:param device: device to pull the configuration from
|
|
55
|
+
:type device: ApexDevice
|
|
56
|
+
:param prefix_file_name: prefix file name, defaults to None.
|
|
57
|
+
:type prefix_file_name: str, optional
|
|
58
|
+
:param start_time: datetime of the start, defaults to None.
|
|
59
|
+
:type start_time: datetime.datetime, optional
|
|
60
|
+
:param stop_time: datetime of the stop, defaults to None.
|
|
61
|
+
:type stop_time: datetime.datetime, optional
|
|
62
|
+
:param user_string_1: user string, defaults to None.
|
|
63
|
+
:type user_string_1: str, optional
|
|
64
|
+
:param user_string_2: user string, defaults to None.
|
|
65
|
+
:type user_string_2: str, optional
|
|
66
|
+
:return: the structure containing provided information
|
|
67
|
+
:rtype: ApexStructures.TMSiDevCardRecCfg
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
config = device.get_card_recording_config()
|
|
71
|
+
config.StartControl = start_control.value
|
|
72
|
+
if prefix_file_name is not None:
|
|
73
|
+
converted_str = bytearray(
|
|
74
|
+
ApexEnums.ApexStringLengths.PrefixFileName.value
|
|
75
|
+
)
|
|
76
|
+
for character in range(len(prefix_file_name)):
|
|
77
|
+
converted_str[character] = ord(prefix_file_name[character])
|
|
78
|
+
config.PrefixFileName = bytes(converted_str)
|
|
79
|
+
if user_string_1 is not None:
|
|
80
|
+
converted_str = bytearray(
|
|
81
|
+
ApexEnums.ApexStringLengths.UserString.value
|
|
82
|
+
)
|
|
83
|
+
for character in range(len(user_string_1)):
|
|
84
|
+
converted_str[character] = ord(user_string_1[character])
|
|
85
|
+
config.UserString1 = bytes(converted_str)
|
|
86
|
+
if user_string_2 is not None:
|
|
87
|
+
converted_str = bytearray(
|
|
88
|
+
ApexEnums.ApexStringLengths.UserString.value
|
|
89
|
+
)
|
|
90
|
+
for character in range(len(user_string_2)):
|
|
91
|
+
converted_str[character] = ord(user_string_2[character])
|
|
92
|
+
config.UserString2 = bytes(converted_str)
|
|
93
|
+
if start_time is not None:
|
|
94
|
+
ApexStructureGenerator.from_datetime_to_tmsitime(
|
|
95
|
+
start_time, config.StartTime
|
|
96
|
+
)
|
|
97
|
+
if stop_time is not None:
|
|
98
|
+
ApexStructureGenerator.from_datetime_to_tmsitime(
|
|
99
|
+
stop_time, config.StopTime
|
|
100
|
+
)
|
|
101
|
+
if pre_measurement_imp is not None:
|
|
102
|
+
config.PreImp = pre_measurement_imp
|
|
103
|
+
if pre_measeurement_imp_seconds is not None:
|
|
104
|
+
config.PreImpSec = pre_measeurement_imp_seconds
|
|
105
|
+
return config
|
|
106
|
+
|
|
107
|
+
def from_qdatetime_to_tmsitime(qdatetime, tmsi_time):
|
|
108
|
+
tmsi_time.Seconds = qdatetime.time().second()
|
|
109
|
+
tmsi_time.Minutes = qdatetime.time().minute()
|
|
110
|
+
tmsi_time.Hours = qdatetime.time().hour()
|
|
111
|
+
tmsi_time.DayOfMonth = qdatetime.date().day()
|
|
112
|
+
tmsi_time.Month = qdatetime.date().month() - 1
|
|
113
|
+
tmsi_time.Year = qdatetime.date().year() - 1900
|
|
114
|
+
return tmsi_time
|
|
115
|
+
|
|
116
|
+
def from_datetime_to_tmsitime(date_time, tmsi_time):
|
|
117
|
+
tmsi_time.Seconds = date_time.time().second
|
|
118
|
+
tmsi_time.Minutes = date_time.time().minute
|
|
119
|
+
tmsi_time.Hours = date_time.time().hour
|
|
120
|
+
tmsi_time.DayOfMonth = date_time.date().day
|
|
121
|
+
tmsi_time.Month = date_time.date().month - 1
|
|
122
|
+
tmsi_time.Year = date_time.date().year - 1900
|
|
123
|
+
return tmsi_time
|
|
124
|
+
|
|
125
|
+
def from_tmsitime_to_datetime(tmsi_time, date_time):
|
|
126
|
+
date_time = datetime.datetime(
|
|
127
|
+
tmsi_time.Year + 1900,
|
|
128
|
+
tmsi_time.Month + 1,
|
|
129
|
+
tmsi_time.DayOfMonth,
|
|
130
|
+
tmsi_time.Hours,
|
|
131
|
+
tmsi_time.Minutes,
|
|
132
|
+
tmsi_time.Seconds,
|
|
133
|
+
)
|
|
134
|
+
return date_time
|
|
@@ -0,0 +1,60 @@
|
|
|
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 decorators.py
|
|
26
|
+
* @brief
|
|
27
|
+
* Decorator class to handle decorative functions.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import time
|
|
34
|
+
import os
|
|
35
|
+
|
|
36
|
+
from .tmsi_logger import TMSiLoggerPerformance
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def LogPerformances(func):
|
|
40
|
+
def performance_logger(*args, **kwargs):
|
|
41
|
+
if "TMSi_ENV" in os.environ:
|
|
42
|
+
env = os.environ["TMSi_ENV"]
|
|
43
|
+
else:
|
|
44
|
+
env = "DLL"
|
|
45
|
+
if "TMSi_PERF" not in os.environ:
|
|
46
|
+
response = func(*args, **kwargs)
|
|
47
|
+
elif os.environ["TMSi_PERF"] == "ON":
|
|
48
|
+
tic = time.perf_counter()
|
|
49
|
+
response = func(*args, **kwargs)
|
|
50
|
+
toc = time.perf_counter()
|
|
51
|
+
TMSiLoggerPerformance().log(
|
|
52
|
+
"{} | {}: {:.3f} ms".format(
|
|
53
|
+
env, func.__qualname__, (toc - tic) * 1_000
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
else:
|
|
57
|
+
response = func(*args, **kwargs)
|
|
58
|
+
return response
|
|
59
|
+
|
|
60
|
+
return performance_logger
|
|
@@ -0,0 +1,42 @@
|
|
|
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 logger_filter.py
|
|
26
|
+
* @brief
|
|
27
|
+
* Filter to handle the logs.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
PERFORMANCE_LOG = 25
|
|
34
|
+
ACTIVITY_LOG = 26
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class LoggerFilter(object):
|
|
38
|
+
def __init__(self, level):
|
|
39
|
+
self.__level = level
|
|
40
|
+
|
|
41
|
+
def filter(self, log_record):
|
|
42
|
+
return log_record.levelno == self.__level
|
|
@@ -0,0 +1,42 @@
|
|
|
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 singleton.py
|
|
26
|
+
* @brief
|
|
27
|
+
* Singleton interface.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Singleton(type):
|
|
35
|
+
_instances = {}
|
|
36
|
+
|
|
37
|
+
def __call__(cls, *args, **kwargs):
|
|
38
|
+
if cls not in cls._instances:
|
|
39
|
+
cls._instances[cls] = super(Singleton, cls).__call__(
|
|
40
|
+
*args, **kwargs
|
|
41
|
+
)
|
|
42
|
+
return cls._instances[cls]
|
|
@@ -0,0 +1,72 @@
|
|
|
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 support_functions.py
|
|
26
|
+
* @brief
|
|
27
|
+
* Generic functions needed in the SDK.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import ctypes.wintypes
|
|
34
|
+
import os
|
|
35
|
+
import struct
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def array_to_matrix(input_array, n_channels):
|
|
39
|
+
n_samples = len(input_array) // n_channels
|
|
40
|
+
return [
|
|
41
|
+
input_array[ii : n_samples * n_channels : n_channels]
|
|
42
|
+
for ii in range(n_channels)
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def matrix_to_multiplexed_array(input_matrix):
|
|
47
|
+
return [
|
|
48
|
+
input_matrix[i][j]
|
|
49
|
+
for j in range(len(input_matrix[0]))
|
|
50
|
+
for i in range(len(input_matrix))
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def float_to_uint(f):
|
|
55
|
+
fmt_pack = "f" * len(f)
|
|
56
|
+
fmt_unpack = "I" * len(f)
|
|
57
|
+
pack_struct = struct.Struct(fmt_pack)
|
|
58
|
+
return struct.unpack(fmt_unpack, pack_struct.pack(*list(f)))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_documents_path():
|
|
62
|
+
CSIDL_PERSONAL = 5
|
|
63
|
+
SHGFP_TYPE_CURRENT = 0
|
|
64
|
+
buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
|
|
65
|
+
ctypes.windll.shell32.SHGetFolderPathW(
|
|
66
|
+
None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf
|
|
67
|
+
)
|
|
68
|
+
return buf.value
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_local_app_data():
|
|
72
|
+
return os.getenv("LOCALAPPDATA")
|
|
@@ -0,0 +1,98 @@
|
|
|
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 tmsi_logger.py
|
|
26
|
+
* @brief
|
|
27
|
+
* Loggers used to handle console or file output for informative and debug reasons.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import os
|
|
34
|
+
from sys import platform
|
|
35
|
+
import logging
|
|
36
|
+
from .logger_filter import PERFORMANCE_LOG, LoggerFilter, ACTIVITY_LOG
|
|
37
|
+
from .singleton import Singleton
|
|
38
|
+
from .support_functions import get_documents_path
|
|
39
|
+
|
|
40
|
+
logging.addLevelName(PERFORMANCE_LOG, "PERFORMANCE")
|
|
41
|
+
logging.addLevelName(ACTIVITY_LOG, "ACTIVITY")
|
|
42
|
+
formatter = logging.Formatter("%(asctime)s | %(levelname)s | %(message)s")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class TMSiLogger(metaclass=Singleton):
|
|
46
|
+
def __init__(self):
|
|
47
|
+
self.__tmsi_log = logging.getLogger("TMSi")
|
|
48
|
+
debug_stream_handler = logging.StreamHandler()
|
|
49
|
+
debug_stream_handler.setFormatter(formatter)
|
|
50
|
+
self.__tmsi_log.handlers = [debug_stream_handler]
|
|
51
|
+
|
|
52
|
+
def critical(self, message):
|
|
53
|
+
self.__tmsi_log.log(level=logging.CRITICAL, msg=message)
|
|
54
|
+
|
|
55
|
+
def debug(self, message):
|
|
56
|
+
self.__tmsi_log.log(level=logging.DEBUG, msg=message)
|
|
57
|
+
|
|
58
|
+
def info(self, message):
|
|
59
|
+
self.__tmsi_log.log(level=logging.INFO, msg=message)
|
|
60
|
+
|
|
61
|
+
def warning(self, message):
|
|
62
|
+
self.__tmsi_log.log(level=logging.WARNING, msg=message)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TMSiLoggerActivity(metaclass=Singleton):
|
|
66
|
+
def __init__(self):
|
|
67
|
+
self.__tmsi_perf = logging.getLogger("TMSiActivity")
|
|
68
|
+
perf_handler = logging.FileHandler("__activity.log")
|
|
69
|
+
perf_handler.setFormatter(formatter)
|
|
70
|
+
perf_handler.setLevel(ACTIVITY_LOG)
|
|
71
|
+
perf_handler.addFilter(LoggerFilter(ACTIVITY_LOG))
|
|
72
|
+
self.__tmsi_perf.handlers = [perf_handler]
|
|
73
|
+
|
|
74
|
+
def log(self, message):
|
|
75
|
+
self.__tmsi_perf.log(level=ACTIVITY_LOG, msg=message)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class TMSiLoggerPerformance(metaclass=Singleton):
|
|
79
|
+
def __init__(self):
|
|
80
|
+
self.__tmsi_perf = logging.getLogger("TMSiPerformance")
|
|
81
|
+
if platform == "win32":
|
|
82
|
+
tmsifolder = os.path.join(
|
|
83
|
+
get_documents_path(), "TMS_International_B.V", "Apex"
|
|
84
|
+
)
|
|
85
|
+
if not os.path.exists(tmsifolder):
|
|
86
|
+
os.makedirs(tmsifolder)
|
|
87
|
+
perf_handler = logging.FileHandler(
|
|
88
|
+
os.path.join(tmsifolder, "__performance.log")
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
perf_handler = logging.FileHandler("__performance.log")
|
|
92
|
+
perf_handler.setFormatter(formatter)
|
|
93
|
+
perf_handler.setLevel(PERFORMANCE_LOG)
|
|
94
|
+
perf_handler.addFilter(LoggerFilter(PERFORMANCE_LOG))
|
|
95
|
+
self.__tmsi_perf.handlers = [perf_handler]
|
|
96
|
+
|
|
97
|
+
def log(self, message):
|
|
98
|
+
self.__tmsi_perf.log(level=PERFORMANCE_LOG, msg=message)
|