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.
Files changed (176) hide show
  1. py_neuromodulation/ConnectivityDecoding/Automated Anatomical Labeling 3 (Rolls 2020).nii +0 -0
  2. py_neuromodulation/ConnectivityDecoding/_get_grid_hull.m +34 -0
  3. py_neuromodulation/ConnectivityDecoding/_get_grid_whole_brain.py +106 -0
  4. py_neuromodulation/ConnectivityDecoding/_helper_write_connectome.py +119 -0
  5. py_neuromodulation/ConnectivityDecoding/mni_coords_cortical_surface.mat +0 -0
  6. py_neuromodulation/ConnectivityDecoding/mni_coords_whole_brain.mat +0 -0
  7. py_neuromodulation/ConnectivityDecoding/rmap_func_all.nii +0 -0
  8. py_neuromodulation/ConnectivityDecoding/rmap_struc.nii +0 -0
  9. py_neuromodulation/data/README +6 -0
  10. py_neuromodulation/data/dataset_description.json +8 -0
  11. py_neuromodulation/data/participants.json +32 -0
  12. py_neuromodulation/data/participants.tsv +2 -0
  13. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +5 -0
  14. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +11 -0
  15. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +11 -0
  16. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.eeg +0 -0
  17. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.json +18 -0
  18. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +35 -0
  19. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +13 -0
  20. py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +2 -0
  21. py_neuromodulation/grid_cortex.tsv +40 -0
  22. py_neuromodulation/grid_subcortex.tsv +1429 -0
  23. py_neuromodulation/nm_settings.json +338 -0
  24. py_neuromodulation/nm_stream_offline.py +7 -6
  25. py_neuromodulation/plots/STN_surf.mat +0 -0
  26. py_neuromodulation/plots/Vertices.mat +0 -0
  27. py_neuromodulation/plots/faces.mat +0 -0
  28. py_neuromodulation/plots/grid.mat +0 -0
  29. {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info}/METADATA +182 -182
  30. py_neuromodulation-0.0.4.dist-info/RECORD +72 -0
  31. {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info}/WHEEL +1 -2
  32. docs/build/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -68
  33. docs/build/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -233
  34. docs/build/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
  35. docs/build/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -97
  36. docs/build/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
  37. docs/build/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -192
  38. docs/build/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
  39. docs/build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -68
  40. docs/build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -239
  41. docs/build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
  42. docs/build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -97
  43. docs/build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
  44. docs/build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -192
  45. docs/build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
  46. docs/source/_build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +0 -76
  47. docs/source/_build/html/_downloads/0d0d0a76e8f648d5d3cbc47da6351932/plot_real_time_demo.py +0 -97
  48. docs/source/_build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +0 -240
  49. docs/source/_build/html/_downloads/5d73cadc59a8805c47e3b84063afc157/plot_example_BIDS.py +0 -233
  50. docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py +0 -63
  51. docs/source/_build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +0 -219
  52. docs/source/_build/html/_downloads/839e5b319379f7fd9e867deb00fd797f/plot_example_gridPointProjection.py +0 -210
  53. docs/source/_build/html/_downloads/ae8be19afe5e559f011fc9b138968ba0/plot_first_demo.py +0 -192
  54. docs/source/_build/html/_downloads/b8b06cacc17969d3725a0b6f1d7741c5/plot_example_sharpwave_analysis.py +0 -219
  55. docs/source/_build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +0 -121
  56. docs/source/_build/html/_downloads/c31a86c0b68cb4167d968091ace8080d/plot_example_add_feature.py +0 -68
  57. docs/source/_build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +0 -64
  58. docs/source/_build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +0 -189
  59. docs/source/_build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +0 -210
  60. docs/source/auto_examples/plot_0_first_demo.py +0 -189
  61. docs/source/auto_examples/plot_1_example_BIDS.py +0 -240
  62. docs/source/auto_examples/plot_2_example_add_feature.py +0 -76
  63. docs/source/auto_examples/plot_3_example_sharpwave_analysis.py +0 -219
  64. docs/source/auto_examples/plot_4_example_gridPointProjection.py +0 -210
  65. docs/source/auto_examples/plot_5_example_rmap_computing.py +0 -64
  66. docs/source/auto_examples/plot_6_real_time_demo.py +0 -121
  67. docs/source/conf.py +0 -105
  68. examples/plot_0_first_demo.py +0 -189
  69. examples/plot_1_example_BIDS.py +0 -240
  70. examples/plot_2_example_add_feature.py +0 -76
  71. examples/plot_3_example_sharpwave_analysis.py +0 -219
  72. examples/plot_4_example_gridPointProjection.py +0 -210
  73. examples/plot_5_example_rmap_computing.py +0 -64
  74. examples/plot_6_real_time_demo.py +0 -121
  75. packages/realtime_decoding/build/lib/realtime_decoding/__init__.py +0 -4
  76. packages/realtime_decoding/build/lib/realtime_decoding/decoder.py +0 -104
  77. packages/realtime_decoding/build/lib/realtime_decoding/features.py +0 -163
  78. packages/realtime_decoding/build/lib/realtime_decoding/helpers.py +0 -15
  79. packages/realtime_decoding/build/lib/realtime_decoding/run_decoding.py +0 -345
  80. packages/realtime_decoding/build/lib/realtime_decoding/trainer.py +0 -54
  81. packages/tmsi/build/lib/TMSiFileFormats/__init__.py +0 -37
  82. packages/tmsi/build/lib/TMSiFileFormats/file_formats/__init__.py +0 -36
  83. packages/tmsi/build/lib/TMSiFileFormats/file_formats/lsl_stream_writer.py +0 -200
  84. packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_file_writer.py +0 -496
  85. packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_to_edf_converter.py +0 -236
  86. packages/tmsi/build/lib/TMSiFileFormats/file_formats/xdf_file_writer.py +0 -977
  87. packages/tmsi/build/lib/TMSiFileFormats/file_readers/__init__.py +0 -35
  88. packages/tmsi/build/lib/TMSiFileFormats/file_readers/edf_reader.py +0 -116
  89. packages/tmsi/build/lib/TMSiFileFormats/file_readers/poly5reader.py +0 -294
  90. packages/tmsi/build/lib/TMSiFileFormats/file_readers/xdf_reader.py +0 -229
  91. packages/tmsi/build/lib/TMSiFileFormats/file_writer.py +0 -102
  92. packages/tmsi/build/lib/TMSiPlotters/__init__.py +0 -2
  93. packages/tmsi/build/lib/TMSiPlotters/gui/__init__.py +0 -39
  94. packages/tmsi/build/lib/TMSiPlotters/gui/_plotter_gui.py +0 -234
  95. packages/tmsi/build/lib/TMSiPlotters/gui/plotting_gui.py +0 -440
  96. packages/tmsi/build/lib/TMSiPlotters/plotters/__init__.py +0 -44
  97. packages/tmsi/build/lib/TMSiPlotters/plotters/hd_emg_plotter.py +0 -446
  98. packages/tmsi/build/lib/TMSiPlotters/plotters/impedance_plotter.py +0 -589
  99. packages/tmsi/build/lib/TMSiPlotters/plotters/signal_plotter.py +0 -1326
  100. packages/tmsi/build/lib/TMSiSDK/__init__.py +0 -54
  101. packages/tmsi/build/lib/TMSiSDK/device.py +0 -588
  102. packages/tmsi/build/lib/TMSiSDK/devices/__init__.py +0 -34
  103. packages/tmsi/build/lib/TMSiSDK/devices/saga/TMSi_Device_API.py +0 -1764
  104. packages/tmsi/build/lib/TMSiSDK/devices/saga/__init__.py +0 -34
  105. packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_device.py +0 -1366
  106. packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_types.py +0 -520
  107. packages/tmsi/build/lib/TMSiSDK/devices/saga/xml_saga_config.py +0 -165
  108. packages/tmsi/build/lib/TMSiSDK/error.py +0 -95
  109. packages/tmsi/build/lib/TMSiSDK/sample_data.py +0 -63
  110. packages/tmsi/build/lib/TMSiSDK/sample_data_server.py +0 -99
  111. packages/tmsi/build/lib/TMSiSDK/settings.py +0 -45
  112. packages/tmsi/build/lib/TMSiSDK/tmsi_device.py +0 -111
  113. packages/tmsi/build/lib/__init__.py +0 -4
  114. packages/tmsi/build/lib/apex_sdk/__init__.py +0 -34
  115. packages/tmsi/build/lib/apex_sdk/device/__init__.py +0 -41
  116. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API.py +0 -1009
  117. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_enums.py +0 -239
  118. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_structures.py +0 -668
  119. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_device.py +0 -1611
  120. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_dongle.py +0 -38
  121. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_event_reader.py +0 -57
  122. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_channel.py +0 -44
  123. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_config.py +0 -150
  124. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_const.py +0 -36
  125. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_impedance_channel.py +0 -48
  126. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_info.py +0 -108
  127. packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/dongle_info.py +0 -39
  128. packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/download_measurement.py +0 -77
  129. packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/eeg_measurement.py +0 -150
  130. packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/impedance_measurement.py +0 -129
  131. packages/tmsi/build/lib/apex_sdk/device/threads/conversion_thread.py +0 -59
  132. packages/tmsi/build/lib/apex_sdk/device/threads/sampling_thread.py +0 -57
  133. packages/tmsi/build/lib/apex_sdk/device/tmsi_channel.py +0 -83
  134. packages/tmsi/build/lib/apex_sdk/device/tmsi_device.py +0 -201
  135. packages/tmsi/build/lib/apex_sdk/device/tmsi_device_enums.py +0 -103
  136. packages/tmsi/build/lib/apex_sdk/device/tmsi_dongle.py +0 -43
  137. packages/tmsi/build/lib/apex_sdk/device/tmsi_event_reader.py +0 -50
  138. packages/tmsi/build/lib/apex_sdk/device/tmsi_measurement.py +0 -118
  139. packages/tmsi/build/lib/apex_sdk/sample_data_server/__init__.py +0 -33
  140. packages/tmsi/build/lib/apex_sdk/sample_data_server/event_data.py +0 -44
  141. packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data.py +0 -50
  142. packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data_server.py +0 -136
  143. packages/tmsi/build/lib/apex_sdk/tmsi_errors/error.py +0 -126
  144. packages/tmsi/build/lib/apex_sdk/tmsi_sdk.py +0 -113
  145. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/apex/apex_structure_generator.py +0 -134
  146. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/decorators.py +0 -60
  147. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/logger_filter.py +0 -42
  148. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/singleton.py +0 -42
  149. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/support_functions.py +0 -72
  150. packages/tmsi/build/lib/apex_sdk/tmsi_utilities/tmsi_logger.py +0 -98
  151. py_neuromodulation-0.0.3.dist-info/RECORD +0 -188
  152. py_neuromodulation-0.0.3.dist-info/top_level.txt +0 -5
  153. tests/__init__.py +0 -0
  154. tests/conftest.py +0 -117
  155. tests/test_all_examples.py +0 -10
  156. tests/test_all_features.py +0 -63
  157. tests/test_bispectra.py +0 -70
  158. tests/test_bursts.py +0 -105
  159. tests/test_feature_sampling_rates.py +0 -143
  160. tests/test_fooof.py +0 -16
  161. tests/test_initalization_offline_stream.py +0 -41
  162. tests/test_multiprocessing.py +0 -58
  163. tests/test_nan_values.py +0 -29
  164. tests/test_nm_filter.py +0 -95
  165. tests/test_nm_resample.py +0 -63
  166. tests/test_normalization_settings.py +0 -146
  167. tests/test_notch_filter.py +0 -31
  168. tests/test_osc_features.py +0 -424
  169. tests/test_preprocessing_filter.py +0 -151
  170. tests/test_rereference.py +0 -171
  171. tests/test_sampling.py +0 -57
  172. tests/test_settings_change_after_init.py +0 -76
  173. tests/test_sharpwave.py +0 -165
  174. tests/test_target_channel_add.py +0 -100
  175. tests/test_timing.py +0 -80
  176. {py_neuromodulation-0.0.3.dist-info → py_neuromodulation-0.0.4.dist-info/licenses}/LICENSE +0 -0
@@ -1,589 +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 ${impedance_plotter.py}
26
- * @brief Plotter object that displays impedance values in real-time.
27
- *
28
- */
29
-
30
-
31
- '''
32
-
33
- from os.path import join, dirname, realpath, normpath, exists
34
- from PySide2 import QtGui, QtCore, QtWidgets
35
- import numpy as np
36
- import pyqtgraph as pg
37
- import time
38
- import queue
39
- import pandas as pd
40
- import math
41
- import datetime
42
- import sys
43
-
44
-
45
- Plotter_dir = dirname(realpath(__file__)) # directory of this file
46
- measurements_dir = join(Plotter_dir, '../../measurements') # directory with all measurements
47
- modules_dir = normpath(join(Plotter_dir, '../..')) # directory with all modules
48
-
49
- from TMSiSDK import tmsi_device
50
- from TMSiSDK import sample_data_server
51
- from TMSiSDK import sample_data
52
- from TMSiSDK.device import DeviceInterfaceType, MeasurementType
53
-
54
- from apex_sdk.device.tmsi_device import TMSiDevice
55
- from apex_sdk.sample_data_server.sample_data_server import SampleDataServer as ApexSampleDataServer
56
-
57
-
58
- class ImpedanceViewer():
59
- """ Class that creates a GUI to display the impedance values in a gridded
60
- layout.
61
- """
62
- def __init__(self, gui_handle, device, layout ='normal', file_storage = False, grid_type = 'none'):
63
- """ Setting up the GUI's elements
64
- """
65
- # Pass the device handle to the GUI
66
- self.device = device
67
-
68
- # Path to store the impedances, if a path is specified
69
- self._save_impedances = file_storage
70
-
71
- self.gui_handle = gui_handle
72
- self.RealTimePlotWidget = self.gui_handle.RealTimePlotWidget
73
-
74
- self.grid_type = grid_type
75
- self._disable_channels = []
76
-
77
- # Number of impedance channels
78
- if isinstance(self.device, TMSiDevice):
79
- self.n_chan = len(self.device.get_device_impedance_channels())
80
- else:
81
- self.n_chan = len(self.device.imp_channels)
82
-
83
- # Set up UI and thread
84
- self.initUI(layout)
85
- self.setupThread()
86
-
87
- def initUI(self, layout):
88
- """ Method responsible for constructing the basic elements in the plot.
89
- All viewboxes have a set size so that the information can be displayed
90
- correctly.
91
- """
92
- # Set view settings
93
- self.RealTimePlotWidget.setBackground('w')
94
- self.RealTimePlotWidget.showMaximized()
95
-
96
- # Add viewbox for the legend
97
- self.RealTimePlotWidget.vb_legend = self.RealTimePlotWidget.addViewBox()
98
- legend = pg.LegendItem()
99
- legend.setParentItem(self.RealTimePlotWidget.vb_legend)
100
-
101
- # Add plot window for the channels
102
- self.RealTimePlotWidget.window = self.RealTimePlotWidget.addPlot()
103
-
104
- if layout!='head':
105
- self.RealTimePlotWidget.window.getViewBox().invertY(True)
106
-
107
- if self.n_chan <= 34:
108
- self.RealTimePlotWidget.window.setAspectLocked(lock=True, ratio = 0.6)
109
- else:
110
- self.RealTimePlotWidget.window.setAspectLocked(lock=True, ratio = 1)
111
- else:
112
- self.RealTimePlotWidget.window.setAspectLocked(lock=True, ratio = 1)
113
-
114
- # Add viewbox for the list of values
115
- self.RealTimePlotWidget.vb_list = self.RealTimePlotWidget.addViewBox()
116
- self.RealTimePlotWidget.vb_list.setMaximumSize(500,150000)
117
-
118
- # Generate the legend by using dummy plots
119
- self.legend_entries = []
120
- legend_spots = self._generate_legend()
121
- for i in range(len(legend_spots)):
122
-
123
- lg_plt = pg.ScatterPlotItem(pos= [(0,0),(0,0)], size = 20,
124
- pen = legend_spots[i]['pen'], brush = legend_spots[i]['brush'],
125
- name = legend_spots[i]['name'])
126
- legend.addItem(lg_plt, legend_spots[i]['name'])
127
- lg_plt.clear()
128
-
129
- # Ensure legend is displayed in the top left of the viewbox
130
- self.RealTimePlotWidget.vb_legend.setMaximumWidth(legend.boundingRect().width() + 10)
131
- legend.anchor((0,0), (0,0))
132
-
133
- # Write the ticks to the plot
134
- self.RealTimePlotWidget.window.hideAxis('left')
135
- self.RealTimePlotWidget.window.hideAxis('bottom')
136
-
137
- # Disable auto-scaling and menu
138
- self.RealTimePlotWidget.window.hideButtons()
139
- self.RealTimePlotWidget.window.setMenuEnabled(False)
140
- self.RealTimePlotWidget.window.setMouseEnabled(x = False, y = False)
141
- self.RealTimePlotWidget.vb_legend.setMouseEnabled(x = False, y = False)
142
- self.RealTimePlotWidget.vb_list.setMouseEnabled(x = False, y = False)
143
-
144
- # Initialise the standard format for the different indicators
145
- self.spots = [{'pos': (0,0), 'size': 20, 'pen': 'k', 'brush': QtGui.QBrush(QtGui.QColor(128, 128, 128))} \
146
- for i in range(self.n_chan)]
147
-
148
- # Get channel names and units
149
- if isinstance(self.device, TMSiDevice):
150
- chs = [[i.get_channel_name(), i.get_channel_unit_name()] for i in self.device.get_device_impedance_channels()]
151
-
152
- if layout=='head':
153
- #read channel locations
154
- chLocs=pd.read_csv(join(modules_dir, 'TMSiSDK','_resources', 'EEGchannelsTMSi.txt'), sep="\t", header=None)
155
- chLocs.columns=['name', 'radius', 'theta']
156
-
157
- #Plot a circle
158
- theta=np.arange(0, 2.02*math.pi, math.pi/50)
159
- x_circle = 0.5*np.cos(theta)
160
- y_circle = 0.5*np.sin(theta)
161
- self.h = pg.PlotCurveItem()
162
- self.h.setData(x_circle, y_circle, pen=pg.mkPen((165, 165, 165), width=5))
163
- self.RealTimePlotWidget.window.addItem(self.h)
164
-
165
- #Plot a nose
166
- y_nose = np.array([x_circle[2], 0.55, x_circle[-3]])
167
- x_nose = np.array([y_circle[2], 0, y_circle[-3]])
168
- self.n = pg.PlotCurveItem()
169
- self.n.setData(x_nose, y_nose, pen=pg.mkPen((165, 165, 165), width=5))
170
- self.RealTimePlotWidget.window.addItem(self.n)
171
-
172
- #Plot ears
173
- x_ears = np.array([0.49, 0.51, 0.52, 0.53, 0.54, 0.54, 0.55, 0.53, 0.51, 0.485])
174
- y_ears = np.array([0.10, 0.1175, 0.1185, 0.1145, 0.0955, -0.0055, -0.0930, -0.1315, -0.1385, -0.12])
175
- self.e = pg.PlotCurveItem()
176
- self.e.setData(x_ears, y_ears, pen=pg.mkPen((165, 165, 165), width=5))
177
- self.RealTimePlotWidget.window.addItem(self.e)
178
- self.e = pg.PlotCurveItem()
179
- self.e.setData(-x_ears, y_ears, pen=pg.mkPen((165, 165, 165), width=5))
180
- self.RealTimePlotWidget.window.addItem(self.e)
181
-
182
- # Set the position for each indicator
183
- for i in range(self.n_chan):
184
- if i == 0:
185
- if isinstance(self.device, TMSiDevice):
186
- self.spots[i]['pos'] = (0, -0.6)
187
- else:
188
- self.spots[i]['pos'] = (-0.05, -0.6)
189
- elif i == self.n_chan - 1 and not isinstance(self.device, TMSiDevice):
190
- self.spots[i]['pos'] = (0.05, -0.6)
191
- else:
192
- if isinstance(self.device, TMSiDevice):
193
- idx_ch = np.where("'" + chs[i][0] + "'" == chLocs['name'])[0][0]
194
-
195
- x=chLocs['radius'].values[idx_ch]*np.sin(np.deg2rad(chLocs['theta'].values[idx_ch]))
196
- y=chLocs['radius'].values[idx_ch]*np.cos(np.deg2rad(chLocs['theta'].values[idx_ch]))
197
- else:
198
- x=chLocs['radius'].values[i-1]*np.sin(np.deg2rad(chLocs['theta'].values[i-1]))
199
- y=chLocs['radius'].values[i-1]*np.cos(np.deg2rad(chLocs['theta'].values[i-1]))
200
-
201
- self.spots[i]['pos'] = (x,y)
202
-
203
- # Place the name of each channel below the respective indicator
204
- if isinstance(self.device, TMSiDevice):
205
- text = f'{chs[i][0]: ^10}'
206
- else:
207
- text = f'{self.device.imp_channels[i].name: ^10}'
208
- t_item = pg.TextItem(text, (0, 0, 0), anchor=(0, 0))
209
- t_item.setPos(self.spots[i]['pos'][0] -.03, self.spots[i]['pos'][1] - .02)
210
- self.RealTimePlotWidget.window.addItem(t_item)
211
-
212
- # Generate the channel conversion list
213
- self.channel_conversion_list = np.arange(0,self.n_chan, dtype = int)
214
-
215
- else:
216
- self.channel_conversion_list = self.gui_handle.channel_conversion_list
217
-
218
- # Insert dummy channels
219
- self.dummy_chan = []
220
- if '11' in self.grid_type:
221
- if not self.grid_type[-1] == '2':
222
- self.dummy_chan.append(10)
223
- if not self.grid_type[-1] == '1':
224
- dummy_chan=max(self.channel_conversion_list)
225
- self.dummy_chan.append(dummy_chan)
226
-
227
- # Insert PGND channel in channel conversion list
228
- self.channel_conversion_list = np.hstack((self.channel_conversion_list, max(self.gui_handle.channel_conversion_list)+1))
229
- # In case of 64 channel device with 32 channel grid, insert channels 33-64
230
- if len(self.device.imp_channels) > 34 and max(self.channel_conversion_list) < 34:
231
- self.channel_conversion_list = np.hstack((self.channel_conversion_list, np.arange(34, 66)))
232
-
233
- row_count = -1
234
- c_offset = 0
235
-
236
- if '11' in self.grid_type:
237
- # Set the position for each indicator
238
- for i in range(len(self.device.imp_channels)):
239
- if i == 0:
240
- if len(self.device.imp_channels) > 34:
241
- self.spots[i]['pos'] = (3, 8)
242
- else:
243
- self.spots[i]['pos'] = (3, 4)
244
- elif i == len(self.device.imp_channels)-1:
245
- if len(self.device.imp_channels) > 34:
246
- self.spots[i]['pos'] = (4, 8)
247
- else:
248
- self.spots[i]['pos'] = (4, 4)
249
- elif i-1 in self.dummy_chan:
250
- row_count += 1
251
- self.spots[i]['pos'] = (0, row_count)
252
- c_offset = i-1
253
- elif (i-1-c_offset) % 11 == 0:
254
- row_count += 1
255
- self.spots[i]['pos'] = (0, row_count)
256
- else:
257
- self.spots[i]['pos'] = (((i-c_offset-1)%11), row_count)
258
- else:
259
- # Set the position for each indicator
260
- for i in range(self.n_chan):
261
- if i == 0:
262
- if self.n_chan > 34:
263
- self.spots[i]['pos'] = (3, 8)
264
- else:
265
- self.spots[i]['pos'] = (3, 4)
266
- elif i == self.n_chan - 1 and not isinstance(self.device, TMSiDevice):
267
- if self.n_chan > 34:
268
- self.spots[i]['pos'] = (4, 8)
269
- else:
270
- self.spots[i]['pos'] = (4, 4)
271
- elif (i-1) % 8 == 0:
272
- row_count += 1
273
- self.spots[i]['pos'] = (((i-1)%8), row_count)
274
- else:
275
- if i == 0:
276
- if len(self.device.imp_channels) > 34:
277
- self.spots[i]['pos'] = (3, 8)
278
- else:
279
- self.spots[i]['pos'] = (3, 4)
280
- elif i == len(self.device.imp_channels)-1:
281
- if len(self.device.imp_channels) > 34:
282
- self.spots[i]['pos'] = (4, 8)
283
- else:
284
- self.spots[i]['pos'] = (4, 4)
285
- elif (i-1) % 8 == 0:
286
- row_count += 1
287
- self.spots[i]['pos'] = (((i-1)%8), row_count)
288
- else:
289
- self.spots[i]['pos'] = (((i-1)%8), row_count)
290
-
291
- for i in range(self.n_chan):
292
- # Place the name of each channel below the respective indicator
293
- if isinstance(self.device, TMSiDevice):
294
- text = f'{chs[self.channel_conversion_list[i]][0]: ^10}'
295
- else:
296
- text = f'{self.device.imp_channels[self.channel_conversion_list[i]].name: ^10}'
297
- t_item = pg.TextItem(text, (128, 128, 128), anchor=(0, 0))
298
- t_item.setPos(self.spots[i]['pos'][0] -.25, self.spots[i]['pos'][1] + .1)
299
- self.RealTimePlotWidget.window.addItem(t_item)
300
-
301
- # Add all indicators to the plot
302
- self.c = pg.ScatterPlotItem(self.spots)
303
- self.RealTimePlotWidget.window.addItem(self.c)
304
-
305
- # Create a list with impedance values to display next to the plot
306
- self.text_items = []
307
- for i in range(self.n_chan):
308
- # Display 33 names per list (66 impedance channels in SAGA64+)
309
- list_split_idx = 33
310
- num_column = np.floor(i/list_split_idx)
311
- value = 5000
312
- if isinstance(self.device, TMSiDevice):
313
- text = f'{chs[self.channel_conversion_list[i]][0]}\t{value:>4}\t{chs[self.channel_conversion_list[i]][1][0]}'
314
- else:
315
- text = f'{self.device.imp_channels[self.channel_conversion_list[i]].name}\t{value:>4}\t{self.device.imp_channels[self.channel_conversion_list[i]].unit_name}'
316
- t_item = pg.TextItem(text, (0, 0, 0),
317
- anchor = (-num_column *1.2, -i*0.9 + list_split_idx * 0.9 * np.floor(i/list_split_idx)))
318
- self.text_items.append(t_item)
319
- self.RealTimePlotWidget.vb_list.addItem(t_item)
320
-
321
-
322
- @QtCore.Slot(object)
323
- def update_plot(self, data):
324
- """ Method that updates the indicators according to the measured impedance values
325
- """
326
- for i in range(len(self.spots)):
327
- if isinstance(self.device, TMSiDevice):
328
- if self.device.get_device_impedance_channels()[self.channel_conversion_list[i]].get_channel_name() in self._disable_channels:
329
- self.spots[i]['brush'] = QtGui.QBrush(QtGui.QColor(175, 175, 175))
330
- else:
331
- self.spots[i]['brush'] = QtGui.QBrush(self._lookup_table(data[i]))
332
- text = f"{self.device.get_device_impedance_channels()[self.channel_conversion_list[i]].get_channel_name()}\t{data[i]:>4}\t{self.device.get_device_impedance_channels()[self.channel_conversion_list[i]].get_channel_unit_name()[0]}"
333
- else:
334
- if self.device.imp_channels[self.channel_conversion_list[i]].name in self._disable_channels:
335
- self.spots[i]['brush'] = QtGui.QBrush(QtGui.QColor(175, 175, 175))
336
- else:
337
- self.spots[i]['brush'] = QtGui.QBrush(self._lookup_table(data[i]))
338
- text = f"{self.device.imp_channels[self.channel_conversion_list[i]].name}\t{data[i]:>4}\t{self.device.imp_channels[self.channel_conversion_list[i]].unit_name}"
339
- self.text_items[i].setText(text)
340
- self.c.setData(self.spots)
341
-
342
-
343
- def _lookup_table(self, value):
344
- """Look up table to convert impedances to color coding is device specific"""
345
- if isinstance(self.device, TMSiDevice):
346
- return self._lookup_table_APEX(value)
347
- else:
348
- return self._lookup_table_SAGA(value)
349
-
350
- def _lookup_table_SAGA(self, value):
351
- """Look up table to convert impedances to color coding"""
352
- if value < 5:
353
- color_code = QtGui.QColor(0, 255, 0)
354
- elif value >= 5 and value < 10:
355
- color_code = QtGui.QColor(0, 204, 0)
356
- elif value >= 10 and value < 30:
357
- color_code = QtGui.QColor(0, 153, 0)
358
- elif value >= 30 and value < 50:
359
- color_code = QtGui.QColor(0, 102, 0)
360
- elif value >= 50 and value < 100:
361
- color_code = QtGui.QColor(255, 255, 0)
362
- elif value >= 100 and value < 200:
363
- color_code = QtGui.QColor(204, 128, 0)
364
- elif value >= 200 and value < 400:
365
- color_code = QtGui.QColor(255, 0, 0)
366
- elif value >= 400 and value < 500:
367
- color_code = QtGui.QColor(153, 0, 0)
368
- elif value == 500:
369
- color_code = QtGui.QColor(0, 0, 0)
370
- elif value == 5000:
371
- color_code = QtGui.QColor(175, 175, 175)
372
- elif value == 5100:
373
- color_code = QtGui.QColor(204, 0, 102)
374
- elif value == 5200:
375
- color_code = QtGui.QColor(0, 0, 179)
376
- return color_code
377
-
378
- def _lookup_table_APEX(self, value):
379
- """Look up table to convert impedances to color coding"""
380
- if value < 5:
381
- color_code = QtGui.QColor(0, 255, 0)
382
- elif value >= 5 and value < 10:
383
- color_code = QtGui.QColor(0, 204, 0)
384
- elif value >= 10 and value < 30:
385
- color_code = QtGui.QColor(0, 153, 0)
386
- elif value >= 30 and value < 50:
387
- color_code = QtGui.QColor(0, 102, 0)
388
- elif value >= 50 and value < 100:
389
- color_code = QtGui.QColor(255, 255, 0)
390
- elif value >= 100 and value < 200:
391
- color_code = QtGui.QColor(204, 128, 0)
392
- elif value >= 200 and value < 400:
393
- color_code = QtGui.QColor(255, 0, 0)
394
- elif value >= 400 and value < 1000:
395
- color_code = QtGui.QColor(153, 0, 0)
396
- else:
397
- color_code = QtGui.QColor(38, 38, 38)
398
- return color_code
399
-
400
-
401
- def _generate_legend(self):
402
- """Generate the device specific legend"""
403
- if isinstance(self.device, TMSiDevice):
404
- return self._generate_APEX_legend()
405
- else:
406
- return self._generate_SAGA_legend()
407
-
408
-
409
- def _generate_SAGA_legend(self):
410
- """ Method that generates the dummy samples needed to plot the legend
411
- """
412
- legend_spots = [{'pos': (0,0), 'size': 10, 'pen': 'k', 'brush': QtGui.QBrush() , 'name': ''} for i in range(12)]
413
- legend_spots[0]['name'] = '0 - 5 k\u03A9'
414
- legend_spots[0]['brush'] = QtGui.QBrush(QtGui.QColor(0, 255, 0))
415
- legend_spots[1]['name'] = '5 - 10 k\u03A9'
416
- legend_spots[1]['brush'] = QtGui.QBrush(QtGui.QColor(0, 204, 0))
417
- legend_spots[2]['name'] = '10 - 30 k\u03A9'
418
- legend_spots[2]['brush'] = QtGui.QBrush(QtGui.QColor(0, 153, 0))
419
- legend_spots[3]['name'] = '30 - 50 k\u03A9'
420
- legend_spots[3]['brush'] = QtGui.QBrush(QtGui.QColor(0, 102, 0))
421
- legend_spots[4]['name'] = '50 - 100 k\u03A9'
422
- legend_spots[4]['brush'] = QtGui.QBrush(QtGui.QColor(255, 255, 0))
423
- legend_spots[5]['name'] = '100 - 200 k\u03A9'
424
- legend_spots[5]['brush'] = QtGui.QBrush(QtGui.QColor(204, 128, 0))
425
- legend_spots[6]['name'] = '200 - 400 k\u03A9'
426
- legend_spots[6]['brush'] = QtGui.QBrush(QtGui.QColor(255, 0, 0))
427
- legend_spots[7]['name'] = '400 - 500 k\u03A9'
428
- legend_spots[7]['brush'] = QtGui.QBrush(QtGui.QColor(153, 0, 0))
429
- legend_spots[8]['name'] = '≥ 500 k\u03A9 / Not connected'
430
- legend_spots[8]['brush'] = QtGui.QBrush(QtGui.QColor(0, 0, 0))
431
- legend_spots[9]['name'] = 'Disabled'
432
- legend_spots[9]['brush'] = QtGui.QBrush(QtGui.QColor(175, 175, 175))
433
- legend_spots[10]['name'] = 'Odd/Even error'
434
- legend_spots[10]['brush'] = QtGui.QBrush(QtGui.QColor(204, 0, 102))
435
- legend_spots[11]['name'] = 'PGND disconnected'
436
- legend_spots[11]['brush'] = QtGui.QBrush(QtGui.QColor(0, 0, 179))
437
- return legend_spots
438
-
439
-
440
- def _generate_APEX_legend(self):
441
- """ Method that generates the dummy samples needed to plot the legend
442
- """
443
- legend_spots = [{'pos': (0,0), 'size': 10, 'pen': 'k', 'brush': QtGui.QBrush() , 'name': ''} for i in range(9)]
444
- legend_spots[0]['name'] = '0 - 5 k\u03A9'
445
- legend_spots[0]['brush'] = QtGui.QBrush(QtGui.QColor(0, 255, 0))
446
- legend_spots[1]['name'] = '5 - 10 k\u03A9'
447
- legend_spots[1]['brush'] = QtGui.QBrush(QtGui.QColor(0, 204, 0))
448
- legend_spots[2]['name'] = '10 - 30 k\u03A9'
449
- legend_spots[2]['brush'] = QtGui.QBrush(QtGui.QColor(0, 153, 0))
450
- legend_spots[3]['name'] = '30 - 50 k\u03A9'
451
- legend_spots[3]['brush'] = QtGui.QBrush(QtGui.QColor(0, 102, 0))
452
- legend_spots[4]['name'] = '50 - 100 k\u03A9'
453
- legend_spots[4]['brush'] = QtGui.QBrush(QtGui.QColor(255, 255, 0))
454
- legend_spots[5]['name'] = '100 - 200 k\u03A9'
455
- legend_spots[5]['brush'] = QtGui.QBrush(QtGui.QColor(204, 128, 0))
456
- legend_spots[6]['name'] = '200 - 400 k\u03A9'
457
- legend_spots[6]['brush'] = QtGui.QBrush(QtGui.QColor(255, 0, 0))
458
- legend_spots[7]['name'] = '400 - 1000 k\u03A9'
459
- legend_spots[7]['brush'] = QtGui.QBrush(QtGui.QColor(153, 0, 0))
460
- legend_spots[8]['name'] = '≥ 1000 k\u03A9 / Not connected'
461
- legend_spots[8]['brush'] = QtGui.QBrush(QtGui.QColor(38, 38, 38))
462
-
463
- return legend_spots
464
-
465
- def _update_active_channels(self):
466
- self._disable_channels = []
467
- # Update the channel selection based on the clicked checkboxes
468
- for i in range(np.size(self.gui_handle._checkboxes,0)):
469
- if not self.gui_handle._checkboxes[i].isChecked():
470
- self._disable_channels.append(self.device.channels[self.gui_handle.active_channel_conversion_list[i]].name)
471
-
472
- def setupThread(self):
473
- """ Method that initialises the sampling thread of the device
474
- """
475
- # Create a Thread
476
- self.thread = QtCore.QThread()
477
- # Instantiate the worker class
478
- self.worker = SamplingThread(self)
479
-
480
- # Move the worker to a Thread
481
- self.worker.moveToThread(self.thread)
482
-
483
- # Connect signals to slots
484
- self.thread.started.connect(self.worker.update_samples)
485
- self.worker.output.connect(self.update_plot)
486
-
487
-
488
- class SamplingThread(QtCore.QObject):
489
- """ Class responsible for sampling the data from the device
490
- """
491
- # Initialise the ouptut object
492
- output = QtCore.Signal(object)
493
- def __init__(self, main_class):
494
- QtCore.QObject.__init__(self)
495
- # Access initialised values from the GUI class
496
- self.device = main_class.device
497
- self._save_impedances = main_class._save_impedances
498
-
499
- self.grid_type = main_class.grid_type
500
- self.channel_conversion_list = main_class.channel_conversion_list
501
-
502
- # Prepare Queue
503
- self.q_sample_sets = queue.Queue(1000)
504
-
505
-
506
- # Register the consumer to the sample server
507
- if isinstance(self.device, TMSiDevice):
508
- ApexSampleDataServer().register_consumer(self.device.get_id(), self.q_sample_sets)
509
- else:
510
- sample_data_server.registerConsumer(self.device.id, self.q_sample_sets)
511
-
512
- # # Start measurement
513
- self.sampling = True
514
-
515
- @QtCore.Slot()
516
- def update_samples(self):
517
- """ Method that retrieves the sample data from the device. The method
518
- gives the impedance value as output
519
- """
520
- while self.sampling:
521
- while not self.q_sample_sets.empty():
522
- sd = self.q_sample_sets.get()
523
- self.q_sample_sets.task_done()
524
-
525
- # Retrieve the data from the queue and write it to a SampleSet object
526
- for i in range(sd.num_sample_sets):
527
- sample_set = sample_data.SampleSet(sd.num_samples_per_sample_set, sd.samples[i*sd.num_samples_per_sample_set:(i+1)*sd.num_samples_per_sample_set])
528
-
529
- # Use the final measured impedance value and convert to integer value
530
- impedance_values = [int(x) for x in sample_set.samples]
531
-
532
- if isinstance(self.device, TMSiDevice):
533
- impedance_values = [impedance_values[i*2] for i in self.channel_conversion_list]
534
- else:
535
- impedance_values = [impedance_values[i] for i in self.channel_conversion_list]
536
-
537
- self.impedance_values = impedance_values
538
-
539
- # Output sample data
540
- self.output.emit(impedance_values)
541
-
542
- # Pause the thread so that the update does not happen too fast
543
- time.sleep(1)
544
-
545
- def stop(self):
546
- """ Method that is executed when the thread is terminated.
547
- This stop event stops the measurement and closes the connection to
548
- the device.
549
- """
550
- self.sampling = False
551
-
552
- if self._save_impedances:
553
- store_imp = []
554
-
555
- for i in range(len(self.impedance_values)):
556
- if isinstance(self.device, TMSiDevice):
557
- store_imp.append(f"{self.device.get_device_impedance_channels()[i].get_channel_name()}\t{self.impedance_values[self.channel_conversion_list[i]]}\t{self.device.get_device_impedance_channels()[self.channel_conversion_list[i]].get_channel_unit_name()[0]}")
558
- else:
559
- store_imp.append(f"{self.device.imp_channels[i].name}\t{self.impedance_values[self.channel_conversion_list[i]]}\t{self.device.imp_channels[self.channel_conversion_list[i]].unit_name}")
560
-
561
- now = datetime.datetime.now()
562
- filetime = now.strftime("%Y%m%d_%H%M%S")
563
- filename = self._save_impedances + '-' + filetime
564
-
565
- with open(filename + '.txt', 'w') as f:
566
- for item in store_imp:
567
- f.write(item + "\n")
568
-
569
- if __name__ == "__main__":
570
- # Initialise the TMSi-SDK first before starting using it
571
- tmsi_device.initialize()
572
-
573
- # Create the device object to interface with the SAGA-system.
574
- dev = tmsi_device.create(tmsi_device.DeviceType.saga, DeviceInterfaceType.docked, DeviceInterfaceType.usb)
575
-
576
- # Find and open a connection to the SAGA-system and print its serial number
577
- dev.open()
578
- print("handle 1 " + str(dev.info.ds_serial_number))
579
-
580
- # Initialise the application
581
- app = QtGui.QApplication(sys.argv)
582
- # Define the GUI object and show it
583
- window = ImpedancePlot(figurename = 'An Impedance Plot', device = dev, layout='normal')
584
- window.show()
585
-
586
- # Enter the event loop
587
- # sys.exit(app.exec_())
588
- app.exec_()
589
- dev.close()