rapidtide 3.0a6__py3-none-any.whl → 3.0a8__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/OrthoImageItem.py +25 -5
- rapidtide/RapidtideDataset.py +1 -0
- rapidtide/correlate.py +7 -5
- rapidtide/data/examples/src/testfmri +3 -14
- rapidtide/data/examples/src/testhappy +7 -2
- rapidtide/happy_supportfuncs.py +77 -8
- rapidtide/helper_classes.py +10 -1
- rapidtide/io.py +4 -2
- rapidtide/simfuncfit.py +1 -1
- rapidtide/tests/test_filter.py +1 -1
- rapidtide/tests/test_fullrunhappy_v2.py +1 -1
- rapidtide/tests/test_fullrunhappy_v3.py +1 -1
- rapidtide/tests/test_fullrunhappy_v4.py +3 -1
- rapidtide/tests/test_fullrunhappy_v5.py +56 -0
- rapidtide/tidepoolTemplate_big.ui +1888 -0
- rapidtide/util.py +1 -2
- rapidtide/workflows/happy.py +122 -90
- rapidtide/workflows/happy_parser.py +24 -22
- rapidtide/workflows/simdata.py +3 -1
- rapidtide/workflows/tidepool.py +435 -282
- {rapidtide-3.0a6.dist-info → rapidtide-3.0a8.dist-info}/METADATA +3 -2
- {rapidtide-3.0a6.dist-info → rapidtide-3.0a8.dist-info}/RECORD +26 -24
- {rapidtide-3.0a6.dist-info → rapidtide-3.0a8.dist-info}/LICENSE +0 -0
- {rapidtide-3.0a6.dist-info → rapidtide-3.0a8.dist-info}/WHEEL +0 -0
- {rapidtide-3.0a6.dist-info → rapidtide-3.0a8.dist-info}/entry_points.txt +0 -0
- {rapidtide-3.0a6.dist-info → rapidtide-3.0a8.dist-info}/top_level.txt +0 -0
rapidtide/OrthoImageItem.py
CHANGED
|
@@ -25,6 +25,7 @@ import os
|
|
|
25
25
|
|
|
26
26
|
import numpy as np
|
|
27
27
|
import pyqtgraph as pg
|
|
28
|
+
from more_itertools.more import first
|
|
28
29
|
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
|
|
29
30
|
|
|
30
31
|
try:
|
|
@@ -68,7 +69,16 @@ def newColorbar(left, top, impixpervoxx, impixpervoxy, imgsize):
|
|
|
68
69
|
return thecolorbarfgwin, thecolorbarbgwin, theviewbox, colorbarvals
|
|
69
70
|
|
|
70
71
|
|
|
71
|
-
def
|
|
72
|
+
def setupViewWindow(
|
|
73
|
+
view,
|
|
74
|
+
left,
|
|
75
|
+
top,
|
|
76
|
+
impixpervoxx,
|
|
77
|
+
impixpervoxy,
|
|
78
|
+
imgsize,
|
|
79
|
+
enableMouse=False,
|
|
80
|
+
):
|
|
81
|
+
|
|
72
82
|
theviewbox = view.addViewBox(enableMouse=enableMouse, enableMenu=False, lockAspect=1.0)
|
|
73
83
|
theviewbox.setAspectLocked()
|
|
74
84
|
theviewbox.setRange(QtCore.QRectF(0, 0, imgsize, imgsize), padding=0.0, disableAutoRange=True)
|
|
@@ -146,6 +156,17 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
146
156
|
self.offsetx = self.imgsize * (0.5 - self.xfov / (2.0 * self.maxfov))
|
|
147
157
|
self.offsety = self.imgsize * (0.5 - self.yfov / (2.0 * self.maxfov))
|
|
148
158
|
self.offsetz = self.imgsize * (0.5 - self.zfov / (2.0 * self.maxfov))
|
|
159
|
+
self.axviewbox = None
|
|
160
|
+
self.corviewbox = None
|
|
161
|
+
self.sagviewbox = None
|
|
162
|
+
self.axviewwin = None
|
|
163
|
+
self.corviewwin = None
|
|
164
|
+
self.sagviewwin = None
|
|
165
|
+
self.axviewbgwin = None
|
|
166
|
+
self.corviewbgwin = None
|
|
167
|
+
self.sagviewbgwin = None
|
|
168
|
+
self.debug = True
|
|
169
|
+
self.arrangement = arrangement
|
|
149
170
|
|
|
150
171
|
if self.verbose > 1:
|
|
151
172
|
print("OrthoImageItem initialization:")
|
|
@@ -162,7 +183,6 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
162
183
|
print(" Offsets:", self.offsetx, self.offsety, self.offsetz)
|
|
163
184
|
self.buttonisdown = False
|
|
164
185
|
|
|
165
|
-
self.arrangement = arrangement
|
|
166
186
|
self.axview.setBackground(None)
|
|
167
187
|
self.axview.setRange(padding=0.0)
|
|
168
188
|
self.axview.ci.layout.setContentsMargins(0, 0, 0, 0)
|
|
@@ -182,7 +202,7 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
182
202
|
self.axviewvLine,
|
|
183
203
|
self.axviewhLine,
|
|
184
204
|
self.axviewbox,
|
|
185
|
-
) =
|
|
205
|
+
) = setupViewWindow(
|
|
186
206
|
self.axview,
|
|
187
207
|
self.offsetx,
|
|
188
208
|
self.offsety,
|
|
@@ -197,7 +217,7 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
197
217
|
self.corviewvLine,
|
|
198
218
|
self.corviewhLine,
|
|
199
219
|
self.corviewbox,
|
|
200
|
-
) =
|
|
220
|
+
) = setupViewWindow(
|
|
201
221
|
self.corview,
|
|
202
222
|
self.offsetx,
|
|
203
223
|
self.offsetz,
|
|
@@ -212,7 +232,7 @@ class OrthoImageItem(QtWidgets.QWidget):
|
|
|
212
232
|
self.sagviewvLine,
|
|
213
233
|
self.sagviewhLine,
|
|
214
234
|
self.sagviewbox,
|
|
215
|
-
) =
|
|
235
|
+
) = setupViewWindow(
|
|
216
236
|
self.sagview,
|
|
217
237
|
self.offsety,
|
|
218
238
|
self.offsetz,
|
rapidtide/RapidtideDataset.py
CHANGED
rapidtide/correlate.py
CHANGED
|
@@ -703,9 +703,12 @@ class AliasedCorrelator:
|
|
|
703
703
|
"""
|
|
704
704
|
|
|
705
705
|
def __init__(self, hiressignal, hires_Fs, numsteps):
|
|
706
|
-
self.hiressignal = tide_math.corrnormalize(hiressignal)
|
|
707
706
|
self.hires_Fs = hires_Fs
|
|
708
707
|
self.numsteps = numsteps
|
|
708
|
+
self.sethiressignal(hiressignal)
|
|
709
|
+
|
|
710
|
+
def sethiressignal(self, hiressignal):
|
|
711
|
+
self.hiressignal = tide_math.corrnormalize(hiressignal)
|
|
709
712
|
self.corrlen = len(self.hiressignal) * 2 + 1
|
|
710
713
|
self.corrx = (
|
|
711
714
|
np.linspace(0.0, self.corrlen, num=self.corrlen) / self.hires_Fs
|
|
@@ -735,10 +738,9 @@ class AliasedCorrelator:
|
|
|
735
738
|
print(offset, self.numsteps)
|
|
736
739
|
osvec = self.hiressignal * 0.0
|
|
737
740
|
osvec[offset :: self.numsteps] = loressignal[:]
|
|
738
|
-
corrfunc = (
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
)
|
|
741
|
+
corrfunc = tide_corr.fastcorrelate(
|
|
742
|
+
tide_math.corrnormalize(osvec), self.hiressignal
|
|
743
|
+
) * np.sqrt(self.numsteps)
|
|
742
744
|
return corrfunc
|
|
743
745
|
|
|
744
746
|
|
|
@@ -14,29 +14,18 @@ rapidtide \
|
|
|
14
14
|
--nprocs -1 \
|
|
15
15
|
--searchrange -5 20 \
|
|
16
16
|
--simcalcrange 50 -1 \
|
|
17
|
-
--outputlevel min \
|
|
18
17
|
--refinedelay \
|
|
19
18
|
sub-RAPIDTIDETEST.nii.gz \
|
|
20
|
-
../dst/sub-
|
|
19
|
+
../dst/sub-RAPIDTIDETEST_filt
|
|
21
20
|
|
|
22
21
|
rapidtide \
|
|
23
|
-
--spatialfilt
|
|
22
|
+
--spatialfilt 0 \
|
|
24
23
|
--nprocs -1 \
|
|
25
24
|
--searchrange -5 20 \
|
|
26
25
|
--simcalcrange 50 -1 \
|
|
27
|
-
--outputlevel min \
|
|
28
26
|
--norefinedelay \
|
|
29
27
|
sub-RAPIDTIDETEST.nii.gz \
|
|
30
|
-
../dst/sub-
|
|
31
|
-
|
|
32
|
-
rapidtide \
|
|
33
|
-
--spatialfilt 5 \
|
|
34
|
-
--nprocs -1 \
|
|
35
|
-
--searchrange -5 20 \
|
|
36
|
-
--simcalcrange 50 -1 \
|
|
37
|
-
--outputlevel min \
|
|
38
|
-
sub-RAPIDTIDETEST.nii.gz \
|
|
39
|
-
../dst/sub-RAPIDTIDETEST_noption
|
|
28
|
+
../dst/sub-RAPIDTIDETEST_nofilt
|
|
40
29
|
|
|
41
30
|
#rapidtide \
|
|
42
31
|
# --spatialfilt 5 \
|
|
@@ -65,5 +65,10 @@
|
|
|
65
65
|
happy \
|
|
66
66
|
sub-HAPPYTEST.nii.gz \
|
|
67
67
|
sub-HAPPYTEST.json \
|
|
68
|
-
../dst/
|
|
69
|
-
|
|
68
|
+
../dst/happy
|
|
69
|
+
|
|
70
|
+
happy \
|
|
71
|
+
sub-HAPPYTEST.nii.gz \
|
|
72
|
+
sub-HAPPYTEST.json \
|
|
73
|
+
../dst/happy_aliasedcorrelation \
|
|
74
|
+
--aliasedcorrelation
|
rapidtide/happy_supportfuncs.py
CHANGED
|
@@ -134,6 +134,27 @@ def calc_3d_optical_flow(video, projmask, flowhdr, outputroot, window_size=3, de
|
|
|
134
134
|
return flow_vectors
|
|
135
135
|
|
|
136
136
|
|
|
137
|
+
def phasejolt(phaseimage):
|
|
138
|
+
|
|
139
|
+
# Compute the gradient of the window in x, y, and z directions
|
|
140
|
+
grad_x, grad_y, grad_z = np.gradient(phaseimage)
|
|
141
|
+
|
|
142
|
+
# Now compute the second order gradients of the window in x, y, and z directions
|
|
143
|
+
grad_xx, grad_xy, grad_xz = np.gradient(grad_x)
|
|
144
|
+
grad_yx, grad_yy, grad_yz = np.gradient(grad_y)
|
|
145
|
+
grad_zx, grad_zy, grad_zz = np.gradient(grad_z)
|
|
146
|
+
|
|
147
|
+
# Calculate our metrics of interest
|
|
148
|
+
jump = (np.fabs(grad_x) + np.fabs(grad_y) + np.fabs(grad_z)) / 3.0
|
|
149
|
+
jolt = (
|
|
150
|
+
(np.fabs(grad_xx) + np.fabs(grad_xy) + np.fabs(grad_xz))
|
|
151
|
+
+ (np.fabs(grad_yx) + np.fabs(grad_yy) + np.fabs(grad_yz))
|
|
152
|
+
+ (np.fabs(grad_zx) + np.fabs(grad_zy) + np.fabs(grad_zz))
|
|
153
|
+
) / 9.0
|
|
154
|
+
laplacian = grad_xx + grad_yy + grad_zz
|
|
155
|
+
return (jump, jolt, laplacian)
|
|
156
|
+
|
|
157
|
+
|
|
137
158
|
def cardiacsig(thisphase, amps=(1.0, 0.0, 0.0), phases=None, overallphase=0.0):
|
|
138
159
|
total = 0.0
|
|
139
160
|
if phases is None:
|
|
@@ -145,7 +166,7 @@ def cardiacsig(thisphase, amps=(1.0, 0.0, 0.0), phases=None, overallphase=0.0):
|
|
|
145
166
|
|
|
146
167
|
def cardiacfromimage(
|
|
147
168
|
normdata_byslice,
|
|
148
|
-
|
|
169
|
+
estweights_byslice,
|
|
149
170
|
numslices,
|
|
150
171
|
timepoints,
|
|
151
172
|
tr,
|
|
@@ -182,7 +203,7 @@ def cardiacfromimage(
|
|
|
182
203
|
|
|
183
204
|
# make sure there is an appflips array
|
|
184
205
|
if appflips_byslice is None:
|
|
185
|
-
appflips_byslice =
|
|
206
|
+
appflips_byslice = estweights_byslice * 0.0 + 1.0
|
|
186
207
|
else:
|
|
187
208
|
if arteriesonly:
|
|
188
209
|
appflips_byslice[np.where(appflips_byslice > 0.0)] = 0.0
|
|
@@ -196,22 +217,22 @@ def cardiacfromimage(
|
|
|
196
217
|
if not verbose:
|
|
197
218
|
print("Averaging slices...")
|
|
198
219
|
if fliparteries:
|
|
199
|
-
|
|
220
|
+
theseweights_byslice = appflips_byslice.astype(np.float64) * estweights_byslice
|
|
200
221
|
else:
|
|
201
|
-
|
|
222
|
+
theseweights_byslice = estweights_byslice
|
|
202
223
|
for theslice in range(numslices):
|
|
203
224
|
if verbose:
|
|
204
225
|
print("Averaging slice", theslice)
|
|
205
226
|
if usemask:
|
|
206
|
-
validestvoxels = np.where(np.abs(
|
|
227
|
+
validestvoxels = np.where(np.abs(theseweights_byslice[:, theslice]) > 0)[0]
|
|
207
228
|
else:
|
|
208
|
-
validestvoxels = np.where(np.abs(
|
|
229
|
+
validestvoxels = np.where(np.abs(theseweights_byslice[:, theslice] >= 0))[0]
|
|
209
230
|
if len(validestvoxels) > 0:
|
|
210
231
|
if madnorm:
|
|
211
232
|
sliceavs[theslice, :], slicenorms[theslice] = tide_math.madnormalize(
|
|
212
233
|
np.mean(
|
|
213
234
|
normdata_byslice[validestvoxels, theslice, :]
|
|
214
|
-
*
|
|
235
|
+
* theseweights_byslice[validestvoxels, theslice, np.newaxis],
|
|
215
236
|
axis=0,
|
|
216
237
|
),
|
|
217
238
|
returnnormfac=True,
|
|
@@ -219,7 +240,7 @@ def cardiacfromimage(
|
|
|
219
240
|
else:
|
|
220
241
|
sliceavs[theslice, :] = np.mean(
|
|
221
242
|
normdata_byslice[validestvoxels, theslice, :]
|
|
222
|
-
*
|
|
243
|
+
* theseweights_byslice[validestvoxels, theslice, np.newaxis],
|
|
223
244
|
axis=0,
|
|
224
245
|
)
|
|
225
246
|
slicenorms[theslice] = 1.0
|
|
@@ -1241,3 +1262,51 @@ def phaseproject(
|
|
|
1241
1262
|
normapp_byslice[validlocs, theslice, :] = np.nan_to_num(
|
|
1242
1263
|
app_byslice[validlocs, theslice, :] / means_byslice[validlocs, theslice, None]
|
|
1243
1264
|
)
|
|
1265
|
+
return app, rawapp, corrected_rawapp, normapp, weights, cine, derivatives
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
def upsampleimage(input_data, input_hdr, numsteps, sliceoffsets, slicesamplerate, outputroot):
|
|
1269
|
+
fmri_data = input_data.byvol()
|
|
1270
|
+
timepoints = input_data.timepoints
|
|
1271
|
+
xsize = input_data.xsize
|
|
1272
|
+
ysize = input_data.ysize
|
|
1273
|
+
numslices = input_data.numslices
|
|
1274
|
+
|
|
1275
|
+
# allocate the image
|
|
1276
|
+
print(f"upsampling fmri data by a factor of {numsteps}")
|
|
1277
|
+
upsampleimage = np.zeros((xsize, ysize, numslices, numsteps * timepoints), dtype=float)
|
|
1278
|
+
upsampleimage_byslice = upsampleimage.reshape(xsize * ysize, numslices, numsteps * timepoints)
|
|
1279
|
+
|
|
1280
|
+
# demean the raw data
|
|
1281
|
+
meanfmri = fmri_data.mean(axis=1)
|
|
1282
|
+
demeaned_data = fmri_data - meanfmri[:, None]
|
|
1283
|
+
|
|
1284
|
+
# drop in the raw data
|
|
1285
|
+
for theslice in range(numslices):
|
|
1286
|
+
upsampleimage[
|
|
1287
|
+
:, :, theslice, sliceoffsets[theslice] : timepoints * numsteps : numsteps
|
|
1288
|
+
] = demeaned_data.reshape((xsize, ysize, numslices, timepoints))[:, :, theslice, :]
|
|
1289
|
+
|
|
1290
|
+
upsampleimage_byslice = upsampleimage.reshape(xsize * ysize, numslices, timepoints * numsteps)
|
|
1291
|
+
|
|
1292
|
+
# interpolate along the slice direction
|
|
1293
|
+
thedstlocs = np.linspace(0, numslices, num=len(sliceoffsets), endpoint=False)
|
|
1294
|
+
print(f"len(destlocst), destlocs: {len(thedstlocs)}, {thedstlocs}")
|
|
1295
|
+
for thetimepoint in range(0, timepoints * numsteps):
|
|
1296
|
+
thestep = thetimepoint % numsteps
|
|
1297
|
+
print(f"interpolating step {thestep}")
|
|
1298
|
+
thesrclocs = np.where(sliceoffsets == thestep)[0]
|
|
1299
|
+
print(f"timepoint: {thetimepoint}, sourcelocs: {thesrclocs}")
|
|
1300
|
+
for thexyvoxel in range(xsize * ysize):
|
|
1301
|
+
theinterps = np.interp(
|
|
1302
|
+
thedstlocs,
|
|
1303
|
+
1.0 * thesrclocs,
|
|
1304
|
+
upsampleimage_byslice[thexyvoxel, thesrclocs, thetimepoint],
|
|
1305
|
+
)
|
|
1306
|
+
upsampleimage_byslice[thexyvoxel, :, thetimepoint] = 1.0 * theinterps
|
|
1307
|
+
|
|
1308
|
+
theheader = copy.deepcopy(input_hdr)
|
|
1309
|
+
theheader["dim"][4] = timepoints * numsteps
|
|
1310
|
+
theheader["pixdim"][4] = 1.0 / slicesamplerate
|
|
1311
|
+
tide_io.savetonifti(upsampleimage, theheader, outputroot + "_upsampled")
|
|
1312
|
+
print("upsampling complete")
|
rapidtide/helper_classes.py
CHANGED
|
@@ -691,6 +691,7 @@ class SimilarityFunctionFitter:
|
|
|
691
691
|
FML_FITWIDTHHIGH = np.uint32(0x0800)
|
|
692
692
|
FML_FITLAGLOW = np.uint32(0x1000)
|
|
693
693
|
FML_FITLAGHIGH = np.uint32(0x2000)
|
|
694
|
+
FML_FITALGOFAIL = np.uint32(0x0400)
|
|
694
695
|
FML_FITFAIL = (
|
|
695
696
|
FML_FITAMPLOW
|
|
696
697
|
| FML_FITAMPHIGH
|
|
@@ -698,6 +699,7 @@ class SimilarityFunctionFitter:
|
|
|
698
699
|
| FML_FITWIDTHHIGH
|
|
699
700
|
| FML_FITLAGLOW
|
|
700
701
|
| FML_FITLAGHIGH
|
|
702
|
+
| FML_FITALGOFAIL
|
|
701
703
|
)
|
|
702
704
|
|
|
703
705
|
def __init__(
|
|
@@ -873,6 +875,8 @@ class SimilarityFunctionFitter:
|
|
|
873
875
|
reasons.append("Fit Lag too low")
|
|
874
876
|
if failreason.astype(np.uint32) & self.FML_FITLAGHIGH:
|
|
875
877
|
reasons.append("Fit Lag too high")
|
|
878
|
+
if failreason.astype(np.uint32) & self.FML_FITALGOFAIL:
|
|
879
|
+
reasons.append("Nonlinear fit failed")
|
|
876
880
|
|
|
877
881
|
if len(reasons) > 0:
|
|
878
882
|
return ", ".join(reasons)
|
|
@@ -1119,6 +1123,7 @@ class SimilarityFunctionFitter:
|
|
|
1119
1123
|
maxlag = np.fmod((1.0 * plsq[1]), self.lagmod)
|
|
1120
1124
|
maxsigma = plsq[2]
|
|
1121
1125
|
except:
|
|
1126
|
+
failreason |= self.FML_FITALGOFAIL
|
|
1122
1127
|
maxval = np.float64(0.0)
|
|
1123
1128
|
maxlag = np.float64(0.0)
|
|
1124
1129
|
maxsigma = np.float64(0.0)
|
|
@@ -1139,6 +1144,7 @@ class SimilarityFunctionFitter:
|
|
|
1139
1144
|
maxlag = np.fmod((1.0 * plsq[1]), self.lagmod)
|
|
1140
1145
|
maxsigma = plsq[2]
|
|
1141
1146
|
except:
|
|
1147
|
+
failreason |= self.FML_FITALGOFAIL
|
|
1142
1148
|
maxval = np.float64(0.0)
|
|
1143
1149
|
maxlag = np.float64(0.0)
|
|
1144
1150
|
maxsigma = np.float64(0.0)
|
|
@@ -1173,6 +1179,7 @@ class SimilarityFunctionFitter:
|
|
|
1173
1179
|
print("poly coffs:", a, b, c)
|
|
1174
1180
|
print("maxlag, maxval, maxsigma:", maxlag, maxval, maxsigma)
|
|
1175
1181
|
except np.lib.polynomial.RankWarning:
|
|
1182
|
+
failreason |= self.FML_FITALGOFAIL
|
|
1176
1183
|
maxlag = 0.0
|
|
1177
1184
|
maxval = 0.0
|
|
1178
1185
|
maxsigma = 0.0
|
|
@@ -1219,6 +1226,7 @@ class SimilarityFunctionFitter:
|
|
|
1219
1226
|
# different rules for mutual information peaks
|
|
1220
1227
|
if ((maxval - baseline) < self.lthreshval * baselinedev) or (maxval < baseline):
|
|
1221
1228
|
failreason |= self.FML_FITAMPLOW
|
|
1229
|
+
maxval_init = 0.0
|
|
1222
1230
|
if self.debug:
|
|
1223
1231
|
if (maxval - baseline) < self.lthreshval * baselinedev:
|
|
1224
1232
|
print(
|
|
@@ -1229,7 +1237,6 @@ class SimilarityFunctionFitter:
|
|
|
1229
1237
|
)
|
|
1230
1238
|
if maxval < baseline:
|
|
1231
1239
|
print("FITAMPLOW: maxval < baseline:", maxval, baseline)
|
|
1232
|
-
maxval_init = 0.0
|
|
1233
1240
|
if self.debug:
|
|
1234
1241
|
print("bad fit amp: maxval is lower than lower limit")
|
|
1235
1242
|
if (self.lagmin > maxlag) or (maxlag > self.lagmax):
|
|
@@ -1269,6 +1276,8 @@ class SimilarityFunctionFitter:
|
|
|
1269
1276
|
maxsigma = np.float64(maxsigma_init)
|
|
1270
1277
|
if failreason != self.FML_NOERROR:
|
|
1271
1278
|
maskval = np.uint16(0)
|
|
1279
|
+
else:
|
|
1280
|
+
maskval = np.uint16(1)
|
|
1272
1281
|
|
|
1273
1282
|
if self.debug or self.displayplots:
|
|
1274
1283
|
print(
|
rapidtide/io.py
CHANGED
|
@@ -355,7 +355,7 @@ def savemaplist(
|
|
|
355
355
|
themap,
|
|
356
356
|
internalspaceshape,
|
|
357
357
|
validvoxels,
|
|
358
|
-
outmaparray,
|
|
358
|
+
outmaparray.astype(themap.dtype),
|
|
359
359
|
debug=False,
|
|
360
360
|
)
|
|
361
361
|
|
|
@@ -1160,13 +1160,15 @@ def getslicetimesfromfile(slicetimename):
|
|
|
1160
1160
|
for idx, thetime in enumerate(slicetimelist):
|
|
1161
1161
|
slicetimes[idx] = float(thetime)
|
|
1162
1162
|
normalizedtotr = False
|
|
1163
|
+
fileisbidsjson = True
|
|
1163
1164
|
except KeyError:
|
|
1164
1165
|
print(slicetimename, "is not a valid BIDS sidecar file")
|
|
1165
1166
|
sys.exit()
|
|
1166
1167
|
else:
|
|
1167
1168
|
slicetimes = readvec(slicetimename)
|
|
1168
1169
|
normalizedtotr = True
|
|
1169
|
-
|
|
1170
|
+
fileisbidsjson = False
|
|
1171
|
+
return slicetimes, normalizedtotr, fileisbidsjson
|
|
1170
1172
|
|
|
1171
1173
|
|
|
1172
1174
|
def readbidssidecar(inputfilename):
|
rapidtide/simfuncfit.py
CHANGED
rapidtide/tests/test_filter.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
#
|
|
4
|
-
# Copyright 2016-
|
|
4
|
+
# Copyright 2016-2025 Blaise Frederick
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
# you may not use this file except in compliance with the License.
|
|
@@ -31,7 +31,7 @@ def test_fullrunhappy_v2(debug=False, displayplots=False):
|
|
|
31
31
|
os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
|
|
32
32
|
os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
|
|
33
33
|
os.path.join(get_test_temp_path(), "happyout2"),
|
|
34
|
-
"--
|
|
34
|
+
"--estweights",
|
|
35
35
|
os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
|
|
36
36
|
"--projmask",
|
|
37
37
|
os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
|
|
@@ -31,7 +31,7 @@ def test_fullrunhappy_v3(debug=False, displayplots=False):
|
|
|
31
31
|
os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
|
|
32
32
|
os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
|
|
33
33
|
os.path.join(get_test_temp_path(), "happyout3"),
|
|
34
|
-
"--
|
|
34
|
+
"--estweights",
|
|
35
35
|
os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
|
|
36
36
|
"--projmask",
|
|
37
37
|
os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
|
|
@@ -31,7 +31,7 @@ def test_fullrunhappy_v4(debug=False, displayplots=False):
|
|
|
31
31
|
os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
|
|
32
32
|
os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
|
|
33
33
|
os.path.join(get_test_temp_path(), "happyout4"),
|
|
34
|
-
"--
|
|
34
|
+
"--estweights",
|
|
35
35
|
os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
|
|
36
36
|
"--projmask",
|
|
37
37
|
os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
|
|
@@ -39,6 +39,8 @@ def test_fullrunhappy_v4(debug=False, displayplots=False):
|
|
|
39
39
|
"-1",
|
|
40
40
|
"--model",
|
|
41
41
|
"model_revised",
|
|
42
|
+
"--motionfile",
|
|
43
|
+
os.path.join(get_examples_path(), "sub-HAPPYTEST_mcf.par"),
|
|
42
44
|
]
|
|
43
45
|
happy_workflow.happy_main(happy_parser.process_args(inputargs=inputargs))
|
|
44
46
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2016-2024 Blaise Frederick
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
#
|
|
19
|
+
import os
|
|
20
|
+
|
|
21
|
+
import matplotlib as mpl
|
|
22
|
+
|
|
23
|
+
import rapidtide.workflows.happy as happy_workflow
|
|
24
|
+
import rapidtide.workflows.happy_parser as happy_parser
|
|
25
|
+
from rapidtide.tests.utils import get_examples_path, get_test_temp_path
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_fullrunhappy_v4(debug=False, displayplots=False):
|
|
29
|
+
# run happy
|
|
30
|
+
inputargs = [
|
|
31
|
+
os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
|
|
32
|
+
os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
|
|
33
|
+
os.path.join(get_test_temp_path(), "happyout5"),
|
|
34
|
+
"--model",
|
|
35
|
+
"model_revised",
|
|
36
|
+
"--motionfile",
|
|
37
|
+
os.path.join(get_examples_path(), "sub-HAPPYTEST_mcf.par"),
|
|
38
|
+
"--nomotderiv",
|
|
39
|
+
"--nomotorthogonalize",
|
|
40
|
+
"--motfiltorder",
|
|
41
|
+
"2",
|
|
42
|
+
"--numskip",
|
|
43
|
+
"5",
|
|
44
|
+
"--motskip",
|
|
45
|
+
"5",
|
|
46
|
+
"--motionhp",
|
|
47
|
+
"0.01",
|
|
48
|
+
"--motionlp",
|
|
49
|
+
"2.0",
|
|
50
|
+
]
|
|
51
|
+
happy_workflow.happy_main(happy_parser.process_args(inputargs=inputargs))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if __name__ == "__main__":
|
|
55
|
+
mpl.use("TkAgg")
|
|
56
|
+
test_fullrunhappy_v4(debug=True, displayplots=True)
|