rapidtide 3.0.2__py3-none-any.whl → 3.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rapidtide/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,10 +1,16 @@
1
1
  #!/bin/bash
2
2
 
3
3
  rapidtide \
4
+ --spatialfilt -1 \
4
5
  --nprocs -1 \
5
- --passes 3 \
6
- --outputlevel max \
7
- --regressderivs 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 \
8
14
  sub-RAPIDTIDETEST.nii.gz \
9
15
  ../dst/sub-RAPIDTIDETEST
10
16
 
@@ -15,7 +21,7 @@ retroregress \
15
21
  ../dst/sub-RAPIDTIDETEST \
16
22
  --alternateoutput ../dst/specialtest \
17
23
  --nprocs -1 \
18
- --outputlevel onlyregressors
24
+ --outputlevel normal
19
25
 
20
26
  #retroregress sub-RAPIDTIDETEST.nii.gz ../dst/sub-RAPIDTIDETEST --alternateoutput ../dst/0deriv_refined --nprocs -1 --regressderivs 0 --makepseudofile --outputlevel max --refinedelay --nofilterwithrefineddelay
21
27
  #retroregress sub-RAPIDTIDETEST.nii.gz ../dst/sub-RAPIDTIDETEST --alternateoutput ../dst/0deriv_refinedfit --nprocs -1 --regressderivs 0 --makepseudofile --outputlevel max --refinedelay
@@ -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
@@ -1996,12 +1996,14 @@ def colspectolist(colspec, debug=False):
1996
1996
  ("APARC_CORTGRAY", "1000-1035,2000-2035"),
1997
1997
  ("APARC_GRAY", "8-13,17-20,26-28,47-56,58-60,96,97,1000-1035,2000-2035"),
1998
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"),
1999
2000
  (
2000
2001
  "APARC_ALLBUTCSF",
2001
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",
2002
2003
  ),
2003
2004
  ("SSEG_GRAY", "3,8,10-13,16-18,26,42,47,49-54,58"),
2004
2005
  ("SSEG_WHITE", "2,7,41,46"),
2006
+ ("SSEG_CSF", "4,5,14,15,24,43,44"),
2005
2007
  )
2006
2008
  preprocessedranges = []
2007
2009
  for thisrange in theranges:
rapidtide/maskutil.py CHANGED
@@ -21,8 +21,10 @@ import logging
21
21
 
22
22
  import numpy as np
23
23
  from nilearn import masking
24
+ from sklearn.decomposition import PCA
24
25
 
25
26
  import rapidtide.io as tide_io
27
+ import rapidtide.miscmath as tide_math
26
28
  import rapidtide.stats as tide_stats
27
29
 
28
30
  LGR = logging.getLogger("GENERAL")
@@ -67,8 +69,16 @@ def readamask(
67
69
  thresh=None,
68
70
  maskname="the",
69
71
  tolerance=1.0e-3,
72
+ debug=False,
70
73
  ):
71
74
  LGR.debug(f"readamask called with filename: {maskfilename} vals: {valslist}")
75
+ if debug:
76
+ print("getmaskset:")
77
+ print(f"{maskname=}")
78
+ print(f"\tincludefilename={maskfilename}")
79
+ print(f"\tincludevals={valslist}")
80
+ print(f"\t{istext=}")
81
+ print(f"\t{tolerance=}")
72
82
  if istext:
73
83
  maskarray = tide_io.readvecs(maskfilename).astype("uint16")
74
84
  theshape = np.shape(maskarray)
@@ -109,11 +119,24 @@ def getmaskset(
109
119
  extramaskthresh=0.1,
110
120
  istext=False,
111
121
  tolerance=1.0e-3,
122
+ debug=False,
112
123
  ):
113
124
  internalincludemask = None
114
125
  internalexcludemask = None
115
126
  internalextramask = None
116
127
 
128
+ if debug:
129
+ print("getmaskset:")
130
+ print(f"{maskname=}")
131
+ print(f"\t{includename=}")
132
+ print(f"\t{includevals=}")
133
+ print(f"\t{excludename=}")
134
+ print(f"\t{excludevals=}")
135
+ print(f"\t{istext=}")
136
+ print(f"\t{tolerance=}")
137
+ print(f"\t{extramask=}")
138
+ print(f"\t{extramaskthresh=}")
139
+
117
140
  if includename is not None:
118
141
  LGR.info(f"constructing {maskname} include mask")
119
142
  theincludemask = readamask(
@@ -178,3 +201,124 @@ def getmaskset(
178
201
  )
179
202
 
180
203
  return internalincludemask, internalexcludemask, internalextramask
204
+
205
+
206
+ def getregionsignal(
207
+ indata,
208
+ filter=None,
209
+ Fs=1.0,
210
+ includemask=None,
211
+ excludemask=None,
212
+ signalgenmethod="sum",
213
+ pcacomponents=0.8,
214
+ signame="global mean",
215
+ rt_floatset=np.float64,
216
+ debug=False,
217
+ ):
218
+ # Start with all voxels
219
+ themask = indata[:, 0] * 0 + 1
220
+
221
+ # modify the mask if needed
222
+ if includemask is not None:
223
+ themask = themask * includemask
224
+ if excludemask is not None:
225
+ themask = themask * (1 - excludemask)
226
+
227
+ # combine all the voxels using one of the three methods
228
+ globalmean = rt_floatset(indata[0, :])
229
+ thesize = np.shape(themask)
230
+ numvoxelsused = int(np.sum(np.where(themask > 0.0, 1, 0)))
231
+ selectedvoxels = indata[np.where(themask > 0.0), :][0]
232
+ if debug:
233
+ print(f"getregionsignal: {selectedvoxels.shape=}")
234
+ LGR.info(f"constructing global mean signal using {signalgenmethod}")
235
+ if signalgenmethod == "sum":
236
+ globalmean = np.mean(selectedvoxels, axis=0)
237
+ globalmean -= np.mean(globalmean)
238
+ elif signalgenmethod == "meanscale":
239
+ themean = np.mean(indata, axis=1)
240
+ for vox in range(0, thesize[0]):
241
+ if themask[vox] > 0.0:
242
+ if themean[vox] != 0.0:
243
+ globalmean += indata[vox, :] / themean[vox] - 1.0
244
+ elif signalgenmethod == "pca":
245
+ themean = np.mean(indata, axis=1)
246
+ thevar = np.var(indata, axis=1)
247
+ scaledvoxels = selectedvoxels * 0.0
248
+ for vox in range(0, selectedvoxels.shape[0]):
249
+ scaledvoxels[vox, :] = selectedvoxels[vox, :] - themean[vox]
250
+ if thevar[vox] > 0.0:
251
+ scaledvoxels[vox, :] = selectedvoxels[vox, :] / thevar[vox]
252
+ try:
253
+ thefit = PCA(n_components=pcacomponents).fit(np.transpose(scaledvoxels))
254
+ except ValueError:
255
+ if pcacomponents == "mle":
256
+ LGR.warning("mle estimation failed - falling back to pcacomponents=0.8")
257
+ thefit = PCA(n_components=0.8).fit(np.transpose(scaledvoxels))
258
+ else:
259
+ raise ValueError("unhandled math exception in PCA refinement - exiting")
260
+
261
+ varex = 100.0 * np.cumsum(thefit.explained_variance_ratio_)[len(thefit.components_) - 1]
262
+ thetransform = thefit.transform(np.transpose(scaledvoxels))
263
+ if debug:
264
+ print(f"getregionsignal: {thetransform.shape=}")
265
+ globalmean = np.mean(thetransform, axis=0)
266
+ globalmean -= np.mean(globalmean)
267
+ if debug:
268
+ print(f"getregionsignal: {varex=}")
269
+ LGR.info(
270
+ f"Using {len(thefit.components_)} component(s), accounting for "
271
+ f"{varex:.2f}% of the variance"
272
+ )
273
+ elif signalgenmethod == "random":
274
+ globalmean = np.random.standard_normal(size=len(globalmean))
275
+ else:
276
+ raise ValueError(f"illegal signal generation method: {signalgenmethod}")
277
+ LGR.info(f"used {numvoxelsused} voxels to calculate {signame} signal")
278
+ if filter is not None:
279
+ globalmean = filter.apply(Fs, globalmean)
280
+ if debug:
281
+ print(f"getregionsignal: {globalmean=}")
282
+ return tide_math.stdnormalize(globalmean), themask
283
+
284
+
285
+ def saveregionaltimeseries(
286
+ tcdesc,
287
+ tcname,
288
+ fmridata,
289
+ includemask,
290
+ fmrifreq,
291
+ outputname,
292
+ filter=None,
293
+ initfile=False,
294
+ excludemask=None,
295
+ filedesc="regional",
296
+ suffix="",
297
+ signalgenmethod="sum",
298
+ pcacomponents=0.8,
299
+ rt_floatset=np.float64,
300
+ debug=False,
301
+ ):
302
+ thetimecourse, themask = getregionsignal(
303
+ fmridata,
304
+ filter=filter,
305
+ Fs=fmrifreq,
306
+ includemask=includemask,
307
+ excludemask=excludemask,
308
+ signalgenmethod=signalgenmethod,
309
+ pcacomponents=pcacomponents,
310
+ signame=tcdesc,
311
+ rt_floatset=rt_floatset,
312
+ debug=debug,
313
+ )
314
+ tide_io.writebidstsv(
315
+ f"{outputname}_desc-{filedesc}_timeseries",
316
+ thetimecourse,
317
+ fmrifreq,
318
+ columns=[f"{tcname}{suffix}"],
319
+ extraheaderinfo={
320
+ "Description": "Regional timecourse averages",
321
+ },
322
+ append=(not initfile),
323
+ )
324
+ return thetimecourse, themask
@@ -0,0 +1,185 @@
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 os
20
+
21
+ import matplotlib as mpl
22
+ import numpy as np
23
+
24
+ import rapidtide.filter as tide_filt
25
+ import rapidtide.helper_classes as tide_classes
26
+ import rapidtide.miscmath as tide_math
27
+ import rapidtide.resample as tide_resample
28
+ import rapidtide.workflows.cleanregressor as tide_cleanregressor
29
+ from rapidtide.tests.utils import get_examples_path, get_test_temp_path, mse
30
+
31
+
32
+ def test_cleanregressor(debug=False, local=False, displayplots=False):
33
+ # set input and output directories
34
+ if local:
35
+ exampleroot = "../data/examples/src"
36
+ testtemproot = "./tmp"
37
+ else:
38
+ exampleroot = get_examples_path()
39
+ testtemproot = get_test_temp_path()
40
+
41
+ outputname = os.path.join(testtemproot, "cleanregressortest")
42
+ thepass = 1
43
+ padtrs = 30
44
+ fmrifreq = 1.0
45
+ oversampfac = 2
46
+ oversampfreq = oversampfac * fmrifreq
47
+ theprefilter = tide_filt.NoncausalFilter("lfo")
48
+ lagmin = -30
49
+ lagmax = 30
50
+ lagmininpts = int((lagmin * oversampfreq) - 0.5)
51
+ lagmaxinpts = int((lagmax * oversampfreq) + 0.5)
52
+ lagmod = 1000.0
53
+ noiseamp = 0.25
54
+ detrendorder = 3
55
+ windowfunc = "hamming"
56
+
57
+ tclen = 500
58
+ osvalidsimcalcstart = 0
59
+ osvalidsimcalcend = tclen * oversampfac
60
+
61
+ theCorrelator = tide_classes.Correlator(
62
+ Fs=oversampfreq,
63
+ ncprefilter=theprefilter,
64
+ detrendorder=1,
65
+ windowfunc="hamming",
66
+ corrweighting="phat",
67
+ )
68
+ theFitter = tide_classes.SimilarityFunctionFitter(
69
+ lagmod=lagmod,
70
+ lagmin=lagmin,
71
+ lagmax=lagmax,
72
+ debug=debug,
73
+ allowhighfitamps=True,
74
+ enforcethresh=False,
75
+ zerooutbadfit=False,
76
+ )
77
+
78
+ # make a reference timecourse
79
+ rng = np.random.default_rng(seed=1234)
80
+ basewave = theprefilter.apply(fmrifreq, rng.normal(loc=0.0, scale=1.0, size=tclen))
81
+ noisewave = rng.normal(loc=0.0, scale=noiseamp, size=tclen)
82
+ theparamsets = [
83
+ [2.0, 0.0, False, 0],
84
+ [2.5, 0.8, True, 0],
85
+ [5.0, 0.5, True, 0],
86
+ [7.5, 0.25, True, 100],
87
+ [10.0, 0.1, True, 0],
88
+ ]
89
+ for paramset in theparamsets:
90
+ echotime = paramset[0]
91
+ echoamp = paramset[1]
92
+ check_autocorrelation = paramset[2]
93
+ osvalidsimcalcstart = paramset[3]
94
+ if debug:
95
+ print(
96
+ "**********Start******************************************************************"
97
+ )
98
+ print(f"{echotime=}, {echoamp=}, {check_autocorrelation=}, {osvalidsimcalcstart=}")
99
+ print(
100
+ "*********************************************************************************"
101
+ )
102
+ theechotc, dummy, dummy, dummy = tide_resample.timeshift(
103
+ basewave, echotime * oversampfreq, padtrs, doplot=displayplots, debug=debug
104
+ )
105
+ resampnonosref_y = basewave + echoamp * theechotc + noisewave
106
+ resampref_y = tide_resample.upsample(resampnonosref_y, fmrifreq, oversampfreq)
107
+ theCorrelator.setreftc(resampnonosref_y)
108
+ referencetc = tide_math.corrnormalize(
109
+ resampref_y[osvalidsimcalcstart:],
110
+ detrendorder=detrendorder,
111
+ windowfunc=windowfunc,
112
+ )
113
+
114
+ resampref_y = tide_resample.upsample(resampnonosref_y, fmrifreq, oversampfreq)
115
+
116
+ (
117
+ cleaned_resampref_y,
118
+ cleaned_referencetc,
119
+ cleaned_nonosreferencetc,
120
+ despeckle_thresh,
121
+ sidelobeamp,
122
+ sidelobetime,
123
+ lagmod,
124
+ acwidth,
125
+ absmaxsigma,
126
+ ) = tide_cleanregressor.cleanregressor(
127
+ outputname,
128
+ thepass,
129
+ referencetc,
130
+ resampref_y,
131
+ resampnonosref_y,
132
+ fmrifreq,
133
+ oversampfreq,
134
+ osvalidsimcalcstart,
135
+ osvalidsimcalcend,
136
+ lagmininpts,
137
+ lagmaxinpts,
138
+ theFitter,
139
+ theCorrelator,
140
+ lagmin,
141
+ lagmax,
142
+ LGR=None,
143
+ check_autocorrelation=check_autocorrelation,
144
+ fix_autocorrelation=True,
145
+ despeckle_thresh=5.0,
146
+ lthreshval=0.0,
147
+ fixdelay=False,
148
+ detrendorder=detrendorder,
149
+ windowfunc=windowfunc,
150
+ respdelete=False,
151
+ displayplots=displayplots,
152
+ debug=debug,
153
+ rt_floattype="float64",
154
+ rt_floatset=np.float64,
155
+ )
156
+ print(f"\t{len(referencetc)=}")
157
+ print(f"\t{len(resampref_y)=}")
158
+ print(f"\t{len(resampnonosref_y)=}")
159
+ print(f"\t{len(cleaned_resampref_y)=}")
160
+ print(f"\t{len(cleaned_referencetc)=}")
161
+ print(f"\t{len(cleaned_nonosreferencetc)=}")
162
+ print(f"\t{check_autocorrelation=}")
163
+ print(f"\t{despeckle_thresh=}")
164
+ print(f"\t{sidelobeamp=}")
165
+ print(f"\t{sidelobetime=}")
166
+ print(f"\t{lagmod=}")
167
+ print(f"\t{acwidth=}")
168
+ print(f"\t{absmaxsigma=}")
169
+ assert len(referencetc) == len(cleaned_referencetc)
170
+ assert len(resampref_y) == len(cleaned_resampref_y)
171
+ assert len(resampnonosref_y) == len(cleaned_nonosreferencetc)
172
+
173
+ if debug:
174
+ print(
175
+ "*********************************************************************************"
176
+ )
177
+ print(f"{echotime=}, {echoamp=}, {check_autocorrelation=}, {osvalidsimcalcstart=}")
178
+ print(
179
+ "**************End****************************************************************"
180
+ )
181
+
182
+
183
+ if __name__ == "__main__":
184
+ mpl.use("TkAgg")
185
+ test_cleanregressor(debug=True, local=True, displayplots=True)
@@ -23,6 +23,7 @@ import matplotlib as mpl
23
23
  import rapidtide.qualitycheck as rapidtide_quality
24
24
  import rapidtide.workflows.rapidtide as rapidtide_workflow
25
25
  import rapidtide.workflows.rapidtide_parser as rapidtide_parser
26
+ import rapidtide.workflows.retroregress as rapidtide_retroregress
26
27
  from rapidtide.tests.utils import get_examples_path, get_test_temp_path
27
28
 
28
29
 
@@ -56,6 +57,8 @@ def test_fullrunrapidtide_v1(debug=False, local=False, displayplots=False):
56
57
  rapidtide_workflow.rapidtide_main(rapidtide_parser.process_args(inputargs=inputargs))
57
58
  rapidtide_quality.qualitycheck(os.path.join(testtemproot, "sub-RAPIDTIDETEST1"))
58
59
 
60
+
61
+ # test fixval
59
62
  inputargs = [
60
63
  os.path.join(exampleroot, "sub-RAPIDTIDETEST.nii.gz"),
61
64
  os.path.join(testtemproot, "sub-RAPIDTIDETEST1_fixval"),
@@ -77,6 +80,7 @@ def test_fullrunrapidtide_v1(debug=False, local=False, displayplots=False):
77
80
  ]
78
81
  rapidtide_workflow.rapidtide_main(rapidtide_parser.process_args(inputargs=inputargs))
79
82
 
83
+ # test fixmap
80
84
  inputargs = [
81
85
  os.path.join(exampleroot, "sub-RAPIDTIDETEST.nii.gz"),
82
86
  os.path.join(testtemproot, "sub-RAPIDTIDETEST1_fixmap"),
@@ -0,0 +1,114 @@
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 os
20
+
21
+ import matplotlib as mpl
22
+ import numpy as np
23
+
24
+ import rapidtide.io as tide_io
25
+ import rapidtide.workflows.rapidtide as rapidtide_workflow
26
+ import rapidtide.workflows.rapidtide_parser as rapidtide_parser
27
+ import rapidtide.workflows.retroregress as rapidtide_retroregress
28
+ from rapidtide.tests.utils import get_examples_path, get_test_temp_path, mse
29
+
30
+
31
+ def test_fullrunrapidtide_v7(debug=False, local=False, displayplots=False):
32
+ # set input and output directories
33
+ if local:
34
+ exampleroot = "../data/examples/src"
35
+ testtemproot = "./tmp"
36
+ else:
37
+ exampleroot = get_examples_path()
38
+ testtemproot = get_test_temp_path()
39
+
40
+ # test anatomic masks
41
+ inputargs = [
42
+ os.path.join(exampleroot, "sub-RAPIDTIDETEST.nii.gz"),
43
+ os.path.join(testtemproot, "sub-RAPIDTIDETEST_seg"),
44
+ "--nprocs",
45
+ "-1",
46
+ "--passes",
47
+ "3",
48
+ "--brainmask",
49
+ os.path.join(exampleroot, "sub-RAPIDTIDETEST_brainmask.nii.gz"),
50
+ "--graymattermask",
51
+ os.path.join(exampleroot, "sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_GRAY"),
52
+ "--whitemattermask",
53
+ os.path.join(exampleroot, "sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_WHITE"),
54
+ "--csfmask",
55
+ os.path.join(exampleroot, "sub-RAPIDTIDETEST_synthseg.nii.gz:SSEG_CSF"),
56
+ ]
57
+ rapidtide_workflow.rapidtide_main(rapidtide_parser.process_args(inputargs=inputargs))
58
+
59
+ inputargs = [
60
+ os.path.join(exampleroot, "sub-RAPIDTIDETEST.nii.gz"),
61
+ os.path.join(testtemproot, "sub-RAPIDTIDETEST_seg"),
62
+ "--alternateoutput",
63
+ os.path.join(testtemproot, "segtest"),
64
+ "--nprocs",
65
+ "-1",
66
+ "--outputlevel",
67
+ "max",
68
+ ]
69
+ rapidtide_retroregress.retroregress(rapidtide_retroregress.process_args(inputargs=inputargs))
70
+
71
+ inputargs = [
72
+ os.path.join(exampleroot, "sub-RAPIDTIDETEST.nii.gz"),
73
+ os.path.join(testtemproot, "sub-RAPIDTIDETEST_seg"),
74
+ "--alternateoutput",
75
+ os.path.join(testtemproot, "regressoronly"),
76
+ "--nprocs",
77
+ "-1",
78
+ "--outputlevel",
79
+ "onlyregressors",
80
+ ]
81
+ rapidtide_retroregress.retroregress(rapidtide_retroregress.process_args(inputargs=inputargs))
82
+
83
+ # check to see that rapidtide and retroregress output match
84
+ msethresh = 1e-6
85
+ aethresh = 2
86
+ tclist = ["brain", "GM", "WM", "CSF"]
87
+ for timecourse in tclist:
88
+ infilespec = os.path.join(
89
+ testtemproot,
90
+ f"sub-RAPIDTIDETEST_seg_desc-regionalpostfilter_timeseries.json:{timecourse}",
91
+ )
92
+ insamplerate, instarttime, incolumns, indata, incompressed, infiletype = (
93
+ tide_io.readvectorsfromtextfile(infilespec, onecol=True, debug=debug)
94
+ )
95
+ outfilespec = os.path.join(
96
+ testtemproot, f"segtest_desc-regionalpostfilter_timeseries.json:{timecourse}"
97
+ )
98
+ outsamplerate, outstarttime, outcolumns, outdata, outcompressed, outfiletype = (
99
+ tide_io.readvectorsfromtextfile(outfilespec, onecol=True, debug=debug)
100
+ )
101
+ assert insamplerate == outsamplerate
102
+ assert instarttime == outstarttime
103
+ assert incompressed == outcompressed
104
+ assert infiletype == outfiletype
105
+ assert incolumns == outcolumns
106
+ assert indata.shape == outdata.shape
107
+ assert indata.shape[0] == indata.shape[0]
108
+ assert mse(indata, outdata) < msethresh
109
+ np.testing.assert_almost_equal(indata, outdata, aethresh)
110
+
111
+
112
+ if __name__ == "__main__":
113
+ mpl.use("TkAgg")
114
+ test_fullrunrapidtide_v7(debug=True, local=True, displayplots=True)