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,496 +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 ${poly5_file_writer.py}
26
- * @brief Poly5 File Writer
27
- *
28
- */
29
-
30
-
31
- """
32
-
33
- from datetime import datetime
34
-
35
- import os
36
- import threading
37
- import queue
38
- import struct
39
- import time
40
- import numpy as np
41
-
42
- from TMSiSDK.error import TMSiError, TMSiErrorCode
43
- from TMSiSDK import sample_data_server
44
- from apex_sdk.device.tmsi_device import TMSiDevice
45
- from apex_sdk.sample_data_server.sample_data_server import (
46
- SampleDataServer as ApexSampleDataServer,
47
- )
48
-
49
- _QUEUE_SIZE = 1000
50
-
51
-
52
- class Poly5Writer:
53
- def __init__(self, filename, download=False):
54
- self.q_sample_sets = queue.Queue(_QUEUE_SIZE)
55
- self.device = None
56
-
57
- fileparts = filename.split(".")
58
- if not download:
59
- now = datetime.now()
60
- filetime = now.strftime("%Y%m%d_%H%M%S")
61
- if fileparts[-1] == "poly5" or fileparts[-1] == "Poly5":
62
- self.filename = (
63
- ".".join(fileparts[:-1]) + "-" + filetime + ".poly5"
64
- )
65
- else:
66
- self.filename = filename + "-" + filetime + ".poly5"
67
- else:
68
- if fileparts[-1] == "poly5" or fileparts[-1] == "Poly5":
69
- self.filename = filename
70
- else:
71
- self.filename = filename + ".poly5"
72
-
73
- self._fp = None
74
- self._date = None
75
-
76
- def open(self, device):
77
- if isinstance(device, TMSiDevice):
78
- self.__open_TMSiDevice(device)
79
- return
80
-
81
- self.device = device
82
- try:
83
- self._fp = open(self.filename, "wb")
84
- self._date = datetime.now()
85
- self._sample_rate = device.config.sample_rate
86
- self._num_channels = len(device.channels)
87
-
88
- # Calculate nr of sample-sets within one sample-data-block:
89
- # This is the nr of sample-sets in 150 milli-seconds or when the
90
- # sample-data-block-size exceeds 64kb the it will become the nr of
91
- # sample-sets that fit in 64kb
92
- self._num_sample_sets_per_sample_data_block = int(
93
- self._sample_rate * 0.15
94
- )
95
- size_one_sample_set = len(self.device.channels) * 4
96
- if (
97
- self._num_sample_sets_per_sample_data_block
98
- * size_one_sample_set
99
- ) > 64000:
100
- self._num_sample_sets_per_sample_data_block = int(
101
- 64000 / size_one_sample_set
102
- )
103
-
104
- # Write poly5-header for thsi measurement
105
- Poly5Writer._writeHeader(
106
- self._fp,
107
- "measurement",
108
- device.config.sample_rate,
109
- len(device.channels),
110
- len(device.channels),
111
- 0,
112
- 0,
113
- self._date,
114
- )
115
- for (i, channel) in enumerate(self.device.channels):
116
- Poly5Writer._writeSignalDescription(
117
- self._fp, i, channel.name, channel.unit_name
118
- )
119
-
120
- fmt = (
121
- "f"
122
- * self._num_channels
123
- * self._num_sample_sets_per_sample_data_block
124
- )
125
- self.pack_struct = struct.Struct(fmt)
126
-
127
- sample_data_server.registerConsumer(
128
- self.device.id, self.q_sample_sets
129
- )
130
-
131
- self._sampling_thread = ConsumerThread(
132
- self, name="poly5-writer : dev-id-" + str(self.device.id)
133
- )
134
- self._sampling_thread.start()
135
- except OSError as e:
136
- print(e)
137
- raise TMSiError(TMSiErrorCode.file_writer_error)
138
- except:
139
- raise TMSiError(TMSiErrorCode.file_writer_error)
140
-
141
- def __open_TMSiDevice(self, device):
142
- self.device = device
143
- try:
144
- self._fp = open(self.filename, "wb")
145
- self._date = datetime.now()
146
- self._sample_rate = self.device.get_device_sampling_frequency()
147
- self._num_channels = self.device.get_num_channels()
148
-
149
- # Calculate nr of sample-sets within one sample-data-block:
150
- # This is the nr of sample-sets in 150 milli-seconds or when the
151
- # sample-data-block-size exceeds 64kb the it will become the nr of
152
- # sample-sets that fit in 64kb
153
- self._num_sample_sets_per_sample_data_block = int(
154
- self._sample_rate * 0.15
155
- )
156
- size_one_sample_set = self._num_channels * 4
157
- if (
158
- self._num_sample_sets_per_sample_data_block
159
- * size_one_sample_set
160
- ) > 64000:
161
- self._num_sample_sets_per_sample_data_block = int(
162
- 64000 / size_one_sample_set
163
- )
164
-
165
- # Write poly5-header for thsi measurement
166
- Poly5Writer._writeHeader(
167
- self._fp,
168
- "measurement",
169
- self._sample_rate,
170
- self._num_channels,
171
- self._num_channels,
172
- 0,
173
- 0,
174
- self._date,
175
- )
176
- for (i, channel) in enumerate(self.device.get_device_channels()):
177
- Poly5Writer._writeSignalDescription(
178
- self._fp,
179
- i,
180
- channel.get_channel_name(),
181
- channel.get_channel_unit_name(),
182
- )
183
-
184
- fmt = (
185
- "f"
186
- * self._num_channels
187
- * self._num_sample_sets_per_sample_data_block
188
- )
189
- self.pack_struct = struct.Struct(fmt)
190
-
191
- ApexSampleDataServer().register_consumer(
192
- self.device.get_id(), self.q_sample_sets
193
- )
194
-
195
- self._sampling_thread = ConsumerThread(
196
- self, name="poly5-writer : dev-id-" + str(self.device.get_id())
197
- )
198
- self._sampling_thread.start()
199
- except OSError as e:
200
- print(e)
201
- raise TMSiError(TMSiErrorCode.file_writer_error)
202
- except:
203
- raise TMSiError(TMSiErrorCode.file_writer_error)
204
-
205
- def close(self):
206
- # print("Poly5Writer-close")
207
- self._sampling_thread.stop_sampling()
208
-
209
- if isinstance(self.device, TMSiDevice):
210
- ApexSampleDataServer().unregister_consumer(
211
- self.device.get_id(), self.q_sample_sets
212
- )
213
- else:
214
- sample_data_server.unregisterConsumer(
215
- self.device.id, self.q_sample_sets
216
- )
217
-
218
- ## Write header of a poly5 file.
219
- #
220
- # This function writes the header of a poly5 file to a file.
221
- # @param f File object
222
- # @param name Name of measurement
223
- # @param numSignals Number of signals
224
- # @param numSamples Number of samples
225
- # @param numDataBlocks Number of data blocks
226
- # @param date Date of measurement
227
- @staticmethod
228
- def _writeHeader(
229
- f,
230
- name,
231
- sample_rate,
232
- num_signals,
233
- num_samples,
234
- num_data_blocks,
235
- num_sample_sets_per_sample_data_block,
236
- date,
237
- ):
238
-
239
- data = struct.pack(
240
- "=31sH81phhBHi4xHHHHHHHiHHH64x",
241
- b"POLY SAMPLE FILEversion 2.03\r\n\x1a",
242
- 203,
243
- bytes(name, "ascii"),
244
- int(sample_rate),
245
- int(sample_rate),
246
- 0,
247
- num_signals * 2,
248
- num_samples,
249
- date.year,
250
- date.month,
251
- date.day,
252
- date.isoweekday() % 7,
253
- date.hour,
254
- date.minute,
255
- date.second,
256
- num_data_blocks,
257
- num_sample_sets_per_sample_data_block,
258
- num_signals * 2 * num_sample_sets_per_sample_data_block * 2,
259
- 0,
260
- )
261
- f.write(data)
262
-
263
- ## Write a signal description
264
- #
265
- # @param f File object
266
- # @param index Index of the signal description
267
- # @param name Name of the signal (channel)
268
- # @param unitname The unit name of the signal
269
- @staticmethod
270
- def _writeSignalDescription(f, index, name, unit_name):
271
- data = struct.pack(
272
- "=41p4x11pffffH62x",
273
- bytes("(Lo) " + name, "ascii"),
274
- bytes(unit_name, "utf-8"),
275
- 0.0,
276
- 1000.0,
277
- 0.0,
278
- 1000.0,
279
- index,
280
- )
281
- f.write(data)
282
-
283
- data = struct.pack(
284
- "=41p4x11pffffH62x",
285
- bytes("(Hi) " + name, "ascii"),
286
- bytes(unit_name, "utf-8"),
287
- 0.0,
288
- 1000.0,
289
- 0.0,
290
- 1000.0,
291
- index,
292
- )
293
- f.write(data)
294
-
295
- ## Write a signal block
296
- #
297
- # @param f File object
298
- # @param index Index of the data block
299
- # @param date Date of the sample_data block (measurement)
300
- # @param signals A list of sample_data, containing NumPy arrays
301
- @staticmethod
302
- def _writeSignalBlock(
303
- f,
304
- index,
305
- date,
306
- sample_sets_block,
307
- num_sample_sets_per_sample_data_block,
308
- n_chan,
309
- pack_struct,
310
- ):
311
- data = struct.pack(
312
- "=i4xHHHHHHH64x",
313
- int(index * num_sample_sets_per_sample_data_block),
314
- date.year,
315
- date.month,
316
- date.day,
317
- date.isoweekday() % 7,
318
- date.hour,
319
- date.minute,
320
- date.second,
321
- )
322
- f.write(data)
323
-
324
- sample_sets_block[n_chan - 1 :: n_chan] = sample_sets_block[
325
- n_chan - 1 :: n_chan
326
- ] % (2**24)
327
-
328
- bin = pack_struct.pack(*sample_sets_block)
329
- f.write(bin)
330
-
331
-
332
- class ConsumerThread(threading.Thread):
333
- def __init__(self, file_writer, name):
334
- super(ConsumerThread, self).__init__()
335
- self.name = name
336
- self.q_sample_sets = file_writer.q_sample_sets
337
- self.sampling = True
338
- self._sample_set_block_index = 0
339
- self._date = file_writer._date
340
- self._fp = file_writer._fp
341
- self._sample_rate = file_writer._sample_rate
342
- self._num_channels = file_writer._num_channels
343
- self._num_sample_sets_per_sample_data_block = (
344
- file_writer._num_sample_sets_per_sample_data_block
345
- )
346
- self._sample_sets_in_block = []
347
- self.pack_struct = file_writer.pack_struct
348
- self._remaining_samples = np.array([])
349
-
350
- def run(self):
351
- # print(self.name, " started")
352
-
353
- while (self.sampling) or (not self.q_sample_sets.empty()):
354
- while not self.q_sample_sets.empty():
355
- sd = self.q_sample_sets.get()
356
- self.q_sample_sets.task_done()
357
-
358
- if self._remaining_samples.size:
359
- samples = np.concatenate(
360
- (self._remaining_samples, sd.samples)
361
- )
362
- else:
363
- samples = np.array(sd.samples)
364
-
365
- n_samp = int(len(samples) / sd.num_samples_per_sample_set)
366
-
367
- try:
368
- for i in range(
369
- np.int(
370
- np.floor(
371
- n_samp
372
- / self._num_sample_sets_per_sample_data_block
373
- )
374
- )
375
- ):
376
- self._sample_sets_in_block = samples[
377
- i
378
- * self._num_sample_sets_per_sample_data_block
379
- * sd.num_samples_per_sample_set : (i + 1)
380
- * self._num_sample_sets_per_sample_data_block
381
- * sd.num_samples_per_sample_set
382
- ]
383
- Poly5Writer._writeSignalBlock(
384
- self._fp,
385
- self._sample_set_block_index,
386
- self._date,
387
- self._sample_sets_in_block,
388
- self._num_sample_sets_per_sample_data_block,
389
- self._num_channels,
390
- self.pack_struct,
391
- )
392
- self._sample_set_block_index += 1
393
-
394
- if not (self._sample_set_block_index % 20):
395
- # Go back to start and rewrite header
396
- self._fp.seek(0)
397
- Poly5Writer._writeHeader(
398
- self._fp,
399
- "measurement",
400
- self._sample_rate,
401
- self._num_channels,
402
- self._sample_set_block_index
403
- * self._num_sample_sets_per_sample_data_block,
404
- self._sample_set_block_index,
405
- self._num_sample_sets_per_sample_data_block,
406
- self._date,
407
- )
408
-
409
- # Flush all data from buffers to the file
410
- self._fp.flush()
411
- os.fsync(self._fp.fileno())
412
-
413
- # Go back to end of file
414
- self._fp.seek(0, os.SEEK_END)
415
-
416
- i = np.int(
417
- np.floor(
418
- n_samp / self._num_sample_sets_per_sample_data_block
419
- )
420
- )
421
- ind = np.arange(
422
- i
423
- * self._num_sample_sets_per_sample_data_block
424
- * sd.num_samples_per_sample_set,
425
- n_samp * sd.num_samples_per_sample_set,
426
- )
427
- if ind.any:
428
- self._remaining_samples = samples[ind]
429
- else:
430
- self._remaining_samples = np.array([])
431
-
432
- except:
433
- raise TMSiError(TMSiErrorCode.file_writer_error)
434
-
435
- time.sleep(0.01)
436
-
437
- while self._remaining_samples.any():
438
- # Last data block is omitted from saving, to prevent an incomplete data block being part of the Poly5 file
439
- # This would result in 0s at the end of the file
440
- if (
441
- np.shape(self._remaining_samples)[0]
442
- < self._num_sample_sets_per_sample_data_block
443
- * self._num_channels
444
- ):
445
- self._remaining_samples = np.array([])
446
-
447
- else:
448
- self._sample_sets_in_block = self._remaining_samples[
449
- : self._num_sample_sets_per_sample_data_block
450
- * self._num_channels
451
- ]
452
-
453
- self._remaining_samples = self._remaining_samples[
454
- self._num_sample_sets_per_sample_data_block
455
- * self._num_channels :
456
- ]
457
-
458
- Poly5Writer._writeSignalBlock(
459
- self._fp,
460
- self._sample_set_block_index,
461
- self._date,
462
- self._sample_sets_in_block,
463
- self._num_sample_sets_per_sample_data_block,
464
- self._num_channels,
465
- self.pack_struct,
466
- )
467
- self._sample_set_block_index += 1
468
-
469
- # Go back to start and rewrite header
470
- self._fp.seek(0)
471
- Poly5Writer._writeHeader(
472
- self._fp,
473
- "measurement",
474
- self._sample_rate,
475
- self._num_channels,
476
- self._sample_set_block_index
477
- * self._num_sample_sets_per_sample_data_block,
478
- self._sample_set_block_index,
479
- self._num_sample_sets_per_sample_data_block,
480
- self._date,
481
- )
482
-
483
- # Flush all data from buffers to the file
484
- self._fp.flush()
485
- os.fsync(self._fp.fileno())
486
-
487
- # Go back to end of file
488
- self._fp.seek(0, os.SEEK_END)
489
-
490
- # print(self.name, " ready, closing file")
491
- self._fp.close()
492
- return
493
-
494
- def stop_sampling(self):
495
- # print(self.name, " stop sampling")
496
- self.sampling = False