vbi 0.1.3__cp310-cp310-manylinux2014_x86_64.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.
- vbi/__init__.py +37 -0
- vbi/_version.py +17 -0
- vbi/dataset/__init__.py +0 -0
- vbi/dataset/connectivity_84/centers.txt +84 -0
- vbi/dataset/connectivity_84/centres.txt +84 -0
- vbi/dataset/connectivity_84/cortical.txt +84 -0
- vbi/dataset/connectivity_84/tract_lengths.txt +84 -0
- vbi/dataset/connectivity_84/weights.txt +84 -0
- vbi/dataset/connectivity_88/Aud_88.txt +88 -0
- vbi/dataset/connectivity_88/Bold.npz +0 -0
- vbi/dataset/connectivity_88/Labels.txt +17 -0
- vbi/dataset/connectivity_88/Region_labels.txt +88 -0
- vbi/dataset/connectivity_88/tract_lengths.txt +88 -0
- vbi/dataset/connectivity_88/weights.txt +88 -0
- vbi/feature_extraction/__init__.py +1 -0
- vbi/feature_extraction/calc_features.py +293 -0
- vbi/feature_extraction/features.json +535 -0
- vbi/feature_extraction/features.py +2124 -0
- vbi/feature_extraction/features_settings.py +374 -0
- vbi/feature_extraction/features_utils.py +1357 -0
- vbi/feature_extraction/infodynamics.jar +0 -0
- vbi/feature_extraction/utility.py +507 -0
- vbi/inference.py +98 -0
- vbi/models/__init__.py +0 -0
- vbi/models/cpp/__init__.py +0 -0
- vbi/models/cpp/_src/__init__.py +0 -0
- vbi/models/cpp/_src/__pycache__/mpr_sde.cpython-310.pyc +0 -0
- vbi/models/cpp/_src/_do.cpython-310-x86_64-linux-gnu.so +0 -0
- vbi/models/cpp/_src/_jr_sdde.cpython-310-x86_64-linux-gnu.so +0 -0
- vbi/models/cpp/_src/_jr_sde.cpython-310-x86_64-linux-gnu.so +0 -0
- vbi/models/cpp/_src/_km_sde.cpython-310-x86_64-linux-gnu.so +0 -0
- vbi/models/cpp/_src/_mpr_sde.cpython-310-x86_64-linux-gnu.so +0 -0
- vbi/models/cpp/_src/_vep.cpython-310-x86_64-linux-gnu.so +0 -0
- vbi/models/cpp/_src/_wc_ode.cpython-310-x86_64-linux-gnu.so +0 -0
- vbi/models/cpp/_src/bold.hpp +303 -0
- vbi/models/cpp/_src/do.hpp +167 -0
- vbi/models/cpp/_src/do.i +17 -0
- vbi/models/cpp/_src/do.py +467 -0
- vbi/models/cpp/_src/do_wrap.cxx +12811 -0
- vbi/models/cpp/_src/jr_sdde.hpp +352 -0
- vbi/models/cpp/_src/jr_sdde.i +19 -0
- vbi/models/cpp/_src/jr_sdde.py +688 -0
- vbi/models/cpp/_src/jr_sdde_wrap.cxx +18718 -0
- vbi/models/cpp/_src/jr_sde.hpp +264 -0
- vbi/models/cpp/_src/jr_sde.i +17 -0
- vbi/models/cpp/_src/jr_sde.py +470 -0
- vbi/models/cpp/_src/jr_sde_wrap.cxx +13406 -0
- vbi/models/cpp/_src/km_sde.hpp +158 -0
- vbi/models/cpp/_src/km_sde.i +19 -0
- vbi/models/cpp/_src/km_sde.py +671 -0
- vbi/models/cpp/_src/km_sde_wrap.cxx +17367 -0
- vbi/models/cpp/_src/makefile +52 -0
- vbi/models/cpp/_src/mpr_sde.hpp +327 -0
- vbi/models/cpp/_src/mpr_sde.i +19 -0
- vbi/models/cpp/_src/mpr_sde.py +711 -0
- vbi/models/cpp/_src/mpr_sde_wrap.cxx +18618 -0
- vbi/models/cpp/_src/utility.hpp +307 -0
- vbi/models/cpp/_src/vep.hpp +171 -0
- vbi/models/cpp/_src/vep.i +16 -0
- vbi/models/cpp/_src/vep.py +464 -0
- vbi/models/cpp/_src/vep_wrap.cxx +12968 -0
- vbi/models/cpp/_src/wc_ode.hpp +294 -0
- vbi/models/cpp/_src/wc_ode.i +19 -0
- vbi/models/cpp/_src/wc_ode.py +686 -0
- vbi/models/cpp/_src/wc_ode_wrap.cxx +24263 -0
- vbi/models/cpp/damp_oscillator.py +143 -0
- vbi/models/cpp/jansen_rit.py +543 -0
- vbi/models/cpp/km.py +187 -0
- vbi/models/cpp/mpr.py +289 -0
- vbi/models/cpp/vep.py +150 -0
- vbi/models/cpp/wc.py +216 -0
- vbi/models/cupy/__init__.py +0 -0
- vbi/models/cupy/bold.py +111 -0
- vbi/models/cupy/ghb.py +284 -0
- vbi/models/cupy/jansen_rit.py +473 -0
- vbi/models/cupy/km.py +224 -0
- vbi/models/cupy/mpr.py +475 -0
- vbi/models/cupy/mpr_modified_bold.py +12 -0
- vbi/models/cupy/utils.py +184 -0
- vbi/models/numba/__init__.py +0 -0
- vbi/models/numba/_ww_EI.py +444 -0
- vbi/models/numba/damp_oscillator.py +162 -0
- vbi/models/numba/ghb.py +208 -0
- vbi/models/numba/mpr.py +383 -0
- vbi/models/pytorch/__init__.py +0 -0
- vbi/models/pytorch/data/default_parameters.npz +0 -0
- vbi/models/pytorch/data/input/ROI_sim.mat +0 -0
- vbi/models/pytorch/data/input/fc_test.csv +68 -0
- vbi/models/pytorch/data/input/fc_train.csv +68 -0
- vbi/models/pytorch/data/input/fc_vali.csv +68 -0
- vbi/models/pytorch/data/input/fcd_test.mat +0 -0
- vbi/models/pytorch/data/input/fcd_test_high_window.mat +0 -0
- vbi/models/pytorch/data/input/fcd_test_low_window.mat +0 -0
- vbi/models/pytorch/data/input/fcd_train.mat +0 -0
- vbi/models/pytorch/data/input/fcd_vali.mat +0 -0
- vbi/models/pytorch/data/input/myelin.csv +68 -0
- vbi/models/pytorch/data/input/rsfc_gradient.csv +68 -0
- vbi/models/pytorch/data/input/run_label_testset.mat +0 -0
- vbi/models/pytorch/data/input/sc_test.csv +68 -0
- vbi/models/pytorch/data/input/sc_train.csv +68 -0
- vbi/models/pytorch/data/input/sc_vali.csv +68 -0
- vbi/models/pytorch/data/obs_kong0.npz +0 -0
- vbi/models/pytorch/ww_sde_kong.py +570 -0
- vbi/models/tvbk/__init__.py +9 -0
- vbi/models/tvbk/tvbk_wrapper.py +166 -0
- vbi/models/tvbk/utils.py +72 -0
- vbi/papers/__init__.py +0 -0
- vbi/papers/pavlides_pcb_2015/pavlides.py +211 -0
- vbi/tests/__init__.py +0 -0
- vbi/tests/_test_mpr_nb.py +36 -0
- vbi/tests/test_features.py +355 -0
- vbi/tests/test_ghb_cupy.py +90 -0
- vbi/tests/test_mpr_cupy.py +49 -0
- vbi/tests/test_mpr_numba.py +84 -0
- vbi/tests/test_suite.py +19 -0
- vbi/utils.py +402 -0
- vbi-0.1.3.dist-info/METADATA +166 -0
- vbi-0.1.3.dist-info/RECORD +121 -0
- vbi-0.1.3.dist-info/WHEEL +5 -0
- vbi-0.1.3.dist-info/licenses/LICENSE +201 -0
- vbi-0.1.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,355 @@
|
|
1
|
+
import unittest
|
2
|
+
import numpy as np
|
3
|
+
from vbi.feature_extraction.features import (abs_energy, average_power, auc, auc_lim, calc_var, calc_std, calc_mean, calc_centroid, calc_kurtosis, calc_skewness, calc_max, calc_min, calc_median, mean_abs_dev, median_abs_dev, rms, interq_range, zero_crossing)
|
4
|
+
from parameterized import parameterized
|
5
|
+
|
6
|
+
|
7
|
+
class TestAbsEnergy(unittest.TestCase):
|
8
|
+
|
9
|
+
@parameterized.expand([
|
10
|
+
("positive_values", [1, 2, 3, 4, 5], None, [55], ['abs_energy_0']),
|
11
|
+
("negative_values", [-1, -2, -3, -4, -5], None, [55], ['abs_energy_0']),
|
12
|
+
("mixed_values", [-1, 2, -3, 4, -5], None, [55], ['abs_energy_0']),
|
13
|
+
("empty_ts", [], None, [np.nan], ["abs_energy_0"]),
|
14
|
+
("nan_values", [1, np.nan, 3, 4, 5], None, [np.nan], ['abs_energy_0']),
|
15
|
+
("infinite_values", [1, np.inf, 3, 4, 5], None, [np.nan], ['abs_energy_0']),
|
16
|
+
("positive_values_fixed", np.array([[1, 2, 3, 4], [5, 6, 7, 8]]), [0,1], [30, 174], ['abs_energy_0', 'abs_energy_1'])
|
17
|
+
])
|
18
|
+
def test_abs_energy(self, name, ts, indices, expected_values, expected_labels):
|
19
|
+
values, labels = abs_energy(ts, indices)
|
20
|
+
if np.isnan(expected_values[0]):
|
21
|
+
self.assertTrue(np.isnan(values[0]))
|
22
|
+
else:
|
23
|
+
np.testing.assert_allclose(values, expected_values)
|
24
|
+
self.assertEqual(labels, expected_labels)
|
25
|
+
|
26
|
+
|
27
|
+
class TestAveragePower(unittest.TestCase):
|
28
|
+
|
29
|
+
@parameterized.expand([
|
30
|
+
("positive_values", [1, 2, 3, 4, 5], 1, None, [13.75], ['average_power_0']),
|
31
|
+
("empty_ts", [], 1, None, [np.nan], ["average_power_0"]),
|
32
|
+
("mixed_values", [-1, 2, -3, 4, -5], 1, None, [13.75], ['average_power_0']),
|
33
|
+
("nan_values", [1, np.nan, 3, 4, 5], 1, None, [np.nan], ['average_power_0']),
|
34
|
+
("infinite_values", [1, np.inf, 3, 4, 5], 1, None, [np.nan], ['average_power_0']),
|
35
|
+
("positive_values_fixed", np.array([[1, 2, 3, 4], [5, 6, 7, 8]]), 1, [0,1], [10.0, 58.0], ['average_power_0', 'average_power_1'])
|
36
|
+
])
|
37
|
+
def test_average_power(self, name, ts, fs, indices, expected_values, expected_labels):
|
38
|
+
values, labels = average_power(ts, fs, indices)
|
39
|
+
if np.isnan(expected_values[0]):
|
40
|
+
self.assertTrue(np.isnan(values[0]))
|
41
|
+
else:
|
42
|
+
np.testing.assert_allclose(values, expected_values)
|
43
|
+
self.assertEqual(labels, expected_labels)
|
44
|
+
|
45
|
+
|
46
|
+
class TestAuc(unittest.TestCase):
|
47
|
+
|
48
|
+
@parameterized.expand([
|
49
|
+
("computes_area_under_curve_with_dx", np.array([[1, 2, 3], [4, 5, 6]]), None, None, None, [4.0, 10.0], ["auc_0", "auc_1"]),
|
50
|
+
("computes_area_under_curve_with_x", np.array([[1, 2, 3], [4, 5, 6]]), None, np.array([0, 1, 2]), None, [4.0, 10.0], ["auc_0", "auc_1"]),
|
51
|
+
("computes_area_under_curve_with_empty_ts", np.array([]), None, None, None, [np.nan], ["auc_0"]),
|
52
|
+
("handles_list_input", [[1, 2, 3], [4, 5, 6]], None, None, None, [4.0, 10.0], ["auc_0", "auc_1"]),
|
53
|
+
("handles_single_value_ts", np.array([1]), None, None, None, [0], ["auc_0"]),
|
54
|
+
("handles_empty_ts", np.array([]), None, None, None, [np.nan], ["auc_0"]),
|
55
|
+
("computes_area_under_curve_with_custom_dx", np.array([[1, 2, 3], [4, 5, 6]]), 0.5, None, [0,1], [2.0, 5.0], ["auc_0", "auc_1"]),
|
56
|
+
("handles_nan_values", np.array([[1, np.nan, 3], [4, 5, np.nan]]), None, None, None, [np.nan], ["auc_0"])
|
57
|
+
])
|
58
|
+
def test_auc(self, name, ts, dx, x, indices, expected_values, expected_labels):
|
59
|
+
values, labels = auc(ts, dx, x, indices)
|
60
|
+
|
61
|
+
np.testing.assert_allclose(values, expected_values)
|
62
|
+
self.assertEqual(labels, expected_labels)
|
63
|
+
|
64
|
+
|
65
|
+
class TestAucLim(unittest.TestCase):
|
66
|
+
|
67
|
+
@parameterized.expand([
|
68
|
+
("computes_area_under_curve_within_limit", np.array([[1, 2, 3], [4, 5, 6]]), None, None, [(0, 2)], None, [4.0, 10.0], ["auc_lim_0", "auc_lim_1"]),
|
69
|
+
("handles_multiple_limits", np.array([[1, 2, 3], [4, 5, 6]]), None, None, [(0, 1), (1, 2)], None, [1.5, 4.5, 2.5, 5.5], ["auc_lim_0", "auc_lim_1", "auc_lim_2", "auc_lim_3"]),
|
70
|
+
("handles_custom_x_values", np.array([[1, 2, 3], [4, 5, 6]]), None, np.array([0, 1, 2]), [(0, 2)], None, [4.0, 10.0], ["auc_lim_0", "auc_lim_1"]),
|
71
|
+
("handles_dx", np.array([[1, 2, 3], [4, 5, 6]]), 0.5, None, [(0, 2)], None, [4.0, 10.0], ["auc_lim_0", "auc_lim_1"]),
|
72
|
+
("handles_empty_ts", np.array([]), None, None, [(0, 2)], None, [np.nan], ["auc_lim_0"]),
|
73
|
+
("handles_nan_values", np.array([[1, np.nan, 3], [4, 5, np.nan]]), None, None, [(0, 2)], [0,1], [np.nan], ["auc_lim_0"])
|
74
|
+
])
|
75
|
+
def test_auc_lim(self, name, ts, dx, x, xlim, indices, expected_values, expected_labels):
|
76
|
+
values, labels = auc_lim(ts, dx, x, xlim)
|
77
|
+
|
78
|
+
if len(expected_values) == 0:
|
79
|
+
self.assertEqual(values, [])
|
80
|
+
self.assertEqual(labels, [])
|
81
|
+
else:
|
82
|
+
np.testing.assert_allclose(values, expected_values)
|
83
|
+
self.assertEqual(labels, expected_labels)
|
84
|
+
|
85
|
+
|
86
|
+
class TestCalcVar(unittest.TestCase):
|
87
|
+
|
88
|
+
@parameterized.expand([
|
89
|
+
("computes_variance_single_ts", [[1, 2, 3, 4, 5]], None, [2], ["var_0"]),
|
90
|
+
("computes_variance_multiple_ts", [[1, 2, 3], [4, 5, 6]], [0,1], [0.66666667, 0.66666667], ["var_0", "var_1"]),
|
91
|
+
("handles_empty_ts", [], None, [np.nan], ["var_0"]),
|
92
|
+
("handles_nan_values", [[1, np.nan, 3], [4, 5, np.nan]], None, [np.nan], ["var_0"])
|
93
|
+
])
|
94
|
+
def test_calc_var(self, name, ts, indices, expected_values, expected_labels):
|
95
|
+
values, labels = calc_var(ts, indices)
|
96
|
+
|
97
|
+
if np.isnan(expected_values[0]):
|
98
|
+
self.assertTrue(np.isnan(values[0]))
|
99
|
+
self.assertEqual(labels, expected_labels)
|
100
|
+
else:
|
101
|
+
np.testing.assert_allclose(values, expected_values)
|
102
|
+
self.assertEqual(labels, expected_labels)
|
103
|
+
|
104
|
+
class TestCalcStd(unittest.TestCase):
|
105
|
+
|
106
|
+
@parameterized.expand([
|
107
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [0.81649658, 0.81649658], ['std_0', 'std_1']),
|
108
|
+
("empty_ts", [], None, [np.nan], ["std_0"]),
|
109
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [2.05480467, 4.78423336], ['std_0', 'std_1']),
|
110
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['std_0']),
|
111
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['std_0']),
|
112
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [0.81649658, 0.81649658], ['std_0', 'std_1'])
|
113
|
+
])
|
114
|
+
def test_calc_std(self, name, ts, indices, expected_values, expected_labels):
|
115
|
+
values, labels = calc_std(ts, indices)
|
116
|
+
for i in range(len(values)):
|
117
|
+
if np.isnan(expected_values[i]):
|
118
|
+
self.assertTrue(np.isnan(values[i]))
|
119
|
+
else:
|
120
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
121
|
+
self.assertEqual(labels, expected_labels)
|
122
|
+
|
123
|
+
class TestCalcMean(unittest.TestCase):
|
124
|
+
|
125
|
+
@parameterized.expand([
|
126
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [2., 5.], ['mean_0', 'mean_1']),
|
127
|
+
("empty_ts", [], None, [np.nan], ["mean_0"]),
|
128
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [-0.66666667, 1.66666667], ['mean_0', 'mean_1']),
|
129
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['mean_0']),
|
130
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['mean_0']),
|
131
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [2., 5.], ['mean_0', 'mean_1'])
|
132
|
+
])
|
133
|
+
def test_calc_mean(self, name, ts, indices, expected_values, expected_labels):
|
134
|
+
values, labels = calc_mean(ts, indices)
|
135
|
+
for i in range(len(values)):
|
136
|
+
if np.isnan(expected_values[i]):
|
137
|
+
self.assertTrue(np.isnan(values[i]))
|
138
|
+
else:
|
139
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
140
|
+
self.assertEqual(labels, expected_labels)
|
141
|
+
|
142
|
+
class TestCalcCentroid(unittest.TestCase):
|
143
|
+
|
144
|
+
@parameterized.expand([
|
145
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), 1, None, [1.57142857, 1.25974026], ['centroid_0', 'centroid_1']),
|
146
|
+
("empty_ts", [], 1, None, [np.nan], ["centroid_0"]),
|
147
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), 1, None, [1.57142857, 1.25974026], ['centroid_0', 'centroid_1']),
|
148
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), 1, None, [np.nan], ['centroid_0']),
|
149
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), 1, None, [np.nan], ['centroid_0']),
|
150
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), 1, [0,1], [1.57142857, 1.25974026], ['centroid_0', 'centroid_1'])
|
151
|
+
])
|
152
|
+
def test_calc_centroid(self, name, ts, fs, indices, expected_values, expected_labels):
|
153
|
+
values, labels = calc_centroid(ts, fs, indices)
|
154
|
+
for i in range(len(values)):
|
155
|
+
if np.isnan(expected_values[i]):
|
156
|
+
self.assertTrue(np.isnan(values[i]))
|
157
|
+
else:
|
158
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
159
|
+
self.assertEqual(labels, expected_labels)
|
160
|
+
|
161
|
+
class TestCalcKurtosis(unittest.TestCase):
|
162
|
+
|
163
|
+
@parameterized.expand([
|
164
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [-1.5, -1.5], ['kurtosis_0', 'kurtosis_1']),
|
165
|
+
("empty_ts", [], None, [np.nan], ["kurtosis_0"]),
|
166
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [-1.5, -1.5], ['kurtosis_0', 'kurtosis_1']),
|
167
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['kurtosis_0']),
|
168
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['kurtosis_0']),
|
169
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [-1.5, -1.5], ['kurtosis_0', 'kurtosis_1'])
|
170
|
+
])
|
171
|
+
def test_calc_kurtosis(self, name, ts, indices, expected_values, expected_labels):
|
172
|
+
values, labels = calc_kurtosis(ts, indices)
|
173
|
+
for i in range(len(values)):
|
174
|
+
if np.isnan(expected_values[i]):
|
175
|
+
self.assertTrue(np.isnan(values[i]))
|
176
|
+
else:
|
177
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
178
|
+
self.assertEqual(labels, expected_labels)
|
179
|
+
|
180
|
+
class TestSkewness(unittest.TestCase):
|
181
|
+
|
182
|
+
@parameterized.expand([
|
183
|
+
("positive_values", np.array([[1, 2, 3, 1], [4, 5, 6, 0]]), None, [ 0.4933822 , -0.83315041], ['skewness_0', 'skewness_1']),
|
184
|
+
("empty_ts", [], None, [np.nan], ["skewness_0"]),
|
185
|
+
("mixed_values", np.array([[-1, 2, -3, 1], [4, -5, 6, 0]]), None, [-0.27803056, -0.39699236], ['skewness_0', 'skewness_1']),
|
186
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['skewness_0']),
|
187
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['skewness_0']),
|
188
|
+
("positive_values_fixed", np.array([[1, 2, 3, 1], [4, 5, 6, 0]]), [0,1], [ 0.4933822 , -0.83315041], ['skewness_0', 'skewness_1'])
|
189
|
+
])
|
190
|
+
def test_skewness(self, name, ts, indices, expected_values, expected_labels):
|
191
|
+
values, labels = calc_skewness(ts, indices)
|
192
|
+
for i in range(len(values)):
|
193
|
+
if np.isnan(expected_values[i]):
|
194
|
+
self.assertTrue(np.isnan(values[i]))
|
195
|
+
else:
|
196
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
197
|
+
self.assertEqual(labels, expected_labels)
|
198
|
+
|
199
|
+
class TestMax(unittest.TestCase):
|
200
|
+
|
201
|
+
@parameterized.expand([
|
202
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [3, 6], ['max_0', 'max_1']),
|
203
|
+
("empty_ts", [], None, [np.nan], ["max_0"]),
|
204
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [2, 6], ['max_0', 'max_1']),
|
205
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['max_0']),
|
206
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['max_0']),
|
207
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [3, 6], ['max_0', 'max_1'])
|
208
|
+
])
|
209
|
+
def test_max(self, name, ts, indices, expected_values, expected_labels):
|
210
|
+
values, labels = calc_max(ts, indices)
|
211
|
+
for i in range(len(values)):
|
212
|
+
if np.isnan(expected_values[i]):
|
213
|
+
self.assertTrue(np.isnan(values[i]))
|
214
|
+
else:
|
215
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
216
|
+
self.assertEqual(labels, expected_labels)
|
217
|
+
|
218
|
+
class TestMin(unittest.TestCase):
|
219
|
+
|
220
|
+
@parameterized.expand([
|
221
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [1, 4], ['min_0', 'min_1']),
|
222
|
+
("empty_ts", [], None, [np.nan], ["min_0"]),
|
223
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [-3, -5], ['min_0', 'min_1']),
|
224
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['min_0']),
|
225
|
+
("infinite_values", np.array([[1, -np.inf, 3], [4, 5, 6]]), None, [np.nan], ['min_0']),
|
226
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [1, 4], ['min_0', 'min_1'])
|
227
|
+
])
|
228
|
+
def test_min(self, name, ts, indices, expected_values, expected_labels):
|
229
|
+
values, labels = calc_min(ts, indices)
|
230
|
+
for i in range(len(values)):
|
231
|
+
if np.isnan(expected_values[i]):
|
232
|
+
self.assertTrue(np.isnan(values[i]))
|
233
|
+
else:
|
234
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
235
|
+
self.assertEqual(labels, expected_labels)
|
236
|
+
|
237
|
+
class TestMedian(unittest.TestCase):
|
238
|
+
|
239
|
+
@parameterized.expand([
|
240
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [2.0, 5.0], ['median_0', 'median_1']),
|
241
|
+
("empty_ts", [], None, [np.nan], ["median_0"]),
|
242
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [-1.0, 4.0], ['median_0', 'median_1']),
|
243
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['median_0']),
|
244
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['median_0']),
|
245
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [2.0, 5.0], ['median_0', 'median_1'])
|
246
|
+
])
|
247
|
+
def test_median(self, name, ts, indices, expected_values, expected_labels):
|
248
|
+
values, labels = calc_median(ts, indices)
|
249
|
+
for i in range(len(values)):
|
250
|
+
if np.isnan(expected_values[i]):
|
251
|
+
self.assertTrue(np.isnan(values[i]))
|
252
|
+
else:
|
253
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
254
|
+
self.assertEqual(labels, expected_labels)
|
255
|
+
|
256
|
+
|
257
|
+
class TestMeanAbsDev(unittest.TestCase):
|
258
|
+
|
259
|
+
@parameterized.expand([
|
260
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [0.66666667, 0.66666667], ['mean_abs_dev_0', 'mean_abs_dev_1']),
|
261
|
+
("empty_ts", [], None, [np.nan], ["mean_abs_dev_0"]),
|
262
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [1.77777778, 4.44444444], ['mean_abs_dev_0', 'mean_abs_dev_1']),
|
263
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['mean_abs_dev_0']),
|
264
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['mean_abs_dev_0']),
|
265
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [0.66666667, 0.66666667], ['mean_abs_dev_0', 'mean_abs_dev_1'])
|
266
|
+
])
|
267
|
+
def test_mean_abs_dev(self, name, ts, indices, expected_values, expected_labels):
|
268
|
+
values, labels = mean_abs_dev(ts, indices)
|
269
|
+
for i in range(len(values)):
|
270
|
+
if np.isnan(expected_values[i]):
|
271
|
+
self.assertTrue(np.isnan(values[i]))
|
272
|
+
else:
|
273
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
274
|
+
self.assertEqual(labels, expected_labels)
|
275
|
+
|
276
|
+
class TestMedianAbsDev(unittest.TestCase):
|
277
|
+
|
278
|
+
@parameterized.expand([
|
279
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [1.0,1.0], ['median_abs_dev_0', 'median_abs_dev_1']),
|
280
|
+
("empty_ts", [], None, [np.nan], ["median_abs_dev_0"]),
|
281
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [2.0, 2.0], ['median_abs_dev_0', 'median_abs_dev_1']),
|
282
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['median_abs_dev_0']),
|
283
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['median_abs_dev_0']),
|
284
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [1.0,1.0], ['median_abs_dev_0', 'median_abs_dev_1'])
|
285
|
+
])
|
286
|
+
def test_median_abs_dev(self, name, ts, indices, expected_values, expected_labels):
|
287
|
+
values, labels = median_abs_dev(ts, indices)
|
288
|
+
for i in range(len(values)):
|
289
|
+
if np.isnan(expected_values[i]):
|
290
|
+
self.assertTrue(np.isnan(values[i]))
|
291
|
+
else:
|
292
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
293
|
+
self.assertEqual(labels, expected_labels)
|
294
|
+
|
295
|
+
class TestRms(unittest.TestCase):
|
296
|
+
|
297
|
+
@parameterized.expand([
|
298
|
+
("positive_values", np.array([[1, 2, 3], [4, 5, 6]]), None, [2.1602469, 5.06622805], ['rms_0', 'rms_1']),
|
299
|
+
("empty_ts", [], None, [np.nan], ["rms_0"]),
|
300
|
+
("mixed_values", np.array([[-1, 2, -3], [4, -5, 6]]), None, [2.1602469, 5.06622805], ['rms_0', 'rms_1']),
|
301
|
+
("nan_values", np.array([[1, np.nan, 3], [4, 5, 6]]), None, [np.nan], ['rms_0']),
|
302
|
+
("infinite_values", np.array([[1, np.inf, 3], [4, 5, 6]]), None, [np.nan], ['rms_0']),
|
303
|
+
("positive_values_fixed", np.array([[1, 2, 3], [4, 5, 6]]), [0,1], [2.1602469, 5.06622805], ['rms_0', 'rms_1'])
|
304
|
+
])
|
305
|
+
def test_rms(self, name, ts, indices, expected_values, expected_labels):
|
306
|
+
values, labels = rms(ts, indices)
|
307
|
+
for i in range(len(values)):
|
308
|
+
if np.isnan(expected_values[i]):
|
309
|
+
self.assertTrue(np.isnan(values[i]))
|
310
|
+
else:
|
311
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
312
|
+
self.assertEqual(labels, expected_labels)
|
313
|
+
|
314
|
+
|
315
|
+
class TestInterqRange(unittest.TestCase):
|
316
|
+
|
317
|
+
@parameterized.expand([
|
318
|
+
(np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]), None, np.array([2, 2]), ["interq_range_0", "interq_range_1"]),
|
319
|
+
(np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]), [0, 1], np.array([2, 2]), ["interq_range_0", "interq_range_1"]),
|
320
|
+
(np.array([]), None, np.array([np.nan]), ["interq_range_0"]),
|
321
|
+
])
|
322
|
+
def test_interq_range(self, ts, indices, expected_values, expected_labels):
|
323
|
+
values, labels = interq_range(ts, indices)
|
324
|
+
for i in range(len(values)):
|
325
|
+
if np.isnan(expected_values[i]):
|
326
|
+
self.assertTrue(np.isnan(values[i]))
|
327
|
+
else:
|
328
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
329
|
+
self.assertEqual(labels, expected_labels)
|
330
|
+
|
331
|
+
class TestZeroCrossing(unittest.TestCase):
|
332
|
+
|
333
|
+
@parameterized.expand([
|
334
|
+
(np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]), None, np.array([0, 0]), ["zero_crossing_0", "zero_crossing_1"]),
|
335
|
+
(np.array([[1, 2, -3, 4, 5], [0, 7, -8, 9, 10]]), [0, 1], np.array([2, 3]), ["zero_crossing_0", "zero_crossing_1"]),
|
336
|
+
(np.array([]), None, np.array([np.nan]), ["zero_crossing_0"]),
|
337
|
+
])
|
338
|
+
|
339
|
+
def test_zero_crossing(self, ts, indices, expected_values, expected_labels):
|
340
|
+
values, labels = zero_crossing(ts, indices)
|
341
|
+
for i in range(len(values)):
|
342
|
+
if np.isnan(expected_values[i]):
|
343
|
+
self.assertTrue(np.isnan(values[i]))
|
344
|
+
else:
|
345
|
+
np.testing.assert_allclose(values[i], expected_values[i])
|
346
|
+
self.assertEqual(labels, expected_labels)
|
347
|
+
|
348
|
+
class TestCalcRess(unittest.TestCase):
|
349
|
+
pass
|
350
|
+
|
351
|
+
|
352
|
+
if __name__ == '__main__':
|
353
|
+
unittest.main()
|
354
|
+
# obj = TestModules()
|
355
|
+
# obj.test_HH_Solution()
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import torch
|
2
|
+
import unittest
|
3
|
+
import numpy as np
|
4
|
+
import networkx as nx
|
5
|
+
from copy import deepcopy
|
6
|
+
from vbi import LoadSample
|
7
|
+
from numpy.random import uniform
|
8
|
+
import matplotlib.pyplot as plt
|
9
|
+
|
10
|
+
GHB_AVAILABLE = True
|
11
|
+
try:
|
12
|
+
from vbi.models.cupy.ghb import GHB_sde
|
13
|
+
except ImportError:
|
14
|
+
GHB_AVAILABLE = False
|
15
|
+
|
16
|
+
# if cupy.cuda is avalable set engine to "gpu" else "cpu"
|
17
|
+
engin = "cpu"
|
18
|
+
try:
|
19
|
+
import cupy
|
20
|
+
if cupy.cuda.is_available():
|
21
|
+
engin = "gpu"
|
22
|
+
except ImportError:
|
23
|
+
pass
|
24
|
+
|
25
|
+
|
26
|
+
seed = 2
|
27
|
+
np.random.seed(seed)
|
28
|
+
torch.manual_seed(seed)
|
29
|
+
|
30
|
+
weights = LoadSample(nn=84).get_weights()
|
31
|
+
nn = len(weights)
|
32
|
+
freq = uniform(0.02, 0.04, nn)
|
33
|
+
omega = 2 * np.pi * freq
|
34
|
+
|
35
|
+
eta_mu = -1.
|
36
|
+
eta_std = 1.
|
37
|
+
eta_heter_rnd = np.random.randn(nn)
|
38
|
+
eta = eta_mu+eta_std * eta_heter_rnd
|
39
|
+
|
40
|
+
|
41
|
+
params = {
|
42
|
+
"eta": eta,
|
43
|
+
"dt": 0.01,
|
44
|
+
"num_sim": 1,
|
45
|
+
"sigma": 0.1,
|
46
|
+
"t_cut": 4.0,
|
47
|
+
"t_end": 15.0,
|
48
|
+
"seed": seed,
|
49
|
+
"G": 10.0,
|
50
|
+
"decimate": 10,
|
51
|
+
"omega": omega,
|
52
|
+
"engine": engin,
|
53
|
+
"weights": weights,
|
54
|
+
"initial_state": uniform(0, 1, (2 * nn, 1)),
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
@unittest.skipIf(not GHB_AVAILABLE, "vbi.models.cupy.ghb.GHB_sde module not available")
|
59
|
+
class testGHBSDE(unittest.TestCase):
|
60
|
+
def test_GHB_sde_cupy(self):
|
61
|
+
ghb = GHB_sde(params)
|
62
|
+
data = ghb.run()
|
63
|
+
t = data['t']
|
64
|
+
bold = data['bold']
|
65
|
+
fc = np.corrcoef(bold.squeeze())
|
66
|
+
# print(fc.mean(), fc.flatten().std())
|
67
|
+
self.assertEqual(fc.shape, (nn, nn))
|
68
|
+
self.assertAlmostEqual(fc.mean(), 0.63, delta=0.1)
|
69
|
+
self.assertAlmostEqual(fc.flatten().std(), 0.3, delta=0.1)
|
70
|
+
def test_GHB_sde_numpy(self):
|
71
|
+
|
72
|
+
par = deepcopy(params)
|
73
|
+
par['engine'] = "cpu"
|
74
|
+
ghb = GHB_sde(par)
|
75
|
+
data = ghb.run()
|
76
|
+
t = data['t']
|
77
|
+
bold = data['bold']
|
78
|
+
fc = np.corrcoef(bold.squeeze())
|
79
|
+
# print(fc.mean(), fc.flatten().std())
|
80
|
+
self.assertEqual(fc.shape, (nn, nn))
|
81
|
+
self.assertAlmostEqual(fc.mean(), 0.27, delta=0.1)
|
82
|
+
self.assertAlmostEqual(fc.flatten().std(), 0.4, delta=0.1)
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
if __name__ == '__main__':
|
87
|
+
unittest.main()
|
88
|
+
# test = testGHBSDE()
|
89
|
+
# test.test_GHB_sde_cupy()
|
90
|
+
# test.test_GHB_sde_numpy()
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import torch
|
2
|
+
import unittest
|
3
|
+
import numpy as np
|
4
|
+
import networkx as nx
|
5
|
+
from copy import deepcopy
|
6
|
+
|
7
|
+
MPR_AVAILABLE = True
|
8
|
+
try:
|
9
|
+
from vbi.models.cupy.mpr import MPR_sde
|
10
|
+
except ImportError:
|
11
|
+
MPR_AVAILABLE = False
|
12
|
+
|
13
|
+
|
14
|
+
seed = 2
|
15
|
+
np.random.seed(seed)
|
16
|
+
torch.manual_seed(seed)
|
17
|
+
|
18
|
+
nn = 3
|
19
|
+
g = nx.complete_graph(nn)
|
20
|
+
sc = nx.to_numpy_array(g) / 10.0
|
21
|
+
|
22
|
+
|
23
|
+
@unittest.skipIf(not MPR_AVAILABLE, "vbi.models.cupy.mpr.MPR_sde module not available")
|
24
|
+
class testMPRSDE(unittest.TestCase):
|
25
|
+
|
26
|
+
mpr = MPR_sde()
|
27
|
+
p = mpr.get_default_parameters()
|
28
|
+
p['weights'] = sc
|
29
|
+
p['seed'] = seed
|
30
|
+
p['t_cut'] = 0.01 * 60 * 1000
|
31
|
+
p['t_end'] = 0.02 * 60 * 1000
|
32
|
+
p['engine'] = "cpu"
|
33
|
+
|
34
|
+
def test_invalid_parameter_raises_value_error(self):
|
35
|
+
invalid_params = {"invalid_param": 42}
|
36
|
+
with self.assertRaises(ValueError):
|
37
|
+
MPR_sde(par=invalid_params)
|
38
|
+
|
39
|
+
def test_run(self):
|
40
|
+
|
41
|
+
par = deepcopy(self.p)
|
42
|
+
par['G'] = 0.1
|
43
|
+
par['eta'] = -4.7
|
44
|
+
mpr = MPR_sde(self.p)
|
45
|
+
sol = mpr.run()
|
46
|
+
x = sol["fmri_d"]
|
47
|
+
t = sol["fmri_t"]
|
48
|
+
self.assertEqual(x.shape[1], nn)
|
49
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import unittest
|
2
|
+
import numpy as np
|
3
|
+
import networkx as nx
|
4
|
+
from vbi.utils import timer
|
5
|
+
from copy import deepcopy
|
6
|
+
import matplotlib.pyplot as plt
|
7
|
+
from vbi.models.numba.mpr import MPR_sde
|
8
|
+
|
9
|
+
seed = 2
|
10
|
+
np.random.seed(seed)
|
11
|
+
|
12
|
+
nn = 6
|
13
|
+
weights = nx.to_numpy_array(nx.complete_graph(nn))
|
14
|
+
params = {
|
15
|
+
"G": 0.33,
|
16
|
+
"weights": weights,
|
17
|
+
"t_end": 2000,
|
18
|
+
"dt": 0.01,
|
19
|
+
"tau": 1.0,
|
20
|
+
"eta": np.array([-4.6]),
|
21
|
+
"rv_decimate": 10, # in time steps
|
22
|
+
"noise_amp": 0.037,
|
23
|
+
"tr": 300.0, # in [ms]
|
24
|
+
"seed": 42,
|
25
|
+
"RECORD_BOLD": True,
|
26
|
+
"RECORD_RV": True,
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
def wrapper(g, par):
|
31
|
+
par = deepcopy(par)
|
32
|
+
sde = MPR_sde(par)
|
33
|
+
control = {"G": g}
|
34
|
+
data = sde.run(control)
|
35
|
+
rv_t = data["rv_t"]
|
36
|
+
rv_d = data["rv_d"]
|
37
|
+
nn = par["weights"].shape[0]
|
38
|
+
r = rv_d[:, :nn]
|
39
|
+
v = rv_d[:, nn:]
|
40
|
+
|
41
|
+
bold_d = data["bold_d"]
|
42
|
+
bold_t = data["bold_t"]
|
43
|
+
|
44
|
+
return rv_t, r, v, bold_t, bold_d
|
45
|
+
|
46
|
+
|
47
|
+
def plot(rv_t, r, v, bold_d, bold_t, g, close=True):
|
48
|
+
step = 10
|
49
|
+
fig, ax = plt.subplots(3, 1, figsize=(12, 6))
|
50
|
+
ax[0].plot(rv_t[::step], r[::step, :], lw=0.1)
|
51
|
+
ax[1].plot(rv_t[::step], v[::step, :], lw=0.1)
|
52
|
+
ax[2].plot(bold_t, bold_d, lw=0.1)
|
53
|
+
ax[0].set_ylabel("r")
|
54
|
+
ax[1].set_ylabel("v")
|
55
|
+
ax[2].set_ylabel("BOLD")
|
56
|
+
|
57
|
+
|
58
|
+
class testMPRSDE(unittest.TestCase):
|
59
|
+
|
60
|
+
# @timer
|
61
|
+
def test_run(self):
|
62
|
+
|
63
|
+
# warm up
|
64
|
+
wrapper(0.1, params)
|
65
|
+
|
66
|
+
params["t_end"] = 30_000
|
67
|
+
rv_t, r, v, bold_t, bold_d = wrapper(0.1, params)
|
68
|
+
fc = np.corrcoef(bold_d.T)
|
69
|
+
print(fc.mean())
|
70
|
+
# plot(rv_t, r, v, bold_d, bold_t, 0.33)
|
71
|
+
|
72
|
+
self.assertEqual(r.shape[1], nn)
|
73
|
+
self.assertEqual(v.shape[1], nn)
|
74
|
+
self.assertEqual(bold_d.shape[1], nn)
|
75
|
+
self.assertTrue((fc.mean() - 0.99) < 0.01)
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
if __name__ == "__main__":
|
80
|
+
unittest.main()
|
81
|
+
# obj = testMPRSDE()
|
82
|
+
# obj.test_run()
|
83
|
+
# plt.show()
|
84
|
+
# obj.test_run()
|
vbi/tests/test_suite.py
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
import os
|
2
|
+
import unittest
|
3
|
+
import importlib
|
4
|
+
|
5
|
+
|
6
|
+
def tests():
|
7
|
+
test_directory = os.path.dirname(__file__)
|
8
|
+
test_modules = [file[:-3] for file in os.listdir(test_directory)
|
9
|
+
if file.startswith("test_") and file.endswith(".py")]
|
10
|
+
test_modules = [module for module in test_modules if module != "test_suite.py"]
|
11
|
+
|
12
|
+
suite = unittest.TestSuite()
|
13
|
+
for module_name in test_modules:
|
14
|
+
module = importlib.import_module(f".{module_name}", package=__package__)
|
15
|
+
tests = unittest.TestLoader().loadTestsFromModule(module)
|
16
|
+
suite.addTests(tests)
|
17
|
+
|
18
|
+
runner = unittest.TextTestRunner(verbosity=0)
|
19
|
+
runner.run(suite)
|