vneumodpy 0.1.6__tar.gz

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 (50) hide show
  1. vneumodpy-0.1.6/LICENSE.md +23 -0
  2. vneumodpy-0.1.6/PKG-INFO +30 -0
  3. vneumodpy-0.1.6/README.md +273 -0
  4. vneumodpy-0.1.6/setup.cfg +4 -0
  5. vneumodpy-0.1.6/setup.py +25 -0
  6. vneumodpy-0.1.6/src/vneumodpy/__init__.py +38 -0
  7. vneumodpy-0.1.6/src/vneumodpy/glm/__init__.py +0 -0
  8. vneumodpy-0.1.6/src/vneumodpy/glm/adjust_volume_dir.py +24 -0
  9. vneumodpy-0.1.6/src/vneumodpy/glm/canonical_hrf.py +23 -0
  10. vneumodpy-0.1.6/src/vneumodpy/glm/contrast_image.py +40 -0
  11. vneumodpy-0.1.6/src/vneumodpy/glm/hrf_design_matrix.py +42 -0
  12. vneumodpy-0.1.6/src/vneumodpy/glm/resampling_nifti_volume.py +73 -0
  13. vneumodpy-0.1.6/src/vneumodpy/glm/roi_ts_from4dimage.py +39 -0
  14. vneumodpy-0.1.6/src/vneumodpy/glm/roi_ts_to4dimage.py +31 -0
  15. vneumodpy-0.1.6/src/vneumodpy/glm/tukey.py +97 -0
  16. vneumodpy-0.1.6/src/vneumodpy/glm/tukey_mp.py +112 -0
  17. vneumodpy-0.1.6/src/vneumodpy/glm/tukey_mth.py +112 -0
  18. vneumodpy-0.1.6/src/vneumodpy/measures/__init__.py +0 -0
  19. vneumodpy-0.1.6/src/vneumodpy/measures/ac.py +32 -0
  20. vneumodpy-0.1.6/src/vneumodpy/measures/ccm.py +63 -0
  21. vneumodpy-0.1.6/src/vneumodpy/measures/cm.py +31 -0
  22. vneumodpy-0.1.6/src/vneumodpy/measures/cos_sim.py +22 -0
  23. vneumodpy-0.1.6/src/vneumodpy/measures/dft.py +43 -0
  24. vneumodpy-0.1.6/src/vneumodpy/measures/mskewkurt.py +30 -0
  25. vneumodpy-0.1.6/src/vneumodpy/measures/mtess.py +309 -0
  26. vneumodpy-0.1.6/src/vneumodpy/measures/pac.py +32 -0
  27. vneumodpy-0.1.6/src/vneumodpy/measures/pccm.py +99 -0
  28. vneumodpy-0.1.6/src/vneumodpy/measures/pccm_.py +81 -0
  29. vneumodpy-0.1.6/src/vneumodpy/measures/pcm.py +56 -0
  30. vneumodpy-0.1.6/src/vneumodpy/models/__init__.py +0 -0
  31. vneumodpy-0.1.6/src/vneumodpy/models/group_range.py +30 -0
  32. vneumodpy-0.1.6/src/vneumodpy/models/multivaliate_var_network.py +256 -0
  33. vneumodpy-0.1.6/src/vneumodpy/models/mvar_init_with_cell_mp.py +69 -0
  34. vneumodpy-0.1.6/src/vneumodpy/models/mvar_init_with_cell_mth.py +22 -0
  35. vneumodpy-0.1.6/src/vneumodpy/models/regress.py +78 -0
  36. vneumodpy-0.1.6/src/vneumodpy/nuisance/__init__.py +0 -0
  37. vneumodpy-0.1.6/src/vneumodpy/nuisance/acompcor.py +61 -0
  38. vneumodpy-0.1.6/src/vneumodpy/nuisance/mean_time_series.py +42 -0
  39. vneumodpy-0.1.6/src/vneumodpy/nuisance/regression_out.py +21 -0
  40. vneumodpy-0.1.6/src/vneumodpy/surrogate/__init__.py +0 -0
  41. vneumodpy-0.1.6/src/vneumodpy/surrogate/dbs_multivariate_var.py +122 -0
  42. vneumodpy-0.1.6/src/vneumodpy/surrogate/multivariate_var.py +91 -0
  43. vneumodpy-0.1.6/src/vneumodpy/surrogate/vnm_addmul_signals.py +66 -0
  44. vneumodpy-0.1.6/src/vneumodpy/surrogate/vnm_subject_perm.py +26 -0
  45. vneumodpy-0.1.6/src/vneumodpy/surrogate/vnm_var_surrogate.py +53 -0
  46. vneumodpy-0.1.6/vneumodpy.egg-info/PKG-INFO +30 -0
  47. vneumodpy-0.1.6/vneumodpy.egg-info/SOURCES.txt +48 -0
  48. vneumodpy-0.1.6/vneumodpy.egg-info/dependency_links.txt +1 -0
  49. vneumodpy-0.1.6/vneumodpy.egg-info/requires.txt +9 -0
  50. vneumodpy-0.1.6/vneumodpy.egg-info/top_level.txt +1 -0
@@ -0,0 +1,23 @@
1
+
2
+
3
+ MIT License
4
+
5
+ Copyright (c) 2022-present T.Okuno, RIKEN CBS
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: vneumodpy
3
+ Version: 0.1.6
4
+ Summary: The Virtual Neuromodulation Toolbox for Python.
5
+ Home-page: https://github.com/takuto-okuno-riken/vneumodpy
6
+ Author: takuto okuno
7
+ License: MIT
8
+ Keywords: vneumod vneumodpy virtual neuromodulation
9
+ Description-Content-Type: text/plain
10
+ License-File: LICENSE.md
11
+ Requires-Dist: matplotlib
12
+ Requires-Dist: scikit-learn
13
+ Requires-Dist: numpy
14
+ Requires-Dist: pandas
15
+ Requires-Dist: scipy
16
+ Requires-Dist: h5py
17
+ Requires-Dist: hdf5storage
18
+ Requires-Dist: nibabel
19
+ Requires-Dist: statsmodels
20
+ Dynamic: author
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: keywords
25
+ Dynamic: license
26
+ Dynamic: license-file
27
+ Dynamic: requires-dist
28
+ Dynamic: summary
29
+
30
+ Please visit https://github.com/takuto-okuno-riken/vneumodpy in detail description
@@ -0,0 +1,273 @@
1
+ [![License: MIT](https://img.shields.io/badge/License-MIT-success.svg)](https://opensource.org/licenses/MIT)
2
+
3
+ # Virtual Neuromodulation Toolbox for Python
4
+ The Virtual Neuromodulation Toolbox for Python (MATLAB version is [here](https://github.com/takuto-okuno-riken/vneumod)).
5
+
6
+
7
+ ## Introduction
8
+ To realize the digital brain, various approaches have been taken at multiple levels.
9
+ We proposed [Group Surrogate Data Generating Model (GSDGM)](https://github.com/takuto-okuno-riken/gsdgmpy), which does not incorporate structural connectivity and focuses on reproducing resting-state functional MRI dynamics (BOLD signal).
10
+ This model can learn multivariate time-series data (BOLD signal) of a group and generate a centroidal and representative multivariate time-series of the group.
11
+ The group surrogate model preserves the statistics of multivariate time-series well, so this allows for the generation of whole-brain dynamics with extremely high accuracy.
12
+
13
+ Whole-brain data-driven model (group surrogate model) assumes no specific brain tissue structure, one voxel of 4 × 4 × 4 mm gray matter, and 25445 voxels based on the Allen human brain atlas.
14
+ All voxels are fully connected, and vector auto-regression (VAR) surrogate is used to learn group data and generate group surrogate data.
15
+
16
+ <div align="center">
17
+ <img src="data/img/fig1.jpg" width="70%">
18
+ </div>
19
+ <br>
20
+
21
+ Then, we extended output of VAR surrogate for virtual neuromodulation.
22
+ <div align="center">
23
+ <img src="data/img/fig2.jpg" width="30%">
24
+ </div>
25
+
26
+
27
+ where x<sub>i</sub>(t) is output of voxel i, y<sub>i</sub>(t) is VAR surrogate output of voxel i, z<sub>i</sub>(t),u<sub>i</sub>(t) are modulation terms of voxel i, and c<sub>i</sub>,σ<sub>X</sub>∈R.
28
+ σ<sub>X</sub> is calculated as the standard deviation from the entire voxel time-series.
29
+ z<sub>i</sub>(t) is constructed by convolution of the canonical Hemodynamic Response Function (HRF) and the Box-car task design.
30
+ u<sub>i</sub>(t) performs direct adjustment to the output of VAR surrogate.
31
+ In other words, if there is a virtual neuromodulation stimulus, it adjusts to prioritize neuromodulation stimulus, such as u<sub>i</sub>(t)=1-0.5∙z<sub>i</sub>(t).
32
+ Using the above-mentioned virtual neuromodulation, BOLD signal addition, i.e., DBS treatment, can be virtually performed for specific voxels.
33
+
34
+
35
+ <b>Command line tools</b>
36
+
37
+ | name | description |
38
+ |:---|:---|
39
+ | gsdgm | Generate a whole-brain data-driven model based on the group surrogate model (VAR surrogate).|
40
+ | vneumod | Generate virtual neuromodulation time-series surrogate data based on the group surrogate model.|
41
+ | mtess | Calculate and plot MTESS for a group of multivariate time-series data. |
42
+
43
+
44
+ ## Requirements: software
45
+ * Python 3.11.14
46
+ * matplotlib 3.10.8
47
+ * scikit_learn 1.8.0
48
+ * h5py 3.15.1
49
+ * pandas 2.3.3
50
+ * statsmodels 0.14.6
51
+
52
+
53
+ ## Installation
54
+ 1. Download this [Toolbox](https://github.com/takuto-okuno-riken/vneumodpy/archive/refs/heads/main.zip) zip files.
55
+ 2. Extract zip file under your working directory <work_path>/vneumodpy-main.
56
+ 3. This is not required, but we recommend using the conda virtual environment.
57
+ ~~~
58
+ (base) work_path>cd vneumodpy-main
59
+ (base) vneumodpy-main>conda create -n vneumod python=3.11.14
60
+ ...
61
+ (base) vneumodpy-main>conda activate vneumod
62
+ (vneumod) vneumodpy-main>
63
+ ~~~
64
+ 4. Install several packages.
65
+ ~~~
66
+ (vneumod) vneumodpy-main>pip install -r requirements.txt
67
+ ...
68
+ ~~~
69
+ 5. Run the following demos.
70
+
71
+
72
+ ## Command Line Tools Demos
73
+ <b>Demo 1</b><br>
74
+ First demo uses a PD group surrogate model to apply sweet spot stimulus of the virtual STN-DBS, performs GLM analysis, and then outputs an NIfTI file.
75
+ Pre-processed subject data and group surrogate model files should be downloaded from [zenodo](https://zenodo.org/records/19312573), and extracted a zip file to overwrite 'results' directory in <work_path>/vneumod-main before running this code.<br/>
76
+ (Please confirm to update results directory.)
77
+
78
+ ~~~
79
+ (vneumod) vneumodpy-main>python vneumod.py --cx results/ppmi81CXAllenCube2s34gmacomp.mat --model results/ppmi81CXAllenCube2s34gmacomp_gsm_var.mat --targatl data/allenCube2atlasStn3.nii.gz --atlas data/allenCube2atlas.nii.gz --out 1 --roi 4525 --glm --nocache
80
+ set savename=ppmi81CXAllenCube2s34gmacomp
81
+ load subject time-series file: results/ppmi81CXAllenCube2s34gmacomp.mat
82
+ load model file: results/ppmi81CXAllenCube2s34gmacomp_gsm_var.mat
83
+ loading subject permutation : results/perm1_ppmi81CXAllenCube2s34gmacomp.mat
84
+ generate modulation (add & mul) time-series, target roi=4525, srframes=160, dbsoffsec=28, dbsonsec=22, dbspw=0.15
85
+ convolution params tr=1.0, res=16, sp=8
86
+ calc virtual neuromodulation surrogate. roi=4525, surrnum=40
87
+ surrogate sample : 1
88
+ done t=9.170302391052246 sec
89
+ surrogate sample : 1
90
+ done t=7.329235553741455 sec
91
+ ...
92
+
93
+ process GLM with Tukey-Taper(8) estimation ...
94
+ done t=22.902510166168213 sec
95
+ calc 2nd-level GLM...
96
+ process GLM with Tukey-Taper(8) estimation ...
97
+ done t=17.72597575187683 sec
98
+ save nifti file : results/ppmi81CXAllenCube2s34gmacomp_4525sr40pr1_2nd-Tukey8.nii.gz
99
+ ~~~
100
+
101
+ When you view the outputted NIfTI file with ITK-SNAP, you can confirm activation of STN sweet spot and deactivation of A4.<br/>
102
+
103
+ <div align="center">
104
+ <img src="data/img/demo1.jpg" width="70%"></div>
105
+
106
+
107
+ ##
108
+ <b>Demo 2</b><br>
109
+ This demo shows creation of a group surrogate model from (pre-processed) rs-fMRI time-series data (25445 ROIs). <br>
110
+ (Caution: model calculation will take like one day.)
111
+ ~~~
112
+ (vneumod) vneumodpy-main>python gsdgm.py --var results/ppmi81CXAllenCube2s34gmacomp.mat
113
+ load subject time-series file: results/ppmi81CXAllenCube2s34gmacomp.mat
114
+ output group surrogate model file : results/ppmi81CXAllenCube2s34gmacomp_gsm_var.mat
115
+ ~~~
116
+
117
+ The group surrogate data is the representative centroid of the group of original time-series data.
118
+
119
+
120
+ ## Command Line Tools Reference
121
+ <b>gsdgm command</b><br>
122
+ ~~~
123
+ (vneumod) vneumodpy-main>python gsdgm.py -h
124
+ usage: gsdgm.py [-h] [--var] [--lag LAG] [--noise NOISE] [--outpath OUTPATH] [--transopt TRANSOPT]
125
+ [--format FORMAT] [--surrnum SURRNUM] [--siglen SIGLEN] [--range RANGE] [--cache]
126
+ [--njobs NJOBS] [--showinsig] [--showinras] [--showsig] [--showras]
127
+ filename [filename ...]
128
+
129
+ positional arguments:
130
+ filename filename of node status time-series (node x frames)
131
+
132
+ options:
133
+ -h, --help show this help message and exit
134
+ --var output Vector Auto-Regression (VAR) group surrogate model
135
+ (<filename>_gsm_var.mat)
136
+ --lag LAG time lag <num> for VAR (default:1)
137
+ --noise NOISE noise type for VAR surrogate model (default:"gaussian" or "residuals")
138
+ --outpath OUTPATH output files path (default:"results")
139
+ --transopt TRANSOPT signal transform option (for type 1:centroid value)
140
+ --format FORMAT save file format <type> 0:csv, 1:mat(each), 2:mat(all) (default:2)
141
+ --surrnum SURRNUM output surrogate sample number <num> (default:0)
142
+ --siglen SIGLEN output time-series length <num> (default:same as input time-series)
143
+ --range RANGE output surrogate value range (default:"auto", sigma:<num>, full:<num>,
144
+ <min>:<max> or "none")
145
+ --cache save cache file at model calculation
146
+ --njobs NJOBS number of jobs (multiprocessing) for model calculation (default:-1)
147
+ --showinsig show input time-series data of <filename>.csv
148
+ --showinras show raster plot of input time-series data of <filename>.csv
149
+ --showsig show output surrogate time-series data
150
+ --showras show raster plot of output surrogate time-series data
151
+ ~~~
152
+ The input .mat file should include input cell data described as follows. The node count must be the same within the group, whereas the time-series length does not have to be the same.
153
+ | name | cell | description |
154
+ |:---|:---|:---|
155
+ |CX |{&lt;nodes&gt; x &lt;length&gt;} x &lt;cell number&gt; |group of multivariate time-series|
156
+ |names |{'data name string'} x &lt;cell number&gt; |names of each time-series data|
157
+
158
+ The output (group surrogate model) .mat file includes the following struct data:
159
+
160
+ | name | type | description |
161
+ |:---|:---|:---|
162
+ |net | struct |struct of group surrogate model|
163
+ |gRange | struct |struct of group range information|
164
+ |name | string |name of group surrogate model|
165
+
166
+ The output (group surrogate data) .mat file includes the following cell data:
167
+
168
+ | name | cell | description |
169
+ |:---|:---|:---|
170
+ |CX |{&lt;nodes&gt; x &lt;length&gt;} x &lt;cell number&gt; |group of multivariate time-series|
171
+ |names |{'data name string'} x &lt;cell number&gt; |names of each time-series data|
172
+
173
+
174
+ ##
175
+ <b>vneumod command</b><br>
176
+ ~~~
177
+ (vneumod) vneumodpy-main>python vneumod.py -h
178
+ usage: vneumod.py [-h] [--cx CX] [--pymodel PYMODEL] [--model MODEL] [--atlas ATLAS]
179
+ [--targatl TARGATL] [--roi ROI] [--out OUT] [--outfrom OUTFROM]
180
+ [--surrnum SURRNUM] [--srframes SRFRAMES] [--vnparam VNPARAM] [--tr TR]
181
+ [--hrfparam HRFPARAM] [--glm] [--njobs NJOBS] [--outpath OUTPATH] [--nocache]
182
+ [filename ...]
183
+
184
+ positional arguments:
185
+ filename filename of subject permutation (1 x length)
186
+
187
+ options:
188
+ -h, --help show this help message and exit
189
+ --cx CX set cells of subject time-series (<filename>.mat)
190
+ --pymodel PYMODEL set (VAR) group surrogate model <path> by vneumodpy
191
+ --model MODEL set (VAR) group surrogate model (<filename>_gsm_var.mat)
192
+ --atlas ATLAS set cube atlas nifti file (<filename>.nii.gz)
193
+ --targatl TARGATL set modulation target atlas nifti file (<filename>.nii.gz)
194
+ --roi ROI set modulation target ROI <num> or <range text>
195
+ --out OUT set output trials (perm & surrogate files) number <num> (default:1)
196
+ --outfrom OUTFROM set surrogate output from <num> (default:1)
197
+ --surrnum SURRNUM output surrogate sessions per one file <num> (default:40)
198
+ --srframes SRFRAMES output surrogate frames <num> (default:160)
199
+ --vnparam VNPARAM set virtual neuromodulation params <num,num,num> (default:28,22,0.15)
200
+ --tr TR set TR (second) of fMRI time-series <num> (default:1)
201
+ --hrfparam HRFPARAM set HRF (for convolution) params <num,num> (default:16,8)
202
+ --glm output GLM result nifti file
203
+ --njobs NJOBS number of jobs (multiprocessing) for glm calculation (default:8)
204
+ --outpath OUTPATH output files path (default:"results")
205
+ --nocache do not output surrogate file
206
+ ~~~
207
+ The input .mat files are optional. It should include subject permutation data for surrogate data generation:
208
+ | name | matrix | description |
209
+ |:---|:---|:---|
210
+ |perm |&lt;1&gt; x &lt;length&gt; | time-series permutation order|
211
+
212
+ The output will be T-value 3D matrix nifti file (GLM result) aligned with cube atlas nifti file.
213
+
214
+ ##
215
+ <b>mtess command</b><br>
216
+ ~~~
217
+ (vneumod) vneumodpy-main>python mtess.py -h
218
+ usage: mtess.py [-h] [--range RANGE] [--aclag ACLAG] [--paclag PACLAG] [--cclag CCLAG]
219
+ [--pcclag PCCLAG] [--outpath OUTPATH] [--format FORMAT] [--transform TRANSFORM]
220
+ [--transopt TRANSOPT] [--showinsig] [--showinras] [--showmat] [--showsig]
221
+ [--showprop] [--shownode] [--showdend SHOWDEND] [--cache] [--cachepath CACHEPATH]
222
+ filename [filename ...]
223
+
224
+ positional arguments:
225
+ filename filename of node status time-series (node x frames)
226
+
227
+ options:
228
+ -h, --help show this help message and exit
229
+ --range RANGE input group value range (default:"auto", sigma:<num>, full:<num> or
230
+ <min>:<max>)
231
+ --aclag ACLAG time lag <num> for Auto Correlation (default:5)
232
+ --paclag PACLAG time lag <num> for Partial Auto Correlation (default:13)
233
+ --cclag CCLAG time lag <num> for Cross Correlation (default:2)
234
+ --pcclag PCCLAG time lag <num> for Partial Cross Correlation (default:4)
235
+ --outpath OUTPATH output files path (default:"results")
236
+ --format FORMAT save file format <type> 0:csv, 1:mat (default:1)
237
+ --transform TRANSFORM
238
+ input signal transform 0:raw, 1:sigmoid (default:0)
239
+ --transopt TRANSOPT signal transform option (for type 1:centroid value)
240
+ --showinsig show input time-series data of <filename>.csv
241
+ --showinras show raster plot of input time-series data of <filename>.csv
242
+ --showmat show result MTESS matrix
243
+ --showsig show 1 vs. others node signals
244
+ --showprop show result polar chart of 1 vs. others MTESS statistical properties
245
+ --shownode show result line plot of 1 vs. others node MTESS
246
+ --showdend SHOWDEND show dendrogram of <algo> hierarchical clustering based on MTESS matrix.
247
+ --cache use cache file for MTESS calculation
248
+ --cachepath CACHEPATH
249
+ cache files <path> (default:"results/cache")
250
+ ~~~
251
+ The input .mat file should include input cell data. The node count must be the same within the group, whereas time-series length does not have to be the same.
252
+ | name | cell | description |
253
+ |:---|:---|:---|
254
+ |CX |{&lt;nodes&gt; x &lt;length&gt;} x &lt;cell number&gt; |group of multivariate time-series|
255
+ |names |{'data name string'} x &lt;cell number&gt; |names of each time-series data|
256
+
257
+ The output .mat file includes the following matrix data:
258
+
259
+ | name | matrix | description |
260
+ |:---|:---|:---|
261
+ |MTS |&lt;cell number&gt; x &lt;cell number&gt; | MTESS matrix (2D)|
262
+ |MTSp |&lt;cell number&gt; x &lt;cell number&gt; x 8| MTESS statistical property matrix (3D)|
263
+ |nMTS |&lt;cell number&gt; x &lt;cell number&gt; x &lt;nodes&gt;| Node MTESS matrix (3D)|
264
+ |nMTSp |&lt;cell number&gt; x &lt;cell number&gt; x &lt;nodes&gt; x 8| Node MTESS statistical property matrix (4D)|
265
+
266
+ Similarities are generated for the following 8 statistical properties: mean, standard deviation, DFT amplitude, correlation, partial correlation, cross-correlation and partial cross-correlation.
267
+
268
+
269
+ ## Citing Virtual Neuromodulation Toolbox
270
+ If you find Virtual Neuromodulation Toolbox useful in your research, please cite it as follows:
271
+
272
+ Takuto Okuno, Alexander Woodward, Hideyuki Okano, Junichi Hata (submitted)
273
+ ["Do distinct DBS targets converge on a common associative circuit? A digital brain study"](https://www.google.com/), ,
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,25 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="vneumodpy",
5
+ version="0.1.6",
6
+ license='MIT',
7
+ packages=find_packages(where='src'),
8
+ package_dir={"vneumodpy": "src/vneumodpy",
9
+ "vneumodpy.glm": "src/vneumodpy/glm",
10
+ "vneumodpy.measures": "src/vneumodpy/measures",
11
+ "vneumodpy.models": "src/vneumodpy/models",
12
+ "vneumodpy.nuisance": "src/vneumodpy/nuisance",
13
+ "vneumodpy.surrogate": "src/vneumodpy/surrogate",
14
+ },
15
+ install_requires=[
16
+ "matplotlib", "scikit-learn", "numpy", "pandas", "scipy", "h5py", "hdf5storage", "nibabel", "statsmodels"
17
+ ],
18
+ author='takuto okuno', # パッケージ作者の名前
19
+ url='https://github.com/takuto-okuno-riken/vneumodpy',
20
+
21
+ description='The Virtual Neuromodulation Toolbox for Python.',
22
+ long_description='Please visit https://github.com/takuto-okuno-riken/vneumodpy in detail description',
23
+ long_description_content_type='text/plain',
24
+ keywords = 'vneumod vneumodpy virtual neuromodulation',
25
+ )
@@ -0,0 +1,38 @@
1
+
2
+ from .models.multivaliate_var_network import MultivariateVARNetwork
3
+ from .models.mvar_init_with_cell_mth import call_executor as mvar_init_with_cell_mth
4
+ from .models.regress import linear
5
+ from .models.regress import prepare
6
+ from .models.regress import inv_qr
7
+ from .models import group_range
8
+
9
+ from .glm.canonical_hrf import get as canonical_hrf
10
+ from .glm.hrf_design_matrix import get as hrf_design_matrix
11
+ from .glm.tukey import calc as tukey
12
+ from .glm.tukey_mp import calc as tukey_mp # multi processing version
13
+ from .glm.contrast_image import calc as contrast_image
14
+ from .glm.roi_ts_to4dimage import get as roi_ts_to4dimage
15
+ from .glm.roi_ts_from4dimage import get as roi_ts_from4dimage
16
+ from .glm.adjust_volume_dir import adjust_volume_dir
17
+ from .glm.resampling_nifti_volume import resampling_nifti_volume
18
+
19
+ from .surrogate.multivariate_var import calc as multivariate_var
20
+ from .surrogate.dbs_multivariate_var import calc as dbs_multivariate_var
21
+ from .surrogate.vnm_addmul_signals import get as vnm_addmul_signals
22
+ from .surrogate.vnm_var_surrogate import calc as vnm_var_surrogate
23
+ from .surrogate.vnm_subject_perm import get as vnm_subject_perm
24
+
25
+ from .measures import ac
26
+ from .measures import pac
27
+ from .measures import cm
28
+ from .measures import ccm
29
+ from .measures import pcm
30
+ from .measures import pccm
31
+ from .measures import pccm_
32
+ from .measures import mtess
33
+ from .measures import mskewkurt
34
+ from .measures.cos_sim import calc as cos_sim
35
+
36
+ from .nuisance.mean_time_series import get as nuisance_mean_time_series
37
+ from .nuisance.acompcor import get as nuisance_acompcor
38
+ from .nuisance.regression_out import get as nuisance_regression_out
File without changes
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##
3
+ # Adjust NIfTI volume direction based on NIfTI info Transpose matrix
4
+ # returns adjusted NIfTI volume
5
+ # input:
6
+ # V nifti 4D volume (X x Y x Z x frames)
7
+
8
+ from __future__ import print_function, division # for Python 2 compatible
9
+
10
+ import numpy as np
11
+
12
+
13
+ def adjust_volume_dir(V, info):
14
+ A = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]])
15
+ if np.sum(np.abs(A * info.affine[:3, :3])) > 0:
16
+ print('nifti volume transformation is not supported.')
17
+ return V
18
+ if info.affine[0, 0] < 0: # check flip X axis
19
+ V = np.flipud(V).copy()
20
+ if info.affine[1, 1] < 0: # check flip Y axis
21
+ V = np.fliplr(V).copy()
22
+ if info.affine[2, 2] < 0: # check flip Z axis
23
+ V = np.flip(V, axis=2).copy()
24
+ return V
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##
3
+ # get GLM Canonical hemodynamic response function
4
+ # returns time range (t), HRF time-series (hrf)
5
+ # input:
6
+ # dt time resolution (sec) (default:0.045)
7
+ # responseDelay delay of response (gamma a)(sec) (default:6)
8
+ # underShootDelay delay of undershoot (gamma a)(sec) (default:16)
9
+ # kernelSec kernel time length (sec) (default: 32)
10
+ # underShootRatio ratio of underShoot (default: 0.167)
11
+ # hrfScale HRF scale (gamma b) (default: 0.9)
12
+
13
+ from __future__ import print_function, division # for Python 2 compatible
14
+
15
+ import numpy as np
16
+ from scipy.stats import gamma
17
+
18
+ def get(dt=0.045, response_delay=6, under_shoot_delay=16, kernel_sec=32, under_shoot_ratio=0.167, hrf_scale=0.9):
19
+
20
+ t = np.arange(0, kernel_sec+dt, dt)
21
+ hrf = gamma.pdf(t,response_delay,scale=hrf_scale) - gamma.pdf(t,under_shoot_delay,scale=hrf_scale) * under_shoot_ratio
22
+ hrf = hrf.T / np.sum(hrf)
23
+ return t, hrf
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##
3
+ # Calculate GLM Contrast Image with prewhitening.
4
+ # based on K.J.Friston et al. (2000), M.W.Woolrich et al. (2001), K.J.Worsley (2001)
5
+ # returns cells of T-value matrix (Ts)
6
+ # input:
7
+ # Cs cells of contrast vectors (contrasts (predictor size) x 1)
8
+ # B predictor variables (node x predictor variables)
9
+ # RSS Residual Sum of Squares (node x 1)
10
+ # X2is Vector or single value of inv(X' * X) for contrast
11
+ # tRs Vector or single value of trace(R) for contrast
12
+
13
+ from __future__ import print_function, division # for Python 2 compatible
14
+
15
+ import numpy as np
16
+ from math import sqrt
17
+
18
+ def calc(Cs, B, RSS, X2is, tRs):
19
+ # GLM contrast image
20
+ # T = (c' * B) / sqrt(c' * X' * inv(V) * X * c * (RSS / trace(R)))
21
+ Ts = []
22
+ roiNum = RSS.shape[0]
23
+ T2 = np.zeros((roiNum,1), dtype=np.float32)
24
+
25
+ for c in Cs:
26
+ for i in range(roiNum):
27
+ if X2is.shape[0] == roiNum:
28
+ X2i = X2is[i, :, :]
29
+ d = sqrt(c.T @ X2i @ c)
30
+ else:
31
+ d = sqrt(c.T @ X2is @ c)
32
+
33
+ if tRs.shape[0] == roiNum:
34
+ se2 = sqrt(RSS[i].item() / tRs[i].item()) # to scalar
35
+ else:
36
+ se2 = sqrt(RSS[i].item() / tRs) # to scalar
37
+
38
+ T2[i] = (c.T @ B[i, :].T) / (d * se2)
39
+ Ts.append(T2.copy())
40
+ return Ts
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ # get GLM HRF (hemodynamic response function) design matrix
3
+ # input:
4
+ # onsets cells of task set start time
5
+ # durations cells of task set duration
6
+ # frames fMRI time frames
7
+ # TR fMRI TR
8
+ # res sampling resolution of HRF
9
+ # sp sampling starting point (in resolution)
10
+ # hrf Canonical hemodynamic response function (optional)
11
+
12
+ from __future__ import print_function, division # for Python 2 compatible
13
+
14
+ import numpy as np
15
+
16
+ from ..glm.canonical_hrf import get as canonical_hrf # for command mode
17
+
18
+ def get(onsets, durations, frames, TR, res, sp, hrf=[]):
19
+
20
+ # get Canonical hemodynamic response function
21
+ if len(hrf) == 0:
22
+ dt = TR / res
23
+ t, hrf = canonical_hrf(dt)
24
+
25
+ tasknum = len(onsets)
26
+ X = np.zeros((frames * res, tasknum), float)
27
+ U = np.zeros((frames * res, tasknum), float)
28
+ for k in range(tasknum):
29
+ onset = onsets[k]
30
+ duration = durations[k]
31
+ for i in range(len(onset)):
32
+ t1 = int(np.ceil(onset[i] / TR * res))
33
+ t2 = int(np.ceil(t1 + duration[i] / TR * res))
34
+ U[t1-1:t2,k] = 1
35
+ # get design matrix
36
+ C = np.convolve(U[:,k], hrf)
37
+ X[:,k] = C[0:frames * res]
38
+
39
+ # final sampling
40
+ X = X[np.arange((sp-1),X.shape[0],res),:]
41
+ U = U[np.arange((sp-1),U.shape[0],res),:]
42
+ return X, U
@@ -0,0 +1,73 @@
1
+ # -*- coding: utf-8 -*-
2
+ # resampling NIfTI volume.
3
+ # returns re-sampled volume (outV)
4
+ # input:
5
+ # V nifti 3D volume (X x Y x Z)
6
+ # stepXY XY axes resampling rate
7
+ # stepZ Z axes resampling rate
8
+ # operation operation for each plane ('mode'(default),'max','min','mean','median')
9
+
10
+ from __future__ import print_function, division # for Python 2 compatible
11
+
12
+ import numpy as np
13
+ from scipy.stats import mode
14
+
15
+ def resampling_nifti_volume(V, stepXY, stepZ, operation='mode'):
16
+ xs = int(np.floor(V.shape[0] / stepXY))
17
+ ys = int(np.floor(V.shape[1] / stepXY))
18
+ zs = int(np.floor(V.shape[2] / stepZ))
19
+ outV = np.zeros((xs, ys, zs), dtype=np.float32)
20
+
21
+ if stepXY >= 1 and stepZ >= 1:
22
+ # scale down
23
+ for z in range(1,zs+1):
24
+ for y in range(1,ys+1):
25
+ for x in range(1,xs+1):
26
+ x_start = int(round(x * stepXY - (stepXY - 1))) - 1
27
+ x_end = int(round(x * stepXY))
28
+ y_start = int(round(y * stepXY - (stepXY - 1))) - 1
29
+ y_end = int(round(y * stepXY))
30
+ z_start = int(round(z * stepZ - (stepZ - 1))) - 1
31
+ z_end = int(round(z * stepZ))
32
+ A = V[x_start:x_end, y_start:y_end, z_start:z_end]
33
+
34
+ if operation == 'mode':
35
+ A_flat = A[~np.isnan(A)]
36
+ if A_flat.size == 0:
37
+ m = np.nan
38
+ else:
39
+ m = mode(A_flat, axis=None).mode[0]
40
+ elif operation == 'min':
41
+ m = np.nanmin(A)
42
+ elif operation == 'max':
43
+ m = np.nanmax(A)
44
+ elif operation == 'mean':
45
+ m = np.nanmean(A)
46
+ elif operation == 'median':
47
+ m = np.nanmedian(A)
48
+ else:
49
+ raise ValueError(f"Unsupported operation: {operation}")
50
+
51
+ outV[x-1, y-1, z-1] = m
52
+ else:
53
+ # scale up
54
+ out_shape = (
55
+ int(np.ceil(V.shape[0] / stepXY)),
56
+ int(np.ceil(V.shape[1] / stepXY)),
57
+ int(np.ceil(V.shape[2] / stepZ))
58
+ )
59
+ outV = np.zeros(out_shape, dtype=np.float32)
60
+
61
+ for z in range(1,V.shape[2]+1):
62
+ for y in range(1,V.shape[1]+1):
63
+ for x in range(1,V.shape[0]+1):
64
+ m = V[x-1, y-1, z-1]
65
+ xx_start = int(round((x-1) / stepXY))
66
+ xx_end = int(round(x / stepXY))
67
+ yy_start = int(round((y-1) / stepXY))
68
+ yy_end = int(round(y / stepXY))
69
+ zz_start = int(round((z-1) / stepZ))
70
+ zz_end = int(round(z / stepZ))
71
+ outV[xx_start:xx_end, yy_start:yy_end, zz_start:zz_end] = m
72
+
73
+ return outV
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##
3
+ # get ROI time-series (matrix) from NIfTI 4D volume.
4
+ # returns ROI time-series (X)
5
+ # input:
6
+ # V nifti 4D volume (X x Y x Z x frames)
7
+ # atlasV nifti 3D atlas (X x Y x Z)
8
+ # operation calc operation for each plane ('mode'(default),'max','min','mean','median','sum')
9
+
10
+ from __future__ import print_function, division # for Python 2 compatible
11
+
12
+ import numpy as np
13
+ from scipy.stats import mode
14
+
15
+ def get(V, atlasV, operation='mode'):
16
+ roiIdx = np.unique(atlasV)
17
+ roiIdx = roiIdx[roiIdx != 0] # remove 0
18
+
19
+ X = np.zeros((len(roiIdx), V.shape[3]), dtype=np.float32)
20
+ A = V.reshape(-1, V.shape[3])
21
+ for i in range(len(roiIdx)):
22
+ j = roiIdx[i]
23
+ B = A[atlasV.flatten() == j, :]
24
+ if operation == 'mode':
25
+ m = mode(B, axis=0, nan_policy='omit').mode[0]
26
+ elif operation == 'min':
27
+ m = np.nanmin(B, axis=0)
28
+ elif operation == 'max':
29
+ m = np.nanmax(B, axis=0)
30
+ elif operation == 'mean':
31
+ m = np.nanmean(B, axis=0)
32
+ elif operation == 'median':
33
+ m = np.nanmedian(B, axis=0)
34
+ elif operation == 'sum':
35
+ m = np.nansum(B, axis=0)
36
+ else:
37
+ raise ValueError(f"Unsupported operation: {operation}")
38
+ X[i, :] = m
39
+ return X