rapidtide 3.0.7.1__py3-none-any.whl → 3.0.9__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/RapidtideDataset.py +1 -1
- rapidtide/_version.py +3 -3
- rapidtide/calcnullsimfunc.py +1 -3
- rapidtide/data/examples/src/test_findmaxlag.py +1 -1
- rapidtide/data/examples/src/testfmri +19 -7
- rapidtide/data/examples/src/testnewrefine +0 -23
- rapidtide/fMRIData_class.py +29 -52
- rapidtide/fit.py +4 -4
- rapidtide/happy_supportfuncs.py +1 -1
- rapidtide/helper_classes.py +0 -1099
- rapidtide/linfitfiltpass.py +82 -4
- rapidtide/makelaggedtcs.py +10 -0
- rapidtide/refinedelay.py +11 -20
- rapidtide/refineregressor.py +1 -1
- rapidtide/resample.py +8 -8
- rapidtide/simFuncClasses.py +1132 -0
- rapidtide/simfuncfit.py +30 -30
- rapidtide/stats.py +5 -2
- rapidtide/tests/.coveragerc +6 -0
- rapidtide/tests/cleanposttest +1 -1
- rapidtide/tests/runlocaltest +2 -2
- rapidtide/tests/test_cleanregressor.py +3 -3
- rapidtide/tests/test_congrid.py +1 -1
- rapidtide/tests/test_corrpass.py +3 -3
- rapidtide/tests/test_delayestimation.py +9 -8
- rapidtide/tests/test_findmaxlag.py +2 -2
- rapidtide/tests/test_fullrunrapidtide_v3.py +2 -1
- rapidtide/tests/test_fullrunrapidtide_v8.py +66 -0
- rapidtide/tests/test_getparsers.py +14 -6
- rapidtide/tests/test_io.py +2 -6
- rapidtide/tests/test_nullcorr.py +3 -3
- rapidtide/tests/test_refinedelay.py +20 -5
- rapidtide/tidepoolTemplate_alt.py +1 -1
- rapidtide/util.py +7 -0
- rapidtide/voxelData.py +3 -6
- rapidtide/workflows/calcSimFuncMap.py +271 -0
- rapidtide/workflows/cleanregressor.py +2 -2
- rapidtide/workflows/delayvar.py +45 -59
- rapidtide/workflows/fitSimFuncMap.py +427 -0
- rapidtide/workflows/happy.py +1 -1
- rapidtide/workflows/rapidtide.py +499 -877
- rapidtide/workflows/rapidtide_parser.py +26 -38
- rapidtide/workflows/refineDelayMap.py +138 -0
- rapidtide/{RegressorRefiner.py → workflows/refineRegressor.py} +200 -28
- rapidtide/workflows/regressfrommaps.py +38 -30
- rapidtide/workflows/retrolagtcs.py +5 -6
- rapidtide/workflows/retroregress.py +73 -191
- rapidtide/workflows/showarbcorr.py +2 -2
- rapidtide/workflows/showxcorrx.py +5 -5
- rapidtide/workflows/tidepool.py +5 -5
- {rapidtide-3.0.7.1.dist-info → rapidtide-3.0.9.dist-info}/METADATA +2 -2
- {rapidtide-3.0.7.1.dist-info → rapidtide-3.0.9.dist-info}/RECORD +56 -52
- rapidtide/workflows/delayestimation.py +0 -483
- {rapidtide-3.0.7.1.dist-info → rapidtide-3.0.9.dist-info}/WHEEL +0 -0
- {rapidtide-3.0.7.1.dist-info → rapidtide-3.0.9.dist-info}/entry_points.txt +0 -0
- {rapidtide-3.0.7.1.dist-info → rapidtide-3.0.9.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.7.1.dist-info → rapidtide-3.0.9.dist-info}/top_level.txt +0 -0
|
@@ -72,7 +72,6 @@ DEFAULT_REFINE_PRENORM = "var"
|
|
|
72
72
|
DEFAULT_REFINE_WEIGHTING = "None"
|
|
73
73
|
DEFAULT_REFINE_PCACOMPONENTS = 0.8
|
|
74
74
|
DEFAULT_REGRESSIONFILTDERIVS = 0
|
|
75
|
-
DEFAULT_REFINEREGRESSDERIVS = 1
|
|
76
75
|
|
|
77
76
|
DEFAULT_DENOISING_LAGMIN = -10.0
|
|
78
77
|
DEFAULT_DENOISING_LAGMAX = 10.0
|
|
@@ -97,6 +96,9 @@ DEFAULT_OUTPUTLEVEL = "normal"
|
|
|
97
96
|
|
|
98
97
|
DEFAULT_SLFONOISEAMP_WINDOWSIZE = 40.0
|
|
99
98
|
|
|
99
|
+
DEFAULT_COARSEDELAY_TYPE = "simfunc"
|
|
100
|
+
DEFAULT_RIPTIDESTEP = 2.0
|
|
101
|
+
|
|
100
102
|
DEFAULT_PATCHTHRESH = 3.0
|
|
101
103
|
DEFAULT_REFINEDELAYMINDELAY = -5.0
|
|
102
104
|
DEFAULT_REFINEDELAYMAXDELAY = 5.0
|
|
@@ -780,10 +782,10 @@ def _get_parser():
|
|
|
780
782
|
dest="similaritymetric",
|
|
781
783
|
action="store",
|
|
782
784
|
type=str,
|
|
783
|
-
choices=["correlation", "mutualinfo", "hybrid"],
|
|
785
|
+
choices=["correlation", "mutualinfo", "hybrid", "riptide"],
|
|
784
786
|
help=(
|
|
785
787
|
"Similarity metric for finding delay values. "
|
|
786
|
-
'Choices are "correlation", "mutualinfo", and "
|
|
788
|
+
'Choices are "correlation", "mutualinfo", "hybrid", and "riptide". '
|
|
787
789
|
f"Default is {DEFAULT_SIMILARITYMETRIC}."
|
|
788
790
|
),
|
|
789
791
|
default=DEFAULT_SIMILARITYMETRIC,
|
|
@@ -1443,17 +1445,23 @@ def _get_parser():
|
|
|
1443
1445
|
experimental = parser.add_argument_group(
|
|
1444
1446
|
"Experimental options (not fully tested, or not tested at all, may not work). Beware!"
|
|
1445
1447
|
)
|
|
1446
|
-
|
|
1447
|
-
"--
|
|
1448
|
-
dest="
|
|
1448
|
+
output.add_argument(
|
|
1449
|
+
"--riptidestep", # was -h
|
|
1450
|
+
dest="riptidestep",
|
|
1449
1451
|
action="store",
|
|
1450
|
-
type=lambda x: pf.
|
|
1451
|
-
metavar="
|
|
1452
|
+
type=lambda x: pf.is_float(parser, x, maxval=5.0),
|
|
1453
|
+
metavar="STEP",
|
|
1452
1454
|
help=(
|
|
1453
|
-
f"
|
|
1454
|
-
f"Default is {DEFAULT_REFINEREGRESSDERIVS}"
|
|
1455
|
+
f"Timestep between RIPTiDe regressors, in seconds. Default is {DEFAULT_RIPTIDESTEP}."
|
|
1455
1456
|
),
|
|
1456
|
-
default=
|
|
1457
|
+
default=DEFAULT_RIPTIDESTEP,
|
|
1458
|
+
)
|
|
1459
|
+
experimental.add_argument(
|
|
1460
|
+
"--refinedelayeachpass",
|
|
1461
|
+
dest="refinedelayeachpass",
|
|
1462
|
+
action="store_true",
|
|
1463
|
+
help=("Do delay refinement in each pass."),
|
|
1464
|
+
default=False,
|
|
1457
1465
|
)
|
|
1458
1466
|
experimental.add_argument(
|
|
1459
1467
|
"--dofinalrefine",
|
|
@@ -1483,13 +1491,6 @@ def _get_parser():
|
|
|
1483
1491
|
),
|
|
1484
1492
|
default=None,
|
|
1485
1493
|
)
|
|
1486
|
-
experimental.add_argument(
|
|
1487
|
-
"--psdfilter",
|
|
1488
|
-
dest="psdfilter",
|
|
1489
|
-
action="store_true",
|
|
1490
|
-
help=("Apply a PSD weighted Wiener filter to shifted timecourses prior to refinement."),
|
|
1491
|
-
default=False,
|
|
1492
|
-
)
|
|
1493
1494
|
experimental.add_argument(
|
|
1494
1495
|
"--wiener",
|
|
1495
1496
|
dest="dodeconv",
|
|
@@ -1497,26 +1498,6 @@ def _get_parser():
|
|
|
1497
1498
|
help=("Do Wiener deconvolution to find voxel transfer function."),
|
|
1498
1499
|
default=False,
|
|
1499
1500
|
)
|
|
1500
|
-
experimental.add_argument(
|
|
1501
|
-
"--corrbaselinespatialsigma",
|
|
1502
|
-
dest="corrbaselinespatialsigma",
|
|
1503
|
-
action="store",
|
|
1504
|
-
type=float,
|
|
1505
|
-
metavar="SIGMA",
|
|
1506
|
-
help=("Spatial lowpass kernel, in mm, for filtering the correlation function baseline. "),
|
|
1507
|
-
default=0.0,
|
|
1508
|
-
)
|
|
1509
|
-
experimental.add_argument(
|
|
1510
|
-
"--corrbaselinetemphpfcutoff",
|
|
1511
|
-
dest="corrbaselinetemphpfcutoff",
|
|
1512
|
-
action="store",
|
|
1513
|
-
type=float,
|
|
1514
|
-
metavar="FREQ",
|
|
1515
|
-
help=(
|
|
1516
|
-
"Temporal highpass cutoff, in Hz, for filtering the correlation function baseline. "
|
|
1517
|
-
),
|
|
1518
|
-
default=0.0,
|
|
1519
|
-
)
|
|
1520
1501
|
experimental.add_argument(
|
|
1521
1502
|
"--echocancel",
|
|
1522
1503
|
dest="echocancel",
|
|
@@ -2239,6 +2220,13 @@ def process_args(inputargs=None):
|
|
|
2239
2220
|
print(f"illegal output level {args['outputlevel']}")
|
|
2240
2221
|
sys.exit()
|
|
2241
2222
|
|
|
2223
|
+
# make the pass options dictionary
|
|
2224
|
+
args["passoptions"] = [
|
|
2225
|
+
{"similaritymetric": "riptide",},
|
|
2226
|
+
{"similaritymetric": "correlation", },
|
|
2227
|
+
{"similaritymetric": "correlation", },
|
|
2228
|
+
]
|
|
2229
|
+
|
|
2242
2230
|
# dispersion calculation
|
|
2243
2231
|
args["dispersioncalc_lower"] = args["lagmin"]
|
|
2244
2232
|
args["dispersioncalc_upper"] = args["lagmax"]
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2016-2025 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 numpy as np
|
|
20
|
+
|
|
21
|
+
import rapidtide.refinedelay as tide_refinedelay
|
|
22
|
+
import rapidtide.stats as tide_stats
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def refineDelay(
|
|
26
|
+
fmri_data_valid,
|
|
27
|
+
initial_fmri_x,
|
|
28
|
+
xdim,
|
|
29
|
+
ydim,
|
|
30
|
+
slicethickness,
|
|
31
|
+
sLFOfiltmask,
|
|
32
|
+
genlagtc,
|
|
33
|
+
oversamptr,
|
|
34
|
+
sLFOfitmean,
|
|
35
|
+
rvalue,
|
|
36
|
+
r2value,
|
|
37
|
+
fitNorm,
|
|
38
|
+
fitcoeff,
|
|
39
|
+
lagtc,
|
|
40
|
+
outputname,
|
|
41
|
+
validvoxels,
|
|
42
|
+
nativespaceshape,
|
|
43
|
+
theinputdata,
|
|
44
|
+
lagtimes,
|
|
45
|
+
optiondict,
|
|
46
|
+
LGR,
|
|
47
|
+
TimingLGR,
|
|
48
|
+
outputlevel="normal",
|
|
49
|
+
gausssigma=-1,
|
|
50
|
+
patchthresh=3.0,
|
|
51
|
+
mindelay=-5.0,
|
|
52
|
+
maxdelay=5.0,
|
|
53
|
+
numpoints=501,
|
|
54
|
+
histlen=101,
|
|
55
|
+
rt_floatset=np.float64,
|
|
56
|
+
rt_floattype="float64",
|
|
57
|
+
debug=False,
|
|
58
|
+
):
|
|
59
|
+
# do the calibration
|
|
60
|
+
TimingLGR.info("Refinement calibration start")
|
|
61
|
+
regressderivratios, regressrvalues = tide_refinedelay.getderivratios(
|
|
62
|
+
fmri_data_valid,
|
|
63
|
+
validvoxels,
|
|
64
|
+
initial_fmri_x,
|
|
65
|
+
lagtimes,
|
|
66
|
+
sLFOfiltmask,
|
|
67
|
+
genlagtc,
|
|
68
|
+
"glm",
|
|
69
|
+
outputname,
|
|
70
|
+
oversamptr,
|
|
71
|
+
sLFOfitmean,
|
|
72
|
+
rvalue,
|
|
73
|
+
r2value,
|
|
74
|
+
fitNorm[:, :2],
|
|
75
|
+
fitcoeff[:, :2],
|
|
76
|
+
None,
|
|
77
|
+
lagtc,
|
|
78
|
+
None,
|
|
79
|
+
LGR,
|
|
80
|
+
TimingLGR,
|
|
81
|
+
optiondict,
|
|
82
|
+
regressderivs=1,
|
|
83
|
+
debug=debug,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
medfiltregressderivratios, filteredregressderivratios, delayoffsetMAD = (
|
|
87
|
+
tide_refinedelay.filterderivratios(
|
|
88
|
+
regressderivratios,
|
|
89
|
+
nativespaceshape,
|
|
90
|
+
validvoxels,
|
|
91
|
+
(xdim, ydim, slicethickness),
|
|
92
|
+
gausssigma=gausssigma,
|
|
93
|
+
patchthresh=patchthresh,
|
|
94
|
+
filetype=theinputdata.filetype,
|
|
95
|
+
rt_floattype=rt_floattype,
|
|
96
|
+
debug=debug,
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# find the mapping of derivative ratios to delays
|
|
101
|
+
tide_refinedelay.trainratiotooffset(
|
|
102
|
+
genlagtc,
|
|
103
|
+
initial_fmri_x,
|
|
104
|
+
outputname,
|
|
105
|
+
outputlevel,
|
|
106
|
+
mindelay=mindelay,
|
|
107
|
+
maxdelay=maxdelay,
|
|
108
|
+
numpoints=numpoints,
|
|
109
|
+
debug=debug,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# now calculate the delay offsets
|
|
113
|
+
delayoffset = np.zeros_like(filteredregressderivratios)
|
|
114
|
+
if debug:
|
|
115
|
+
print(f"calculating delayoffsets for {filteredregressderivratios.shape[0]} voxels")
|
|
116
|
+
for i in range(filteredregressderivratios.shape[0]):
|
|
117
|
+
delayoffset[i], closestoffset = tide_refinedelay.ratiotodelay(
|
|
118
|
+
filteredregressderivratios[i]
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
namesuffix = "_desc-delayoffset_hist"
|
|
122
|
+
tide_stats.makeandsavehistogram(
|
|
123
|
+
delayoffset[np.where(sLFOfiltmask > 0)],
|
|
124
|
+
histlen,
|
|
125
|
+
1,
|
|
126
|
+
outputname + namesuffix,
|
|
127
|
+
displaytitle="Histogram of delay offsets calculated from regression coefficients",
|
|
128
|
+
dictvarname="delayoffsethist",
|
|
129
|
+
thedict=optiondict,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
delayoffset,
|
|
134
|
+
regressderivratios,
|
|
135
|
+
medfiltregressderivratios,
|
|
136
|
+
filteredregressderivratios,
|
|
137
|
+
delayoffsetMAD,
|
|
138
|
+
)
|
|
@@ -16,10 +16,7 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#
|
|
18
18
|
#
|
|
19
|
-
|
|
20
|
-
A class to impmement regressor refinement
|
|
21
|
-
"""
|
|
22
|
-
import copy
|
|
19
|
+
import sys
|
|
23
20
|
|
|
24
21
|
import numpy as np
|
|
25
22
|
|
|
@@ -32,6 +29,10 @@ import rapidtide.stats as tide_stats
|
|
|
32
29
|
import rapidtide.util as tide_util
|
|
33
30
|
from rapidtide.tests.utils import mse
|
|
34
31
|
|
|
32
|
+
"""
|
|
33
|
+
A class to implement regressor refinement
|
|
34
|
+
"""
|
|
35
|
+
|
|
35
36
|
|
|
36
37
|
class RegressorRefiner:
|
|
37
38
|
|
|
@@ -137,33 +138,33 @@ class RegressorRefiner:
|
|
|
137
138
|
self.excludemask = excludemask
|
|
138
139
|
|
|
139
140
|
def _allocatemem(self, pid):
|
|
141
|
+
self.shiftedtcs, self.shiftedtcs_shm = tide_util.allocarray(
|
|
142
|
+
self.internalvalidfmrishape,
|
|
143
|
+
self.rt_floattype,
|
|
144
|
+
shared=self.sharedmem,
|
|
145
|
+
name=f"shiftedtcs_{pid}",
|
|
146
|
+
)
|
|
147
|
+
self.weights, self.weights_shm = tide_util.allocarray(
|
|
148
|
+
self.internalvalidfmrishape,
|
|
149
|
+
self.rt_floattype,
|
|
150
|
+
shared=self.sharedmem,
|
|
151
|
+
name=f"weights_{pid}",
|
|
152
|
+
)
|
|
153
|
+
self.paddedshiftedtcs, self.paddedshiftedtcs_shm = tide_util.allocarray(
|
|
154
|
+
self.internalvalidpaddedfmrishape,
|
|
155
|
+
self.rt_floattype,
|
|
156
|
+
shared=self.sharedmem,
|
|
157
|
+
name=f"paddedshiftedtcs_{pid}",
|
|
158
|
+
)
|
|
159
|
+
self.paddedweights, self.paddedweights_shm = tide_util.allocarray(
|
|
160
|
+
self.internalvalidpaddedfmrishape,
|
|
161
|
+
self.rt_floattype,
|
|
162
|
+
shared=self.sharedmem,
|
|
163
|
+
name=f"paddedweights_{pid}",
|
|
164
|
+
)
|
|
140
165
|
if self.sharedmem:
|
|
141
|
-
self.shiftedtcs, self.shiftedtcs_shm = tide_util.allocshared(
|
|
142
|
-
self.internalvalidfmrishape, self.rt_floatset, name=f"shiftedtcs_{pid}"
|
|
143
|
-
)
|
|
144
|
-
self.weights, self.weights_shm = tide_util.allocshared(
|
|
145
|
-
self.internalvalidfmrishape, self.rt_floatset, name=f"weights_{pid}"
|
|
146
|
-
)
|
|
147
|
-
self.paddedshiftedtcs, self.paddedshiftedtcs_shm = tide_util.allocshared(
|
|
148
|
-
self.internalvalidpaddedfmrishape,
|
|
149
|
-
self.rt_floatset,
|
|
150
|
-
name=f"paddedshiftedtcs_{pid}",
|
|
151
|
-
)
|
|
152
|
-
self.paddedweights, self.paddedweights_shm = tide_util.allocshared(
|
|
153
|
-
self.internalvalidpaddedfmrishape,
|
|
154
|
-
self.rt_floatset,
|
|
155
|
-
name=f"paddedweights_{pid}",
|
|
156
|
-
)
|
|
157
166
|
ramlocation = "in shared memory"
|
|
158
167
|
else:
|
|
159
|
-
self.shiftedtcs = np.zeros(self.internalvalidfmrishape, dtype=self.rt_floattype)
|
|
160
|
-
self.weights = np.zeros(self.internalvalidfmrishape, dtype=self.rt_floattype)
|
|
161
|
-
self.paddedshiftedtcs = np.zeros(
|
|
162
|
-
self.internalvalidpaddedfmrishape, dtype=self.rt_floattype
|
|
163
|
-
)
|
|
164
|
-
self.paddedweights = np.zeros(
|
|
165
|
-
self.internalvalidpaddedfmrishape, dtype=self.rt_floattype
|
|
166
|
-
)
|
|
167
168
|
ramlocation = "locally"
|
|
168
169
|
totalrefinementbytes = (
|
|
169
170
|
self.shiftedtcs.nbytes
|
|
@@ -462,3 +463,174 @@ class RegressorRefiner:
|
|
|
462
463
|
refinestopreason,
|
|
463
464
|
genlagtc,
|
|
464
465
|
)
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
def refineRegressor(
|
|
469
|
+
LGR,
|
|
470
|
+
TimingLGR,
|
|
471
|
+
thepass,
|
|
472
|
+
optiondict,
|
|
473
|
+
fitmask,
|
|
474
|
+
internaloffsetincludemask_valid,
|
|
475
|
+
internaloffsetexcludemask_valid,
|
|
476
|
+
internalrefineincludemask_valid,
|
|
477
|
+
internalrefineexcludemask_valid,
|
|
478
|
+
internaldespeckleincludemask,
|
|
479
|
+
validvoxels,
|
|
480
|
+
theRegressorRefiner,
|
|
481
|
+
lagtimes,
|
|
482
|
+
lagstrengths,
|
|
483
|
+
lagsigma,
|
|
484
|
+
fmri_data_valid,
|
|
485
|
+
fmritr,
|
|
486
|
+
R2,
|
|
487
|
+
theprefilter,
|
|
488
|
+
previousnormoutputdata,
|
|
489
|
+
theinputdata,
|
|
490
|
+
numpadtrs,
|
|
491
|
+
outputname,
|
|
492
|
+
nativefmrishape,
|
|
493
|
+
bidsbasedict,
|
|
494
|
+
rt_floatset=np.float64,
|
|
495
|
+
rt_floattype="float64",
|
|
496
|
+
):
|
|
497
|
+
LGR.info(f"\n\nRegressor refinement, pass {thepass}")
|
|
498
|
+
TimingLGR.info(f"Regressor refinement start, pass {thepass}")
|
|
499
|
+
if optiondict["refineoffset"]:
|
|
500
|
+
# check that we won't end up excluding all voxels from offset calculation before accepting mask
|
|
501
|
+
offsetmask = np.uint16(fitmask)
|
|
502
|
+
if internaloffsetincludemask_valid is not None:
|
|
503
|
+
offsetmask[np.where(internaloffsetincludemask_valid == 0)] = 0
|
|
504
|
+
if internaloffsetexcludemask_valid is not None:
|
|
505
|
+
offsetmask[np.where(internaloffsetexcludemask_valid != 0.0)] = 0
|
|
506
|
+
if tide_stats.getmasksize(offsetmask) == 0:
|
|
507
|
+
LGR.warning(
|
|
508
|
+
"NB: cannot exclude voxels from offset calculation mask - including for this pass"
|
|
509
|
+
)
|
|
510
|
+
offsetmask = fitmask + 0
|
|
511
|
+
|
|
512
|
+
peaklag, dummy, dummy = tide_stats.gethistprops(
|
|
513
|
+
lagtimes[np.where(offsetmask > 0)],
|
|
514
|
+
optiondict["histlen"],
|
|
515
|
+
pickleft=optiondict["pickleft"],
|
|
516
|
+
peakthresh=optiondict["pickleftthresh"],
|
|
517
|
+
)
|
|
518
|
+
optiondict["offsettime"] = peaklag
|
|
519
|
+
optiondict["offsettime_total"] += peaklag
|
|
520
|
+
optiondict[f"offsettime_pass{thepass}"] = optiondict["offsettime"]
|
|
521
|
+
optiondict[f"offsettime_total_pass{thepass}"] = optiondict["offsettime_total"]
|
|
522
|
+
LGR.info(
|
|
523
|
+
f"offset time set to {optiondict['offsettime']:.3f}, "
|
|
524
|
+
f"total is {optiondict['offsettime_total']:.3f}"
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
if optiondict["refinedespeckled"] or (optiondict["despeckle_passes"] == 0):
|
|
528
|
+
# if refinedespeckled is true, or there is no despeckling, masks are unaffected
|
|
529
|
+
thisinternalrefineexcludemask_valid = internalrefineexcludemask_valid
|
|
530
|
+
else:
|
|
531
|
+
# if refinedespeckled is false and there is despeckling, need to make a proper mask
|
|
532
|
+
if internalrefineexcludemask_valid is None:
|
|
533
|
+
# if there is currently no exclude mask, set exclude mask = despeckle mask
|
|
534
|
+
thisinternalrefineexcludemask_valid = np.where(
|
|
535
|
+
internaldespeckleincludemask[validvoxels] == 0.0, 0, 1
|
|
536
|
+
)
|
|
537
|
+
else:
|
|
538
|
+
# if there is a current exclude mask, add any voxels that are being despeckled
|
|
539
|
+
thisinternalrefineexcludemask_valid = np.where(
|
|
540
|
+
internalrefineexcludemask_valid > 0, 1, 0
|
|
541
|
+
)
|
|
542
|
+
thisinternalrefineexcludemask_valid[
|
|
543
|
+
np.where(internaldespeckleincludemask[validvoxels] != 0.0)
|
|
544
|
+
] = 1
|
|
545
|
+
|
|
546
|
+
# now check that we won't end up excluding all voxels from refinement before accepting mask
|
|
547
|
+
overallmask = np.uint16(fitmask)
|
|
548
|
+
if internalrefineincludemask_valid is not None:
|
|
549
|
+
overallmask[np.where(internalrefineincludemask_valid == 0)] = 0
|
|
550
|
+
if thisinternalrefineexcludemask_valid is not None:
|
|
551
|
+
overallmask[np.where(thisinternalrefineexcludemask_valid != 0.0)] = 0
|
|
552
|
+
if tide_stats.getmasksize(overallmask) == 0:
|
|
553
|
+
LGR.warning(
|
|
554
|
+
"NB: cannot exclude despeckled voxels from refinement - including for this pass"
|
|
555
|
+
)
|
|
556
|
+
thisinternalrefineexcludemask_valid = internalrefineexcludemask_valid
|
|
557
|
+
theRegressorRefiner.setmasks(
|
|
558
|
+
internalrefineincludemask_valid, thisinternalrefineexcludemask_valid
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
# regenerate regressor for next pass
|
|
562
|
+
# create the refinement mask
|
|
563
|
+
LGR.info("making refine mask")
|
|
564
|
+
createdmask = theRegressorRefiner.makemask(lagstrengths, lagtimes, lagsigma, fitmask)
|
|
565
|
+
print(f"Refine mask has {theRegressorRefiner.refinemaskvoxels} voxels")
|
|
566
|
+
if not createdmask:
|
|
567
|
+
print("no voxels qualify for refinement - exiting")
|
|
568
|
+
sys.exit()
|
|
569
|
+
|
|
570
|
+
# align timecourses to prepare for refinement
|
|
571
|
+
LGR.info("aligning timecourses")
|
|
572
|
+
tide_util.disablemkl(optiondict["nprocs_refine"], debug=optiondict["threaddebug"])
|
|
573
|
+
voxelsprocessed_rra = theRegressorRefiner.alignvoxels(fmri_data_valid, fmritr, lagtimes)
|
|
574
|
+
tide_util.enablemkl(optiondict["mklthreads"], debug=optiondict["threaddebug"])
|
|
575
|
+
LGR.info(f"align complete: {voxelsprocessed_rra=}")
|
|
576
|
+
|
|
577
|
+
# prenormalize
|
|
578
|
+
LGR.info("prenormalizing timecourses")
|
|
579
|
+
theRegressorRefiner.prenormalize(lagtimes, lagstrengths, R2)
|
|
580
|
+
|
|
581
|
+
# now doing the refinement
|
|
582
|
+
(
|
|
583
|
+
voxelsprocessed_rr,
|
|
584
|
+
outputdict,
|
|
585
|
+
previousnormoutputdata,
|
|
586
|
+
resampref_y,
|
|
587
|
+
resampnonosref_y,
|
|
588
|
+
stoprefining,
|
|
589
|
+
refinestopreason,
|
|
590
|
+
genlagtc,
|
|
591
|
+
) = theRegressorRefiner.refine(
|
|
592
|
+
theprefilter,
|
|
593
|
+
fmritr,
|
|
594
|
+
thepass,
|
|
595
|
+
lagstrengths,
|
|
596
|
+
lagtimes,
|
|
597
|
+
previousnormoutputdata,
|
|
598
|
+
optiondict["corrmasksize"],
|
|
599
|
+
)
|
|
600
|
+
TimingLGR.info(
|
|
601
|
+
f"Regressor refinement end, pass {thepass}",
|
|
602
|
+
{
|
|
603
|
+
"message2": voxelsprocessed_rr,
|
|
604
|
+
"message3": "voxels",
|
|
605
|
+
},
|
|
606
|
+
)
|
|
607
|
+
for key, value in outputdict.items():
|
|
608
|
+
optiondict[key] = value
|
|
609
|
+
|
|
610
|
+
# Save shifted timecourses for César
|
|
611
|
+
if optiondict["saveintermediatemaps"] and optiondict["savelagregressors"]:
|
|
612
|
+
theheader = theinputdata.copyheader()
|
|
613
|
+
bidspasssuffix = f"_intermediatedata-pass{thepass}"
|
|
614
|
+
maplist = [
|
|
615
|
+
(
|
|
616
|
+
(theRegressorRefiner.getpaddedshiftedtcs())[:, numpadtrs:-numpadtrs],
|
|
617
|
+
"shiftedtcs",
|
|
618
|
+
"bold",
|
|
619
|
+
None,
|
|
620
|
+
"The filtered input fMRI data, in voxels used for refinement, time shifted by the negated delay in every voxel so that the moving blood component is aligned.",
|
|
621
|
+
),
|
|
622
|
+
]
|
|
623
|
+
tide_io.savemaplist(
|
|
624
|
+
f"{outputname}{bidspasssuffix}",
|
|
625
|
+
maplist,
|
|
626
|
+
validvoxels,
|
|
627
|
+
nativefmrishape,
|
|
628
|
+
theheader,
|
|
629
|
+
bidsbasedict,
|
|
630
|
+
filetype=theinputdata.filetype,
|
|
631
|
+
rt_floattype=rt_floattype,
|
|
632
|
+
cifti_hdr=theinputdata.cifti_hdr,
|
|
633
|
+
debug=True,
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
return resampref_y, resampnonosref_y, stoprefining, refinestopreason, genlagtc
|
|
@@ -49,24 +49,25 @@ def regressfrommaps(
|
|
|
49
49
|
nprocs_makelaggedtcs=1,
|
|
50
50
|
nprocs_regressionfilt=1,
|
|
51
51
|
regressderivs=0,
|
|
52
|
-
|
|
52
|
+
chunksize=50000,
|
|
53
53
|
showprogressbar=True,
|
|
54
54
|
alwaysmultiproc=False,
|
|
55
55
|
saveEVsandquit=False,
|
|
56
|
+
coefficientsonly=False,
|
|
56
57
|
debug=False,
|
|
57
58
|
):
|
|
58
59
|
if debug:
|
|
59
60
|
print("regressfrommaps: Starting")
|
|
60
|
-
print(f"{nprocs_makelaggedtcs=}")
|
|
61
|
-
print(f"{nprocs_regressionfilt=}")
|
|
62
|
-
print(f"{regressderivs=}")
|
|
63
|
-
print(f"{
|
|
64
|
-
print(f"{showprogressbar=}")
|
|
65
|
-
print(f"{alwaysmultiproc=}")
|
|
66
|
-
print(f"{mode=}")
|
|
67
|
-
print(f"{outputname=}")
|
|
68
|
-
print(f"{oversamptr=}")
|
|
69
|
-
print(f"{regressfiltthreshval=}")
|
|
61
|
+
print(f"\t{nprocs_makelaggedtcs=}")
|
|
62
|
+
print(f"\t{nprocs_regressionfilt=}")
|
|
63
|
+
print(f"\t{regressderivs=}")
|
|
64
|
+
print(f"\t{chunksize=}")
|
|
65
|
+
print(f"\t{showprogressbar=}")
|
|
66
|
+
print(f"\t{alwaysmultiproc=}")
|
|
67
|
+
print(f"\t{mode=}")
|
|
68
|
+
print(f"\t{outputname=}")
|
|
69
|
+
print(f"\t{oversamptr=}")
|
|
70
|
+
print(f"\t{regressfiltthreshval=}")
|
|
70
71
|
rt_floatset = np.float64
|
|
71
72
|
rt_floattype = "float64"
|
|
72
73
|
numvalidspatiallocs = np.shape(validvoxels)[0]
|
|
@@ -87,15 +88,16 @@ def regressfrommaps(
|
|
|
87
88
|
nprocs=nprocs_makelaggedtcs,
|
|
88
89
|
alwaysmultiproc=alwaysmultiproc,
|
|
89
90
|
showprogressbar=showprogressbar,
|
|
90
|
-
chunksize=
|
|
91
|
+
chunksize=chunksize,
|
|
91
92
|
rt_floatset=rt_floatset,
|
|
92
93
|
rt_floattype=rt_floattype,
|
|
94
|
+
debug=debug,
|
|
93
95
|
)
|
|
94
96
|
if debug:
|
|
95
|
-
print(f"{lagtimes.shape=}")
|
|
97
|
+
print(f"\t{lagtimes.shape=}")
|
|
96
98
|
threshmask = np.where(fitmask > 0, 1, 0)
|
|
97
|
-
print(f"{np.sum(threshmask)} nonzero mask voxels")
|
|
98
|
-
print(f"
|
|
99
|
+
print(f"\t{np.sum(threshmask)} nonzero mask voxels")
|
|
100
|
+
print(f"\tafter makelaggedtcs: shifted {voxelsprocessed_makelagged} timecourses")
|
|
99
101
|
if LGR is not None:
|
|
100
102
|
LGR.info("End lagged timecourse creation")
|
|
101
103
|
if TimingLGR is not None:
|
|
@@ -144,13 +146,15 @@ def regressfrommaps(
|
|
|
144
146
|
fitNorm,
|
|
145
147
|
movingsignal,
|
|
146
148
|
filtereddata,
|
|
149
|
+
coefficientsonly=coefficientsonly,
|
|
147
150
|
nprocs=nprocs_regressionfilt,
|
|
148
151
|
alwaysmultiproc=alwaysmultiproc,
|
|
149
152
|
showprogressbar=showprogressbar,
|
|
150
153
|
verbose=(LGR is not None),
|
|
151
|
-
|
|
154
|
+
chunksize=chunksize,
|
|
152
155
|
rt_floatset=rt_floatset,
|
|
153
156
|
rt_floattype=rt_floattype,
|
|
157
|
+
debug=debug,
|
|
154
158
|
)
|
|
155
159
|
|
|
156
160
|
if mode == "cvrmap":
|
|
@@ -158,19 +162,23 @@ def regressfrommaps(
|
|
|
158
162
|
fitcoeff *= 100.0
|
|
159
163
|
|
|
160
164
|
# determine what was removed
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
165
|
+
if not coefficientsonly:
|
|
166
|
+
removeddata = fmri_data_valid - filtereddata
|
|
167
|
+
noiseremoved = np.var(removeddata, axis=0)
|
|
168
|
+
if saveminimumsLFOfiltfiles:
|
|
169
|
+
tide_io.writebidstsv(
|
|
170
|
+
f"{outputname}_desc-lfofilterNoiseRemoved_timeseries",
|
|
171
|
+
noiseremoved,
|
|
172
|
+
1.0 / oversamptr,
|
|
173
|
+
starttime=0.0,
|
|
174
|
+
columns=[f"removedbyglm"],
|
|
175
|
+
extraheaderinfo={
|
|
176
|
+
"Description": "Variance over space of data removed by the sLFO filter at each timepoint"
|
|
177
|
+
},
|
|
178
|
+
append=False,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
if debug:
|
|
182
|
+
print("regressfrommaps: End\n\n")
|
|
175
183
|
|
|
176
184
|
return voxelsprocessed_regressionfilt, regressorset, evset
|
|
@@ -226,15 +226,14 @@ def retrolagtcs(args):
|
|
|
226
226
|
if usesharedmem:
|
|
227
227
|
if args.debug:
|
|
228
228
|
print("allocating shared memory")
|
|
229
|
-
fitNorm, fitNorm_shm = tide_util.allocshared(internalvalidspaceshapederivs, rt_outfloatset)
|
|
230
|
-
fitcoeff, fitcoeff_shm = tide_util.allocshared(
|
|
231
|
-
internalvalidspaceshapederivs, rt_outfloatset
|
|
232
|
-
)
|
|
233
|
-
lagtc, lagtc_shm = tide_util.allocshared(internalvalidfmrishape, rt_floatset)
|
|
234
229
|
else:
|
|
235
230
|
if args.debug:
|
|
236
231
|
print("allocating memory")
|
|
237
|
-
|
|
232
|
+
fitNorm, fitNorm_shm = tide_util.allocarray(internalvalidspaceshapederivs, rt_outfloattype, shared=usesharedmem)
|
|
233
|
+
fitcoeff, fitcoeff_shm = tide_util.allocarray(
|
|
234
|
+
internalvalidspaceshapederivs, rt_outfloattype, shared=usesharedmem
|
|
235
|
+
)
|
|
236
|
+
lagtc, lagtc_shm = tide_util.allocarray(internalvalidfmrishape, rt_floattype, shared=usesharedmem)
|
|
238
237
|
|
|
239
238
|
outputpath = os.path.dirname(args.outputroot)
|
|
240
239
|
rawsources = [
|