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/util.py
CHANGED
|
@@ -26,8 +26,7 @@ import subprocess
|
|
|
26
26
|
import sys
|
|
27
27
|
import time
|
|
28
28
|
from datetime import datetime
|
|
29
|
-
from multiprocessing import
|
|
30
|
-
from os.path import split
|
|
29
|
+
from multiprocessing import shared_memory
|
|
31
30
|
|
|
32
31
|
import matplotlib.pyplot as plt
|
|
33
32
|
import numpy as np
|
rapidtide/workflows/happy.py
CHANGED
|
@@ -236,8 +236,10 @@ def happy_main(argparsingfunc):
|
|
|
236
236
|
# filter out motion regressors here
|
|
237
237
|
if args.motionfilename is not None:
|
|
238
238
|
timings.append(["Motion filtering start", time.time(), None, None])
|
|
239
|
+
motiondict = tide_io.readmotion(args.motionfilename, tr=tr)
|
|
239
240
|
confoundregressors, confoundregressorlabels = tide_fit.calcexpandedregressors(
|
|
240
|
-
|
|
241
|
+
motiondict,
|
|
242
|
+
labels=["xtrans", "ytrans", "ztrans", "xrot", "yrot", "zrot"],
|
|
241
243
|
deriv=args.motfilt_deriv,
|
|
242
244
|
order=args.motfilt_order,
|
|
243
245
|
)
|
|
@@ -284,10 +286,21 @@ def happy_main(argparsingfunc):
|
|
|
284
286
|
timings.append(["Motion filtered data saved", time.time(), numspatiallocs, "voxels"])
|
|
285
287
|
|
|
286
288
|
# get slice times
|
|
287
|
-
slicetimes, normalizedtotr = tide_io.getslicetimesfromfile(slicetimename)
|
|
289
|
+
slicetimes, normalizedtotr, fileisbidsjson = tide_io.getslicetimesfromfile(slicetimename)
|
|
288
290
|
if normalizedtotr and not args.slicetimesareinseconds:
|
|
289
291
|
slicetimes *= tr
|
|
290
|
-
|
|
292
|
+
if args.teoffset is not None:
|
|
293
|
+
teoffset = float(args.teoffset)
|
|
294
|
+
else:
|
|
295
|
+
if fileisbidsjson:
|
|
296
|
+
jsoninfodict = tide_io.readdictfromjson(slicetimename)
|
|
297
|
+
try:
|
|
298
|
+
teoffset = jsoninfodict["EchoTime"]
|
|
299
|
+
except KeyError:
|
|
300
|
+
teoffset = 0.0
|
|
301
|
+
else:
|
|
302
|
+
teoffset = 0.0
|
|
303
|
+
infodict["teoffset"] = teoffset
|
|
291
304
|
timings.append(["Slice times determined", time.time(), None, None])
|
|
292
305
|
|
|
293
306
|
# normalize the input data
|
|
@@ -317,30 +330,32 @@ def happy_main(argparsingfunc):
|
|
|
317
330
|
tide_io.savetonifti(mads.reshape((xsize, ysize, numslices)), theheader, madsfilename)
|
|
318
331
|
|
|
319
332
|
# read in estimation mask if present. Otherwise, otherwise use intensity mask.
|
|
320
|
-
infodict["
|
|
333
|
+
infodict["estweightsname"] = args.estweightsname
|
|
321
334
|
if args.debug:
|
|
322
|
-
print(args.
|
|
323
|
-
if args.
|
|
324
|
-
tide_util.logmem("before reading in
|
|
325
|
-
|
|
326
|
-
args.
|
|
335
|
+
print(args.estweightsname)
|
|
336
|
+
if args.estweightsname is not None:
|
|
337
|
+
tide_util.logmem("before reading in estweights")
|
|
338
|
+
estweights = happy_support.readextmask(
|
|
339
|
+
args.estweightsname, nim_hdr, xsize, ysize, numslices, args.debug
|
|
327
340
|
)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
print("using estmask from file", args.estmaskname)
|
|
341
|
+
estweights_byslice = estweights.reshape(xsize * ysize, numslices)
|
|
342
|
+
print("using estweights from file", args.estweightsname)
|
|
331
343
|
numpasses = 1
|
|
332
344
|
else:
|
|
333
345
|
# just fall back to the intensity mask
|
|
334
|
-
|
|
346
|
+
estweights_byslice = mask_byslice.astype("float64")
|
|
335
347
|
numpasses = 2
|
|
336
348
|
print("Not using separate estimation mask - doing initial estimate using intensity mask")
|
|
337
|
-
|
|
338
|
-
|
|
349
|
+
|
|
350
|
+
# add another pass to refine the waveform after getting the new appflips
|
|
351
|
+
if args.fliparteries or args.doaliasedcorrelation:
|
|
339
352
|
numpasses += 1
|
|
340
|
-
print("Adding a pass to regenerate cardiac waveform using better
|
|
353
|
+
print("Adding a pass to regenerate cardiac waveform using better vessel specification")
|
|
341
354
|
|
|
342
355
|
# output mask size
|
|
343
|
-
print(
|
|
356
|
+
print(
|
|
357
|
+
f"estweights has {len(np.where(estweights_byslice[:, :] > 0)[0])} voxels above threshold."
|
|
358
|
+
)
|
|
344
359
|
|
|
345
360
|
infodict["numpasses"] = numpasses
|
|
346
361
|
|
|
@@ -369,7 +384,7 @@ def happy_main(argparsingfunc):
|
|
|
369
384
|
slicenorms,
|
|
370
385
|
) = happy_support.cardiacfromimage(
|
|
371
386
|
normdata_byslice,
|
|
372
|
-
|
|
387
|
+
estweights_byslice,
|
|
373
388
|
numslices,
|
|
374
389
|
timepoints,
|
|
375
390
|
tr,
|
|
@@ -396,43 +411,15 @@ def happy_main(argparsingfunc):
|
|
|
396
411
|
]
|
|
397
412
|
)
|
|
398
413
|
infodict["cardfromfmri_normfac"] = cardfromfmri_normfac
|
|
399
|
-
slicetimeaxis =
|
|
400
|
-
0.0, tr * timepoints, num=(timepoints * numsteps), endpoint=False
|
|
414
|
+
slicetimeaxis = (
|
|
415
|
+
np.linspace(0.0, tr * timepoints, num=(timepoints * numsteps), endpoint=False)
|
|
416
|
+
+ teoffset
|
|
401
417
|
)
|
|
402
418
|
if (thispass == 0) and args.doupsampling:
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
upsampleimage_byslice = upsampleimage.reshape(
|
|
406
|
-
xsize * ysize, numslices, numsteps * timepoints
|
|
419
|
+
happy_support.upsampleimage(
|
|
420
|
+
input_data, nim_hdr, numsteps, sliceoffsets, slicesamplerate, outputroot
|
|
407
421
|
)
|
|
408
|
-
|
|
409
|
-
# drop in the raw data
|
|
410
|
-
for theslice in range(numslices):
|
|
411
|
-
upsampleimage[
|
|
412
|
-
:, :, theslice, sliceoffsets[theslice] : timepoints * numsteps : numsteps
|
|
413
|
-
] = fmri_data.reshape((xsize, ysize, numslices, timepoints))[:, :, theslice, :]
|
|
414
|
-
|
|
415
|
-
# interpolate along the slice direction
|
|
416
|
-
for thestep in range(numsteps):
|
|
417
|
-
print(f"interpolating step {thestep}")
|
|
418
|
-
thesrclocs = np.where(sliceoffsets == thestep)[0]
|
|
419
|
-
print(f"sourcelocs: {thesrclocs}")
|
|
420
|
-
thedstlocs = np.linspace(0, numslices, num=len(sliceoffsets), endpoint=False)
|
|
421
|
-
print(f"len(destlocst), destlocs: {len(thedstlocs)}, {thedstlocs}")
|
|
422
|
-
for thetimepoint in range(0, timepoints * numsteps):
|
|
423
|
-
print(f"timepoint: {thetimepoint}")
|
|
424
|
-
for thexyvoxel in range(xsize * ysize):
|
|
425
|
-
theinterps = np.interp(
|
|
426
|
-
thedstlocs,
|
|
427
|
-
1.0 * thesrclocs,
|
|
428
|
-
upsampleimage_byslice[thexyvoxel, thesrclocs, thetimepoint],
|
|
429
|
-
)
|
|
430
|
-
upsampleimage_byslice[thexyvoxel, :, thetimepoint] = 1.0 * theinterps
|
|
431
|
-
|
|
432
|
-
theheader = copy.deepcopy(nim_hdr)
|
|
433
|
-
theheader["dim"][4] = timepoints * numsteps
|
|
434
|
-
theheader["pixdim"][4] = 1.0 / slicesamplerate
|
|
435
|
-
tide_io.savetonifti(upsampleimage, theheader, outputroot + "_upsampled")
|
|
422
|
+
sys.exit(0)
|
|
436
423
|
|
|
437
424
|
if thispass == numpasses - 1:
|
|
438
425
|
tide_io.writebidstsv(
|
|
@@ -1171,20 +1158,12 @@ def happy_main(argparsingfunc):
|
|
|
1171
1158
|
# construct the destination arrays
|
|
1172
1159
|
tide_util.logmem("before making destination arrays")
|
|
1173
1160
|
app = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
|
|
1174
|
-
app_byslice = app.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1175
1161
|
cine = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
|
|
1176
|
-
cine_byslice = cine.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1177
1162
|
rawapp = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
|
|
1178
|
-
rawapp_byslice = rawapp.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1179
1163
|
corrected_rawapp = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
|
|
1180
|
-
corrected_rawapp_byslice = rawapp.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1181
1164
|
normapp = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
|
|
1182
|
-
normapp_byslice = normapp.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1183
1165
|
weights = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
|
|
1184
|
-
weight_byslice = weights.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1185
1166
|
derivatives = np.zeros((xsize, ysize, numslices, 4), dtype=np.float64)
|
|
1186
|
-
derivatives_byslice = derivatives.reshape((xsize * ysize, numslices, 4))
|
|
1187
|
-
|
|
1188
1167
|
timings.append(["Output arrays allocated" + passstring, time.time(), None, None])
|
|
1189
1168
|
|
|
1190
1169
|
if args.centric:
|
|
@@ -1198,6 +1177,42 @@ def happy_main(argparsingfunc):
|
|
|
1198
1177
|
# now do the phase projection
|
|
1199
1178
|
#
|
|
1200
1179
|
#
|
|
1180
|
+
"""app, rawapp, corrected_rawapp, normapp, weights, cine, derivatives = (
|
|
1181
|
+
happy_support.phaseproject(
|
|
1182
|
+
demeandata,
|
|
1183
|
+
means,
|
|
1184
|
+
args.destpoints,
|
|
1185
|
+
numsteps,
|
|
1186
|
+
timings,
|
|
1187
|
+
cardfromfmri_sliceres,
|
|
1188
|
+
instantaneous_cardiacphase,
|
|
1189
|
+
thispass,
|
|
1190
|
+
numpasses,
|
|
1191
|
+
args,
|
|
1192
|
+
outputroot,
|
|
1193
|
+
slicesamplerate,
|
|
1194
|
+
pleth_sliceres,
|
|
1195
|
+
mrsamplerate,
|
|
1196
|
+
projmask_byslice,
|
|
1197
|
+
cardphasevals,
|
|
1198
|
+
thetimes,
|
|
1199
|
+
centric=True,
|
|
1200
|
+
passstring="",
|
|
1201
|
+
badpointlist=None,
|
|
1202
|
+
congridbins=3.0,
|
|
1203
|
+
gridkernel="kaiser",
|
|
1204
|
+
)
|
|
1205
|
+
)"""
|
|
1206
|
+
app_byslice = app.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1207
|
+
rawapp_byslice = rawapp.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1208
|
+
corrected_rawapp_byslice = corrected_rawapp.reshape(
|
|
1209
|
+
(xsize * ysize, numslices, args.destpoints)
|
|
1210
|
+
)
|
|
1211
|
+
normapp_byslice = normapp.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1212
|
+
weights_byslice = weights.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1213
|
+
cine_byslice = cine.reshape((xsize * ysize, numslices, args.destpoints))
|
|
1214
|
+
derivatives_byslice = derivatives.reshape((xsize * ysize, numslices, 4))
|
|
1215
|
+
|
|
1201
1216
|
demeandata_byslice = demeandata.reshape((xsize * ysize, numslices, timepoints))
|
|
1202
1217
|
means_byslice = means.reshape((xsize * ysize, numslices))
|
|
1203
1218
|
|
|
@@ -1216,7 +1231,7 @@ def happy_main(argparsingfunc):
|
|
|
1216
1231
|
procpoints = np.where(censorpoints < 1)[0]
|
|
1217
1232
|
|
|
1218
1233
|
# do phase averaging
|
|
1219
|
-
app_bypoint,
|
|
1234
|
+
app_bypoint, weights_bypoint = happy_support.cardiaccycleaverage(
|
|
1220
1235
|
instantaneous_cardiacphase,
|
|
1221
1236
|
outphases,
|
|
1222
1237
|
cardfromfmri_sliceres,
|
|
@@ -1238,7 +1253,7 @@ def happy_main(argparsingfunc):
|
|
|
1238
1253
|
)
|
|
1239
1254
|
tide_io.writebidstsv(
|
|
1240
1255
|
outputroot + "_desc-cardiaccycleweightfromfmri_timeseries",
|
|
1241
|
-
|
|
1256
|
+
weights_bypoint,
|
|
1242
1257
|
1.0 / (outphases[1] - outphases[0]),
|
|
1243
1258
|
starttime=outphases[0],
|
|
1244
1259
|
columns=["cardiaccycleweightfromfmri"],
|
|
@@ -1295,7 +1310,7 @@ def happy_main(argparsingfunc):
|
|
|
1295
1310
|
outtimes = np.linspace(
|
|
1296
1311
|
0.0, maxtime, num=int(maxtime / args.pulsereconstepsize), endpoint=False
|
|
1297
1312
|
)
|
|
1298
|
-
atp_bypoint,
|
|
1313
|
+
atp_bypoint, atpweights_bypoint = happy_support.cardiaccycleaverage(
|
|
1299
1314
|
instantaneous_cardiactime,
|
|
1300
1315
|
outtimes,
|
|
1301
1316
|
cardfromfmri_sliceres,
|
|
@@ -1326,13 +1341,14 @@ def happy_main(argparsingfunc):
|
|
|
1326
1341
|
appsmoothingfilter.setfreqs(0.0, 0.0, phaseFc, phaseFc)
|
|
1327
1342
|
|
|
1328
1343
|
# setup for aliased correlation if we're going to do it
|
|
1329
|
-
if args.doaliasedcorrelation
|
|
1344
|
+
if args.doaliasedcorrelation:
|
|
1330
1345
|
if args.cardiacfilename and False:
|
|
1331
1346
|
signal_sliceres = pleth_sliceres
|
|
1332
|
-
# signal_stdres = pleth_stdres
|
|
1333
1347
|
else:
|
|
1334
1348
|
signal_sliceres = cardfromfmri_sliceres
|
|
1335
|
-
|
|
1349
|
+
|
|
1350
|
+
# zero out bad points
|
|
1351
|
+
signal_sliceres *= 1.0 - badpointlist
|
|
1336
1352
|
|
|
1337
1353
|
theAliasedCorrelator = tide_corr.AliasedCorrelator(
|
|
1338
1354
|
signal_sliceres,
|
|
@@ -1345,16 +1361,21 @@ def happy_main(argparsingfunc):
|
|
|
1345
1361
|
)
|
|
1346
1362
|
correndloc = tide_util.valtoindex(thealiasedcorrx, args.aliasedcorrelationwidth / 2.0)
|
|
1347
1363
|
aliasedcorrelationpts = correndloc - corrstartloc + 1
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1364
|
+
if thispass == 0:
|
|
1365
|
+
thecorrfunc = np.zeros(
|
|
1366
|
+
(xsize, ysize, numslices, aliasedcorrelationpts), dtype=np.float64
|
|
1367
|
+
)
|
|
1368
|
+
thecorrfunc_byslice = thecorrfunc.reshape(
|
|
1369
|
+
(xsize * ysize, numslices, aliasedcorrelationpts)
|
|
1370
|
+
)
|
|
1371
|
+
wavedelay = np.zeros((xsize, ysize, numslices), dtype=np.float64)
|
|
1372
|
+
wavedelay_byslice = wavedelay.reshape((xsize * ysize, numslices))
|
|
1373
|
+
waveamp = np.zeros((xsize, ysize, numslices), dtype=np.float64)
|
|
1374
|
+
waveamp_byslice = waveamp.reshape((xsize * ysize, numslices))
|
|
1375
|
+
else:
|
|
1376
|
+
thecorrfunc *= 0.0
|
|
1377
|
+
wavedelay *= 0.0
|
|
1378
|
+
waveamp *= 0.0
|
|
1358
1379
|
|
|
1359
1380
|
# now project the data
|
|
1360
1381
|
fmri_data_byslice = input_data.byslice()
|
|
@@ -1381,20 +1402,21 @@ def happy_main(argparsingfunc):
|
|
|
1381
1402
|
cyclic=True,
|
|
1382
1403
|
)
|
|
1383
1404
|
for i in range(len(theindices)):
|
|
1384
|
-
|
|
1405
|
+
weights_byslice[validlocs, theslice, theindices[i]] += theweights[i]
|
|
1385
1406
|
# rawapp_byslice[validlocs, theslice, theindices[i]] += (
|
|
1386
1407
|
# theweights[i] * filteredmr
|
|
1387
1408
|
# )
|
|
1388
1409
|
rawapp_byslice[validlocs, theslice, theindices[i]] += filteredmr
|
|
1389
1410
|
cine_byslice[validlocs, theslice, theindices[i]] += theweights[i] * cinemr
|
|
1390
1411
|
for d in range(args.destpoints):
|
|
1391
|
-
if
|
|
1392
|
-
|
|
1412
|
+
if weights_byslice[validlocs[0], theslice, d] == 0.0:
|
|
1413
|
+
weights_byslice[validlocs, theslice, d] = 1.0
|
|
1393
1414
|
rawapp_byslice[validlocs, theslice, :] = np.nan_to_num(
|
|
1394
|
-
rawapp_byslice[validlocs, theslice, :]
|
|
1415
|
+
rawapp_byslice[validlocs, theslice, :]
|
|
1416
|
+
/ weights_byslice[validlocs, theslice, :]
|
|
1395
1417
|
)
|
|
1396
1418
|
cine_byslice[validlocs, theslice, :] = np.nan_to_num(
|
|
1397
|
-
cine_byslice[validlocs, theslice, :] /
|
|
1419
|
+
cine_byslice[validlocs, theslice, :] / weights_byslice[validlocs, theslice, :]
|
|
1398
1420
|
)
|
|
1399
1421
|
else:
|
|
1400
1422
|
rawapp_byslice[:, theslice, :] = 0.0
|
|
@@ -1419,7 +1441,7 @@ def happy_main(argparsingfunc):
|
|
|
1419
1441
|
corrected_rawapp_byslice[validlocs, theslice, :] = (
|
|
1420
1442
|
rawapp_byslice[validlocs, theslice, :] - timecoursemean
|
|
1421
1443
|
) * appflips_byslice[validlocs, theslice, None] + timecoursemean
|
|
1422
|
-
if args.doaliasedcorrelation and (thispass
|
|
1444
|
+
if args.doaliasedcorrelation and (thispass > 0):
|
|
1423
1445
|
for theloc in validlocs:
|
|
1424
1446
|
thecorrfunc_byslice[theloc, theslice, :] = theAliasedCorrelator.apply(
|
|
1425
1447
|
-appflips_byslice[theloc, theslice]
|
|
@@ -1430,14 +1452,14 @@ def happy_main(argparsingfunc):
|
|
|
1430
1452
|
wavedelay_byslice[theloc, theslice] = (
|
|
1431
1453
|
thealiasedcorrx[corrstartloc : correndloc + 1]
|
|
1432
1454
|
)[maxloc]
|
|
1433
|
-
waveamp_byslice[theloc, theslice] =
|
|
1434
|
-
theloc, theslice, maxloc
|
|
1435
|
-
|
|
1455
|
+
waveamp_byslice[theloc, theslice] = np.fabs(
|
|
1456
|
+
thecorrfunc_byslice[theloc, theslice, maxloc]
|
|
1457
|
+
)
|
|
1436
1458
|
else:
|
|
1437
1459
|
corrected_rawapp_byslice[validlocs, theslice, :] = rawapp_byslice[
|
|
1438
1460
|
validlocs, theslice, :
|
|
1439
1461
|
]
|
|
1440
|
-
if args.doaliasedcorrelation and (thispass
|
|
1462
|
+
if args.doaliasedcorrelation and (thispass > 0):
|
|
1441
1463
|
for theloc in validlocs:
|
|
1442
1464
|
thecorrfunc_byslice[theloc, theslice, :] = theAliasedCorrelator.apply(
|
|
1443
1465
|
-demeandata_byslice[theloc, theslice, :],
|
|
@@ -1447,9 +1469,9 @@ def happy_main(argparsingfunc):
|
|
|
1447
1469
|
wavedelay_byslice[theloc, theslice] = (
|
|
1448
1470
|
thealiasedcorrx[corrstartloc : correndloc + 1]
|
|
1449
1471
|
)[maxloc]
|
|
1450
|
-
waveamp_byslice[theloc, theslice] =
|
|
1451
|
-
theloc, theslice, maxloc
|
|
1452
|
-
|
|
1472
|
+
waveamp_byslice[theloc, theslice] = np.fabs(
|
|
1473
|
+
thecorrfunc_byslice[theloc, theslice, maxloc]
|
|
1474
|
+
)
|
|
1453
1475
|
timecoursemin = np.min(
|
|
1454
1476
|
corrected_rawapp_byslice[validlocs, theslice, :], axis=1
|
|
1455
1477
|
).reshape((-1, 1))
|
|
@@ -1622,8 +1644,18 @@ def happy_main(argparsingfunc):
|
|
|
1622
1644
|
tide_io.savetonifti(veins, theheader, veinmapfilename)
|
|
1623
1645
|
timings.append(["Masks saved" + passstring, time.time(), None, None])
|
|
1624
1646
|
|
|
1647
|
+
# save the mask we used for this pass
|
|
1648
|
+
tide_io.savetonifti(
|
|
1649
|
+
estweights_byslice.reshape((xsize, ysize, numslices)),
|
|
1650
|
+
theheader,
|
|
1651
|
+
f"{outputroot}_desc-estweightspass{thispass}_map",
|
|
1652
|
+
)
|
|
1653
|
+
|
|
1625
1654
|
# now get ready to start again with a new mask
|
|
1626
|
-
|
|
1655
|
+
if args.doaliasedcorrelation and thispass > 0:
|
|
1656
|
+
estweights_byslice = waveamp_byslice * vesselmask.reshape((xsize * ysize, numslices))
|
|
1657
|
+
else:
|
|
1658
|
+
estweights_byslice = vesselmask.reshape((xsize * ysize, numslices)) + 0
|
|
1627
1659
|
|
|
1628
1660
|
# save a vessel image
|
|
1629
1661
|
if args.unnormvesselmap:
|
|
@@ -17,13 +17,14 @@
|
|
|
17
17
|
#
|
|
18
18
|
#
|
|
19
19
|
import argparse
|
|
20
|
-
import sys
|
|
21
20
|
|
|
22
21
|
import numpy as np
|
|
23
22
|
|
|
24
23
|
import rapidtide.io as tide_io
|
|
25
24
|
import rapidtide.workflows.parser_funcs as pf
|
|
26
25
|
|
|
26
|
+
DEFAULT_ALIASEDCORRELATIONWIDTH = 5.0
|
|
27
|
+
|
|
27
28
|
|
|
28
29
|
def _get_parser():
|
|
29
30
|
"""
|
|
@@ -207,10 +208,10 @@ def _get_parser():
|
|
|
207
208
|
# Cardiac estimation tuning
|
|
208
209
|
cardiac_est_tuning = parser.add_argument_group("Cardiac estimation tuning")
|
|
209
210
|
cardiac_est_tuning.add_argument(
|
|
210
|
-
"--
|
|
211
|
-
dest="
|
|
211
|
+
"--estweights",
|
|
212
|
+
dest="estweightsname",
|
|
212
213
|
action="store",
|
|
213
|
-
metavar="
|
|
214
|
+
metavar="WEIGHTSNAME",
|
|
214
215
|
help=(
|
|
215
216
|
"Generation of cardiac waveform from data will be restricted to "
|
|
216
217
|
"voxels in MASKNAME and weighted by the mask intensity. If this is "
|
|
@@ -292,6 +293,15 @@ def _get_parser():
|
|
|
292
293
|
),
|
|
293
294
|
default=False,
|
|
294
295
|
)
|
|
296
|
+
cardiac_est_tuning.add_argument(
|
|
297
|
+
"--teoffset",
|
|
298
|
+
dest="teoffset",
|
|
299
|
+
action="store",
|
|
300
|
+
metavar="TE",
|
|
301
|
+
type=lambda x: pf.is_float(parser, x),
|
|
302
|
+
help="Specify the echo time in seconds. This is used when combining multiecho data. Default is 0. ",
|
|
303
|
+
default=None,
|
|
304
|
+
)
|
|
295
305
|
|
|
296
306
|
# External cardiac waveform options
|
|
297
307
|
external_cardiac_opts = parser.add_argument_group("External cardiac waveform options")
|
|
@@ -538,6 +548,15 @@ def _get_parser():
|
|
|
538
548
|
help="Attempt to calculate absolute delay using an aliased correlation (experimental).",
|
|
539
549
|
default=False,
|
|
540
550
|
)
|
|
551
|
+
misc_opts.add_argument(
|
|
552
|
+
"--aliasedcorrelationwidth",
|
|
553
|
+
dest="aliasedcorrelationwidth",
|
|
554
|
+
metavar="WIDTH",
|
|
555
|
+
action="store",
|
|
556
|
+
type=lambda x: pf.is_float(parser, x),
|
|
557
|
+
help=f"Width of the aliased correlation calculation (default is {DEFAULT_ALIASEDCORRELATIONWIDTH}). ",
|
|
558
|
+
default=DEFAULT_ALIASEDCORRELATIONWIDTH,
|
|
559
|
+
)
|
|
541
560
|
misc_opts.add_argument(
|
|
542
561
|
"--upsample",
|
|
543
562
|
dest="doupsampling",
|
|
@@ -666,23 +685,7 @@ def process_args(inputargs=None):
|
|
|
666
685
|
"""
|
|
667
686
|
Compile arguments for rapidtide workflow.
|
|
668
687
|
"""
|
|
669
|
-
|
|
670
|
-
print("processing command line arguments")
|
|
671
|
-
# write out the command used
|
|
672
|
-
try:
|
|
673
|
-
args = _get_parser().parse_args()
|
|
674
|
-
argstowrite = sys.argv
|
|
675
|
-
except SystemExit:
|
|
676
|
-
_get_parser().print_help()
|
|
677
|
-
raise
|
|
678
|
-
else:
|
|
679
|
-
print("processing passed argument list:")
|
|
680
|
-
try:
|
|
681
|
-
args = _get_parser().parse_args(inputargs)
|
|
682
|
-
argstowrite = inputargs
|
|
683
|
-
except SystemExit:
|
|
684
|
-
print("Use --help option for detailed information on options.")
|
|
685
|
-
raise
|
|
688
|
+
args, argstowrite = pf.setargs(_get_parser, inputargs=inputargs)
|
|
686
689
|
|
|
687
690
|
# save the raw and formatted command lines
|
|
688
691
|
args.commandline = " ".join(argstowrite)
|
|
@@ -723,7 +726,6 @@ def process_args(inputargs=None):
|
|
|
723
726
|
args.upsamplefac = 100
|
|
724
727
|
args.centric = True
|
|
725
728
|
args.pulsereconstepsize = 0.01
|
|
726
|
-
args.aliasedcorrelationwidth = 3.0
|
|
727
729
|
args.unnormvesselmap = True
|
|
728
730
|
args.histlen = 100
|
|
729
731
|
args.softvesselfrac = 0.4
|
rapidtide/workflows/simdata.py
CHANGED
|
@@ -308,7 +308,9 @@ def simdata(args):
|
|
|
308
308
|
_get_parser().print_help()
|
|
309
309
|
sys.exit()
|
|
310
310
|
|
|
311
|
-
sliceoffsettimes, normalizedtotr = tide_io.getslicetimesfromfile(
|
|
311
|
+
sliceoffsettimes, normalizedtotr, fileisjson = tide_io.getslicetimesfromfile(
|
|
312
|
+
args.slicetimefile
|
|
313
|
+
)
|
|
312
314
|
|
|
313
315
|
fmritr, numtrs = tide_io.fmritimeinfo(args.fmrifilename)
|
|
314
316
|
if normalizedtotr:
|