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.
Files changed (33) hide show
  1. rapidtide/DerivativeDelay.py +0 -4
  2. rapidtide/calcsimfunc.py +3 -0
  3. rapidtide/correlate.py +18 -1
  4. rapidtide/data/examples/src/testfmri +7 -4
  5. rapidtide/data/examples/src/testretro +15 -13
  6. rapidtide/happy_supportfuncs.py +70 -234
  7. rapidtide/helper_classes.py +4 -4
  8. rapidtide/io.py +21 -23
  9. rapidtide/maskutil.py +144 -0
  10. rapidtide/refinedelay.py +4 -7
  11. rapidtide/tests/cleanposttest +0 -1
  12. rapidtide/tests/test_cleanregressor.py +185 -0
  13. rapidtide/tests/test_fullrunrapidtide_v1.py +4 -0
  14. rapidtide/tests/test_fullrunrapidtide_v3.py +10 -0
  15. rapidtide/tests/test_fullrunrapidtide_v6.py +0 -1
  16. rapidtide/tests/test_fullrunrapidtide_v7.py +114 -0
  17. rapidtide/tests/test_io.py +58 -13
  18. rapidtide/tests/test_refinedelay.py +0 -3
  19. rapidtide/voxelData.py +126 -14
  20. rapidtide/workflows/cleanregressor.py +43 -6
  21. rapidtide/workflows/delayestimation.py +8 -13
  22. rapidtide/workflows/delayvar.py +11 -13
  23. rapidtide/workflows/happy.py +72 -179
  24. rapidtide/workflows/rapidtide.py +335 -329
  25. rapidtide/workflows/rapidtide_parser.py +115 -66
  26. rapidtide/workflows/regressfrommaps.py +12 -7
  27. rapidtide/workflows/retroregress.py +533 -337
  28. {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/METADATA +1 -1
  29. {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/RECORD +33 -31
  30. {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/WHEEL +1 -1
  31. {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/entry_points.txt +0 -0
  32. {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/licenses/LICENSE +0 -0
  33. {rapidtide-3.0.1.dist-info → rapidtide-3.0.3.dist-info}/top_level.txt +0 -0
@@ -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.1,
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 max \
9
- --acfix \
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-RAPIDTIDETEST_acfix
12
-
15
+ ../dst/sub-RAPIDTIDETEST
@@ -1,25 +1,27 @@
1
1
  #!/bin/bash
2
2
 
3
- #rapidtide \
4
- # --nprocs -1 \
5
- # --passes 3 \
6
- # --refinetype unweighted_average \
7
- # --numnull 0 \
8
- # --outputlevel max \
9
- # --regressderivs 1 \
10
- # sub-RAPIDTIDETEST.nii.gz \
11
- # ../dst/sub-RAPIDTIDETEST
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/wintest \
22
+ --alternateoutput ../dst/specialtest \
19
23
  --nprocs -1 \
20
- --outputlevel max \
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
@@ -999,211 +999,42 @@ def circularderivs(timecourse):
999
999
 
1000
1000
 
1001
1001
  def phaseproject(
1002
- datatoproject,
1003
- means,
1004
- destpoints,
1005
- numsteps,
1006
- timings,
1007
- cardfromfmri_sliceres,
1008
- instantaneous_cardiacphase,
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
- outputroot,
1013
- slicesamplerate,
1014
- pleth_sliceres,
1015
- mrsamplerate,
1016
- projmask_byslice,
1015
+ sliceoffsets,
1017
1016
  cardphasevals,
1018
- thetimes,
1019
- centric=True,
1020
- passstring="",
1021
- badpointlist=None,
1022
- congridbins=3.0,
1023
- gridkernel="kaiser",
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 = datatoproject.shape
1026
- # construct the destination arrays
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 = -datatoproject_byslice[validlocs, theslice, t]
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
- weight_byslice[validlocs, theslice, theindices[i]] += theweights[i]
1229
- rawapp_byslice[validlocs, theslice, theindices[i]] += (
1230
- theweights[i] * filteredmr
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 weight_byslice[validlocs[0], theslice, d] == 0.0:
1235
- weight_byslice[validlocs, theslice, d] = 1.0
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, :] / weight_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, :] / weight_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 == numpasses - 1):
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
- * datatoproject_byslice[theloc, theslice, :],
1268
- -thetimes[theslice][0],
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] = corrsearchvals[maxloc]
1272
- waveamp_byslice[theloc, theslice] = thecorrfunc_byslice[
1273
- theloc, theslice, maxloc
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 == numpasses - 1):
1114
+ if args.doaliasedcorrelation and (thispass > 0):
1280
1115
  for theloc in validlocs:
1281
1116
  thecorrfunc_byslice[theloc, theslice, :] = theAliasedCorrelator.apply(
1282
- -datatoproject_byslice[theloc, theslice, :],
1283
- -thetimes[theslice][0],
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] = corrsearchvals[maxloc]
1287
- waveamp_byslice[theloc, theslice] = thecorrfunc_byslice[
1288
- theloc, theslice, maxloc
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 app, rawapp, corrected_rawapp, normapp, weights, cine, derivatives
1136
+ return appflips_byslice
1300
1137
 
1301
1138
 
1302
- def upsampleimage(input_data, input_hdr, numsteps, sliceoffsets, slicesamplerate, outputroot):
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 = copy.deepcopy(input_hdr)
1343
- theheader["dim"][4] = timepoints * numsteps
1344
- theheader["pixdim"][4] = 1.0 / slicesamplerate
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")
@@ -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
- textio=False,
267
- fileiscifti=False,
266
+ filetype="nifti",
268
267
  rt_floattype="float64",
269
268
  ):
270
- if textio:
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
- if fileiscifti:
279
- spaceindex = len(destshape) - 1
280
- timeindex = spaceindex - 1
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
- internalspaceshape = int(destshape[0]) * int(destshape[1]) * int(destshape[2])
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
- textio=False,
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
- textio=textio,
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 textio:
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 not fileiscifti:
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: