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/DerivativeDelay.py
CHANGED
|
@@ -135,8 +135,6 @@ class DerivativeDelay:
|
|
|
135
135
|
(xdim, ydim, slicedim),
|
|
136
136
|
gausssigma=args.delayoffsetgausssigma,
|
|
137
137
|
patchthresh=args.delaypatchthresh,
|
|
138
|
-
fileiscifti=False,
|
|
139
|
-
textio=False,
|
|
140
138
|
rt_floattype=rt_floattype,
|
|
141
139
|
debug=args.debug,
|
|
142
140
|
)
|
|
@@ -181,8 +179,6 @@ class DerivativeDelay:
|
|
|
181
179
|
(xdim, ydim, slicedim),
|
|
182
180
|
gausssigma=args.delayoffsetgausssigma,
|
|
183
181
|
patchthresh=args.delaypatchthresh,
|
|
184
|
-
fileiscifti=False,
|
|
185
|
-
textio=False,
|
|
186
182
|
rt_floattype=rt_floattype,
|
|
187
183
|
debug=args.debug,
|
|
188
184
|
)
|
rapidtide/calcsimfunc.py
CHANGED
|
@@ -69,6 +69,7 @@ def correlationpass(
|
|
|
69
69
|
chunksize=1000,
|
|
70
70
|
rt_floatset=np.float64,
|
|
71
71
|
rt_floattype="float64",
|
|
72
|
+
debug=False,
|
|
72
73
|
):
|
|
73
74
|
"""
|
|
74
75
|
|
|
@@ -96,6 +97,8 @@ def correlationpass(
|
|
|
96
97
|
-------
|
|
97
98
|
|
|
98
99
|
"""
|
|
100
|
+
if debug:
|
|
101
|
+
print(f"calling setreftc in calcsimfunc with length {len(referencetc)}")
|
|
99
102
|
theCorrelator.setreftc(referencetc)
|
|
100
103
|
theCorrelator.setlimits(lagmininpts, lagmaxinpts)
|
|
101
104
|
|
rapidtide/correlate.py
CHANGED
|
@@ -86,11 +86,12 @@ def disablenumba():
|
|
|
86
86
|
def check_autocorrelation(
|
|
87
87
|
corrscale,
|
|
88
88
|
thexcorr,
|
|
89
|
-
delta=0.
|
|
89
|
+
delta=0.05,
|
|
90
90
|
acampthresh=0.1,
|
|
91
91
|
aclagthresh=10.0,
|
|
92
92
|
displayplots=False,
|
|
93
93
|
detrendorder=1,
|
|
94
|
+
debug=False,
|
|
94
95
|
):
|
|
95
96
|
"""Check for autocorrelation in an array.
|
|
96
97
|
|
|
@@ -110,10 +111,23 @@ def check_autocorrelation(
|
|
|
110
111
|
sidelobetime
|
|
111
112
|
sidelobeamp
|
|
112
113
|
"""
|
|
114
|
+
if debug:
|
|
115
|
+
print("check_autocorrelation:")
|
|
116
|
+
print(f"delta: {delta}")
|
|
117
|
+
print(f"acampthresh: {acampthresh}")
|
|
118
|
+
print(f"aclagthresh: {aclagthresh}")
|
|
119
|
+
print(f"displayplots: {displayplots}")
|
|
113
120
|
lookahead = 2
|
|
121
|
+
if displayplots:
|
|
122
|
+
print(f"check_autocorrelation: {displayplots=}")
|
|
123
|
+
plt.plot(corrscale, thexcorr)
|
|
124
|
+
plt.show()
|
|
114
125
|
peaks = tide_fit.peakdetect(thexcorr, x_axis=corrscale, delta=delta, lookahead=lookahead)
|
|
115
126
|
maxpeaks = np.asarray(peaks[0], dtype="float64")
|
|
116
127
|
if len(peaks[0]) > 0:
|
|
128
|
+
if debug:
|
|
129
|
+
print(f"found {len(peaks[0])} peaks")
|
|
130
|
+
print(peaks)
|
|
117
131
|
LGR.debug(peaks)
|
|
118
132
|
zeropkindex = np.argmin(abs(maxpeaks[:, 0]))
|
|
119
133
|
for i in range(zeropkindex + 1, maxpeaks.shape[0]):
|
|
@@ -155,6 +169,9 @@ def check_autocorrelation(
|
|
|
155
169
|
)
|
|
156
170
|
plt.show()
|
|
157
171
|
return sidelobetime, sidelobeamp
|
|
172
|
+
else:
|
|
173
|
+
if debug:
|
|
174
|
+
print("no peaks found")
|
|
158
175
|
return None, None
|
|
159
176
|
|
|
160
177
|
|
|
@@ -5,8 +5,11 @@ rapidtide \
|
|
|
5
5
|
--nprocs -1 \
|
|
6
6
|
--searchrange -5 20 \
|
|
7
7
|
--simcalcrange 50 -1 \
|
|
8
|
-
--outputlevel
|
|
9
|
-
--
|
|
8
|
+
--outputlevel more \
|
|
9
|
+
--dofinalrefine \
|
|
10
|
+
--graymattermask sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_GRAY \
|
|
11
|
+
--brainmask sub-RAPIDTIDETEST_brainmask.nii.gz \
|
|
12
|
+
--whitemattermask sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_WHITE \
|
|
13
|
+
--csfmask sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_CSF \
|
|
10
14
|
sub-RAPIDTIDETEST.nii.gz \
|
|
11
|
-
../dst/sub-
|
|
12
|
-
|
|
15
|
+
../dst/sub-RAPIDTIDETEST
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
rapidtide \
|
|
4
|
+
--spatialfilt -1 \
|
|
5
|
+
--nprocs -1 \
|
|
6
|
+
--searchrange -5 20 \
|
|
7
|
+
--simcalcrange 50 -1 \
|
|
8
|
+
--outputlevel more \
|
|
9
|
+
--dofinalrefine \
|
|
10
|
+
--graymattermask sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_GRAY \
|
|
11
|
+
--brainmask sub-RAPIDTIDETEST_brainmask.nii.gz \
|
|
12
|
+
--whitemattermask sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_WHITE \
|
|
13
|
+
--csfmask sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_CSF \
|
|
14
|
+
sub-RAPIDTIDETEST.nii.gz \
|
|
15
|
+
../dst/sub-RAPIDTIDETEST
|
|
12
16
|
|
|
13
17
|
##retroregress sub-RAPIDTIDETEST.nii.gz ../dst/sub-RAPIDTIDETEST --alternateoutput ../dst/0deriv --nprocs -1
|
|
14
18
|
|
|
15
19
|
retroregress \
|
|
16
20
|
sub-RAPIDTIDETEST.nii.gz \
|
|
17
21
|
../dst/sub-RAPIDTIDETEST \
|
|
18
|
-
--alternateoutput ../dst/
|
|
22
|
+
--alternateoutput ../dst/specialtest \
|
|
19
23
|
--nprocs -1 \
|
|
20
|
-
--outputlevel
|
|
21
|
-
--focaldebug \
|
|
22
|
-
--delayoffsetspatialfilt -1
|
|
24
|
+
--outputlevel normal
|
|
23
25
|
|
|
24
26
|
#retroregress sub-RAPIDTIDETEST.nii.gz ../dst/sub-RAPIDTIDETEST --alternateoutput ../dst/0deriv_refined --nprocs -1 --regressderivs 0 --makepseudofile --outputlevel max --refinedelay --nofilterwithrefineddelay
|
|
25
27
|
#retroregress sub-RAPIDTIDETEST.nii.gz ../dst/sub-RAPIDTIDETEST --alternateoutput ../dst/0deriv_refinedfit --nprocs -1 --regressderivs 0 --makepseudofile --outputlevel max --refinedelay
|
rapidtide/happy_supportfuncs.py
CHANGED
|
@@ -999,211 +999,42 @@ def circularderivs(timecourse):
|
|
|
999
999
|
|
|
1000
1000
|
|
|
1001
1001
|
def phaseproject(
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1002
|
+
input_data,
|
|
1003
|
+
demeandata_byslice,
|
|
1004
|
+
means_byslice,
|
|
1005
|
+
rawapp_byslice,
|
|
1006
|
+
app_byslice,
|
|
1007
|
+
normapp_byslice,
|
|
1008
|
+
weights_byslice,
|
|
1009
|
+
cine_byslice,
|
|
1010
|
+
projmask_byslice,
|
|
1011
|
+
derivatives_byslice,
|
|
1012
|
+
proctrs,
|
|
1009
1013
|
thispass,
|
|
1010
|
-
numpasses,
|
|
1011
1014
|
args,
|
|
1012
|
-
|
|
1013
|
-
slicesamplerate,
|
|
1014
|
-
pleth_sliceres,
|
|
1015
|
-
mrsamplerate,
|
|
1016
|
-
projmask_byslice,
|
|
1015
|
+
sliceoffsets,
|
|
1017
1016
|
cardphasevals,
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1017
|
+
outphases,
|
|
1018
|
+
appsmoothingfilter,
|
|
1019
|
+
phaseFs,
|
|
1020
|
+
thecorrfunc_byslice,
|
|
1021
|
+
waveamp_byslice,
|
|
1022
|
+
wavedelay_byslice,
|
|
1023
|
+
wavedelayCOM_byslice,
|
|
1024
|
+
corrected_rawapp_byslice,
|
|
1025
|
+
corrstartloc,
|
|
1026
|
+
correndloc,
|
|
1027
|
+
thealiasedcorrx,
|
|
1028
|
+
theAliasedCorrelator,
|
|
1024
1029
|
):
|
|
1025
|
-
xsize, ysize, numslices, timepoints =
|
|
1026
|
-
|
|
1027
|
-
tide_util.logmem("before making destination arrays")
|
|
1028
|
-
app = np.zeros((xsize, ysize, numslices, destpoints), dtype=np.float64)
|
|
1029
|
-
app_byslice = app.reshape((xsize * ysize, numslices, destpoints))
|
|
1030
|
-
cine = np.zeros((xsize, ysize, numslices, destpoints), dtype=np.float64)
|
|
1031
|
-
cine_byslice = cine.reshape((xsize * ysize, numslices, destpoints))
|
|
1032
|
-
rawapp = np.zeros((xsize, ysize, numslices, destpoints), dtype=np.float64)
|
|
1033
|
-
rawapp_byslice = rawapp.reshape((xsize * ysize, numslices, destpoints))
|
|
1034
|
-
corrected_rawapp = np.zeros((xsize, ysize, numslices, destpoints), dtype=np.float64)
|
|
1035
|
-
corrected_rawapp_byslice = rawapp.reshape((xsize * ysize, numslices, destpoints))
|
|
1036
|
-
normapp = np.zeros((xsize, ysize, numslices, destpoints), dtype=np.float64)
|
|
1037
|
-
normapp_byslice = normapp.reshape((xsize * ysize, numslices, destpoints))
|
|
1038
|
-
weights = np.zeros((xsize, ysize, numslices, destpoints), dtype=np.float64)
|
|
1039
|
-
weight_byslice = weights.reshape((xsize * ysize, numslices, destpoints))
|
|
1040
|
-
derivatives = np.zeros((xsize, ysize, numslices, 4), dtype=np.float64)
|
|
1041
|
-
derivatives_byslice = derivatives.reshape((xsize * ysize, numslices, 4))
|
|
1042
|
-
|
|
1043
|
-
timings.append(["Output arrays allocated" + passstring, time.time(), None, None])
|
|
1044
|
-
|
|
1045
|
-
if centric:
|
|
1046
|
-
outphases = np.linspace(-np.pi, np.pi, num=destpoints, endpoint=False)
|
|
1047
|
-
else:
|
|
1048
|
-
outphases = np.linspace(0.0, 2.0 * np.pi, num=destpoints, endpoint=False)
|
|
1049
|
-
phasestep = outphases[1] - outphases[0]
|
|
1050
|
-
|
|
1051
|
-
#######################################################################################################
|
|
1052
|
-
#
|
|
1053
|
-
# now do the phase projection
|
|
1054
|
-
#
|
|
1055
|
-
#
|
|
1056
|
-
datatoproject_byslice = datatoproject.reshape((xsize * ysize, numslices, timepoints))
|
|
1057
|
-
means_byslice = means.reshape((xsize * ysize, numslices))
|
|
1058
|
-
|
|
1059
|
-
timings.append(["Phase projection to image started" + passstring, time.time(), None, None])
|
|
1060
|
-
print("Starting phase projection")
|
|
1061
|
-
proctrs = range(timepoints) # proctrs is the list of all fmri trs to be projected
|
|
1062
|
-
procpoints = range(
|
|
1063
|
-
timepoints * numsteps
|
|
1064
|
-
) # procpoints is the list of all sliceres datapoints to be projected
|
|
1065
|
-
if badpointlist is not None:
|
|
1066
|
-
censortrs = np.zeros(timepoints, dtype="int")
|
|
1067
|
-
censorpoints = np.zeros(timepoints * numsteps, dtype="int")
|
|
1068
|
-
censortrs[np.where(badpointlist > 0.0)[0] // numsteps] = 1
|
|
1069
|
-
censorpoints[np.where(badpointlist > 0.0)[0]] = 1
|
|
1070
|
-
proctrs = np.where(censortrs < 1)[0]
|
|
1071
|
-
procpoints = np.where(censorpoints < 1)[0]
|
|
1072
|
-
|
|
1073
|
-
# do phase averaging
|
|
1074
|
-
app_bypoint = cardiaccycleaverage(
|
|
1075
|
-
instantaneous_cardiacphase,
|
|
1076
|
-
outphases,
|
|
1077
|
-
cardfromfmri_sliceres,
|
|
1078
|
-
procpoints,
|
|
1079
|
-
congridbins,
|
|
1080
|
-
gridkernel,
|
|
1081
|
-
centric,
|
|
1082
|
-
cyclic=True,
|
|
1083
|
-
)
|
|
1084
|
-
if thispass == numpasses - 1:
|
|
1085
|
-
tide_io.writebidstsv(
|
|
1086
|
-
outputroot + "_desc-cardiaccyclefromfmri_timeseries",
|
|
1087
|
-
app_bypoint,
|
|
1088
|
-
1.0 / (outphases[1] - outphases[0]),
|
|
1089
|
-
starttime=outphases[0],
|
|
1090
|
-
columns=["cardiaccyclefromfmri"],
|
|
1091
|
-
append=False,
|
|
1092
|
-
debug=args.debug,
|
|
1093
|
-
)
|
|
1094
|
-
|
|
1095
|
-
# now do time averaging
|
|
1096
|
-
lookaheadval = int(slicesamplerate / 4.0)
|
|
1097
|
-
print("lookaheadval = ", lookaheadval)
|
|
1098
|
-
wrappedcardiacphase = tide_math.phasemod(instantaneous_cardiacphase, centric=centric)
|
|
1099
|
-
max_peaks, min_peaks = tide_fit.peakdetect(wrappedcardiacphase, lookahead=lookaheadval)
|
|
1100
|
-
# start on a maximum
|
|
1101
|
-
if max_peaks[0][0] > min_peaks[0][0]:
|
|
1102
|
-
min_peaks = min_peaks[1:]
|
|
1103
|
-
# work only with pairs
|
|
1104
|
-
if len(max_peaks) > len(min_peaks):
|
|
1105
|
-
max_peaks = max_peaks[:-1]
|
|
1106
|
-
|
|
1107
|
-
zerophaselocs = []
|
|
1108
|
-
for idx, peak in enumerate(max_peaks):
|
|
1109
|
-
minloc = min_peaks[idx][0]
|
|
1110
|
-
maxloc = max_peaks[idx][0]
|
|
1111
|
-
minval = min_peaks[idx][1]
|
|
1112
|
-
maxval = max_peaks[idx][1]
|
|
1113
|
-
if minloc > 0:
|
|
1114
|
-
if wrappedcardiacphase[minloc - 1] < wrappedcardiacphase[minloc]:
|
|
1115
|
-
minloc -= 1
|
|
1116
|
-
minval = wrappedcardiacphase[minloc]
|
|
1117
|
-
phasediff = minval - (maxval - 2.0 * np.pi)
|
|
1118
|
-
timediff = minloc - maxloc
|
|
1119
|
-
zerophaselocs.append(1.0 * minloc - (minval - outphases[0]) * timediff / phasediff)
|
|
1120
|
-
# print(idx, [maxloc, maxval], [minloc, minval], phasediff, timediff, zerophaselocs[-1])
|
|
1121
|
-
instantaneous_cardiactime = instantaneous_cardiacphase * 0.0
|
|
1122
|
-
|
|
1123
|
-
whichpeak = 0
|
|
1124
|
-
for t in procpoints:
|
|
1125
|
-
if whichpeak < len(zerophaselocs) - 1:
|
|
1126
|
-
if t > zerophaselocs[whichpeak + 1]:
|
|
1127
|
-
whichpeak += 1
|
|
1128
|
-
if t > zerophaselocs[whichpeak]:
|
|
1129
|
-
instantaneous_cardiactime[t] = (t - zerophaselocs[whichpeak]) / slicesamplerate
|
|
1130
|
-
# print(t, whichpeak, zerophaselocs[whichpeak], instantaneous_cardiactime[t])
|
|
1131
|
-
maxtime = (
|
|
1132
|
-
np.ceil(
|
|
1133
|
-
int(
|
|
1134
|
-
1.02
|
|
1135
|
-
* tide_stats.getfracval(instantaneous_cardiactime, 0.98)
|
|
1136
|
-
// args.pulsereconstepsize
|
|
1137
|
-
)
|
|
1138
|
-
)
|
|
1139
|
-
* args.pulsereconstepsize
|
|
1140
|
-
)
|
|
1141
|
-
outtimes = np.linspace(
|
|
1142
|
-
0.0, maxtime, num=int(maxtime / args.pulsereconstepsize), endpoint=False
|
|
1143
|
-
)
|
|
1144
|
-
atp_bypoint = cardiaccycleaverage(
|
|
1145
|
-
instantaneous_cardiactime,
|
|
1146
|
-
outtimes,
|
|
1147
|
-
cardfromfmri_sliceres,
|
|
1148
|
-
procpoints,
|
|
1149
|
-
congridbins,
|
|
1150
|
-
gridkernel,
|
|
1151
|
-
False,
|
|
1152
|
-
cyclic=True,
|
|
1153
|
-
)
|
|
1154
|
-
if thispass == numpasses - 1:
|
|
1155
|
-
tide_io.writebidstsv(
|
|
1156
|
-
outputroot + "_desc-cardpulsefromfmri_timeseries",
|
|
1157
|
-
atp_bypoint,
|
|
1158
|
-
1.0 / (outtimes[1] - outtimes[0]),
|
|
1159
|
-
starttime=outtimes[0],
|
|
1160
|
-
columns=["pulsefromfmri"],
|
|
1161
|
-
append=False,
|
|
1162
|
-
debug=args.debug,
|
|
1163
|
-
)
|
|
1164
|
-
|
|
1165
|
-
if not args.verbose:
|
|
1166
|
-
print("Phase projecting...")
|
|
1167
|
-
|
|
1168
|
-
# make a lowpass filter for the projected data. Limit frequency to 3 cycles per 2pi (1/6th Fs)
|
|
1169
|
-
phaseFs = 1.0 / phasestep
|
|
1170
|
-
phaseFc = phaseFs / 6.0
|
|
1171
|
-
appsmoothingfilter = tide_filt.NoncausalFilter("arb", cyclic=True, padtime=0.0)
|
|
1172
|
-
appsmoothingfilter.setfreqs(0.0, 0.0, phaseFc, phaseFc)
|
|
1173
|
-
|
|
1174
|
-
# setup for aliased correlation if we're going to do it
|
|
1175
|
-
if args.doaliasedcorrelation and (thispass == numpasses - 1):
|
|
1176
|
-
if args.cardiacfilename:
|
|
1177
|
-
signal_sliceres = pleth_sliceres
|
|
1178
|
-
# signal_stdres = pleth_stdres
|
|
1179
|
-
else:
|
|
1180
|
-
signal_sliceres = cardfromfmri_sliceres
|
|
1181
|
-
# signal_stdres = dlfilteredcard_stdres
|
|
1182
|
-
corrsearchvals = (
|
|
1183
|
-
np.linspace(0.0, args.aliasedcorrelationwidth, num=args.aliasedcorrelationpts)
|
|
1184
|
-
- args.aliasedcorrelationwidth / 2.0
|
|
1185
|
-
)
|
|
1186
|
-
theAliasedCorrelator = tide_corr.AliasedCorrelator(
|
|
1187
|
-
signal_sliceres,
|
|
1188
|
-
slicesamplerate,
|
|
1189
|
-
numsteps,
|
|
1190
|
-
)
|
|
1191
|
-
thecorrfunc = np.zeros(
|
|
1192
|
-
(xsize, ysize, numslices, args.aliasedcorrelationpts), dtype=np.float64
|
|
1193
|
-
)
|
|
1194
|
-
thecorrfunc_byslice = thecorrfunc.reshape(
|
|
1195
|
-
(xsize * ysize, numslices, args.aliasedcorrelationpts)
|
|
1196
|
-
)
|
|
1197
|
-
wavedelay = np.zeros((xsize, ysize, numslices), dtype=np.float64)
|
|
1198
|
-
wavedelay_byslice = wavedelay.reshape((xsize * ysize, numslices))
|
|
1199
|
-
waveamp = np.zeros((xsize, ysize, numslices), dtype=np.float64)
|
|
1200
|
-
waveamp_byslice = waveamp.reshape((xsize * ysize, numslices))
|
|
1030
|
+
xsize, ysize, numslices, timepoints = input_data.getdims()
|
|
1031
|
+
fmri_data_byslice = input_data.byslice()
|
|
1201
1032
|
|
|
1202
|
-
# now project the data
|
|
1203
1033
|
for theslice in tqdm(
|
|
1204
1034
|
range(numslices),
|
|
1205
1035
|
desc="Slice",
|
|
1206
1036
|
unit="slices",
|
|
1037
|
+
disable=(not args.showprogressbar),
|
|
1207
1038
|
):
|
|
1208
1039
|
if args.verbose:
|
|
1209
1040
|
print("Phase projecting for slice", theslice)
|
|
@@ -1211,33 +1042,31 @@ def phaseproject(
|
|
|
1211
1042
|
# indexlist = range(0, len(cardphasevals[theslice, :]))
|
|
1212
1043
|
if len(validlocs) > 0:
|
|
1213
1044
|
for t in proctrs:
|
|
1214
|
-
filteredmr = -
|
|
1215
|
-
cinemr =
|
|
1216
|
-
datatoproject_byslice[validlocs, theslice, t]
|
|
1217
|
-
+ means_byslice[validlocs, theslice, t]
|
|
1218
|
-
)
|
|
1045
|
+
filteredmr = -demeandata_byslice[validlocs, theslice, t]
|
|
1046
|
+
cinemr = fmri_data_byslice[validlocs, theslice, t]
|
|
1219
1047
|
thevals, theweights, theindices = tide_resample.congrid(
|
|
1220
1048
|
outphases,
|
|
1221
1049
|
cardphasevals[theslice, t],
|
|
1222
1050
|
1.0,
|
|
1223
|
-
congridbins,
|
|
1224
|
-
kernel=gridkernel,
|
|
1051
|
+
args.congridbins,
|
|
1052
|
+
kernel=args.gridkernel,
|
|
1225
1053
|
cyclic=True,
|
|
1226
1054
|
)
|
|
1227
1055
|
for i in range(len(theindices)):
|
|
1228
|
-
|
|
1229
|
-
rawapp_byslice[validlocs, theslice, theindices[i]] += (
|
|
1230
|
-
|
|
1231
|
-
)
|
|
1056
|
+
weights_byslice[validlocs, theslice, theindices[i]] += theweights[i]
|
|
1057
|
+
# rawapp_byslice[validlocs, theslice, theindices[i]] += (
|
|
1058
|
+
# theweights[i] * filteredmr
|
|
1059
|
+
# )
|
|
1060
|
+
rawapp_byslice[validlocs, theslice, theindices[i]] += filteredmr
|
|
1232
1061
|
cine_byslice[validlocs, theslice, theindices[i]] += theweights[i] * cinemr
|
|
1233
|
-
for d in range(destpoints):
|
|
1234
|
-
if
|
|
1235
|
-
|
|
1062
|
+
for d in range(args.destpoints):
|
|
1063
|
+
if weights_byslice[validlocs[0], theslice, d] == 0.0:
|
|
1064
|
+
weights_byslice[validlocs, theslice, d] = 1.0
|
|
1236
1065
|
rawapp_byslice[validlocs, theslice, :] = np.nan_to_num(
|
|
1237
|
-
rawapp_byslice[validlocs, theslice, :] /
|
|
1066
|
+
rawapp_byslice[validlocs, theslice, :] / weights_byslice[validlocs, theslice, :]
|
|
1238
1067
|
)
|
|
1239
1068
|
cine_byslice[validlocs, theslice, :] = np.nan_to_num(
|
|
1240
|
-
cine_byslice[validlocs, theslice, :] /
|
|
1069
|
+
cine_byslice[validlocs, theslice, :] / weights_byslice[validlocs, theslice, :]
|
|
1241
1070
|
)
|
|
1242
1071
|
else:
|
|
1243
1072
|
rawapp_byslice[:, theslice, :] = 0.0
|
|
@@ -1260,33 +1089,41 @@ def phaseproject(
|
|
|
1260
1089
|
corrected_rawapp_byslice[validlocs, theslice, :] = (
|
|
1261
1090
|
rawapp_byslice[validlocs, theslice, :] - timecoursemean
|
|
1262
1091
|
) * appflips_byslice[validlocs, theslice, None] + timecoursemean
|
|
1263
|
-
if args.doaliasedcorrelation and (thispass
|
|
1092
|
+
if args.doaliasedcorrelation and (thispass > 0):
|
|
1264
1093
|
for theloc in validlocs:
|
|
1265
1094
|
thecorrfunc_byslice[theloc, theslice, :] = theAliasedCorrelator.apply(
|
|
1266
1095
|
-appflips_byslice[theloc, theslice]
|
|
1267
|
-
*
|
|
1268
|
-
|
|
1269
|
-
)
|
|
1096
|
+
* demeandata_byslice[theloc, theslice, :],
|
|
1097
|
+
int(sliceoffsets[theslice]),
|
|
1098
|
+
)[corrstartloc : correndloc + 1]
|
|
1270
1099
|
maxloc = np.argmax(thecorrfunc_byslice[theloc, theslice, :])
|
|
1271
|
-
wavedelay_byslice[theloc, theslice] =
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
]
|
|
1100
|
+
wavedelay_byslice[theloc, theslice] = (
|
|
1101
|
+
thealiasedcorrx[corrstartloc : correndloc + 1]
|
|
1102
|
+
)[maxloc]
|
|
1103
|
+
waveamp_byslice[theloc, theslice] = np.fabs(
|
|
1104
|
+
thecorrfunc_byslice[theloc, theslice, maxloc]
|
|
1105
|
+
)
|
|
1106
|
+
wavedelayCOM_byslice[theloc, theslice] = theCOM(
|
|
1107
|
+
thealiasedcorrx[corrstartloc : correndloc + 1],
|
|
1108
|
+
np.fabs(thecorrfunc_byslice[theloc, theslice, :]),
|
|
1109
|
+
)
|
|
1275
1110
|
else:
|
|
1276
1111
|
corrected_rawapp_byslice[validlocs, theslice, :] = rawapp_byslice[
|
|
1277
1112
|
validlocs, theslice, :
|
|
1278
1113
|
]
|
|
1279
|
-
if args.doaliasedcorrelation and (thispass
|
|
1114
|
+
if args.doaliasedcorrelation and (thispass > 0):
|
|
1280
1115
|
for theloc in validlocs:
|
|
1281
1116
|
thecorrfunc_byslice[theloc, theslice, :] = theAliasedCorrelator.apply(
|
|
1282
|
-
-
|
|
1283
|
-
|
|
1284
|
-
)
|
|
1117
|
+
-demeandata_byslice[theloc, theslice, :],
|
|
1118
|
+
int(sliceoffsets[theslice]),
|
|
1119
|
+
)[corrstartloc : correndloc + 1]
|
|
1285
1120
|
maxloc = np.argmax(np.abs(thecorrfunc_byslice[theloc, theslice, :]))
|
|
1286
|
-
wavedelay_byslice[theloc, theslice] =
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
]
|
|
1121
|
+
wavedelay_byslice[theloc, theslice] = (
|
|
1122
|
+
thealiasedcorrx[corrstartloc : correndloc + 1]
|
|
1123
|
+
)[maxloc]
|
|
1124
|
+
waveamp_byslice[theloc, theslice] = np.fabs(
|
|
1125
|
+
thecorrfunc_byslice[theloc, theslice, maxloc]
|
|
1126
|
+
)
|
|
1290
1127
|
timecoursemin = np.min(corrected_rawapp_byslice[validlocs, theslice, :], axis=1).reshape(
|
|
1291
1128
|
(-1, 1)
|
|
1292
1129
|
)
|
|
@@ -1296,10 +1133,10 @@ def phaseproject(
|
|
|
1296
1133
|
normapp_byslice[validlocs, theslice, :] = np.nan_to_num(
|
|
1297
1134
|
app_byslice[validlocs, theslice, :] / means_byslice[validlocs, theslice, None]
|
|
1298
1135
|
)
|
|
1299
|
-
return
|
|
1136
|
+
return appflips_byslice
|
|
1300
1137
|
|
|
1301
1138
|
|
|
1302
|
-
def upsampleimage(input_data,
|
|
1139
|
+
def upsampleimage(input_data, numsteps, sliceoffsets, slicesamplerate, outputroot):
|
|
1303
1140
|
fmri_data = input_data.byvol()
|
|
1304
1141
|
timepoints = input_data.timepoints
|
|
1305
1142
|
xsize = input_data.xsize
|
|
@@ -1309,7 +1146,6 @@ def upsampleimage(input_data, input_hdr, numsteps, sliceoffsets, slicesamplerate
|
|
|
1309
1146
|
# allocate the image
|
|
1310
1147
|
print(f"upsampling fmri data by a factor of {numsteps}")
|
|
1311
1148
|
upsampleimage = np.zeros((xsize, ysize, numslices, numsteps * timepoints), dtype=float)
|
|
1312
|
-
upsampleimage_byslice = upsampleimage.reshape(xsize * ysize, numslices, numsteps * timepoints)
|
|
1313
1149
|
|
|
1314
1150
|
# demean the raw data
|
|
1315
1151
|
meanfmri = fmri_data.mean(axis=1)
|
|
@@ -1339,8 +1175,8 @@ def upsampleimage(input_data, input_hdr, numsteps, sliceoffsets, slicesamplerate
|
|
|
1339
1175
|
)
|
|
1340
1176
|
upsampleimage_byslice[thexyvoxel, :, thetimepoint] = 1.0 * theinterps
|
|
1341
1177
|
|
|
1342
|
-
theheader =
|
|
1343
|
-
|
|
1344
|
-
|
|
1178
|
+
theheader = input_data.copyheader(
|
|
1179
|
+
numtimepoints=(timepoints * numsteps), tr=(1.0 / slicesamplerate)
|
|
1180
|
+
)
|
|
1345
1181
|
tide_io.savetonifti(upsampleimage, theheader, outputroot + "_upsampled")
|
|
1346
1182
|
print("upsampling complete")
|
rapidtide/helper_classes.py
CHANGED
|
@@ -310,7 +310,7 @@ class MutualInformationator(SimilarityFunctionator):
|
|
|
310
310
|
def run(self, thetc, locs=None, trim=True, gettimeaxis=True):
|
|
311
311
|
if len(thetc) != len(self.reftc):
|
|
312
312
|
print(
|
|
313
|
-
"timecourses are of different sizes:",
|
|
313
|
+
"MutualInformationator: timecourses are of different sizes:",
|
|
314
314
|
len(thetc),
|
|
315
315
|
"!=",
|
|
316
316
|
len(self.reftc),
|
|
@@ -434,7 +434,7 @@ class Correlator(SimilarityFunctionator):
|
|
|
434
434
|
def run(self, thetc, trim=True):
|
|
435
435
|
if len(thetc) != len(self.reftc):
|
|
436
436
|
print(
|
|
437
|
-
"timecourses are of different sizes:",
|
|
437
|
+
"Correlator: timecourses are of different sizes:",
|
|
438
438
|
len(thetc),
|
|
439
439
|
"!=",
|
|
440
440
|
len(self.reftc),
|
|
@@ -580,7 +580,7 @@ class Coherer:
|
|
|
580
580
|
def run(self, thetc, trim=True, alt=False):
|
|
581
581
|
if len(thetc) != len(self.reftc):
|
|
582
582
|
print(
|
|
583
|
-
"timecourses are of different sizes:",
|
|
583
|
+
"Coherer: timecourses are of different sizes:",
|
|
584
584
|
len(thetc),
|
|
585
585
|
"!=",
|
|
586
586
|
len(self.reftc),
|
|
@@ -1076,7 +1076,7 @@ class SimilarityFunctionFitter:
|
|
|
1076
1076
|
maxval_init = 0.0
|
|
1077
1077
|
if self.debug:
|
|
1078
1078
|
print("bad initial amp:", maxval_init, "is less than 0.0")
|
|
1079
|
-
if maxval_init > 1.0:
|
|
1079
|
+
if (maxval_init > 1.0) and self.enforcethresh:
|
|
1080
1080
|
failreason |= self.FML_INITAMPHIGH
|
|
1081
1081
|
maxval_init = 1.0
|
|
1082
1082
|
if self.debug:
|
rapidtide/io.py
CHANGED
|
@@ -139,7 +139,7 @@ def parseniftidims(thedims):
|
|
|
139
139
|
nx, ny, nz, nt : int
|
|
140
140
|
Number of points along each dimension
|
|
141
141
|
"""
|
|
142
|
-
return thedims[1], thedims[2], thedims[3], thedims[4]
|
|
142
|
+
return int(thedims[1]), int(thedims[2]), int(thedims[3]), int(thedims[4])
|
|
143
143
|
|
|
144
144
|
|
|
145
145
|
# sizes are the mapping between voxels and physical coordinates
|
|
@@ -263,32 +263,30 @@ def niftihdrfromarray(data):
|
|
|
263
263
|
|
|
264
264
|
def makedestarray(
|
|
265
265
|
destshape,
|
|
266
|
-
|
|
267
|
-
fileiscifti=False,
|
|
266
|
+
filetype="nifti",
|
|
268
267
|
rt_floattype="float64",
|
|
269
268
|
):
|
|
270
|
-
if
|
|
269
|
+
if filetype == "text":
|
|
271
270
|
try:
|
|
272
271
|
internalspaceshape = destshape[0]
|
|
273
272
|
timedim = destshape[1]
|
|
274
273
|
except TypeError:
|
|
275
274
|
internalspaceshape = destshape
|
|
276
275
|
timedim = None
|
|
276
|
+
elif filetype == "cifti":
|
|
277
|
+
spaceindex = len(destshape) - 1
|
|
278
|
+
timeindex = spaceindex - 1
|
|
279
|
+
internalspaceshape = destshape[spaceindex]
|
|
280
|
+
if destshape[timeindex] > 1:
|
|
281
|
+
timedim = destshape[timeindex]
|
|
282
|
+
else:
|
|
283
|
+
timedim = None
|
|
277
284
|
else:
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
internalspaceshape = destshape[spaceindex]
|
|
282
|
-
if destshape[timeindex] > 1:
|
|
283
|
-
timedim = destshape[timeindex]
|
|
284
|
-
else:
|
|
285
|
-
timedim = None
|
|
285
|
+
internalspaceshape = int(destshape[0]) * int(destshape[1]) * int(destshape[2])
|
|
286
|
+
if len(destshape) == 3:
|
|
287
|
+
timedim = None
|
|
286
288
|
else:
|
|
287
|
-
|
|
288
|
-
if len(destshape) == 3:
|
|
289
|
-
timedim = None
|
|
290
|
-
else:
|
|
291
|
-
timedim = destshape[3]
|
|
289
|
+
timedim = destshape[3]
|
|
292
290
|
if timedim is None:
|
|
293
291
|
outmaparray = np.zeros(internalspaceshape, dtype=rt_floattype)
|
|
294
292
|
else:
|
|
@@ -329,8 +327,7 @@ def savemaplist(
|
|
|
329
327
|
destshape,
|
|
330
328
|
theheader,
|
|
331
329
|
bidsbasedict,
|
|
332
|
-
|
|
333
|
-
fileiscifti=False,
|
|
330
|
+
filetype="nifti",
|
|
334
331
|
rt_floattype="float64",
|
|
335
332
|
cifti_hdr=None,
|
|
336
333
|
savejson=True,
|
|
@@ -338,8 +335,7 @@ def savemaplist(
|
|
|
338
335
|
):
|
|
339
336
|
outmaparray, internalspaceshape = makedestarray(
|
|
340
337
|
destshape,
|
|
341
|
-
|
|
342
|
-
fileiscifti=fileiscifti,
|
|
338
|
+
filetype=filetype,
|
|
343
339
|
rt_floattype=rt_floattype,
|
|
344
340
|
)
|
|
345
341
|
for themap, mapsuffix, maptype, theunit, thedescription in maplist:
|
|
@@ -365,7 +361,7 @@ def savemaplist(
|
|
|
365
361
|
bidsdict["Units"] = theunit
|
|
366
362
|
if thedescription is not None:
|
|
367
363
|
bidsdict["Description"] = thedescription
|
|
368
|
-
if
|
|
364
|
+
if filetype == "text":
|
|
369
365
|
writenpvecs(
|
|
370
366
|
outmaparray.reshape(destshape),
|
|
371
367
|
f"{outputname}_{mapsuffix}.txt",
|
|
@@ -374,7 +370,7 @@ def savemaplist(
|
|
|
374
370
|
savename = f"{outputname}_desc-{mapsuffix}_{maptype}"
|
|
375
371
|
if savejson:
|
|
376
372
|
writedicttojson(bidsdict, savename + ".json")
|
|
377
|
-
if
|
|
373
|
+
if filetype == "nifti":
|
|
378
374
|
savetonifti(outmaparray.reshape(destshape), theheader, savename)
|
|
379
375
|
else:
|
|
380
376
|
isseries = len(outmaparray.shape) != 1
|
|
@@ -2000,12 +1996,14 @@ def colspectolist(colspec, debug=False):
|
|
|
2000
1996
|
("APARC_CORTGRAY", "1000-1035,2000-2035"),
|
|
2001
1997
|
("APARC_GRAY", "8-13,17-20,26-28,47-56,58-60,96,97,1000-1035,2000-2035"),
|
|
2002
1998
|
("APARC_WHITE", "2,7,41,46,177,219,3000-3035,4000-4035,5001,5002"),
|
|
1999
|
+
("APARC_CSF", "4,5,14,15,24,31,43,44,63,72"),
|
|
2003
2000
|
(
|
|
2004
2001
|
"APARC_ALLBUTCSF",
|
|
2005
2002
|
"2,7-13,17-20,26-28,41,46-56,58-60,96,97,177,219,1000-1035,2000-2035,3000-3035,4000-4035,5001,5002",
|
|
2006
2003
|
),
|
|
2007
2004
|
("SSEG_GRAY", "3,8,10-13,16-18,26,42,47,49-54,58"),
|
|
2008
2005
|
("SSEG_WHITE", "2,7,41,46"),
|
|
2006
|
+
("SSEG_CSF", "4,5,14,15,24,43,44"),
|
|
2009
2007
|
)
|
|
2010
2008
|
preprocessedranges = []
|
|
2011
2009
|
for thisrange in theranges:
|