rapidtide 3.0.11__py3-none-any.whl → 3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rapidtide/Colortables.py +492 -27
- rapidtide/OrthoImageItem.py +1049 -46
- rapidtide/RapidtideDataset.py +1533 -86
- rapidtide/_version.py +3 -3
- rapidtide/calccoherence.py +196 -29
- rapidtide/calcnullsimfunc.py +191 -40
- rapidtide/calcsimfunc.py +245 -42
- rapidtide/correlate.py +1210 -393
- rapidtide/data/examples/src/testLD +56 -0
- rapidtide/data/examples/src/testalign +1 -1
- rapidtide/data/examples/src/testdelayvar +0 -1
- rapidtide/data/examples/src/testfmri +19 -1
- rapidtide/data/examples/src/testglmfilt +5 -5
- rapidtide/data/examples/src/testhappy +25 -3
- rapidtide/data/examples/src/testppgproc +17 -0
- rapidtide/data/examples/src/testrolloff +11 -0
- rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
- rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
- rapidtide/decorators.py +91 -0
- rapidtide/dlfilter.py +2225 -108
- rapidtide/dlfiltertorch.py +4843 -0
- rapidtide/externaltools.py +327 -12
- rapidtide/fMRIData_class.py +79 -40
- rapidtide/filter.py +1899 -810
- rapidtide/fit.py +2004 -574
- rapidtide/genericmultiproc.py +93 -18
- rapidtide/happy_supportfuncs.py +2044 -171
- rapidtide/helper_classes.py +584 -43
- rapidtide/io.py +2363 -370
- rapidtide/linfitfiltpass.py +341 -75
- rapidtide/makelaggedtcs.py +211 -20
- rapidtide/maskutil.py +423 -53
- rapidtide/miscmath.py +827 -121
- rapidtide/multiproc.py +210 -22
- rapidtide/patchmatch.py +234 -33
- rapidtide/peakeval.py +32 -30
- rapidtide/ppgproc.py +2203 -0
- rapidtide/qualitycheck.py +352 -39
- rapidtide/refinedelay.py +422 -57
- rapidtide/refineregressor.py +498 -184
- rapidtide/resample.py +671 -185
- rapidtide/scripts/applyppgproc.py +28 -0
- rapidtide/simFuncClasses.py +1052 -77
- rapidtide/simfuncfit.py +260 -46
- rapidtide/stats.py +540 -238
- rapidtide/tests/happycomp +9 -0
- rapidtide/tests/test_dlfiltertorch.py +627 -0
- rapidtide/tests/test_findmaxlag.py +24 -8
- rapidtide/tests/test_fullrunhappy_v1.py +0 -2
- rapidtide/tests/test_fullrunhappy_v2.py +0 -2
- rapidtide/tests/test_fullrunhappy_v3.py +1 -0
- rapidtide/tests/test_fullrunhappy_v4.py +2 -2
- rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
- rapidtide/tests/test_simroundtrip.py +8 -8
- rapidtide/tests/utils.py +9 -8
- rapidtide/tidepoolTemplate.py +142 -38
- rapidtide/tidepoolTemplate_alt.py +165 -44
- rapidtide/tidepoolTemplate_big.py +189 -52
- rapidtide/util.py +1217 -118
- rapidtide/voxelData.py +684 -37
- rapidtide/wiener.py +19 -12
- rapidtide/wiener2.py +113 -7
- rapidtide/wiener_doc.py +255 -0
- rapidtide/workflows/adjustoffset.py +105 -3
- rapidtide/workflows/aligntcs.py +85 -2
- rapidtide/workflows/applydlfilter.py +87 -10
- rapidtide/workflows/applyppgproc.py +522 -0
- rapidtide/workflows/atlasaverage.py +210 -47
- rapidtide/workflows/atlastool.py +100 -3
- rapidtide/workflows/calcSimFuncMap.py +294 -64
- rapidtide/workflows/calctexticc.py +201 -9
- rapidtide/workflows/ccorrica.py +97 -4
- rapidtide/workflows/cleanregressor.py +168 -29
- rapidtide/workflows/delayvar.py +163 -10
- rapidtide/workflows/diffrois.py +81 -3
- rapidtide/workflows/endtidalproc.py +144 -4
- rapidtide/workflows/fdica.py +195 -15
- rapidtide/workflows/filtnifti.py +70 -3
- rapidtide/workflows/filttc.py +74 -3
- rapidtide/workflows/fitSimFuncMap.py +206 -48
- rapidtide/workflows/fixtr.py +73 -3
- rapidtide/workflows/gmscalc.py +113 -3
- rapidtide/workflows/happy.py +801 -199
- rapidtide/workflows/happy2std.py +144 -12
- rapidtide/workflows/happy_parser.py +138 -9
- rapidtide/workflows/histnifti.py +118 -2
- rapidtide/workflows/histtc.py +84 -3
- rapidtide/workflows/linfitfilt.py +117 -4
- rapidtide/workflows/localflow.py +328 -28
- rapidtide/workflows/mergequality.py +79 -3
- rapidtide/workflows/niftidecomp.py +322 -18
- rapidtide/workflows/niftistats.py +174 -4
- rapidtide/workflows/pairproc.py +88 -2
- rapidtide/workflows/pairwisemergenifti.py +85 -2
- rapidtide/workflows/parser_funcs.py +1421 -40
- rapidtide/workflows/physiofreq.py +137 -11
- rapidtide/workflows/pixelcomp.py +208 -5
- rapidtide/workflows/plethquality.py +103 -21
- rapidtide/workflows/polyfitim.py +151 -11
- rapidtide/workflows/proj2flow.py +75 -2
- rapidtide/workflows/rankimage.py +111 -4
- rapidtide/workflows/rapidtide.py +272 -15
- rapidtide/workflows/rapidtide2std.py +98 -2
- rapidtide/workflows/rapidtide_parser.py +109 -9
- rapidtide/workflows/refineDelayMap.py +143 -33
- rapidtide/workflows/refineRegressor.py +682 -93
- rapidtide/workflows/regressfrommaps.py +152 -31
- rapidtide/workflows/resamplenifti.py +85 -3
- rapidtide/workflows/resampletc.py +91 -3
- rapidtide/workflows/retrolagtcs.py +98 -6
- rapidtide/workflows/retroregress.py +165 -9
- rapidtide/workflows/roisummarize.py +173 -5
- rapidtide/workflows/runqualitycheck.py +71 -3
- rapidtide/workflows/showarbcorr.py +147 -4
- rapidtide/workflows/showhist.py +86 -2
- rapidtide/workflows/showstxcorr.py +160 -3
- rapidtide/workflows/showtc.py +159 -3
- rapidtide/workflows/showxcorrx.py +184 -4
- rapidtide/workflows/showxy.py +185 -15
- rapidtide/workflows/simdata.py +262 -36
- rapidtide/workflows/spatialfit.py +77 -2
- rapidtide/workflows/spatialmi.py +251 -27
- rapidtide/workflows/spectrogram.py +305 -32
- rapidtide/workflows/synthASL.py +154 -3
- rapidtide/workflows/tcfrom2col.py +76 -2
- rapidtide/workflows/tcfrom3col.py +74 -2
- rapidtide/workflows/tidepool.py +2969 -130
- rapidtide/workflows/utils.py +19 -14
- rapidtide/workflows/utils_doc.py +293 -0
- rapidtide/workflows/variabilityizer.py +116 -3
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/METADATA +3 -2
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/RECORD +139 -122
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/entry_points.txt +1 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/WHEEL +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/top_level.txt +0 -0
rapidtide/linfitfiltpass.py
CHANGED
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#
|
|
18
18
|
#
|
|
19
|
+
from typing import Any, Callable
|
|
20
|
+
|
|
19
21
|
import numpy as np
|
|
22
|
+
from numpy.typing import NDArray
|
|
20
23
|
from scipy.special import factorial
|
|
21
24
|
from tqdm import tqdm
|
|
22
25
|
|
|
@@ -27,8 +30,63 @@ import rapidtide.multiproc as tide_multiproc
|
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
def _procOneRegressionFitItem(
|
|
30
|
-
vox
|
|
31
|
-
|
|
33
|
+
vox: int,
|
|
34
|
+
theevs: NDArray,
|
|
35
|
+
thedata: NDArray,
|
|
36
|
+
rt_floatset: type = np.float64,
|
|
37
|
+
rt_floattype: str = "float64",
|
|
38
|
+
) -> tuple[int, Any, Any, Any, Any, Any, NDArray, NDArray]:
|
|
39
|
+
"""
|
|
40
|
+
Perform single regression fit on voxel data and return fit results.
|
|
41
|
+
|
|
42
|
+
This function fits a linear regression model to the provided evs and data,
|
|
43
|
+
handling both univariate and multivariate cases. It computes fit coefficients,
|
|
44
|
+
R-squared value, and residual data.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
vox : int
|
|
49
|
+
Voxel index.
|
|
50
|
+
theevs : numpy.ndarray
|
|
51
|
+
Experimental design matrix. If 2D, dimension 0 is number of points,
|
|
52
|
+
dimension 1 is number of evs.
|
|
53
|
+
thedata : numpy.ndarray
|
|
54
|
+
Dependent variable data corresponding to the evs.
|
|
55
|
+
rt_floatset : type, optional
|
|
56
|
+
Data type for floating-point results, default is ``np.float64``.
|
|
57
|
+
rt_floattype : str, optional
|
|
58
|
+
String representation of the floating-point type, default is ``"float64"``.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
tuple[int, Any, Any, Any, Any, Any, numpy.ndarray, numpy.ndarray]
|
|
63
|
+
A tuple containing:
|
|
64
|
+
- voxel index (`int`)
|
|
65
|
+
- intercept term (`Any`)
|
|
66
|
+
- signed square root of R-squared (`Any`)
|
|
67
|
+
- R-squared value (`Any`)
|
|
68
|
+
- fit coefficients (`Any` or `numpy.ndarray`)
|
|
69
|
+
- normalized fit coefficients (`Any`)
|
|
70
|
+
- data removed by fitting (`numpy.ndarray`)
|
|
71
|
+
- residuals (`numpy.ndarray`)
|
|
72
|
+
|
|
73
|
+
Notes
|
|
74
|
+
-----
|
|
75
|
+
For multivariate regressions (2D `theevs`), the function computes the fit
|
|
76
|
+
using `tide_fit.mlregress`. If the fit fails, a zero matrix is returned.
|
|
77
|
+
For univariate regressions (1D `theevs`), the function directly computes
|
|
78
|
+
the fit and handles edge cases such as zero coefficients.
|
|
79
|
+
|
|
80
|
+
Examples
|
|
81
|
+
--------
|
|
82
|
+
>>> import numpy as np
|
|
83
|
+
>>> from tide_fit import mlregress
|
|
84
|
+
>>> theevs = np.array([[1, 2], [3, 4], [5, 6]], dtype=np.float64)
|
|
85
|
+
>>> thedata = np.array([1, 2, 3], dtype=np.float64)
|
|
86
|
+
>>> result = _procOneRegressionFitItem(0, theevs, thedata)
|
|
87
|
+
>>> print(result[0]) # voxel index
|
|
88
|
+
0
|
|
89
|
+
"""
|
|
32
90
|
# NOTE: if theevs is 2D, dimension 0 is number of points, dimension 1 is number of evs
|
|
33
91
|
thefit, R2 = tide_fit.mlregress(theevs, thedata)
|
|
34
92
|
if theevs.ndim > 1:
|
|
@@ -78,36 +136,132 @@ def _procOneRegressionFitItem(
|
|
|
78
136
|
|
|
79
137
|
|
|
80
138
|
def linfitfiltpass(
|
|
81
|
-
numprocitems,
|
|
82
|
-
fmri_data,
|
|
83
|
-
threshval,
|
|
84
|
-
theevs,
|
|
85
|
-
meanvalue,
|
|
86
|
-
rvalue,
|
|
87
|
-
r2value,
|
|
88
|
-
fitcoeff,
|
|
89
|
-
fitNorm,
|
|
90
|
-
datatoremove,
|
|
91
|
-
filtereddata,
|
|
92
|
-
nprocs=1,
|
|
93
|
-
alwaysmultiproc=False,
|
|
94
|
-
|
|
95
|
-
confoundregress=False,
|
|
96
|
-
coefficientsonly=False,
|
|
97
|
-
procbyvoxel=True,
|
|
98
|
-
showprogressbar=True,
|
|
99
|
-
chunksize=1000,
|
|
100
|
-
rt_floatset=np.float64,
|
|
101
|
-
rt_floattype="float64",
|
|
102
|
-
verbose=True,
|
|
103
|
-
debug=False,
|
|
104
|
-
):
|
|
139
|
+
numprocitems: int,
|
|
140
|
+
fmri_data: NDArray,
|
|
141
|
+
threshval: float | None,
|
|
142
|
+
theevs: NDArray,
|
|
143
|
+
meanvalue: NDArray | None,
|
|
144
|
+
rvalue: NDArray | None,
|
|
145
|
+
r2value: NDArray,
|
|
146
|
+
fitcoeff: NDArray | None,
|
|
147
|
+
fitNorm: NDArray | None,
|
|
148
|
+
datatoremove: NDArray | None,
|
|
149
|
+
filtereddata: NDArray,
|
|
150
|
+
nprocs: int = 1,
|
|
151
|
+
alwaysmultiproc: bool = False,
|
|
152
|
+
constantevs: bool = False,
|
|
153
|
+
confoundregress: bool = False,
|
|
154
|
+
coefficientsonly: bool = False,
|
|
155
|
+
procbyvoxel: bool = True,
|
|
156
|
+
showprogressbar: bool = True,
|
|
157
|
+
chunksize: int = 1000,
|
|
158
|
+
rt_floatset: type = np.float64,
|
|
159
|
+
rt_floattype: str = "float64",
|
|
160
|
+
verbose: bool = True,
|
|
161
|
+
debug: bool = False,
|
|
162
|
+
) -> int:
|
|
163
|
+
"""
|
|
164
|
+
Perform linear regression fitting and filtering on fMRI data.
|
|
165
|
+
|
|
166
|
+
This function fits a linear model to fMRI data using specified experimental variables
|
|
167
|
+
and applies filtering to remove noise. It supports both voxel-wise and timepoint-wise
|
|
168
|
+
processing, with optional multiprocessing for performance.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
----------
|
|
172
|
+
numprocitems : int
|
|
173
|
+
Number of items to process (voxels or timepoints depending on ``procbyvoxel``).
|
|
174
|
+
fmri_data : ndarray
|
|
175
|
+
Input fMRI data array with shape ``(n_voxels, n_timepoints)`` or ``(n_timepoints, n_voxels)``.
|
|
176
|
+
threshval : float, optional
|
|
177
|
+
Threshold value for masking. If ``None``, no masking is applied.
|
|
178
|
+
theevs : ndarray
|
|
179
|
+
Experimental variables (design matrix) with shape ``(n_voxels, n_timepoints)`` or ``(n_timepoints, n_voxels)``.
|
|
180
|
+
meanvalue : ndarray, optional
|
|
181
|
+
Array to store mean values of the data. Shape depends on ``procbyvoxel``.
|
|
182
|
+
rvalue : ndarray, optional
|
|
183
|
+
Array to store correlation coefficients. Shape depends on ``procbyvoxel``.
|
|
184
|
+
r2value : ndarray
|
|
185
|
+
Array to store R-squared values. Shape depends on ``procbyvoxel``.
|
|
186
|
+
fitcoeff : ndarray, optional
|
|
187
|
+
Array to store fit coefficients. Shape depends on ``procbyvoxel`` and ``constantevs``.
|
|
188
|
+
fitNorm : ndarray, optional
|
|
189
|
+
Array to store normalized fit coefficients. Shape depends on ``procbyvoxel``.
|
|
190
|
+
datatoremove : ndarray, optional
|
|
191
|
+
Array to store data to be removed after fitting. Shape depends on ``procbyvoxel``.
|
|
192
|
+
filtereddata : ndarray
|
|
193
|
+
Array to store filtered data after regression. Shape depends on ``procbyvoxel``.
|
|
194
|
+
nprocs : int, default: 1
|
|
195
|
+
Number of processes to use for multiprocessing. If 1 and ``alwaysmultiproc`` is False, uses single-threaded processing.
|
|
196
|
+
alwaysmultiproc : bool, default: False
|
|
197
|
+
If True, always use multiprocessing even if ``nprocs`` is 1.
|
|
198
|
+
constantevs : bool, default: False
|
|
199
|
+
If True, treat experimental variables as constant across voxels/timepoints.
|
|
200
|
+
confoundregress : bool, default: False
|
|
201
|
+
If True, perform confound regression only (no output of coefficients or residuals).
|
|
202
|
+
coefficientsonly : bool, default: False
|
|
203
|
+
If True, store only regression coefficients and R-squared values.
|
|
204
|
+
procbyvoxel : bool, default: True
|
|
205
|
+
If True, process data voxel-wise; otherwise, process by timepoint.
|
|
206
|
+
showprogressbar : bool, default: True
|
|
207
|
+
If True, display a progress bar during processing.
|
|
208
|
+
chunksize : int, default: 1000
|
|
209
|
+
Size of chunks for multiprocessing.
|
|
210
|
+
rt_floatset : type, default: np.float64
|
|
211
|
+
Data type for internal floating-point calculations.
|
|
212
|
+
rt_floattype : str, default: "float64"
|
|
213
|
+
String representation of the floating-point data type.
|
|
214
|
+
verbose : bool, default: True
|
|
215
|
+
If True, print verbose output.
|
|
216
|
+
debug : bool, default: False
|
|
217
|
+
If True, enable debug printing.
|
|
218
|
+
|
|
219
|
+
Returns
|
|
220
|
+
-------
|
|
221
|
+
int
|
|
222
|
+
Total number of items processed.
|
|
223
|
+
|
|
224
|
+
Notes
|
|
225
|
+
-----
|
|
226
|
+
- The function modifies the output arrays in-place.
|
|
227
|
+
- For ``confoundregress=True``, only ``r2value`` and ``filtereddata`` are populated.
|
|
228
|
+
- When ``coefficientsonly=True``, only ``meanvalue``, ``rvalue``, ``r2value``, ``fitcoeff``, and ``fitNorm`` are populated.
|
|
229
|
+
- If ``threshval`` is provided, a mask is generated based on mean or standard deviation of the data.
|
|
230
|
+
|
|
231
|
+
Examples
|
|
232
|
+
--------
|
|
233
|
+
>>> import numpy as np
|
|
234
|
+
>>> from typing import NDArray
|
|
235
|
+
>>> fmri_data = np.random.rand(100, 200)
|
|
236
|
+
>>> theevs = np.random.rand(100, 200)
|
|
237
|
+
>>> r2value = np.zeros(100)
|
|
238
|
+
>>> filtereddata = np.zeros_like(fmri_data)
|
|
239
|
+
>>> numprocitems = 100
|
|
240
|
+
>>> items_processed = linfitfiltpass(
|
|
241
|
+
... numprocitems=numprocitems,
|
|
242
|
+
... fmri_data=fmri_data,
|
|
243
|
+
... threshval=None,
|
|
244
|
+
... theevs=theevs,
|
|
245
|
+
... meanvalue=None,
|
|
246
|
+
... rvalue=None,
|
|
247
|
+
... r2value=r2value,
|
|
248
|
+
... fitcoeff=None,
|
|
249
|
+
... fitNorm=None,
|
|
250
|
+
... datatoremove=None,
|
|
251
|
+
... filtereddata=filtereddata,
|
|
252
|
+
... nprocs=4,
|
|
253
|
+
... procbyvoxel=True,
|
|
254
|
+
... showprogressbar=True
|
|
255
|
+
... )
|
|
256
|
+
>>> print(f"Processed {items_processed} items.")
|
|
257
|
+
"""
|
|
105
258
|
inputshape = np.shape(fmri_data)
|
|
106
259
|
if debug:
|
|
107
260
|
print(f"{numprocitems=}")
|
|
108
261
|
print(f"{fmri_data.shape=}")
|
|
109
262
|
print(f"{threshval=}")
|
|
110
|
-
print(f"{theevs.shape=}")
|
|
263
|
+
print(f"{theevs.shape=}, {np.min(theevs)=}, {np.max(theevs)=}")
|
|
264
|
+
print(f"{theevs=}")
|
|
111
265
|
if procbyvoxel:
|
|
112
266
|
indexaxis = 0
|
|
113
267
|
procunit = "voxels"
|
|
@@ -143,7 +297,7 @@ def linfitfiltpass(
|
|
|
143
297
|
|
|
144
298
|
# process and send the data
|
|
145
299
|
if procbyvoxel:
|
|
146
|
-
if confoundregress or
|
|
300
|
+
if confoundregress or constantevs:
|
|
147
301
|
outQ.put(
|
|
148
302
|
_procOneRegressionFitItem(
|
|
149
303
|
val,
|
|
@@ -164,7 +318,7 @@ def linfitfiltpass(
|
|
|
164
318
|
)
|
|
165
319
|
)
|
|
166
320
|
else:
|
|
167
|
-
if confoundregress or
|
|
321
|
+
if confoundregress or constantevs:
|
|
168
322
|
outQ.put(
|
|
169
323
|
_procOneRegressionFitItem(
|
|
170
324
|
val,
|
|
@@ -214,7 +368,7 @@ def linfitfiltpass(
|
|
|
214
368
|
meanvalue[voxel[0]] = voxel[1]
|
|
215
369
|
rvalue[voxel[0]] = voxel[2]
|
|
216
370
|
r2value[voxel[0]] = voxel[3]
|
|
217
|
-
if
|
|
371
|
+
if fitcoeff.ndim > 1:
|
|
218
372
|
fitcoeff[voxel[0], :] = voxel[4]
|
|
219
373
|
fitNorm[voxel[0], :] = voxel[5]
|
|
220
374
|
else:
|
|
@@ -226,7 +380,7 @@ def linfitfiltpass(
|
|
|
226
380
|
meanvalue[voxel[0]] = voxel[1]
|
|
227
381
|
rvalue[voxel[0]] = voxel[2]
|
|
228
382
|
r2value[voxel[0]] = voxel[3]
|
|
229
|
-
if
|
|
383
|
+
if fitcoeff.ndim > 1:
|
|
230
384
|
fitcoeff[voxel[0], :] = voxel[4]
|
|
231
385
|
fitNorm[voxel[0], :] = voxel[5]
|
|
232
386
|
else:
|
|
@@ -246,7 +400,7 @@ def linfitfiltpass(
|
|
|
246
400
|
meanvalue[timepoint[0]] = timepoint[1]
|
|
247
401
|
rvalue[timepoint[0]] = timepoint[2]
|
|
248
402
|
r2value[timepoint[0]] = timepoint[3]
|
|
249
|
-
if
|
|
403
|
+
if fitcoeff.ndim > 1:
|
|
250
404
|
fitcoeff[:, timepoint[0]] = timepoint[4]
|
|
251
405
|
fitNorm[:, timepoint[0]] = timepoint[5]
|
|
252
406
|
else:
|
|
@@ -258,7 +412,7 @@ def linfitfiltpass(
|
|
|
258
412
|
meanvalue[timepoint[0]] = timepoint[1]
|
|
259
413
|
rvalue[timepoint[0]] = timepoint[2]
|
|
260
414
|
r2value[timepoint[0]] = timepoint[3]
|
|
261
|
-
if
|
|
415
|
+
if fitcoeff.ndim > 1:
|
|
262
416
|
fitcoeff[:, timepoint[0]] = timepoint[4]
|
|
263
417
|
fitNorm[:, timepoint[0]] = timepoint[5]
|
|
264
418
|
else:
|
|
@@ -270,6 +424,7 @@ def linfitfiltpass(
|
|
|
270
424
|
|
|
271
425
|
del data_out
|
|
272
426
|
else:
|
|
427
|
+
# this is the single proc path
|
|
273
428
|
itemstotal = 0
|
|
274
429
|
if procbyvoxel:
|
|
275
430
|
for vox in tqdm(
|
|
@@ -298,7 +453,7 @@ def linfitfiltpass(
|
|
|
298
453
|
rt_floattype=rt_floattype,
|
|
299
454
|
)
|
|
300
455
|
elif coefficientsonly:
|
|
301
|
-
if
|
|
456
|
+
if not constantevs:
|
|
302
457
|
(
|
|
303
458
|
dummy,
|
|
304
459
|
meanvalue[vox],
|
|
@@ -377,22 +532,40 @@ def linfitfiltpass(
|
|
|
377
532
|
rt_floattype=rt_floattype,
|
|
378
533
|
)
|
|
379
534
|
elif coefficientsonly:
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
535
|
+
if not constantevs:
|
|
536
|
+
(
|
|
537
|
+
dummy,
|
|
538
|
+
meanvalue[timepoint],
|
|
539
|
+
rvalue[timepoint],
|
|
540
|
+
r2value[timepoint],
|
|
541
|
+
fitcoeff[timepoint],
|
|
542
|
+
fitNorm[timepoint],
|
|
543
|
+
dummy,
|
|
544
|
+
dummy,
|
|
545
|
+
) = _procOneRegressionFitItem(
|
|
546
|
+
timepoint,
|
|
547
|
+
theevs[:, timepoint],
|
|
548
|
+
thedata,
|
|
549
|
+
rt_floatset=rt_floatset,
|
|
550
|
+
rt_floattype=rt_floattype,
|
|
551
|
+
)
|
|
552
|
+
else:
|
|
553
|
+
(
|
|
554
|
+
dummy,
|
|
555
|
+
meanvalue[timepoint],
|
|
556
|
+
rvalue[timepoint],
|
|
557
|
+
r2value[timepoint],
|
|
558
|
+
fitcoeff[timepoint],
|
|
559
|
+
fitNorm[timepoint],
|
|
560
|
+
dummy,
|
|
561
|
+
dummy,
|
|
562
|
+
) = _procOneRegressionFitItem(
|
|
563
|
+
timepoint,
|
|
564
|
+
theevs,
|
|
565
|
+
thedata,
|
|
566
|
+
rt_floatset=rt_floatset,
|
|
567
|
+
rt_floattype=rt_floattype,
|
|
568
|
+
)
|
|
396
569
|
else:
|
|
397
570
|
(
|
|
398
571
|
dummy,
|
|
@@ -410,30 +583,56 @@ def linfitfiltpass(
|
|
|
410
583
|
rt_floatset=rt_floatset,
|
|
411
584
|
rt_floattype=rt_floattype,
|
|
412
585
|
)
|
|
586
|
+
|
|
413
587
|
itemstotal += 1
|
|
414
588
|
if showprogressbar:
|
|
415
589
|
print()
|
|
416
590
|
return itemstotal
|
|
417
591
|
|
|
418
592
|
|
|
419
|
-
def makevoxelspecificderivs(theevs, nderivs=1, debug=False):
|
|
420
|
-
|
|
421
|
-
|
|
593
|
+
def makevoxelspecificderivs(theevs: NDArray, nderivs: int = 1, debug: bool = False) -> NDArray:
|
|
594
|
+
"""
|
|
595
|
+
Perform multicomponent expansion on voxel-specific explanatory variables by computing
|
|
596
|
+
derivatives up to a specified order.
|
|
597
|
+
|
|
598
|
+
This function takes an array of voxel-specific timecourses and expands each one
|
|
599
|
+
into a set of components representing the original signal and its derivatives.
|
|
600
|
+
Each component corresponds to a higher-order derivative of the signal, scaled by
|
|
601
|
+
the inverse factorial of the derivative order (Taylor series coefficients).
|
|
422
602
|
|
|
423
603
|
Parameters
|
|
424
604
|
----------
|
|
425
605
|
theevs : 2D numpy array
|
|
426
|
-
NxP array of voxel
|
|
427
|
-
|
|
606
|
+
NxP array of voxel-specific explanatory variables, where N is the number of voxels
|
|
607
|
+
and P is the number of timepoints.
|
|
608
|
+
nderivs : int, optional
|
|
609
|
+
Number of derivative components to compute for each voxel. Default is 1.
|
|
610
|
+
If 0, the original `theevs` are returned without modification.
|
|
611
|
+
debug : bool, optional
|
|
612
|
+
If True, print debugging information including input and output shapes.
|
|
613
|
+
Default is False.
|
|
428
614
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
615
|
+
Returns
|
|
616
|
+
-------
|
|
617
|
+
3D numpy array
|
|
618
|
+
Array of shape (N, P, nderivs + 1) containing the original signal and its
|
|
619
|
+
derivatives up to order `nderivs` for each voxel. The first component is the
|
|
620
|
+
original signal, followed by the first, second, ..., up to `nderivs`-th derivative.
|
|
433
621
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
622
|
+
Notes
|
|
623
|
+
-----
|
|
624
|
+
- The function uses `numpy.gradient` to compute numerical derivatives.
|
|
625
|
+
- Each derivative component is scaled by the inverse factorial of the derivative order
|
|
626
|
+
to align with Taylor series expansion coefficients.
|
|
627
|
+
- If `nderivs=0`, the function returns a copy of the input `theevs`.
|
|
628
|
+
|
|
629
|
+
Examples
|
|
630
|
+
--------
|
|
631
|
+
>>> import numpy as np
|
|
632
|
+
>>> theevs = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
|
|
633
|
+
>>> result = makevoxelspecificderivs(theevs, nderivs=2)
|
|
634
|
+
>>> print(result.shape)
|
|
635
|
+
(2, 4, 3)
|
|
437
636
|
"""
|
|
438
637
|
if debug:
|
|
439
638
|
print(f"{theevs.shape=}")
|
|
@@ -459,19 +658,86 @@ def makevoxelspecificderivs(theevs, nderivs=1, debug=False):
|
|
|
459
658
|
|
|
460
659
|
|
|
461
660
|
def confoundregress(
|
|
462
|
-
theregressors,
|
|
463
|
-
theregressorlabels,
|
|
464
|
-
thedataarray,
|
|
465
|
-
tr,
|
|
466
|
-
nprocs=1,
|
|
467
|
-
orthogonalize=True,
|
|
468
|
-
tcstart=0,
|
|
469
|
-
tcend
|
|
470
|
-
tchp=None,
|
|
471
|
-
tclp=None,
|
|
472
|
-
showprogressbar=True,
|
|
473
|
-
debug=False,
|
|
474
|
-
):
|
|
661
|
+
theregressors: NDArray,
|
|
662
|
+
theregressorlabels: list[str],
|
|
663
|
+
thedataarray: NDArray,
|
|
664
|
+
tr: float,
|
|
665
|
+
nprocs: int = 1,
|
|
666
|
+
orthogonalize: bool = True,
|
|
667
|
+
tcstart: int = 0,
|
|
668
|
+
tcend: int = -1,
|
|
669
|
+
tchp: float | None = None,
|
|
670
|
+
tclp: float | None = None,
|
|
671
|
+
showprogressbar: bool = True,
|
|
672
|
+
debug: bool = False,
|
|
673
|
+
) -> tuple[NDArray, list[str], NDArray, NDArray]:
|
|
674
|
+
"""
|
|
675
|
+
Perform confound regression on fMRI data using linear regression.
|
|
676
|
+
|
|
677
|
+
This function applies confound regression to remove noise from fMRI time series
|
|
678
|
+
by regressing out specified confounding variables (e.g., motion parameters,
|
|
679
|
+
physiological signals). It supports optional filtering, orthogonalization of
|
|
680
|
+
regressors, and parallel processing for performance.
|
|
681
|
+
|
|
682
|
+
Parameters
|
|
683
|
+
----------
|
|
684
|
+
theregressors : ndarray
|
|
685
|
+
Array of confounding variables with shape (n_regressors, n_timepoints).
|
|
686
|
+
theregressorlabels : list of str
|
|
687
|
+
List of labels corresponding to each regressor.
|
|
688
|
+
thedataarray : ndarray
|
|
689
|
+
3D or 4D array of fMRI data with shape (n_voxels, n_timepoints) or
|
|
690
|
+
(n_voxels, n_timepoints, n_volumes).
|
|
691
|
+
tr : float
|
|
692
|
+
Repetition time (TR) in seconds.
|
|
693
|
+
nprocs : int, optional
|
|
694
|
+
Number of processes to use for parallel processing. Default is 1.
|
|
695
|
+
orthogonalize : bool, optional
|
|
696
|
+
If True, orthogonalize the regressors to reduce multicollinearity.
|
|
697
|
+
Default is True.
|
|
698
|
+
tcstart : int, optional
|
|
699
|
+
Start timepoint index for regressor data. Default is 0.
|
|
700
|
+
tcend : int, optional
|
|
701
|
+
End timepoint index for regressor data. If -1, use all timepoints
|
|
702
|
+
from `tcstart`. Default is -1.
|
|
703
|
+
tchp : float, optional
|
|
704
|
+
High-pass cutoff frequency for filtering. If None, no high-pass filtering
|
|
705
|
+
is applied.
|
|
706
|
+
tclp : float, optional
|
|
707
|
+
Low-pass cutoff frequency for filtering. If None, no low-pass filtering
|
|
708
|
+
is applied.
|
|
709
|
+
showprogressbar : bool, optional
|
|
710
|
+
If True, display a progress bar during processing. Default is True.
|
|
711
|
+
debug : bool, optional
|
|
712
|
+
If True, enable debug output. Default is False.
|
|
713
|
+
|
|
714
|
+
Returns
|
|
715
|
+
-------
|
|
716
|
+
tuple of (NDArray, list of str, NDArray, NDArray)
|
|
717
|
+
- `theregressors`: Processed regressors (possibly orthogonalized).
|
|
718
|
+
- `theregressorlabels`: Updated labels for the regressors.
|
|
719
|
+
- `filtereddata`: Data with confounds removed.
|
|
720
|
+
- `r2value`: R-squared values for each voxel (or None if not computed).
|
|
721
|
+
|
|
722
|
+
Notes
|
|
723
|
+
-----
|
|
724
|
+
- The function applies standard deviation normalization to regressors for
|
|
725
|
+
numerical stability.
|
|
726
|
+
- If `orthogonalize` is True, Gram-Schmidt orthogonalization is applied to
|
|
727
|
+
the regressors.
|
|
728
|
+
- Filtering is applied using a trapezoidal filter if `tchp` or `tclp` are provided.
|
|
729
|
+
- The function uses `linfitfiltpass` internally for the actual regression.
|
|
730
|
+
|
|
731
|
+
Examples
|
|
732
|
+
--------
|
|
733
|
+
>>> regressors = np.random.rand(3, 100)
|
|
734
|
+
>>> labels = ['motion_x', 'motion_y', 'motion_z']
|
|
735
|
+
>>> data = np.random.rand(50, 100)
|
|
736
|
+
>>> tr = 2.0
|
|
737
|
+
>>> processed_regressors, labels, filtered_data, r2 = confoundregress(
|
|
738
|
+
... regressors, labels, data, tr, nprocs=4
|
|
739
|
+
... )
|
|
740
|
+
"""
|
|
475
741
|
if tcend == -1:
|
|
476
742
|
theregressors = theregressors[:, tcstart:]
|
|
477
743
|
else:
|