rapidtide 3.0.1__py3-none-any.whl → 3.0.3__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/DerivativeDelay.py +0 -4
- rapidtide/calcsimfunc.py +3 -0
- rapidtide/correlate.py +18 -1
- rapidtide/data/examples/src/testfmri +7 -4
- rapidtide/data/examples/src/testretro +15 -13
- rapidtide/happy_supportfuncs.py +70 -234
- rapidtide/helper_classes.py +4 -4
- rapidtide/io.py +21 -23
- rapidtide/maskutil.py +144 -0
- rapidtide/refinedelay.py +4 -7
- rapidtide/tests/cleanposttest +0 -1
- rapidtide/tests/test_cleanregressor.py +185 -0
- rapidtide/tests/test_fullrunrapidtide_v1.py +4 -0
- rapidtide/tests/test_fullrunrapidtide_v3.py +10 -0
- rapidtide/tests/test_fullrunrapidtide_v6.py +0 -1
- rapidtide/tests/test_fullrunrapidtide_v7.py +114 -0
- rapidtide/tests/test_io.py +58 -13
- rapidtide/tests/test_refinedelay.py +0 -3
- rapidtide/voxelData.py +126 -14
- rapidtide/workflows/cleanregressor.py +43 -6
- rapidtide/workflows/delayestimation.py +8 -13
- rapidtide/workflows/delayvar.py +11 -13
- rapidtide/workflows/happy.py +72 -179
- rapidtide/workflows/rapidtide.py +335 -329
- rapidtide/workflows/rapidtide_parser.py +115 -66
- rapidtide/workflows/regressfrommaps.py +12 -7
- rapidtide/workflows/retroregress.py +533 -337
- {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/METADATA +1 -1
- {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/RECORD +33 -31
- {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/WHEEL +1 -1
- {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/entry_points.txt +0 -0
- {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/top_level.txt +0 -0
rapidtide/tests/test_io.py
CHANGED
|
@@ -25,9 +25,17 @@ import rapidtide.io as tide_io
|
|
|
25
25
|
from rapidtide.tests.utils import create_dir, get_examples_path, get_test_temp_path, mse
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def test_io(debug=True, displayplots=False):
|
|
28
|
+
def test_io(debug=True, local=False, displayplots=False):
|
|
29
|
+
# set input and output directories
|
|
30
|
+
if local:
|
|
31
|
+
exampleroot = "../data/examples/src"
|
|
32
|
+
testtemproot = "./tmp"
|
|
33
|
+
else:
|
|
34
|
+
exampleroot = get_examples_path()
|
|
35
|
+
testtemproot = get_test_temp_path()
|
|
36
|
+
|
|
29
37
|
# create outputdir if it doesn't exist
|
|
30
|
-
create_dir(
|
|
38
|
+
create_dir(testtemproot)
|
|
31
39
|
|
|
32
40
|
# test checkifnifti
|
|
33
41
|
assert tide_io.checkifnifti("test.nii") == True
|
|
@@ -88,12 +96,12 @@ def test_io(debug=True, displayplots=False):
|
|
|
88
96
|
# test fmritimeinfo
|
|
89
97
|
fmritimeinfothresh = 1e-2
|
|
90
98
|
tr, timepoints = tide_io.fmritimeinfo(
|
|
91
|
-
os.path.join(
|
|
99
|
+
os.path.join(exampleroot, "sub-HAPPYTEST.nii.gz")
|
|
92
100
|
)
|
|
93
101
|
assert np.fabs(tr - 1.16) < fmritimeinfothresh
|
|
94
102
|
assert timepoints == 110
|
|
95
103
|
tr, timepoints = tide_io.fmritimeinfo(
|
|
96
|
-
os.path.join(
|
|
104
|
+
os.path.join(exampleroot, "sub-RAPIDTIDETEST.nii.gz")
|
|
97
105
|
)
|
|
98
106
|
assert np.fabs(tr - 1.5) < fmritimeinfothresh
|
|
99
107
|
assert timepoints == 260
|
|
@@ -101,10 +109,10 @@ def test_io(debug=True, displayplots=False):
|
|
|
101
109
|
# test niftifile reading
|
|
102
110
|
sizethresh = 1e-3
|
|
103
111
|
happy_img, happy_data, happy_hdr, happydims, happysizes = tide_io.readfromnifti(
|
|
104
|
-
os.path.join(
|
|
112
|
+
os.path.join(exampleroot, "sub-HAPPYTEST.nii.gz")
|
|
105
113
|
)
|
|
106
114
|
fmri_img, fmri_data, fmri_hdr, fmridims, fmrisizes = tide_io.readfromnifti(
|
|
107
|
-
os.path.join(
|
|
115
|
+
os.path.join(exampleroot, "sub-RAPIDTIDETEST.nii.gz")
|
|
108
116
|
)
|
|
109
117
|
targetdims = [4, 65, 89, 64, 110, 1, 1, 1]
|
|
110
118
|
targetsizes = [-1.00, 2.39583, 2.395830, 2.4, 1.16, 0.00, 0.00, 0.00]
|
|
@@ -120,7 +128,7 @@ def test_io(debug=True, displayplots=False):
|
|
|
120
128
|
# test file writing
|
|
121
129
|
datathresh = 2e-3 # relaxed threshold because sub-RAPIDTIDETEST has been converted to INT16
|
|
122
130
|
tide_io.savetonifti(
|
|
123
|
-
fmri_data, fmri_hdr, os.path.join(
|
|
131
|
+
fmri_data, fmri_hdr, os.path.join(testtemproot, "sub-RAPIDTIDETEST_copy.nii.gz")
|
|
124
132
|
)
|
|
125
133
|
(
|
|
126
134
|
fmricopy_img,
|
|
@@ -128,7 +136,7 @@ def test_io(debug=True, displayplots=False):
|
|
|
128
136
|
fmricopy_hdr,
|
|
129
137
|
fmricopydims,
|
|
130
138
|
fmricopysizes,
|
|
131
|
-
) = tide_io.readfromnifti(os.path.join(
|
|
139
|
+
) = tide_io.readfromnifti(os.path.join(testtemproot, "sub-RAPIDTIDETEST_copy.nii.gz"))
|
|
132
140
|
assert tide_io.checkspacematch(fmri_hdr, fmricopy_hdr)
|
|
133
141
|
assert tide_io.checktimematch(fmridims, fmridims)
|
|
134
142
|
assert mse(fmri_data, fmricopy_data) < datathresh
|
|
@@ -141,10 +149,10 @@ def test_io(debug=True, displayplots=False):
|
|
|
141
149
|
|
|
142
150
|
# test writing and reading text files
|
|
143
151
|
debug = False
|
|
144
|
-
DESTDIR =
|
|
145
|
-
SOURCEDIR =
|
|
152
|
+
DESTDIR = testtemproot
|
|
153
|
+
SOURCEDIR = exampleroot
|
|
146
154
|
EPSILON = 1e-5
|
|
147
|
-
numpoints =
|
|
155
|
+
numpoints = 100
|
|
148
156
|
the2darray = np.zeros((6, numpoints), dtype=float)
|
|
149
157
|
the2darray[0, :] = np.linspace(0, 1.0, numpoints, endpoint=False)
|
|
150
158
|
the2darray[1, :] = np.sin(the2darray[0, :] * 2.0 * np.pi)
|
|
@@ -174,7 +182,7 @@ def test_io(debug=True, displayplots=False):
|
|
|
174
182
|
["plaintsv", True, ".tsv.gz"],
|
|
175
183
|
]
|
|
176
184
|
|
|
177
|
-
print("writing files")
|
|
185
|
+
print("writing files as a unit")
|
|
178
186
|
for thistest in thetests:
|
|
179
187
|
thetype = thistest[0]
|
|
180
188
|
compressed = thistest[1]
|
|
@@ -218,6 +226,43 @@ def test_io(debug=True, displayplots=False):
|
|
|
218
226
|
debug=debug,
|
|
219
227
|
)
|
|
220
228
|
|
|
229
|
+
theappendtests = [
|
|
230
|
+
["bidscontinuous", False, ".tsv"],
|
|
231
|
+
["bidscontinuous", True, ".tsv.gz"],
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
print("writing files with append")
|
|
235
|
+
for thistest in theappendtests:
|
|
236
|
+
thetype = thistest[0]
|
|
237
|
+
compressed = thistest[1]
|
|
238
|
+
if compressed:
|
|
239
|
+
compname = "compressed"
|
|
240
|
+
else:
|
|
241
|
+
compname = "uncompressed"
|
|
242
|
+
|
|
243
|
+
print(f"{the2darray.shape=}")
|
|
244
|
+
thefileroot = os.path.join(DESTDIR, f"testout_withcol_{thetype}_{compname}")
|
|
245
|
+
print(f"\t writing: {thefileroot}")
|
|
246
|
+
tide_io.writebidstsv(
|
|
247
|
+
thefileroot + "_append",
|
|
248
|
+
the2darray[:5, :],
|
|
249
|
+
inputsamplerate,
|
|
250
|
+
starttime=inputstarttime,
|
|
251
|
+
columns=thecols[:5],
|
|
252
|
+
compressed=compressed,
|
|
253
|
+
debug=debug,
|
|
254
|
+
)
|
|
255
|
+
tide_io.writebidstsv(
|
|
256
|
+
thefileroot + "_append",
|
|
257
|
+
the2darray[5, :],
|
|
258
|
+
inputsamplerate,
|
|
259
|
+
starttime=inputstarttime,
|
|
260
|
+
columns=[thecols[5]],
|
|
261
|
+
compressed=compressed,
|
|
262
|
+
append=True,
|
|
263
|
+
debug=debug,
|
|
264
|
+
)
|
|
265
|
+
|
|
221
266
|
print("reading complete files")
|
|
222
267
|
for thistest in thetests:
|
|
223
268
|
thetype = thistest[0]
|
|
@@ -456,4 +501,4 @@ def test_io(debug=True, displayplots=False):
|
|
|
456
501
|
|
|
457
502
|
|
|
458
503
|
if __name__ == "__main__":
|
|
459
|
-
test_io(debug=True, displayplots=True)
|
|
504
|
+
test_io(debug=True, local=True, displayplots=True)
|
|
@@ -153,7 +153,6 @@ def eval_refinedelay(
|
|
|
153
153
|
"alwaysmultiproc": False,
|
|
154
154
|
"focaldebug": debug,
|
|
155
155
|
"fmrifreq": Fs,
|
|
156
|
-
"textio": False,
|
|
157
156
|
}
|
|
158
157
|
|
|
159
158
|
regressderivratios, regressrvalues = tide_refinedelay.getderivratios(
|
|
@@ -186,8 +185,6 @@ def eval_refinedelay(
|
|
|
186
185
|
validvoxels,
|
|
187
186
|
(xdim, ydim, slicedim),
|
|
188
187
|
patchthresh=3.0,
|
|
189
|
-
fileiscifti=False,
|
|
190
|
-
textio=False,
|
|
191
188
|
rt_floattype="float64",
|
|
192
189
|
debug=debug,
|
|
193
190
|
)
|
rapidtide/voxelData.py
CHANGED
|
@@ -16,14 +16,78 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#
|
|
18
18
|
#
|
|
19
|
+
import copy
|
|
20
|
+
|
|
19
21
|
import numpy as np
|
|
20
|
-
from tf_keras.src.layers.preprocessing.benchmarks.index_lookup_forward_benchmark import (
|
|
21
|
-
get_vocab,
|
|
22
|
-
)
|
|
23
22
|
from tqdm import tqdm
|
|
24
23
|
|
|
25
24
|
import rapidtide.filter as tide_filt
|
|
26
25
|
import rapidtide.io as tide_io
|
|
26
|
+
import rapidtide.util as tide_util
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class dataVolume:
|
|
30
|
+
xsize = None
|
|
31
|
+
ysize = None
|
|
32
|
+
numslices = None
|
|
33
|
+
numspatiallocs = None
|
|
34
|
+
timepoints = None
|
|
35
|
+
dtype = None
|
|
36
|
+
dimensions = None
|
|
37
|
+
data = None
|
|
38
|
+
data_shm = None
|
|
39
|
+
thepid = None
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
shape,
|
|
44
|
+
shared=False,
|
|
45
|
+
dtype=np.float64,
|
|
46
|
+
thepid=0,
|
|
47
|
+
):
|
|
48
|
+
if len(shape) == 3:
|
|
49
|
+
self.xsize = int(shape[0])
|
|
50
|
+
self.ysize = int(shape[1])
|
|
51
|
+
self.numslices = int(shape[2])
|
|
52
|
+
self.timepoints = 1
|
|
53
|
+
self.dimensions = 3
|
|
54
|
+
elif len(shape) == 4:
|
|
55
|
+
self.xsize = int(shape[0])
|
|
56
|
+
self.ysize = int(shape[1])
|
|
57
|
+
self.numslices = int(shape[2])
|
|
58
|
+
self.timepoints = int(shape[3])
|
|
59
|
+
self.dimensions = 4
|
|
60
|
+
else:
|
|
61
|
+
print(f"illegal shape: {shape}")
|
|
62
|
+
self.numspatiallocs = self.xsize * self.ysize * self.numslices
|
|
63
|
+
self.dtype = dtype
|
|
64
|
+
if not shared:
|
|
65
|
+
self.data = np.zeros(shape, dtype=dtype)
|
|
66
|
+
else:
|
|
67
|
+
self.data, self.data_shm = tide_util.allocshared(
|
|
68
|
+
shape, self.dtype, name=f"filtereddata_{thepid}"
|
|
69
|
+
)
|
|
70
|
+
return self.data
|
|
71
|
+
|
|
72
|
+
def byvol(self):
|
|
73
|
+
return self.data
|
|
74
|
+
|
|
75
|
+
def byslice(self):
|
|
76
|
+
if self.dimensions == 3:
|
|
77
|
+
return self.data.reshape(self.xsize * self.ysize, -1)
|
|
78
|
+
else:
|
|
79
|
+
return self.data.reshape(self.xsize * self.ysize, self.numslices, -1)
|
|
80
|
+
|
|
81
|
+
def byvoxel(self):
|
|
82
|
+
if self.dimensions == 3:
|
|
83
|
+
return self.data.reshape(self.numspatiallocs)
|
|
84
|
+
else:
|
|
85
|
+
return self.data.reshape(self.numspatiallocs, -1)
|
|
86
|
+
|
|
87
|
+
def destroy(self):
|
|
88
|
+
del self.data
|
|
89
|
+
if self.data_shm is not None:
|
|
90
|
+
tide_util.cleanup_shm(self.data_shm)
|
|
27
91
|
|
|
28
92
|
|
|
29
93
|
class VoxelData:
|
|
@@ -36,14 +100,17 @@ class VoxelData:
|
|
|
36
100
|
ysize = None
|
|
37
101
|
numslices = None
|
|
38
102
|
timepoints = None
|
|
103
|
+
realtimepoints = None
|
|
39
104
|
xdim = None
|
|
40
105
|
ydim = None
|
|
41
106
|
slicethickness = None
|
|
42
107
|
timestep = None
|
|
43
108
|
thesizes = None
|
|
44
109
|
thedims = None
|
|
110
|
+
numslicelocs = None
|
|
45
111
|
numspatiallocs = None
|
|
46
112
|
nativespaceshape = None
|
|
113
|
+
nativefmrishape = None
|
|
47
114
|
validvoxels = None
|
|
48
115
|
cifti_hdr = None
|
|
49
116
|
filetype = None
|
|
@@ -61,6 +128,7 @@ class VoxelData:
|
|
|
61
128
|
self.readdata(timestep, validstart, validend)
|
|
62
129
|
|
|
63
130
|
def readdata(self, timestep, validstart, validend):
|
|
131
|
+
# load the data
|
|
64
132
|
self.load()
|
|
65
133
|
|
|
66
134
|
if tide_io.checkiftext(self.filename):
|
|
@@ -71,7 +139,8 @@ class VoxelData:
|
|
|
71
139
|
self.xsize = self.theshape[0]
|
|
72
140
|
self.ysize = 1
|
|
73
141
|
self.numslices = 1
|
|
74
|
-
self.
|
|
142
|
+
self.numslicelocs = None
|
|
143
|
+
self.timepoints = int(self.theshape[1])
|
|
75
144
|
self.thesizes = [0, int(self.xsize), 1, 1, int(self.timepoints)]
|
|
76
145
|
self.toffset = 0.0
|
|
77
146
|
self.numspatiallocs = int(self.xsize)
|
|
@@ -81,7 +150,8 @@ class VoxelData:
|
|
|
81
150
|
if tide_io.checkifcifti(self.filename):
|
|
82
151
|
self.filetype = "cifti"
|
|
83
152
|
self.nim_affine = None
|
|
84
|
-
self.
|
|
153
|
+
self.numslicelocs = None
|
|
154
|
+
self.timepoints = int(self.nim_data.shape[1])
|
|
85
155
|
self.numspatiallocs = self.nim_data.shape[0]
|
|
86
156
|
self.nativespaceshape = (1, 1, 1, 1, self.numspatiallocs)
|
|
87
157
|
else:
|
|
@@ -90,6 +160,7 @@ class VoxelData:
|
|
|
90
160
|
self.xsize, self.ysize, self.numslices, self.timepoints = tide_io.parseniftidims(
|
|
91
161
|
self.thedims
|
|
92
162
|
)
|
|
163
|
+
self.numslicelocs = int(self.xsize) * int(self.ysize)
|
|
93
164
|
self.numspatiallocs = int(self.xsize) * int(self.ysize) * int(self.numslices)
|
|
94
165
|
self.cifti_hdr = None
|
|
95
166
|
self.nativespaceshape = (self.xsize, self.ysize, self.numslices)
|
|
@@ -120,6 +191,30 @@ class VoxelData:
|
|
|
120
191
|
self.setvalidtimes(validstart, validend)
|
|
121
192
|
self.resident = True
|
|
122
193
|
|
|
194
|
+
def copyheader(self, numtimepoints=None, tr=None, toffset=None):
|
|
195
|
+
if self.filetype == "text":
|
|
196
|
+
return None
|
|
197
|
+
else:
|
|
198
|
+
thisheader = copy.deepcopy(self.nim_hdr)
|
|
199
|
+
if self.filetype == "cifti":
|
|
200
|
+
timeindex = thisheader["dim"][0] - 1
|
|
201
|
+
spaceindex = thisheader["dim"][0]
|
|
202
|
+
thisheader["dim"][timeindex] = numtimepoints
|
|
203
|
+
thisheader["dim"][spaceindex] = self.numspatiallocs
|
|
204
|
+
else:
|
|
205
|
+
if numtimepoints is not None:
|
|
206
|
+
thisheader["dim"][4] = numtimepoints
|
|
207
|
+
if numtimepoints > 1:
|
|
208
|
+
thisheader["dim"][0] = 4
|
|
209
|
+
else:
|
|
210
|
+
thisheader["dim"][0] = 3
|
|
211
|
+
thisheader["pixdim"][4] = 1.0
|
|
212
|
+
if toffset is not None:
|
|
213
|
+
thisheader["toffset"] = toffset
|
|
214
|
+
if tr is not None:
|
|
215
|
+
thisheader["pixdim"][4] = tr
|
|
216
|
+
return thisheader
|
|
217
|
+
|
|
123
218
|
def getsizes(self):
|
|
124
219
|
return self.xdim, self.ydim, self.slicethickness, self.timestep
|
|
125
220
|
|
|
@@ -167,32 +262,48 @@ class VoxelData:
|
|
|
167
262
|
self.validend = self.timepoints - 1
|
|
168
263
|
else:
|
|
169
264
|
self.validend = validend
|
|
265
|
+
self.realtimepoints = self.validend - self.validstart + 1
|
|
266
|
+
if self.filetype == "nifti":
|
|
267
|
+
self.nativefmrishape = (self.xsize, self.ysize, self.numslices, self.realtimepoints)
|
|
268
|
+
elif self.filetype == "cifti":
|
|
269
|
+
self.nativefmrishape = (1, 1, 1, self.realtimepoints, self.numspatiallocs)
|
|
270
|
+
else:
|
|
271
|
+
self.nativefmrishape = (self.xsize, self.realtimepoints)
|
|
170
272
|
|
|
171
273
|
def setvalidvoxels(self, validvoxels):
|
|
172
274
|
self.validvoxels = validvoxels
|
|
173
275
|
self.numvalidspatiallocs = np.shape(self.validvoxels)[0]
|
|
174
276
|
|
|
175
|
-
def
|
|
277
|
+
def byvol(self):
|
|
176
278
|
if not self.resident:
|
|
177
279
|
self.load()
|
|
178
280
|
return self.nim_data
|
|
179
281
|
|
|
180
|
-
def
|
|
282
|
+
def byvoltrimmed(self):
|
|
181
283
|
if not self.resident:
|
|
182
284
|
self.load()
|
|
183
285
|
if self.filetype == "nifti":
|
|
184
286
|
return self.nim_data[:, :, :, self.validstart : self.validend + 1]
|
|
185
287
|
else:
|
|
186
|
-
return self.nim_data[:, self.validstart: self.validend + 1]
|
|
288
|
+
return self.nim_data[:, self.validstart : self.validend + 1]
|
|
289
|
+
|
|
290
|
+
def byvoxel(self):
|
|
291
|
+
return self.byvoltrimmed().reshape(self.numspatiallocs, -1)
|
|
187
292
|
|
|
188
|
-
def
|
|
189
|
-
return self.
|
|
293
|
+
def byslice(self):
|
|
294
|
+
return self.byvoltrimmed().reshape(self.numslicelocs, self.numslices, -1)
|
|
190
295
|
|
|
191
|
-
def
|
|
296
|
+
def validdata(self):
|
|
192
297
|
if self.validvoxels is None:
|
|
193
|
-
return self.
|
|
298
|
+
return self.byvoxel()
|
|
194
299
|
else:
|
|
195
|
-
return self.
|
|
300
|
+
return self.byvoxel()[self.validvoxels, :]
|
|
301
|
+
|
|
302
|
+
# def validdatabyslice(self):
|
|
303
|
+
# if self.validvoxels is None:
|
|
304
|
+
# return self.byslice()
|
|
305
|
+
# else:
|
|
306
|
+
# return self.byvoxel()[self.validvoxels, :].reshape(self.numslicelocs, self.numslices, -1)
|
|
196
307
|
|
|
197
308
|
def smooth(
|
|
198
309
|
self,
|
|
@@ -241,7 +352,7 @@ class VoxelData:
|
|
|
241
352
|
f"applying gaussian spatial filter to timepoints {self.validstart} "
|
|
242
353
|
f"to {self.validend} with sigma={gausssigma}"
|
|
243
354
|
)
|
|
244
|
-
sourcedata = self.
|
|
355
|
+
sourcedata = self.byvol()
|
|
245
356
|
for i in tqdm(
|
|
246
357
|
range(self.validstart, self.validend + 1),
|
|
247
358
|
desc="Timepoint",
|
|
@@ -271,6 +382,7 @@ class VoxelData:
|
|
|
271
382
|
print(f"\t{self.timestep=}")
|
|
272
383
|
print(f"\t{self.thesizes=}")
|
|
273
384
|
print(f"\t{self.thedims=}")
|
|
385
|
+
print(f"\t{self.numslicelocs=}")
|
|
274
386
|
print(f"\t{self.numspatiallocs=}")
|
|
275
387
|
print(f"\t{self.nativespaceshape=}")
|
|
276
388
|
print(f"\t{self.cifti_hdr=}")
|
|
@@ -51,10 +51,32 @@ def cleanregressor(
|
|
|
51
51
|
detrendorder=3,
|
|
52
52
|
windowfunc="hamming",
|
|
53
53
|
respdelete=False,
|
|
54
|
+
displayplots=False,
|
|
54
55
|
debug=False,
|
|
55
56
|
rt_floattype="float64",
|
|
56
57
|
rt_floatset=np.float64,
|
|
57
58
|
):
|
|
59
|
+
# print debugging info
|
|
60
|
+
if debug:
|
|
61
|
+
print("cleanregressor:")
|
|
62
|
+
print(f"\t{thepass=}")
|
|
63
|
+
print(f"\t{lagmininpts=}")
|
|
64
|
+
print(f"\t{lagmaxinpts=}")
|
|
65
|
+
print(f"\t{lagmin=}")
|
|
66
|
+
print(f"\t{lagmax=}")
|
|
67
|
+
print(f"\t{detrendorder=}")
|
|
68
|
+
print(f"\t{windowfunc=}")
|
|
69
|
+
print(f"\t{respdelete=}")
|
|
70
|
+
print(f"\t{check_autocorrelation=}")
|
|
71
|
+
print(f"\t{fix_autocorrelation=}")
|
|
72
|
+
print(f"\t{despeckle_thresh=}")
|
|
73
|
+
print(f"\t{lthreshval=}")
|
|
74
|
+
print(f"\t{fixdelay=}")
|
|
75
|
+
print(f"\t{check_autocorrelation=}")
|
|
76
|
+
print(f"\t{displayplots=}")
|
|
77
|
+
print(f"\t{rt_floattype=}")
|
|
78
|
+
print(f"\t{rt_floatset=}")
|
|
79
|
+
|
|
58
80
|
# check the regressor for periodic components in the passband
|
|
59
81
|
dolagmod = True
|
|
60
82
|
doreferencenotch = True
|
|
@@ -121,21 +143,33 @@ def cleanregressor(
|
|
|
121
143
|
f"searching for sidelobes with amplitude > {theampthresh} "
|
|
122
144
|
f"with abs(lag) < {thelagthresh} s"
|
|
123
145
|
)
|
|
146
|
+
if debug:
|
|
147
|
+
print(
|
|
148
|
+
(
|
|
149
|
+
f"searching for sidelobes with amplitude > {theampthresh} "
|
|
150
|
+
f"with abs(lag) < {thelagthresh} s"
|
|
151
|
+
)
|
|
152
|
+
)
|
|
124
153
|
sidelobetime, sidelobeamp = tide_corr.check_autocorrelation(
|
|
125
154
|
accheckcorrscale,
|
|
126
155
|
thexcorr,
|
|
127
156
|
acampthresh=theampthresh,
|
|
128
157
|
aclagthresh=thelagthresh,
|
|
129
158
|
detrendorder=detrendorder,
|
|
159
|
+
displayplots=displayplots,
|
|
160
|
+
debug=debug,
|
|
130
161
|
)
|
|
162
|
+
if debug:
|
|
163
|
+
print(f"check_autocorrelation returned: {sidelobetime=}, {sidelobeamp=}")
|
|
131
164
|
absmaxsigma = acwidth * 10.0
|
|
132
165
|
passsuffix = "_pass" + str(thepass)
|
|
133
166
|
if sidelobetime is not None:
|
|
134
167
|
despeckle_thresh = np.max([despeckle_thresh, sidelobetime / 2.0])
|
|
135
|
-
LGR
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
168
|
+
if LGR is not None:
|
|
169
|
+
LGR.warning(
|
|
170
|
+
f"\n\nWARNING: check_autocorrelation found bad sidelobe at {sidelobetime} "
|
|
171
|
+
f"seconds ({1.0 / sidelobetime} Hz)..."
|
|
172
|
+
)
|
|
139
173
|
# bidsify
|
|
140
174
|
"""tide_io.writebidstsv(
|
|
141
175
|
f"{outputname}_desc-movingregressor_timeseries",
|
|
@@ -160,7 +194,7 @@ def cleanregressor(
|
|
|
160
194
|
LGR.info("removing spectral component at sidelobe frequency")
|
|
161
195
|
acstopfreq = 1.0 / sidelobetime
|
|
162
196
|
acfixfilter = tide_filt.NoncausalFilter(
|
|
163
|
-
debug=
|
|
197
|
+
debug=False,
|
|
164
198
|
)
|
|
165
199
|
acfixfilter.settype("arb_stop")
|
|
166
200
|
acfixfilter.setfreqs(
|
|
@@ -175,7 +209,7 @@ def cleanregressor(
|
|
|
175
209
|
detrendorder=detrendorder,
|
|
176
210
|
)
|
|
177
211
|
cleaned_referencetc = tide_math.corrnormalize(
|
|
178
|
-
cleaned_resampref_y,
|
|
212
|
+
cleaned_resampref_y[osvalidsimcalcstart : osvalidsimcalcend + 1],
|
|
179
213
|
detrendorder=detrendorder,
|
|
180
214
|
windowfunc=windowfunc,
|
|
181
215
|
)
|
|
@@ -222,6 +256,9 @@ def cleanregressor(
|
|
|
222
256
|
cleaned_referencetc = 1.0 * referencetc
|
|
223
257
|
cleaned_nonosreferencetc = 1.0 * resampnonosref_y
|
|
224
258
|
else:
|
|
259
|
+
sidelobetime = None
|
|
260
|
+
sidelobeamp = None
|
|
261
|
+
lagmod = 1000.0
|
|
225
262
|
acwidth = None
|
|
226
263
|
absmaxsigma = None
|
|
227
264
|
cleaned_resampref_y = 1.0 * tide_math.corrnormalize(
|
|
@@ -130,7 +130,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
|
|
|
130
130
|
if optiondict["checkpoint"]:
|
|
131
131
|
outcorrarray[:, :] = 0.0
|
|
132
132
|
outcorrarray[validvoxels, :] = corrout[:, :]
|
|
133
|
-
if
|
|
133
|
+
if theinputdata.filetype == "text":
|
|
134
134
|
tide_io.writenpvecs(
|
|
135
135
|
outcorrarray.reshape(nativecorrshape),
|
|
136
136
|
f"{outputname}_corrout_prefit_pass" + str(thepass) + ".txt",
|
|
@@ -320,8 +320,8 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
|
|
|
320
320
|
if optiondict["savedespecklemasks"] and (optiondict["despeckle_passes"] > 0):
|
|
321
321
|
despecklesavemask = np.where(internaldespeckleincludemask[validvoxels] == 0.0, 0, 1)
|
|
322
322
|
if thepass == optiondict["passes"]:
|
|
323
|
-
if
|
|
324
|
-
if
|
|
323
|
+
if theinputdata.filetype != "text":
|
|
324
|
+
if theinputdata.filetype == "cifti":
|
|
325
325
|
timeindex = theheader["dim"][0] - 1
|
|
326
326
|
spaceindex = theheader["dim"][0]
|
|
327
327
|
theheader["dim"][timeindex] = 1
|
|
@@ -346,8 +346,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
|
|
|
346
346
|
nativespaceshape,
|
|
347
347
|
theheader,
|
|
348
348
|
bidsbasedict,
|
|
349
|
-
|
|
350
|
-
fileiscifti=fileiscifti,
|
|
349
|
+
filetype=theinputdata.filetype,
|
|
351
350
|
rt_floattype=rt_floattype,
|
|
352
351
|
cifti_hdr=cifti_hdr,
|
|
353
352
|
)
|
|
@@ -384,8 +383,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
|
|
|
384
383
|
nativespaceshape,
|
|
385
384
|
theheader,
|
|
386
385
|
bidsbasedict,
|
|
387
|
-
|
|
388
|
-
fileiscifti=fileiscifti,
|
|
386
|
+
filetype=theinputdata.filetype,
|
|
389
387
|
rt_floattype=rt_floattype,
|
|
390
388
|
cifti_hdr=cifti_hdr,
|
|
391
389
|
)
|
|
@@ -417,8 +415,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
|
|
|
417
415
|
nativespaceshape,
|
|
418
416
|
theheader,
|
|
419
417
|
bidsbasedict,
|
|
420
|
-
|
|
421
|
-
fileiscifti=fileiscifti,
|
|
418
|
+
filetype=theinputdata.filetype,
|
|
422
419
|
rt_floattype=rt_floattype,
|
|
423
420
|
cifti_hdr=cifti_hdr,
|
|
424
421
|
)
|
|
@@ -442,8 +439,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
|
|
|
442
439
|
nativespaceshape,
|
|
443
440
|
theheader,
|
|
444
441
|
bidsbasedict,
|
|
445
|
-
|
|
446
|
-
fileiscifti=fileiscifti,
|
|
442
|
+
filetype=theinputdata.filetype,
|
|
447
443
|
rt_floattype=rt_floattype,
|
|
448
444
|
cifti_hdr=cifti_hdr,
|
|
449
445
|
)
|
|
@@ -478,8 +474,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
|
|
|
478
474
|
nativespaceshape,
|
|
479
475
|
theheader,
|
|
480
476
|
bidsbasedict,
|
|
481
|
-
|
|
482
|
-
fileiscifti=fileiscifti,
|
|
477
|
+
filetype=theinputdata.filetype,
|
|
483
478
|
rt_floattype=rt_floattype,
|
|
484
479
|
cifti_hdr=cifti_hdr,
|
|
485
480
|
)
|
rapidtide/workflows/delayvar.py
CHANGED
|
@@ -36,6 +36,7 @@ import rapidtide.refinedelay as tide_refinedelay
|
|
|
36
36
|
import rapidtide.resample as tide_resample
|
|
37
37
|
import rapidtide.stats as tide_stats
|
|
38
38
|
import rapidtide.util as tide_util
|
|
39
|
+
import rapidtide.voxelData as tide_voxelData
|
|
39
40
|
import rapidtide.workflows.parser_funcs as pf
|
|
40
41
|
import rapidtide.workflows.regressfrommaps as tide_regressfrommaps
|
|
41
42
|
|
|
@@ -381,19 +382,19 @@ def delayvar(args):
|
|
|
381
382
|
|
|
382
383
|
# read the fmri input files
|
|
383
384
|
print("reading fmrifile")
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
)
|
|
385
|
+
theinputdata = tide_voxelData.VoxelData(args.fmrifile)
|
|
386
|
+
xsize, ysize, numslices, timepoints = theinputdata.getdims()
|
|
387
|
+
xdim, ydim, slicethickness, fmritr = theinputdata.getsizes()
|
|
388
|
+
fmri_header = theinputdata.copyheader()
|
|
389
|
+
fmri_data = theinputdata.byvol()
|
|
390
|
+
numspatiallocs = theinputdata.numspatiallocs
|
|
387
391
|
|
|
388
392
|
# create the canary file
|
|
389
393
|
Path(f"{outputname}_DELAYVARISRUNNING.txt").touch()
|
|
390
394
|
|
|
391
395
|
if args.debug:
|
|
392
396
|
print(f"{fmri_data.shape=}")
|
|
393
|
-
|
|
394
|
-
xsize, ysize, numslices, timepoints = tide_io.parseniftidims(fmri_dims)
|
|
395
|
-
numspatiallocs = int(xsize) * int(ysize) * int(numslices)
|
|
396
|
-
fmri_data_spacebytime = fmri_data.reshape((numspatiallocs, timepoints))
|
|
397
|
+
fmri_data_spacebytime = theinputdata.byvoxel()
|
|
397
398
|
if args.debug:
|
|
398
399
|
print(f"{fmri_data_spacebytime.shape=}")
|
|
399
400
|
|
|
@@ -530,7 +531,7 @@ def delayvar(args):
|
|
|
530
531
|
|
|
531
532
|
if args.windelayoffsetgausssigma < 0.0:
|
|
532
533
|
# set gausssigma automatically
|
|
533
|
-
args.windelayoffsetgausssigma = np.mean([xdim, ydim,
|
|
534
|
+
args.windelayoffsetgausssigma = np.mean([xdim, ydim, slicethickness]) / 2.0
|
|
534
535
|
|
|
535
536
|
wintrs = int(np.round(args.windowsize / fmritr, 0))
|
|
536
537
|
wintrs += wintrs % 2
|
|
@@ -590,8 +591,7 @@ def delayvar(args):
|
|
|
590
591
|
(xsize, ysize, numslices, validtimepoints),
|
|
591
592
|
theheader,
|
|
592
593
|
bidsbasedict,
|
|
593
|
-
|
|
594
|
-
fileiscifti=False,
|
|
594
|
+
filetype=theinputdata.filetype,
|
|
595
595
|
rt_floattype=rt_floattype,
|
|
596
596
|
cifti_hdr=None,
|
|
597
597
|
)
|
|
@@ -737,11 +737,9 @@ def delayvar(args):
|
|
|
737
737
|
windowedregressderivratios[:, thewin],
|
|
738
738
|
(xsize, ysize, numslices),
|
|
739
739
|
validvoxels,
|
|
740
|
-
(xdim, ydim,
|
|
740
|
+
(xdim, ydim, slicethickness),
|
|
741
741
|
gausssigma=args.windelayoffsetgausssigma,
|
|
742
742
|
patchthresh=args.delaypatchthresh,
|
|
743
|
-
fileiscifti=False,
|
|
744
|
-
textio=False,
|
|
745
743
|
rt_floattype=rt_floattype,
|
|
746
744
|
verbose=args.verbose,
|
|
747
745
|
debug=args.debug,
|