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.
Files changed (121) hide show
  1. vbi/__init__.py +37 -0
  2. vbi/_version.py +17 -0
  3. vbi/dataset/__init__.py +0 -0
  4. vbi/dataset/connectivity_84/centers.txt +84 -0
  5. vbi/dataset/connectivity_84/centres.txt +84 -0
  6. vbi/dataset/connectivity_84/cortical.txt +84 -0
  7. vbi/dataset/connectivity_84/tract_lengths.txt +84 -0
  8. vbi/dataset/connectivity_84/weights.txt +84 -0
  9. vbi/dataset/connectivity_88/Aud_88.txt +88 -0
  10. vbi/dataset/connectivity_88/Bold.npz +0 -0
  11. vbi/dataset/connectivity_88/Labels.txt +17 -0
  12. vbi/dataset/connectivity_88/Region_labels.txt +88 -0
  13. vbi/dataset/connectivity_88/tract_lengths.txt +88 -0
  14. vbi/dataset/connectivity_88/weights.txt +88 -0
  15. vbi/feature_extraction/__init__.py +1 -0
  16. vbi/feature_extraction/calc_features.py +293 -0
  17. vbi/feature_extraction/features.json +535 -0
  18. vbi/feature_extraction/features.py +2124 -0
  19. vbi/feature_extraction/features_settings.py +374 -0
  20. vbi/feature_extraction/features_utils.py +1357 -0
  21. vbi/feature_extraction/infodynamics.jar +0 -0
  22. vbi/feature_extraction/utility.py +507 -0
  23. vbi/inference.py +98 -0
  24. vbi/models/__init__.py +0 -0
  25. vbi/models/cpp/__init__.py +0 -0
  26. vbi/models/cpp/_src/__init__.py +0 -0
  27. vbi/models/cpp/_src/__pycache__/mpr_sde.cpython-310.pyc +0 -0
  28. vbi/models/cpp/_src/_do.cpython-310-x86_64-linux-gnu.so +0 -0
  29. vbi/models/cpp/_src/_jr_sdde.cpython-310-x86_64-linux-gnu.so +0 -0
  30. vbi/models/cpp/_src/_jr_sde.cpython-310-x86_64-linux-gnu.so +0 -0
  31. vbi/models/cpp/_src/_km_sde.cpython-310-x86_64-linux-gnu.so +0 -0
  32. vbi/models/cpp/_src/_mpr_sde.cpython-310-x86_64-linux-gnu.so +0 -0
  33. vbi/models/cpp/_src/_vep.cpython-310-x86_64-linux-gnu.so +0 -0
  34. vbi/models/cpp/_src/_wc_ode.cpython-310-x86_64-linux-gnu.so +0 -0
  35. vbi/models/cpp/_src/bold.hpp +303 -0
  36. vbi/models/cpp/_src/do.hpp +167 -0
  37. vbi/models/cpp/_src/do.i +17 -0
  38. vbi/models/cpp/_src/do.py +467 -0
  39. vbi/models/cpp/_src/do_wrap.cxx +12811 -0
  40. vbi/models/cpp/_src/jr_sdde.hpp +352 -0
  41. vbi/models/cpp/_src/jr_sdde.i +19 -0
  42. vbi/models/cpp/_src/jr_sdde.py +688 -0
  43. vbi/models/cpp/_src/jr_sdde_wrap.cxx +18718 -0
  44. vbi/models/cpp/_src/jr_sde.hpp +264 -0
  45. vbi/models/cpp/_src/jr_sde.i +17 -0
  46. vbi/models/cpp/_src/jr_sde.py +470 -0
  47. vbi/models/cpp/_src/jr_sde_wrap.cxx +13406 -0
  48. vbi/models/cpp/_src/km_sde.hpp +158 -0
  49. vbi/models/cpp/_src/km_sde.i +19 -0
  50. vbi/models/cpp/_src/km_sde.py +671 -0
  51. vbi/models/cpp/_src/km_sde_wrap.cxx +17367 -0
  52. vbi/models/cpp/_src/makefile +52 -0
  53. vbi/models/cpp/_src/mpr_sde.hpp +327 -0
  54. vbi/models/cpp/_src/mpr_sde.i +19 -0
  55. vbi/models/cpp/_src/mpr_sde.py +711 -0
  56. vbi/models/cpp/_src/mpr_sde_wrap.cxx +18618 -0
  57. vbi/models/cpp/_src/utility.hpp +307 -0
  58. vbi/models/cpp/_src/vep.hpp +171 -0
  59. vbi/models/cpp/_src/vep.i +16 -0
  60. vbi/models/cpp/_src/vep.py +464 -0
  61. vbi/models/cpp/_src/vep_wrap.cxx +12968 -0
  62. vbi/models/cpp/_src/wc_ode.hpp +294 -0
  63. vbi/models/cpp/_src/wc_ode.i +19 -0
  64. vbi/models/cpp/_src/wc_ode.py +686 -0
  65. vbi/models/cpp/_src/wc_ode_wrap.cxx +24263 -0
  66. vbi/models/cpp/damp_oscillator.py +143 -0
  67. vbi/models/cpp/jansen_rit.py +543 -0
  68. vbi/models/cpp/km.py +187 -0
  69. vbi/models/cpp/mpr.py +289 -0
  70. vbi/models/cpp/vep.py +150 -0
  71. vbi/models/cpp/wc.py +216 -0
  72. vbi/models/cupy/__init__.py +0 -0
  73. vbi/models/cupy/bold.py +111 -0
  74. vbi/models/cupy/ghb.py +284 -0
  75. vbi/models/cupy/jansen_rit.py +473 -0
  76. vbi/models/cupy/km.py +224 -0
  77. vbi/models/cupy/mpr.py +475 -0
  78. vbi/models/cupy/mpr_modified_bold.py +12 -0
  79. vbi/models/cupy/utils.py +184 -0
  80. vbi/models/numba/__init__.py +0 -0
  81. vbi/models/numba/_ww_EI.py +444 -0
  82. vbi/models/numba/damp_oscillator.py +162 -0
  83. vbi/models/numba/ghb.py +208 -0
  84. vbi/models/numba/mpr.py +383 -0
  85. vbi/models/pytorch/__init__.py +0 -0
  86. vbi/models/pytorch/data/default_parameters.npz +0 -0
  87. vbi/models/pytorch/data/input/ROI_sim.mat +0 -0
  88. vbi/models/pytorch/data/input/fc_test.csv +68 -0
  89. vbi/models/pytorch/data/input/fc_train.csv +68 -0
  90. vbi/models/pytorch/data/input/fc_vali.csv +68 -0
  91. vbi/models/pytorch/data/input/fcd_test.mat +0 -0
  92. vbi/models/pytorch/data/input/fcd_test_high_window.mat +0 -0
  93. vbi/models/pytorch/data/input/fcd_test_low_window.mat +0 -0
  94. vbi/models/pytorch/data/input/fcd_train.mat +0 -0
  95. vbi/models/pytorch/data/input/fcd_vali.mat +0 -0
  96. vbi/models/pytorch/data/input/myelin.csv +68 -0
  97. vbi/models/pytorch/data/input/rsfc_gradient.csv +68 -0
  98. vbi/models/pytorch/data/input/run_label_testset.mat +0 -0
  99. vbi/models/pytorch/data/input/sc_test.csv +68 -0
  100. vbi/models/pytorch/data/input/sc_train.csv +68 -0
  101. vbi/models/pytorch/data/input/sc_vali.csv +68 -0
  102. vbi/models/pytorch/data/obs_kong0.npz +0 -0
  103. vbi/models/pytorch/ww_sde_kong.py +570 -0
  104. vbi/models/tvbk/__init__.py +9 -0
  105. vbi/models/tvbk/tvbk_wrapper.py +166 -0
  106. vbi/models/tvbk/utils.py +72 -0
  107. vbi/papers/__init__.py +0 -0
  108. vbi/papers/pavlides_pcb_2015/pavlides.py +211 -0
  109. vbi/tests/__init__.py +0 -0
  110. vbi/tests/_test_mpr_nb.py +36 -0
  111. vbi/tests/test_features.py +355 -0
  112. vbi/tests/test_ghb_cupy.py +90 -0
  113. vbi/tests/test_mpr_cupy.py +49 -0
  114. vbi/tests/test_mpr_numba.py +84 -0
  115. vbi/tests/test_suite.py +19 -0
  116. vbi/utils.py +402 -0
  117. vbi-0.1.3.dist-info/METADATA +166 -0
  118. vbi-0.1.3.dist-info/RECORD +121 -0
  119. vbi-0.1.3.dist-info/WHEEL +5 -0
  120. vbi-0.1.3.dist-info/licenses/LICENSE +201 -0
  121. 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()
@@ -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)