pyNIBS 0.2024.8__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.
- pyNIBS-0.2024.8.dist-info/LICENSE +623 -0
- pyNIBS-0.2024.8.dist-info/METADATA +723 -0
- pyNIBS-0.2024.8.dist-info/RECORD +107 -0
- pyNIBS-0.2024.8.dist-info/WHEEL +5 -0
- pyNIBS-0.2024.8.dist-info/top_level.txt +1 -0
- pynibs/__init__.py +34 -0
- pynibs/coil.py +1367 -0
- pynibs/congruence/__init__.py +15 -0
- pynibs/congruence/congruence.py +1108 -0
- pynibs/congruence/ext_metrics.py +257 -0
- pynibs/congruence/stimulation_threshold.py +318 -0
- pynibs/data/configuration_exp0.yaml +59 -0
- pynibs/data/configuration_linear_MEP.yaml +61 -0
- pynibs/data/configuration_linear_RT.yaml +61 -0
- pynibs/data/configuration_sigmoid4.yaml +68 -0
- pynibs/data/network mapping configuration/configuration guide.md +238 -0
- pynibs/data/network mapping configuration/configuration_TEMPLATE.yaml +42 -0
- pynibs/data/network mapping configuration/configuration_for_testing.yaml +43 -0
- pynibs/data/network mapping configuration/configuration_modelTMS.yaml +43 -0
- pynibs/data/network mapping configuration/configuration_reg_isi_05.yaml +43 -0
- pynibs/data/network mapping configuration/output_documentation.md +185 -0
- pynibs/data/network mapping configuration/recommendations_for_accuracy_threshold.md +77 -0
- pynibs/data/neuron/models/L23_PC_cADpyr_biphasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L23_PC_cADpyr_monophasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L4_LBC_biphasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L4_LBC_monophasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L4_NBC_biphasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L4_NBC_monophasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L4_SBC_biphasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L4_SBC_monophasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L5_TTPC2_cADpyr_biphasic_v1.csv +1281 -0
- pynibs/data/neuron/models/L5_TTPC2_cADpyr_monophasic_v1.csv +1281 -0
- pynibs/expio/Mep.py +1518 -0
- pynibs/expio/__init__.py +8 -0
- pynibs/expio/brainsight.py +979 -0
- pynibs/expio/brainvis.py +71 -0
- pynibs/expio/cobot.py +239 -0
- pynibs/expio/exp.py +1876 -0
- pynibs/expio/fit_funs.py +287 -0
- pynibs/expio/localite.py +1987 -0
- pynibs/expio/signal_ced.py +51 -0
- pynibs/expio/visor.py +624 -0
- pynibs/freesurfer.py +502 -0
- pynibs/hdf5_io/__init__.py +10 -0
- pynibs/hdf5_io/hdf5_io.py +1857 -0
- pynibs/hdf5_io/xdmf.py +1542 -0
- pynibs/mesh/__init__.py +3 -0
- pynibs/mesh/mesh_struct.py +1394 -0
- pynibs/mesh/transformations.py +866 -0
- pynibs/mesh/utils.py +1103 -0
- pynibs/models/_TMS.py +211 -0
- pynibs/models/__init__.py +0 -0
- pynibs/muap.py +392 -0
- pynibs/neuron/__init__.py +2 -0
- pynibs/neuron/neuron_regression.py +284 -0
- pynibs/neuron/util.py +58 -0
- pynibs/optimization/__init__.py +5 -0
- pynibs/optimization/multichannel.py +278 -0
- pynibs/optimization/opt_mep.py +152 -0
- pynibs/optimization/optimization.py +1445 -0
- pynibs/optimization/workhorses.py +698 -0
- pynibs/pckg/__init__.py +0 -0
- pynibs/pckg/biosig/biosig4c++-1.9.5.src_fixed.tar.gz +0 -0
- pynibs/pckg/libeep/__init__.py +0 -0
- pynibs/pckg/libeep/pyeep.so +0 -0
- pynibs/regression/__init__.py +11 -0
- pynibs/regression/dual_node_detection.py +2375 -0
- pynibs/regression/regression.py +2984 -0
- pynibs/regression/score_types.py +0 -0
- pynibs/roi/__init__.py +2 -0
- pynibs/roi/roi.py +895 -0
- pynibs/roi/roi_structs.py +1233 -0
- pynibs/subject.py +1009 -0
- pynibs/tensor_scaling.py +144 -0
- pynibs/tests/data/InstrumentMarker20200225163611937.xml +19 -0
- pynibs/tests/data/TriggerMarkers_Coil0_20200225163443682.xml +14 -0
- pynibs/tests/data/TriggerMarkers_Coil1_20200225170337572.xml +6373 -0
- pynibs/tests/data/Xdmf.dtd +89 -0
- pynibs/tests/data/brainsight_niiImage_nifticoord.txt +145 -0
- pynibs/tests/data/brainsight_niiImage_nifticoord_largefile.txt +1434 -0
- pynibs/tests/data/brainsight_niiImage_niifticoord_mixedtargets.txt +47 -0
- pynibs/tests/data/create_subject_testsub.py +332 -0
- pynibs/tests/data/data.hdf5 +0 -0
- pynibs/tests/data/geo.hdf5 +0 -0
- pynibs/tests/test_coil.py +474 -0
- pynibs/tests/test_elements2nodes.py +100 -0
- pynibs/tests/test_hdf5_io/test_xdmf.py +61 -0
- pynibs/tests/test_mesh_transformations.py +123 -0
- pynibs/tests/test_mesh_utils.py +143 -0
- pynibs/tests/test_nnav_imports.py +101 -0
- pynibs/tests/test_quality_measures.py +117 -0
- pynibs/tests/test_regressdata.py +289 -0
- pynibs/tests/test_roi.py +17 -0
- pynibs/tests/test_rotations.py +86 -0
- pynibs/tests/test_subject.py +71 -0
- pynibs/tests/test_util.py +24 -0
- pynibs/tms_pulse.py +34 -0
- pynibs/util/__init__.py +4 -0
- pynibs/util/dosing.py +233 -0
- pynibs/util/quality_measures.py +562 -0
- pynibs/util/rotations.py +340 -0
- pynibs/util/simnibs.py +763 -0
- pynibs/util/util.py +727 -0
- pynibs/visualization/__init__.py +2 -0
- pynibs/visualization/para.py +4372 -0
- pynibs/visualization/plot_2D.py +137 -0
- pynibs/visualization/render_3D.py +347 -0
pynibs/subject.py
ADDED
|
@@ -0,0 +1,1009 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import h5py
|
|
3
|
+
import pickle
|
|
4
|
+
import warnings
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pynibs
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Subject:
|
|
10
|
+
"""
|
|
11
|
+
Subject containing subject specific information, like mesh, roi, uncertainties, plot settings.
|
|
12
|
+
|
|
13
|
+
Attributes
|
|
14
|
+
----------
|
|
15
|
+
self.id : str
|
|
16
|
+
Subject id.
|
|
17
|
+
|
|
18
|
+
Notes
|
|
19
|
+
-----
|
|
20
|
+
**Initialization**
|
|
21
|
+
|
|
22
|
+
.. code-block:: python
|
|
23
|
+
|
|
24
|
+
sub = pynibs.subject(subject_ID, mesh)
|
|
25
|
+
|
|
26
|
+
**Parameters**
|
|
27
|
+
|
|
28
|
+
id : str
|
|
29
|
+
Subject id.
|
|
30
|
+
fn_mesh : str
|
|
31
|
+
.msh or .hdf5 file containing the mesh information.
|
|
32
|
+
|
|
33
|
+
**Subject.seg, segmentation information dictionary**
|
|
34
|
+
|
|
35
|
+
fn_lh_wm : str
|
|
36
|
+
Filename of left hemisphere white matter surface.
|
|
37
|
+
fn_rh_wm : str
|
|
38
|
+
Filename of right hemisphere white matter surface.
|
|
39
|
+
fn_lh_gm : str
|
|
40
|
+
Filename of left hemisphere grey matter surface.
|
|
41
|
+
fn_rh_gm : str
|
|
42
|
+
Filename of right hemisphere grey matter surface.
|
|
43
|
+
fn_lh_curv : str
|
|
44
|
+
Filename of left hemisphere curvature data on grey matter surface.
|
|
45
|
+
fn_rh_curv : str
|
|
46
|
+
Filename of right hemisphere curvature data on grey matter surface.
|
|
47
|
+
|
|
48
|
+
**Subject.mri, mri information dictionary**
|
|
49
|
+
|
|
50
|
+
fn_mri_T1 : str
|
|
51
|
+
Filename of T1 image.
|
|
52
|
+
fn_mri_T2 : str
|
|
53
|
+
Filename of T2 image.
|
|
54
|
+
fn_mri_DTI : str
|
|
55
|
+
Filename of DTI dataset.
|
|
56
|
+
fn_mri_DTI_bvec : str
|
|
57
|
+
Filename of DTI bvec file.
|
|
58
|
+
fn_mri_DTI_bval : str
|
|
59
|
+
Filename of DTI bval file.
|
|
60
|
+
fn_mri_conform : str
|
|
61
|
+
Filename of conform T1 image resulting from SimNIBS mri2mesh function.
|
|
62
|
+
|
|
63
|
+
**Subject.ps, plot settings dictionary**
|
|
64
|
+
|
|
65
|
+
see plot functions in para.py for more details
|
|
66
|
+
|
|
67
|
+
**Subject.exp, experiment dictionary**
|
|
68
|
+
|
|
69
|
+
info : str
|
|
70
|
+
General information about the experiment.
|
|
71
|
+
date : str
|
|
72
|
+
Date of experiment (e.g. 01/01/2018).
|
|
73
|
+
fn_tms_nav : str
|
|
74
|
+
Path to TMS navigator folder.
|
|
75
|
+
fn_data : str
|
|
76
|
+
Path to data folder or files.
|
|
77
|
+
fn_exp_csv : str
|
|
78
|
+
Filename of experimental data .csv file containing the merged experimental data information.
|
|
79
|
+
fn_coil : str
|
|
80
|
+
Filename of .ccd or .nii file of coil used in the experiment (contains ID).
|
|
81
|
+
fn_mri_nii : str
|
|
82
|
+
Filename of MRI .nii file used during the experiment.
|
|
83
|
+
cond : str or list of str
|
|
84
|
+
Conditions in the experiment in the recorded order (e.g. ['PA-45', 'PP-00']).
|
|
85
|
+
experimenter : str
|
|
86
|
+
Name of experimenter who conducted the experiment.
|
|
87
|
+
incidents : str
|
|
88
|
+
Description of special events occurred during the experiment.
|
|
89
|
+
|
|
90
|
+
**Subject.mesh, mesh dictionary**
|
|
91
|
+
|
|
92
|
+
info : str
|
|
93
|
+
Information about the mesh (e.g. dicretization, etc.).
|
|
94
|
+
fn_mesh_msh : str
|
|
95
|
+
Filename of the .msh file containing the FEM mesh.
|
|
96
|
+
fn_mesh_hdf5 : str
|
|
97
|
+
Filename of the .hdf5 file containing the FEM mesh.
|
|
98
|
+
seg_idx : int
|
|
99
|
+
Index indicating to which segmentation dictionary the mesh belongs.
|
|
100
|
+
|
|
101
|
+
**Subject.roi region of interest dictionary**
|
|
102
|
+
|
|
103
|
+
type : str
|
|
104
|
+
Specify type of ROI ('surface', 'volume')
|
|
105
|
+
info : str
|
|
106
|
+
Info about the region of interest, e.g. "M1 midlayer from freesurfer mask xyz".
|
|
107
|
+
region : list of str or float
|
|
108
|
+
Filename for freesurfer mask or ``[[X_min, X_max], [Y_min, Y_max], [Z_min, Z_max]]``.
|
|
109
|
+
delta : float
|
|
110
|
+
Distance parameter between WM and GM (0 -> WM, 1 -> GM) (for surfaces only).
|
|
111
|
+
"""
|
|
112
|
+
def __init__(self, subject_id, subject_folder):
|
|
113
|
+
self.id = subject_id # subject id
|
|
114
|
+
self.subject_folder = subject_folder # folder containing subject information
|
|
115
|
+
self.mri = [] # list containing mri information
|
|
116
|
+
self.mesh = {} # dict containing mesh information
|
|
117
|
+
self.exp = {} # dict containing information about conducted experiments
|
|
118
|
+
self.ps = [] # list containing plot settings
|
|
119
|
+
self.roi = {} # dict containing the roi information
|
|
120
|
+
|
|
121
|
+
def __str__(self):
|
|
122
|
+
""" Overload method to allow print(subject_object)"""
|
|
123
|
+
ret = f'{"=" * 64}\n' \
|
|
124
|
+
f'Subject ID : {self.id}\n' \
|
|
125
|
+
f'Folder : {self.subject_folder}\n' \
|
|
126
|
+
f'Meshes : {len(self.mesh.items())}\n' \
|
|
127
|
+
f'Experiments: {len(self.exp.items())}\n'
|
|
128
|
+
ret += f'{"=" * 64}\n\n'
|
|
129
|
+
ret += '------------------------------MRI------------------------------\n'
|
|
130
|
+
if not self.mri:
|
|
131
|
+
ret += 'None\n'
|
|
132
|
+
else:
|
|
133
|
+
for idx_mesh, mri in enumerate(self.mri):
|
|
134
|
+
ret += f"|- MRI[{idx_mesh}]\n"
|
|
135
|
+
for k, d in mri.items():
|
|
136
|
+
if k == list(mri.keys())[-1]:
|
|
137
|
+
pref = '└-'
|
|
138
|
+
else:
|
|
139
|
+
pref = '|-'
|
|
140
|
+
ret += f' {pref} {k: >19}: {d}\n'
|
|
141
|
+
|
|
142
|
+
ret += '\n------------------------------MESH------------------------------\n'
|
|
143
|
+
if not self.mesh:
|
|
144
|
+
ret += 'None\n'
|
|
145
|
+
else:
|
|
146
|
+
for idx_mesh, mesh in self.mesh.items():
|
|
147
|
+
ret += f"|- Mesh name: {idx_mesh}\n"
|
|
148
|
+
|
|
149
|
+
# plot roi keys
|
|
150
|
+
if idx_mesh in self.roi.keys():
|
|
151
|
+
for r_idx, roi in self.roi[idx_mesh].items():
|
|
152
|
+
key_list_roi = []
|
|
153
|
+
ret += f' |-- ROI: {r_idx}\n'
|
|
154
|
+
for k, d in roi.items():
|
|
155
|
+
if d is not None and k != 'name' and k != 'mesh_name':
|
|
156
|
+
key_list_roi.append(k)
|
|
157
|
+
for k in key_list_roi:
|
|
158
|
+
if k == key_list_roi[-1]:
|
|
159
|
+
pref = '└-'
|
|
160
|
+
else:
|
|
161
|
+
pref = '|-'
|
|
162
|
+
ret += f' {pref} {k: >19}: {roi[k]}\n'
|
|
163
|
+
|
|
164
|
+
# plot mesh keys
|
|
165
|
+
key_list_mesh = []
|
|
166
|
+
for k, d in mesh.items():
|
|
167
|
+
if d is not None and k != 'name' and k != 'subject_id':
|
|
168
|
+
key_list_mesh.append(k)
|
|
169
|
+
for k in key_list_mesh:
|
|
170
|
+
if k == key_list_mesh[-1]:
|
|
171
|
+
pref = '└-'
|
|
172
|
+
else:
|
|
173
|
+
pref = '|-'
|
|
174
|
+
ret += f' {pref} {k: >19}: {mesh[k]}\n'
|
|
175
|
+
|
|
176
|
+
ret += "\n"
|
|
177
|
+
ret += '\n----------------------------Experiments-------------------------\n'
|
|
178
|
+
if not self.exp:
|
|
179
|
+
ret += 'None\n'
|
|
180
|
+
else:
|
|
181
|
+
for idx_exp, exp in self.exp.items():
|
|
182
|
+
ret += f"|- Exp name: {idx_exp}\n"
|
|
183
|
+
key_list_exp = []
|
|
184
|
+
for k, d in exp.items():
|
|
185
|
+
if d is not None and k != 'name' and k != 'subject_id':
|
|
186
|
+
key_list_exp.append(k)
|
|
187
|
+
for k in key_list_exp:
|
|
188
|
+
if k == key_list_exp[-1]:
|
|
189
|
+
pref = '└-'
|
|
190
|
+
else:
|
|
191
|
+
pref = '|-'
|
|
192
|
+
ret += f' {pref} {k: >19}: {exp[k]}\n'
|
|
193
|
+
return ret
|
|
194
|
+
|
|
195
|
+
def add_mesh_info(self, mesh_dict):
|
|
196
|
+
"""
|
|
197
|
+
Adding filename information of the mesh to the subject object (multiple filenames possible).
|
|
198
|
+
|
|
199
|
+
Parameters
|
|
200
|
+
----------
|
|
201
|
+
mesh_dict : dict or list of dict
|
|
202
|
+
Dictionary containing the mesh information.
|
|
203
|
+
|
|
204
|
+
Notes
|
|
205
|
+
-----
|
|
206
|
+
**Adds Attributes**
|
|
207
|
+
|
|
208
|
+
Subject.mesh : list of dict
|
|
209
|
+
Dictionaries containing the mesh information.
|
|
210
|
+
"""
|
|
211
|
+
if type(mesh_dict) is list:
|
|
212
|
+
for mesh in mesh_dict:
|
|
213
|
+
self.mesh.append(mesh)
|
|
214
|
+
|
|
215
|
+
else:
|
|
216
|
+
self.mesh = mesh_dict
|
|
217
|
+
|
|
218
|
+
def add_roi_info(self, roi_dict):
|
|
219
|
+
"""
|
|
220
|
+
Adding ROI (surface) information of the mesh with mesh_index to the subject object (multiple ROIs possible).
|
|
221
|
+
|
|
222
|
+
Parameters
|
|
223
|
+
----------
|
|
224
|
+
roi_dict : dict of dict or list of dict
|
|
225
|
+
Dictionary containing the ROI information of the mesh with mesh_index ``[mesh_idx][roi_idx]``.
|
|
226
|
+
|
|
227
|
+
Notes
|
|
228
|
+
-----
|
|
229
|
+
**Adds Attributes**
|
|
230
|
+
|
|
231
|
+
Subject.mesh[mesh_index].roi : list of dict
|
|
232
|
+
Dictionaries containing ROI information.
|
|
233
|
+
"""
|
|
234
|
+
for mesh_idx in roi_dict.keys():
|
|
235
|
+
self.roi[mesh_idx] = dict()
|
|
236
|
+
|
|
237
|
+
for roi_idx in roi_dict[mesh_idx].keys():
|
|
238
|
+
self.roi[mesh_idx][roi_idx] = roi_dict[mesh_idx][roi_idx]
|
|
239
|
+
|
|
240
|
+
def add_plotsettings(self, ps_dict):
|
|
241
|
+
"""
|
|
242
|
+
Adding ROI information to the subject object (multiple ROIs possible).
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
ps_dict : dict or list of dict
|
|
247
|
+
Dictionary containing plot settings of the subject.
|
|
248
|
+
|
|
249
|
+
Notes
|
|
250
|
+
-----
|
|
251
|
+
**Adds Attributes**
|
|
252
|
+
|
|
253
|
+
Subject.ps : list of dict
|
|
254
|
+
Dictionary containing plot settings of the subject.
|
|
255
|
+
"""
|
|
256
|
+
if type(ps_dict) is not list:
|
|
257
|
+
ps_dict = [ps_dict]
|
|
258
|
+
|
|
259
|
+
for ps in ps_dict:
|
|
260
|
+
self.ps.append(ps)
|
|
261
|
+
|
|
262
|
+
def add_mri_info(self, mri_dict):
|
|
263
|
+
"""
|
|
264
|
+
Adding MRI information to the subject object (multiple MRIs possible).
|
|
265
|
+
|
|
266
|
+
Parameters
|
|
267
|
+
----------
|
|
268
|
+
mri_dict : dict or list of dict
|
|
269
|
+
Dictionary containing the MRI information of the subject.
|
|
270
|
+
|
|
271
|
+
Notes
|
|
272
|
+
-----
|
|
273
|
+
**Adds Attributes**
|
|
274
|
+
|
|
275
|
+
Subject.mri : list of dict
|
|
276
|
+
Dictionary containing the MRI information of the subject.
|
|
277
|
+
"""
|
|
278
|
+
if type(mri_dict) is not list:
|
|
279
|
+
mri_dict = [mri_dict]
|
|
280
|
+
|
|
281
|
+
for mri in mri_dict:
|
|
282
|
+
self.mri.append(mri)
|
|
283
|
+
|
|
284
|
+
@staticmethod
|
|
285
|
+
def _prep_fn(val):
|
|
286
|
+
if type(val) is dict:
|
|
287
|
+
pass
|
|
288
|
+
elif type(val) is not list:
|
|
289
|
+
val = [val]
|
|
290
|
+
for j in range(len(val)):
|
|
291
|
+
_ = check_file_and_format(val[j])
|
|
292
|
+
return val
|
|
293
|
+
|
|
294
|
+
def add_experiment_info(self, exp_dict):
|
|
295
|
+
"""
|
|
296
|
+
Adding information about a particular experiment.
|
|
297
|
+
|
|
298
|
+
Parameters
|
|
299
|
+
----------
|
|
300
|
+
exp_dict : dict of dict or list of dict
|
|
301
|
+
Dictionary containing information about the experiment.
|
|
302
|
+
|
|
303
|
+
Notes
|
|
304
|
+
-----
|
|
305
|
+
**Adds Attributes**
|
|
306
|
+
|
|
307
|
+
exp : list of dict
|
|
308
|
+
Dictionary containing information about the experiment.
|
|
309
|
+
"""
|
|
310
|
+
fns = ['fn_data', 'fn_coil', 'fn_mri_nii']
|
|
311
|
+
if exp_dict is None:
|
|
312
|
+
return
|
|
313
|
+
|
|
314
|
+
# if type(exp_dict) is not list:
|
|
315
|
+
# exp_dict = [exp_dict
|
|
316
|
+
# check if files and folder exist and convert to list
|
|
317
|
+
for i in exp_dict.keys():
|
|
318
|
+
|
|
319
|
+
# # fn_tms_nav
|
|
320
|
+
# if type(exp_dict[i]['fn_tms_nav']) is not list:
|
|
321
|
+
# exp_dict[i]['fn_tms_nav'] = [exp_dict[i]['fn_tms_nav']]
|
|
322
|
+
# for j in range(len(exp_dict[i]['fn_tms_nav'])):
|
|
323
|
+
# _ = check_file_and_format(exp_dict[i]['fn_tms_nav'][j])
|
|
324
|
+
|
|
325
|
+
# fn_data
|
|
326
|
+
for fn in fns:
|
|
327
|
+
try:
|
|
328
|
+
exp_dict[i][fn] = self._prep_fn(exp_dict[i][fn])
|
|
329
|
+
except KeyError:
|
|
330
|
+
pass
|
|
331
|
+
|
|
332
|
+
# new subject files have 'cond' as dictionary
|
|
333
|
+
if 'cond' in exp_dict[i].keys():
|
|
334
|
+
if isinstance(exp_dict[i]['cond'], dict):
|
|
335
|
+
for cond_name in exp_dict[i]['cond'].keys():
|
|
336
|
+
for fn in fns:
|
|
337
|
+
try:
|
|
338
|
+
exp_dict[i]['cond'][cond_name][fn] = self._prep_fn(exp_dict[i]['cond'][cond_name][fn])
|
|
339
|
+
except KeyError:
|
|
340
|
+
pass
|
|
341
|
+
else:
|
|
342
|
+
exp_dict[i]['cond'] = [[""]]
|
|
343
|
+
|
|
344
|
+
for exp in exp_dict:
|
|
345
|
+
self.exp[exp] = exp_dict[exp]
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def fill_from_dict(obj, d):
|
|
349
|
+
"""
|
|
350
|
+
Set all attributes from d in obj.
|
|
351
|
+
|
|
352
|
+
Parameters
|
|
353
|
+
----------
|
|
354
|
+
obj : pynibs.Mesh or pynibs.roi.ROI
|
|
355
|
+
Object to fill with ``d``.
|
|
356
|
+
d : dict
|
|
357
|
+
Dictionary containing the attributes to set.
|
|
358
|
+
|
|
359
|
+
Returns
|
|
360
|
+
-------
|
|
361
|
+
obj : pynibs.Mesh or pynibs.ROI
|
|
362
|
+
Object with attributes set from ``d``.
|
|
363
|
+
"""
|
|
364
|
+
for key, value in d.items():
|
|
365
|
+
if not hasattr(obj, f"{key}"):
|
|
366
|
+
warnings.warn(f"{key} not existing.")
|
|
367
|
+
setattr(obj, key, value)
|
|
368
|
+
|
|
369
|
+
return obj
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def save_subject(subject_id, subject_folder, fname, mri_dict=None, mesh_dict=None, roi_dict=None,
|
|
373
|
+
exp_dict=None, ps_dict=None, **kwargs):
|
|
374
|
+
"""
|
|
375
|
+
Saves subject information in .pkl or .hdf5 format (preferred)
|
|
376
|
+
|
|
377
|
+
Parameters
|
|
378
|
+
----------
|
|
379
|
+
subject_id : str
|
|
380
|
+
ID of subject.
|
|
381
|
+
subject_folder : str
|
|
382
|
+
Subject folder
|
|
383
|
+
fname : str
|
|
384
|
+
Filename with .hdf5 or .pkl extension (incl. path).
|
|
385
|
+
mri_dict : list of dict, optional
|
|
386
|
+
MRI info.
|
|
387
|
+
mesh_dict : list of dict, optional
|
|
388
|
+
Mesh info.
|
|
389
|
+
roi_dict : list of list of dict, optional
|
|
390
|
+
Mesh info.
|
|
391
|
+
exp_dict : list of dict, optional
|
|
392
|
+
Experiment info.
|
|
393
|
+
ps_dict : list of dict, optional
|
|
394
|
+
Plot-settings info.
|
|
395
|
+
kwargs : str or np.ndarray
|
|
396
|
+
Additional information saved in the parent folder of the .hdf5 file.
|
|
397
|
+
|
|
398
|
+
Returns
|
|
399
|
+
-------
|
|
400
|
+
<File> : .hdf5 file
|
|
401
|
+
Subject information
|
|
402
|
+
"""
|
|
403
|
+
filetype = os.path.splitext(fname)[1]
|
|
404
|
+
|
|
405
|
+
if filetype == ".hdf5":
|
|
406
|
+
if os.path.exists(fname):
|
|
407
|
+
os.remove(fname)
|
|
408
|
+
|
|
409
|
+
save_subject_hdf5(subject_id=subject_id,
|
|
410
|
+
subject_folder=subject_folder,
|
|
411
|
+
fname=fname,
|
|
412
|
+
mri_dict=mri_dict,
|
|
413
|
+
mesh_dict=mesh_dict,
|
|
414
|
+
roi_dict=roi_dict,
|
|
415
|
+
exp_dict=exp_dict,
|
|
416
|
+
ps_dict=ps_dict,
|
|
417
|
+
**kwargs)
|
|
418
|
+
|
|
419
|
+
elif filetype == ".pkl":
|
|
420
|
+
raise NotImplementedError
|
|
421
|
+
#
|
|
422
|
+
# # create and initialize subject
|
|
423
|
+
# subject = Subject(subject_id=subject_id)
|
|
424
|
+
#
|
|
425
|
+
# # add mri information
|
|
426
|
+
# subject.add_mri_info(mri_dict=mri_dict)
|
|
427
|
+
#
|
|
428
|
+
# # add mesh information
|
|
429
|
+
# subject.add_mesh_info(mesh_dict=mesh_dict)
|
|
430
|
+
#
|
|
431
|
+
# # add roi info to mesh
|
|
432
|
+
# subject.add_roi_info(roi_dict=roi_dict)
|
|
433
|
+
#
|
|
434
|
+
# # add experiment info
|
|
435
|
+
# subject.add_experiment_info(exp_dict=exp_dict)
|
|
436
|
+
#
|
|
437
|
+
# # add plotsettings
|
|
438
|
+
# subject.add_plotsettings(ps_dict=ps_dict)
|
|
439
|
+
#
|
|
440
|
+
# save_subject_pkl(sobj=subject, fname=fname)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def save_subject_pkl(sobj, fname):
|
|
444
|
+
"""
|
|
445
|
+
Saving subject object as pickle file.
|
|
446
|
+
|
|
447
|
+
Parameters
|
|
448
|
+
----------
|
|
449
|
+
sobj: object
|
|
450
|
+
Subject object to save
|
|
451
|
+
fname: str
|
|
452
|
+
Filename with .pkl extension
|
|
453
|
+
|
|
454
|
+
Returns
|
|
455
|
+
-------
|
|
456
|
+
<File> : .pkl file
|
|
457
|
+
Subject object instance
|
|
458
|
+
"""
|
|
459
|
+
|
|
460
|
+
if type(fname) is list:
|
|
461
|
+
fname = fname[0]
|
|
462
|
+
|
|
463
|
+
with open(fname, 'wb') as output:
|
|
464
|
+
pickle.dump(sobj, output, -1)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def save_subject_hdf5(subject_id, subject_folder, fname, mri_dict=None, mesh_dict=None, roi_dict=None,
|
|
468
|
+
exp_dict=None, ps_dict=None, overwrite=True, check_file_exist=False, verbose=False, **kwargs):
|
|
469
|
+
"""
|
|
470
|
+
Saving subject information in hdf5 file.
|
|
471
|
+
|
|
472
|
+
Parameters
|
|
473
|
+
----------
|
|
474
|
+
subject_id : str
|
|
475
|
+
ID of subject.
|
|
476
|
+
subject_folder : str
|
|
477
|
+
Subject folder.
|
|
478
|
+
fname : str
|
|
479
|
+
Filename with .hdf5 extension (incl. path).
|
|
480
|
+
mri_dict : list of dict, optional
|
|
481
|
+
MRI info.
|
|
482
|
+
mesh_dict : list of dict, optional
|
|
483
|
+
Mesh info.
|
|
484
|
+
roi_dict : list of list of dict, optional
|
|
485
|
+
Mesh info.
|
|
486
|
+
exp_dict : list of dict or dict of dict, optional
|
|
487
|
+
Experiment info.
|
|
488
|
+
ps_dict : list of dict, optional, default:None
|
|
489
|
+
Plot-settings info.
|
|
490
|
+
overwrite : bool
|
|
491
|
+
Overwrites existing .hdf5 file.
|
|
492
|
+
check_file_exist : bool
|
|
493
|
+
Hide warnings.
|
|
494
|
+
verbose : bool
|
|
495
|
+
Print information about meshes and ROIs.
|
|
496
|
+
kwargs : str or np.ndarray
|
|
497
|
+
Additional information saved in the parent folder of the .hdf5 file.
|
|
498
|
+
|
|
499
|
+
Returns
|
|
500
|
+
-------
|
|
501
|
+
<File> : .hdf5 file
|
|
502
|
+
Subject information.
|
|
503
|
+
"""
|
|
504
|
+
assert fname.endswith('.hdf5')
|
|
505
|
+
|
|
506
|
+
if overwrite and os.path.exists(fname):
|
|
507
|
+
os.remove(fname)
|
|
508
|
+
|
|
509
|
+
with h5py.File(fname, 'a') as f:
|
|
510
|
+
f["subject_id"] = np.array(subject_id).astype("|S")
|
|
511
|
+
f["subject_folder"] = np.array(subject_folder).astype("|S")
|
|
512
|
+
|
|
513
|
+
if mri_dict is not None:
|
|
514
|
+
if isinstance(mri_dict, list):
|
|
515
|
+
mri_dict = {i: mri_dict[i] for i in range(len(mri_dict))}
|
|
516
|
+
|
|
517
|
+
for i in mri_dict.keys():
|
|
518
|
+
pynibs.write_dict_to_hdf5(fn_hdf5=fname, data=mri_dict[i], folder=f"mri/{i}", check_file_exist=True)
|
|
519
|
+
|
|
520
|
+
if mesh_dict is not None:
|
|
521
|
+
if isinstance(mesh_dict, list):
|
|
522
|
+
mesh_dict = {i: mesh_dict[i] for i in range(len(mesh_dict))}
|
|
523
|
+
|
|
524
|
+
for mesh_name, mesh_dict in mesh_dict.items():
|
|
525
|
+
mesh = pynibs.Mesh(mesh_name=mesh_name, subject_id=subject_id, subject_folder=subject_folder)
|
|
526
|
+
mesh.fill_defaults(mesh_dict['approach'])
|
|
527
|
+
mesh = fill_from_dict(mesh, mesh_dict)
|
|
528
|
+
mesh.write_to_hdf5(fn_hdf5=fname, check_file_exist=check_file_exist, verbose=verbose)
|
|
529
|
+
|
|
530
|
+
if roi_dict is not None:
|
|
531
|
+
for mesh_name in roi_dict.keys():
|
|
532
|
+
for roi_name, roi_dict_i in roi_dict[mesh_name].items():
|
|
533
|
+
roi = pynibs.ROI(subject_id=subject_id, roi_name=roi_name, mesh_name=mesh_name)
|
|
534
|
+
roi = fill_from_dict(roi, roi_dict_i)
|
|
535
|
+
roi.write_to_hdf5(fn_hdf5=fname, check_file_exist=check_file_exist, verbose=verbose)
|
|
536
|
+
|
|
537
|
+
if exp_dict is not None:
|
|
538
|
+
if isinstance(exp_dict, list):
|
|
539
|
+
exp_dict = {i: exp_dict[i] for i in range(len(exp_dict))}
|
|
540
|
+
for i in exp_dict.keys():
|
|
541
|
+
pynibs.write_dict_to_hdf5(fn_hdf5=fname, data=exp_dict[i], folder=f"exp/{i}",
|
|
542
|
+
check_file_exist=check_file_exist)
|
|
543
|
+
|
|
544
|
+
if ps_dict is not None:
|
|
545
|
+
for i in range(len(ps_dict)):
|
|
546
|
+
pynibs.write_dict_to_hdf5(fn_hdf5=fname, data=ps_dict[i], folder=f"ps/{i}",
|
|
547
|
+
check_file_exist=check_file_exist)
|
|
548
|
+
|
|
549
|
+
with h5py.File(fname, 'a') as f:
|
|
550
|
+
for key, value in kwargs.items():
|
|
551
|
+
try:
|
|
552
|
+
del f[key]
|
|
553
|
+
except KeyError:
|
|
554
|
+
pass
|
|
555
|
+
f.create_dataset(name=key, data=value)
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def load_subject_hdf5(fname):
|
|
559
|
+
"""
|
|
560
|
+
Loading subject information from .hdf5 file and returning subject object.
|
|
561
|
+
|
|
562
|
+
Parameters
|
|
563
|
+
----------
|
|
564
|
+
fname : str
|
|
565
|
+
Filename with .hdf5 extension (incl. path).
|
|
566
|
+
|
|
567
|
+
Returns
|
|
568
|
+
-------
|
|
569
|
+
subject : pynibs.subject.Subject
|
|
570
|
+
The Subject object.
|
|
571
|
+
"""
|
|
572
|
+
with h5py.File(fname, 'r') as f:
|
|
573
|
+
subject_id = str(f["subject_id"][()].astype(str))
|
|
574
|
+
subject_folder = str(f["subject_folder"][()].astype(str))
|
|
575
|
+
|
|
576
|
+
# create and initialize subject
|
|
577
|
+
subject = Subject(subject_id=subject_id, subject_folder=subject_folder)
|
|
578
|
+
|
|
579
|
+
# add mri information
|
|
580
|
+
try:
|
|
581
|
+
mri_keys = f["mri"].keys()
|
|
582
|
+
mri = []
|
|
583
|
+
|
|
584
|
+
for key in mri_keys:
|
|
585
|
+
mri.append(pynibs.read_dict_from_hdf5(fn_hdf5=fname, folder=f"mri/{key}"))
|
|
586
|
+
|
|
587
|
+
except KeyError:
|
|
588
|
+
mri = None
|
|
589
|
+
|
|
590
|
+
subject.add_mri_info(mri_dict=mri)
|
|
591
|
+
|
|
592
|
+
# add mesh information
|
|
593
|
+
try:
|
|
594
|
+
mesh_keys = f["mesh"].keys()
|
|
595
|
+
mesh = {}
|
|
596
|
+
|
|
597
|
+
for key in mesh_keys:
|
|
598
|
+
mesh[key] = pynibs.read_dict_from_hdf5(fn_hdf5=fname, folder=f"mesh/{key}")
|
|
599
|
+
|
|
600
|
+
except KeyError:
|
|
601
|
+
mesh = None
|
|
602
|
+
|
|
603
|
+
subject.add_mesh_info(mesh_dict=mesh)
|
|
604
|
+
|
|
605
|
+
# add roi info
|
|
606
|
+
try:
|
|
607
|
+
mesh_idx_keys = f["roi"].keys()
|
|
608
|
+
roi = dict()
|
|
609
|
+
|
|
610
|
+
for mesh_idx in mesh_idx_keys:
|
|
611
|
+
try:
|
|
612
|
+
roi_idx_keys = f[f"roi/{mesh_idx}"].keys()
|
|
613
|
+
roi[mesh_idx] = dict()
|
|
614
|
+
|
|
615
|
+
for roi_idx in roi_idx_keys:
|
|
616
|
+
roi[mesh_idx][roi_idx] = pynibs.read_dict_from_hdf5(fn_hdf5=fname,
|
|
617
|
+
folder=f"roi/{mesh_idx}/{roi_idx}")
|
|
618
|
+
|
|
619
|
+
except KeyError:
|
|
620
|
+
roi[mesh_idx] = None
|
|
621
|
+
|
|
622
|
+
subject.add_roi_info(roi_dict=roi)
|
|
623
|
+
|
|
624
|
+
except KeyError:
|
|
625
|
+
pass
|
|
626
|
+
|
|
627
|
+
# add experiment information
|
|
628
|
+
try:
|
|
629
|
+
exp_keys = f["exp"].keys()
|
|
630
|
+
exp = {}
|
|
631
|
+
|
|
632
|
+
for key in exp_keys:
|
|
633
|
+
exp[key] = pynibs.read_dict_from_hdf5(fn_hdf5=fname, folder=f"exp/{key}")
|
|
634
|
+
|
|
635
|
+
except KeyError:
|
|
636
|
+
exp = None
|
|
637
|
+
|
|
638
|
+
subject.add_experiment_info(exp_dict=exp)
|
|
639
|
+
|
|
640
|
+
# add plotsettings information
|
|
641
|
+
try:
|
|
642
|
+
ps_keys = f["ps"].keys()
|
|
643
|
+
ps = []
|
|
644
|
+
|
|
645
|
+
for key in ps_keys:
|
|
646
|
+
ps.append(pynibs.read_dict_from_hdf5(fn_hdf5=fname, folder=f"ps/{key}"))
|
|
647
|
+
|
|
648
|
+
except KeyError:
|
|
649
|
+
ps = None
|
|
650
|
+
|
|
651
|
+
subject.add_plotsettings(ps_dict=ps)
|
|
652
|
+
|
|
653
|
+
return subject
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
def load_subject(fname, filetype=None):
|
|
657
|
+
"""
|
|
658
|
+
Wrapper for pkl and hdf5 subject loader
|
|
659
|
+
|
|
660
|
+
Parameters
|
|
661
|
+
----------
|
|
662
|
+
fname: str
|
|
663
|
+
endswith('.pkl') | endswith('.hdf5').
|
|
664
|
+
filetype: str
|
|
665
|
+
Explicitly set file version.
|
|
666
|
+
|
|
667
|
+
Returns
|
|
668
|
+
-------
|
|
669
|
+
subject : pynibs.subject.Subject
|
|
670
|
+
Loaded Subject object.
|
|
671
|
+
"""
|
|
672
|
+
# explicit set fname type
|
|
673
|
+
if filetype:
|
|
674
|
+
if filetype.lower().endswith("hdf5"):
|
|
675
|
+
filetype = "hdf5"
|
|
676
|
+
elif filetype.lower().endswith("pkl"):
|
|
677
|
+
filetype = "pkl"
|
|
678
|
+
else:
|
|
679
|
+
raise NotImplementedError(f"{filetype} unknown.")
|
|
680
|
+
|
|
681
|
+
# determine fname type from file-ending
|
|
682
|
+
else:
|
|
683
|
+
if fname.lower().endswith("hdf5"):
|
|
684
|
+
filetype = "hdf5"
|
|
685
|
+
elif fname.lower().endswith("pkl"):
|
|
686
|
+
filetype = "pkl"
|
|
687
|
+
else:
|
|
688
|
+
raise NotImplementedError(f"{fname} type unknown.")
|
|
689
|
+
|
|
690
|
+
# load file using correct load function
|
|
691
|
+
if filetype == "hdf5":
|
|
692
|
+
return load_subject_hdf5(fname)
|
|
693
|
+
elif filetype == "pkl":
|
|
694
|
+
return load_subject_pkl(fname)
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
def load_subject_pkl(fname):
|
|
698
|
+
"""
|
|
699
|
+
Loading subject object from .pkl file.
|
|
700
|
+
|
|
701
|
+
Parameters
|
|
702
|
+
----------
|
|
703
|
+
fname : str
|
|
704
|
+
Filename with .pkl extension.
|
|
705
|
+
|
|
706
|
+
Returns
|
|
707
|
+
-------
|
|
708
|
+
subject : pynibs.subject.Subject
|
|
709
|
+
Loaded Subject object.
|
|
710
|
+
"""
|
|
711
|
+
try:
|
|
712
|
+
with open(fname, 'rb') as f:
|
|
713
|
+
return pickle.load(f)
|
|
714
|
+
|
|
715
|
+
except UnicodeDecodeError:
|
|
716
|
+
print(".pkl file version does not match python version... recreating subject object")
|
|
717
|
+
fn_scipt = os.path.join(os.path.split(fname)[0],
|
|
718
|
+
"create_subject_" +
|
|
719
|
+
os.path.splitext(os.path.split(fname)[1])[0] + ".py")
|
|
720
|
+
pynibs.bash_call("python {}".format(fn_scipt))
|
|
721
|
+
|
|
722
|
+
with open(fname, 'rb') as f:
|
|
723
|
+
return pickle.load(f)
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
def check_file_and_format(fname):
|
|
727
|
+
"""
|
|
728
|
+
Checking existence of file and transforming to list if necessary.
|
|
729
|
+
|
|
730
|
+
Parameters
|
|
731
|
+
----------
|
|
732
|
+
fname: str or list of str
|
|
733
|
+
Filename(s) to check.
|
|
734
|
+
|
|
735
|
+
Returns
|
|
736
|
+
-------
|
|
737
|
+
fname: list of str
|
|
738
|
+
Checked filename(s) as list.
|
|
739
|
+
"""
|
|
740
|
+
if type(fname) is not list:
|
|
741
|
+
fname = [fname]
|
|
742
|
+
|
|
743
|
+
for fn in fname:
|
|
744
|
+
if not (os.path.exists(fn)):
|
|
745
|
+
Exception('File/Folder {} does not exist!'.format(fn))
|
|
746
|
+
|
|
747
|
+
return fname
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
def create_plot_settings_dict(plotfunction_type):
|
|
751
|
+
"""
|
|
752
|
+
Creates a dictionary with default plotsettings.
|
|
753
|
+
|
|
754
|
+
Parameters
|
|
755
|
+
----------
|
|
756
|
+
plotfunction_type : str
|
|
757
|
+
Plot function the dictionary is generated for:
|
|
758
|
+
|
|
759
|
+
* 'surface_vector_plot'
|
|
760
|
+
* 'surface_vector_plot_vtu'
|
|
761
|
+
* 'volume_plot'
|
|
762
|
+
* 'volume_plot_vtu'
|
|
763
|
+
|
|
764
|
+
Returns
|
|
765
|
+
-------
|
|
766
|
+
ps : dict
|
|
767
|
+
Dictionary containing the plotsettings.
|
|
768
|
+
axes : bool
|
|
769
|
+
Show orientation axes.
|
|
770
|
+
background_color : nparray
|
|
771
|
+
(1m 3) Set background color of exported image RGB (0...1).
|
|
772
|
+
calculator : str
|
|
773
|
+
Format string with placeholder of the calculator expression the quantity to plot is modified with,
|
|
774
|
+
e.g.: "{}^5".
|
|
775
|
+
clip_coords : nparray of float
|
|
776
|
+
(N_clips, 3) Coordinates of clip surface origins (x,y,z).
|
|
777
|
+
clip_normals : nparray of float
|
|
778
|
+
(N_clips, 3) Surface normals of clip surfaces pointing in the direction where the volume is kept for
|
|
779
|
+
clip_type = ['clip' ...] (x,y,z).
|
|
780
|
+
clip_type : list of str
|
|
781
|
+
Type of clipping:
|
|
782
|
+
|
|
783
|
+
* 'clip': cut geometry but keep volume behind
|
|
784
|
+
* 'slice': cut geometry and keep only the slice
|
|
785
|
+
coil_dipole_scaling : list [1 x 2]
|
|
786
|
+
Specify the scaling type of the dipoles (2 entries):
|
|
787
|
+
``coil_dipole_scaling[0]``:
|
|
788
|
+
|
|
789
|
+
* 'uniform': uniform scaling, i.e. all dipoles have the same size
|
|
790
|
+
+ 'scaled': size scaled according to dipole magnitude
|
|
791
|
+
|
|
792
|
+
``coil_dipole_scaling[1]``:
|
|
793
|
+
|
|
794
|
+
* scalar scale parameter of dipole size
|
|
795
|
+
coil_dipole_color : str or list
|
|
796
|
+
Color of the dipoles; either str to specify colormap (e.g. 'jet') or list of RGB values [1 x 3] (0...1).
|
|
797
|
+
coil_axes : bool, default: True
|
|
798
|
+
Plot coil axes visualizing the principle direction and orientation of the coil.
|
|
799
|
+
colorbar_label : str
|
|
800
|
+
Label of plotted data close to colorbar.
|
|
801
|
+
colorbar_position : list of float
|
|
802
|
+
(1, 2) Position of colorbar (lower left corner) 0...1 [x_pos, y_pos].
|
|
803
|
+
colorbar_orientation : str
|
|
804
|
+
Orientation of colorbar (``'Vertical'``, ``'Horizontal'``).
|
|
805
|
+
colorbar_aspectratio : int
|
|
806
|
+
Aspectratio of colorbar (higher values make it thicker).
|
|
807
|
+
colorbar_titlefontsize : float
|
|
808
|
+
Fontsize of colorbar title.
|
|
809
|
+
colorbar_labelfontsize : float
|
|
810
|
+
Fontsize of colorbar labels (numbers).
|
|
811
|
+
colorbar_labelformat : str
|
|
812
|
+
Format of colorbar labels (e.g.: '%-#6.3g').
|
|
813
|
+
colorbar_numberoflabels : int
|
|
814
|
+
maximum number of colorbar labels.
|
|
815
|
+
colorbar_labelcolor : list of float
|
|
816
|
+
(1, 3) Color of colorbar labels in RGB (0...1).
|
|
817
|
+
colormap : str or nparray
|
|
818
|
+
If nparray [1 x 4*N]: custom colormap providing data and corresponding RGB values
|
|
819
|
+
|
|
820
|
+
.. math::
|
|
821
|
+
\\begin{bmatrix}
|
|
822
|
+
data_{1} & R_1 & G_1 & B_1 \\\\
|
|
823
|
+
data_{2} & R_2 & G_2 & B_2 \\\\
|
|
824
|
+
... & ... & ... & ... \\\\
|
|
825
|
+
data_{N} & R_N & G_N & B_N \\\\
|
|
826
|
+
\\end{bmatrix}
|
|
827
|
+
|
|
828
|
+
if str: colormap of plotted data chosen from included presets:
|
|
829
|
+
|
|
830
|
+
* 'Cool to Warm',
|
|
831
|
+
* 'Cool to Warm (Extended)',
|
|
832
|
+
* 'Blue to Red Rainbow',
|
|
833
|
+
* 'X Ray',
|
|
834
|
+
* 'Grayscale',
|
|
835
|
+
* 'jet',
|
|
836
|
+
* 'hsv',
|
|
837
|
+
* 'erdc_iceFire_L',
|
|
838
|
+
* 'Plasma (matplotlib)',
|
|
839
|
+
* 'Viridis (matplotlib)',
|
|
840
|
+
* 'gray_Matlab',
|
|
841
|
+
* 'Spectral_lowBlue',
|
|
842
|
+
+ 'BuRd'
|
|
843
|
+
* 'Rainbow Blended White'
|
|
844
|
+
* 'b2rcw'
|
|
845
|
+
colormap_categories : bool
|
|
846
|
+
Use categorized (discrete) colormap.
|
|
847
|
+
datarange : list
|
|
848
|
+
(1, 2) Minimum and Maximum of plotted datarange [MIN, MAX] (default: automatic).
|
|
849
|
+
domain_IDs : int or list of int
|
|
850
|
+
Domain IDs
|
|
851
|
+
surface plot: Index of surface where the data is plotted on (Default: 0)
|
|
852
|
+
volume plot: Specify the domains IDs to show in plot (default: all) Attention! Has to be included in the
|
|
853
|
+
dataset under the name 'tissue'! e.g. for SimNIBS:
|
|
854
|
+
|
|
855
|
+
* 1 -> white matter (WM)
|
|
856
|
+
* 2 -> grey matter (GM)
|
|
857
|
+
* 3 -> cerebrospinal fluid (CSF)
|
|
858
|
+
* 4 -> skull
|
|
859
|
+
* 5 -> skin
|
|
860
|
+
domain_label : str
|
|
861
|
+
Label of the dataset which contains the domain IDs (default: 'tissue_type').
|
|
862
|
+
edges : BOOL
|
|
863
|
+
Show edges of mesh.
|
|
864
|
+
fname_in : str or list of str
|
|
865
|
+
Filenames of input files, 2 possibilities:
|
|
866
|
+
|
|
867
|
+
* .xdmf-file: filename of .xmdf (needs the corresponding .hdf5 file(s) in the same folder)
|
|
868
|
+
* .hdf5-file(s): filename(s) of .hdf5 file(s) containing the data and the geometry. The data can be provided
|
|
869
|
+
in the first hdf5 file and the geometry can be provided in the second file. However, both can be also
|
|
870
|
+
provided in a single hdf5 file.
|
|
871
|
+
fname_png : str
|
|
872
|
+
Name of output .png file (incl. path).
|
|
873
|
+
fname_vtu_volume : str
|
|
874
|
+
Name of .vtu volume file containing volume data (incl. path).
|
|
875
|
+
fname_vtu_surface : str
|
|
876
|
+
Name of .vtu surface file containing surface data (incl. path) (to distinguish tissues).
|
|
877
|
+
fname_vtu_coil : str, optional
|
|
878
|
+
Name of coil .vtu file (incl. path).
|
|
879
|
+
info : str
|
|
880
|
+
Information about the plot the settings belong to.
|
|
881
|
+
interpolate : bool
|
|
882
|
+
Interpolate data for visual smoothness.
|
|
883
|
+
NanColor : list of float
|
|
884
|
+
(3) RGB color values for "Not a Number" values (range 0 ... 1).
|
|
885
|
+
opacitymap : np.ndarray
|
|
886
|
+
Points defining the piecewise linear opacity transfer function (transparency) (default: no transparency)
|
|
887
|
+
connecting data values with opacity (alpha) values ranging from 0 (max. transparency) to 1 (no transparency).
|
|
888
|
+
|
|
889
|
+
.. math::
|
|
890
|
+
\\begin{bmatrix}
|
|
891
|
+
data_{1} & opac_1 & 0.5 & 0 \\\\
|
|
892
|
+
data_{2} & opac_2 & 0.5 & 0 \\\\
|
|
893
|
+
... & ... & ... & ...\\\\
|
|
894
|
+
data_{N} & opac_N & 0.5 & 0 \\\\
|
|
895
|
+
\\end{bmatrix}
|
|
896
|
+
plot_function : str
|
|
897
|
+
Function the plot is generated with:
|
|
898
|
+
|
|
899
|
+
- 'surface_vector_plot'
|
|
900
|
+
- 'surface_vector_plot_vtu'
|
|
901
|
+
- 'volume_plot'
|
|
902
|
+
- 'volume_plot_vtu'
|
|
903
|
+
png_resolution : float
|
|
904
|
+
Resolution parameter of output image (1...5).
|
|
905
|
+
quantity : str
|
|
906
|
+
Label of magnitude dataset to plot.
|
|
907
|
+
surface_color : np.ndarray
|
|
908
|
+
(1, 3) Color of brain surface in RGB (0...1) for better visibility of tissue borders.
|
|
909
|
+
surface_smoothing : bool
|
|
910
|
+
Smooth the plotted surface (True/False).
|
|
911
|
+
show_coil : bool, default: True
|
|
912
|
+
show coil if present in dataset as block termed 'coil'.
|
|
913
|
+
vcolor : np.ndarray of float
|
|
914
|
+
(N_vecs, 3) Array containing the RGB values between 0...1 of the vector groups in dataset to plot.
|
|
915
|
+
vector_mode : dict
|
|
916
|
+
Key determines the type how many vectors are shown:
|
|
917
|
+
|
|
918
|
+
- 'All Points'
|
|
919
|
+
- 'Every Nth Point'
|
|
920
|
+
- 'Uniform Spatial Distribution'
|
|
921
|
+
|
|
922
|
+
Value (int) is the corresponding number of vectors:
|
|
923
|
+
|
|
924
|
+
- 'All Points' (not set)
|
|
925
|
+
- 'Every Nth Point' (every Nth vector is shown in the grid)
|
|
926
|
+
- 'Uniform Spatial Distribution' (not set)
|
|
927
|
+
view : list
|
|
928
|
+
Camera position and angle in 3D space:
|
|
929
|
+
``[[3 x CameraPosition], [3 x CameraFocalPoint], [3 x CameraViewUp], 1 x CameraParallelScale]``.
|
|
930
|
+
viewsize : nparray [1 x 2]
|
|
931
|
+
Set size of exported image in pixel [width x height] will be extra scaled by parameter png_resolution.
|
|
932
|
+
vlabels : list of str
|
|
933
|
+
Labels of vector datasets to plot (other present datasets are ignored).
|
|
934
|
+
vscales : list of float
|
|
935
|
+
Scale parameters of vector groups to plot.
|
|
936
|
+
vscale_mode : list of str [N_vecs x 1]
|
|
937
|
+
List containing the type of vector scaling:
|
|
938
|
+
|
|
939
|
+
- 'off': all vectors are normalized
|
|
940
|
+
- 'vector': vectors are scaled according to their magnitudeeee
|
|
941
|
+
"""
|
|
942
|
+
if plotfunction_type not in ['surface_vector_plot', 'surface_vector_plot_vtu', 'volume_plot', 'volume_plot_vtu']:
|
|
943
|
+
raise Exception('plotfunction_type not set correctly, specify either [\'surface_vector_plot\', \
|
|
944
|
+
\'surface_vector_plot_vtu\', \'volume_plot\', \'volume_plot_vtu\']')
|
|
945
|
+
|
|
946
|
+
ps = dict()
|
|
947
|
+
ps['info'] = []
|
|
948
|
+
ps['plot_function'] = plotfunction_type
|
|
949
|
+
ps['fname_png'] = []
|
|
950
|
+
ps['png_resolution'] = 1
|
|
951
|
+
ps['quantity'] = None
|
|
952
|
+
ps['datarange'] = None
|
|
953
|
+
ps['colorbar_label'] = ''
|
|
954
|
+
ps['colorbar_position'] = []
|
|
955
|
+
ps['colorbar_orientation'] = 'Vertical'
|
|
956
|
+
ps['colorbar_aspectratio'] = 20
|
|
957
|
+
ps['colorbar_titlefontsize'] = 7
|
|
958
|
+
ps['colorbar_labelfontsize'] = 7
|
|
959
|
+
ps['colorbar_labelformat'] = '%-#6.3g'
|
|
960
|
+
ps['colorbar_numberoflabels'] = 5
|
|
961
|
+
ps['colorbar_labelcolor'] = [0, 0, 0]
|
|
962
|
+
ps['colorbar_font'] = 'Arial'
|
|
963
|
+
ps['view'] = 0
|
|
964
|
+
ps['interpolate'] = False
|
|
965
|
+
ps['edges'] = False
|
|
966
|
+
ps['axes'] = True
|
|
967
|
+
ps['colormap'] = "jet"
|
|
968
|
+
ps['colormap_categories'] = False
|
|
969
|
+
ps['opacitymap'] = None
|
|
970
|
+
ps['background_color'] = [1, 1, 1]
|
|
971
|
+
ps['viewsize'] = [800, 800]
|
|
972
|
+
ps['NanColor'] = [1, 1, 1]
|
|
973
|
+
ps["surface_smoothing"] = True
|
|
974
|
+
ps["calculator"] = None
|
|
975
|
+
|
|
976
|
+
# filename of input files
|
|
977
|
+
if plotfunction_type in ['surface_vector_plot', 'surface_vector_plot_vtu', 'volume_plot']:
|
|
978
|
+
ps['fname_in'] = []
|
|
979
|
+
|
|
980
|
+
elif plotfunction_type in ['volume_plot_vtu']:
|
|
981
|
+
ps['fname_vtu_volume'] = []
|
|
982
|
+
ps['fname_vtu_surface'] = []
|
|
983
|
+
ps['fname_vtu_coil'] = []
|
|
984
|
+
|
|
985
|
+
# new features in .xdmf plot functions
|
|
986
|
+
if plotfunction_type in ['surface_vector_plot', 'volume_plot', 'volume_plot_vtu']:
|
|
987
|
+
ps['domain_label'] = 'tissue_type'
|
|
988
|
+
ps['domain_IDs'] = 0
|
|
989
|
+
ps['show_coil'] = True
|
|
990
|
+
ps['coil_dipole_scaling'] = ['uniform', 1]
|
|
991
|
+
ps['coil_dipole_color'] = 'jet'
|
|
992
|
+
ps['coil_axes'] = True
|
|
993
|
+
|
|
994
|
+
# surface specific properties
|
|
995
|
+
if plotfunction_type in ['surface_vector_plot', 'surface_vector_plot_vtu']:
|
|
996
|
+
ps['vlabels'] = ''
|
|
997
|
+
ps['vscales'] = np.array([1])
|
|
998
|
+
ps['vscale_mode'] = 'vector'
|
|
999
|
+
ps['vector_mode'] = {'All Points': 0}
|
|
1000
|
+
ps['vcolor'] = np.array([1.0, 0.0, 0.0])
|
|
1001
|
+
|
|
1002
|
+
# volume specific properties
|
|
1003
|
+
if plotfunction_type in ['volume_plot', 'volume_plot_vtu']:
|
|
1004
|
+
ps['clip_coords'] = np.array([])
|
|
1005
|
+
ps['clip_normals'] = np.array([])
|
|
1006
|
+
ps['clip_type'] = []
|
|
1007
|
+
ps['surface_color'] = [1, 1, 1]
|
|
1008
|
+
|
|
1009
|
+
return ps
|