rapidtide 3.0a5__py3-none-any.whl → 3.0a7__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/correlate.py CHANGED
@@ -703,9 +703,12 @@ class AliasedCorrelator:
703
703
  """
704
704
 
705
705
  def __init__(self, hiressignal, hires_Fs, numsteps):
706
- self.hiressignal = tide_math.corrnormalize(hiressignal)
707
706
  self.hires_Fs = hires_Fs
708
707
  self.numsteps = numsteps
708
+ self.sethiressignal(hiressignal)
709
+
710
+ def sethiressignal(self, hiressignal):
711
+ self.hiressignal = tide_math.corrnormalize(hiressignal)
709
712
  self.corrlen = len(self.hiressignal) * 2 + 1
710
713
  self.corrx = (
711
714
  np.linspace(0.0, self.corrlen, num=self.corrlen) / self.hires_Fs
@@ -735,10 +738,9 @@ class AliasedCorrelator:
735
738
  print(offset, self.numsteps)
736
739
  osvec = self.hiressignal * 0.0
737
740
  osvec[offset :: self.numsteps] = loressignal[:]
738
- corrfunc = (
739
- tide_corr.fastcorrelate(tide_math.corrnormalize(osvec), self.hiressignal)
740
- * self.numsteps
741
- )
741
+ corrfunc = tide_corr.fastcorrelate(
742
+ tide_math.corrnormalize(osvec), self.hiressignal
743
+ ) * np.sqrt(self.numsteps)
742
744
  return corrfunc
743
745
 
744
746
 
@@ -9,13 +9,13 @@
9
9
  # --infotag tag2 value2 \
10
10
  # --model model_revised
11
11
 
12
- happy \
13
- sub-HAPPYTEST.nii.gz \
14
- sub-HAPPYTEST.json \
15
- ../dst/happy \
16
- --mklthreads 8 \
17
- --model model_revised \
18
- --spatialglm --aliasedcorrelation
12
+ #happy \
13
+ #sub-HAPPYTEST.nii.gz \
14
+ #sub-HAPPYTEST.json \
15
+ #../dst/happy \
16
+ #--mklthreads 8 \
17
+ #--model model_revised \
18
+ #--spatialglm --aliasedcorrelation
19
19
 
20
20
 
21
21
  #happy \
@@ -62,9 +62,13 @@ happy \
62
62
  #--dodlfilter
63
63
 
64
64
 
65
- #happy \
66
- #ses-060_bold_trunc.nii.gz \
67
- #ses-060_bold_trunc.json \
68
- #../dst/happy_motion \
69
- #--mklthreads 8 \
70
- #--motionfile ses-060_bold_trunc_prefiltered_func_data_mcf.par
65
+ happy \
66
+ sub-HAPPYTEST.nii.gz \
67
+ sub-HAPPYTEST.json \
68
+ ../dst/happy
69
+
70
+ happy \
71
+ sub-HAPPYTEST.nii.gz \
72
+ sub-HAPPYTEST.json \
73
+ ../dst/happy_aliasedcorrelation \
74
+ --aliasedcorrelation
@@ -145,7 +145,7 @@ def cardiacsig(thisphase, amps=(1.0, 0.0, 0.0), phases=None, overallphase=0.0):
145
145
 
146
146
  def cardiacfromimage(
147
147
  normdata_byslice,
148
- estmask_byslice,
148
+ estweights_byslice,
149
149
  numslices,
150
150
  timepoints,
151
151
  tr,
@@ -182,7 +182,7 @@ def cardiacfromimage(
182
182
 
183
183
  # make sure there is an appflips array
184
184
  if appflips_byslice is None:
185
- appflips_byslice = estmask_byslice * 0.0 + 1.0
185
+ appflips_byslice = estweights_byslice * 0.0 + 1.0
186
186
  else:
187
187
  if arteriesonly:
188
188
  appflips_byslice[np.where(appflips_byslice > 0.0)] = 0.0
@@ -196,22 +196,22 @@ def cardiacfromimage(
196
196
  if not verbose:
197
197
  print("Averaging slices...")
198
198
  if fliparteries:
199
- thismask_byslice = appflips_byslice.astype(np.int64) * estmask_byslice
199
+ theseweights_byslice = appflips_byslice.astype(np.float64) * estweights_byslice
200
200
  else:
201
- thismask_byslice = estmask_byslice
201
+ theseweights_byslice = estweights_byslice
202
202
  for theslice in range(numslices):
203
203
  if verbose:
204
204
  print("Averaging slice", theslice)
205
205
  if usemask:
206
- validestvoxels = np.where(np.abs(thismask_byslice[:, theslice]) > 0)[0]
206
+ validestvoxels = np.where(np.abs(theseweights_byslice[:, theslice]) > 0)[0]
207
207
  else:
208
- validestvoxels = np.where(np.abs(thismask_byslice[:, theslice] >= 0))[0]
208
+ validestvoxels = np.where(np.abs(theseweights_byslice[:, theslice] >= 0))[0]
209
209
  if len(validestvoxels) > 0:
210
210
  if madnorm:
211
211
  sliceavs[theslice, :], slicenorms[theslice] = tide_math.madnormalize(
212
212
  np.mean(
213
213
  normdata_byslice[validestvoxels, theslice, :]
214
- * thismask_byslice[validestvoxels, theslice, np.newaxis],
214
+ * theseweights_byslice[validestvoxels, theslice, np.newaxis],
215
215
  axis=0,
216
216
  ),
217
217
  returnnormfac=True,
@@ -219,7 +219,7 @@ def cardiacfromimage(
219
219
  else:
220
220
  sliceavs[theslice, :] = np.mean(
221
221
  normdata_byslice[validestvoxels, theslice, :]
222
- * thismask_byslice[validestvoxels, theslice, np.newaxis],
222
+ * theseweights_byslice[validestvoxels, theslice, np.newaxis],
223
223
  axis=0,
224
224
  )
225
225
  slicenorms[theslice] = 1.0
@@ -1241,3 +1241,51 @@ def phaseproject(
1241
1241
  normapp_byslice[validlocs, theslice, :] = np.nan_to_num(
1242
1242
  app_byslice[validlocs, theslice, :] / means_byslice[validlocs, theslice, None]
1243
1243
  )
1244
+ return app, rawapp, corrected_rawapp, normapp, weights, cine, derivatives
1245
+
1246
+
1247
+ def upsampleimage(input_data, input_hdr, numsteps, sliceoffsets, slicesamplerate, outputroot):
1248
+ fmri_data = input_data.byvol()
1249
+ timepoints = input_data.timepoints
1250
+ xsize = input_data.xsize
1251
+ ysize = input_data.ysize
1252
+ numslices = input_data.numslices
1253
+
1254
+ # allocate the image
1255
+ print(f"upsampling fmri data by a factor of {numsteps}")
1256
+ upsampleimage = np.zeros((xsize, ysize, numslices, numsteps * timepoints), dtype=float)
1257
+ upsampleimage_byslice = upsampleimage.reshape(xsize * ysize, numslices, numsteps * timepoints)
1258
+
1259
+ # demean the raw data
1260
+ meanfmri = fmri_data.mean(axis=1)
1261
+ demeaned_data = fmri_data - meanfmri[:, None]
1262
+
1263
+ # drop in the raw data
1264
+ for theslice in range(numslices):
1265
+ upsampleimage[
1266
+ :, :, theslice, sliceoffsets[theslice] : timepoints * numsteps : numsteps
1267
+ ] = demeaned_data.reshape((xsize, ysize, numslices, timepoints))[:, :, theslice, :]
1268
+
1269
+ upsampleimage_byslice = upsampleimage.reshape(xsize * ysize, numslices, timepoints * numsteps)
1270
+
1271
+ # interpolate along the slice direction
1272
+ thedstlocs = np.linspace(0, numslices, num=len(sliceoffsets), endpoint=False)
1273
+ print(f"len(destlocst), destlocs: {len(thedstlocs)}, {thedstlocs}")
1274
+ for thetimepoint in range(0, timepoints * numsteps):
1275
+ thestep = thetimepoint % numsteps
1276
+ print(f"interpolating step {thestep}")
1277
+ thesrclocs = np.where(sliceoffsets == thestep)[0]
1278
+ print(f"timepoint: {thetimepoint}, sourcelocs: {thesrclocs}")
1279
+ for thexyvoxel in range(xsize * ysize):
1280
+ theinterps = np.interp(
1281
+ thedstlocs,
1282
+ 1.0 * thesrclocs,
1283
+ upsampleimage_byslice[thexyvoxel, thesrclocs, thetimepoint],
1284
+ )
1285
+ upsampleimage_byslice[thexyvoxel, :, thetimepoint] = 1.0 * theinterps
1286
+
1287
+ theheader = copy.deepcopy(input_hdr)
1288
+ theheader["dim"][4] = timepoints * numsteps
1289
+ theheader["pixdim"][4] = 1.0 / slicesamplerate
1290
+ tide_io.savetonifti(upsampleimage, theheader, outputroot + "_upsampled")
1291
+ print("upsampling complete")
rapidtide/io.py CHANGED
@@ -1160,13 +1160,15 @@ def getslicetimesfromfile(slicetimename):
1160
1160
  for idx, thetime in enumerate(slicetimelist):
1161
1161
  slicetimes[idx] = float(thetime)
1162
1162
  normalizedtotr = False
1163
+ fileisbidsjson = True
1163
1164
  except KeyError:
1164
1165
  print(slicetimename, "is not a valid BIDS sidecar file")
1165
1166
  sys.exit()
1166
1167
  else:
1167
1168
  slicetimes = readvec(slicetimename)
1168
1169
  normalizedtotr = True
1169
- return slicetimes, normalizedtotr
1170
+ fileisbidsjson = False
1171
+ return slicetimes, normalizedtotr, fileisbidsjson
1170
1172
 
1171
1173
 
1172
1174
  def readbidssidecar(inputfilename):
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding: utf-8 -*-
3
3
  #
4
- # Copyright 2016-2024 Blaise Frederick
4
+ # Copyright 2016-2025 Blaise Frederick
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ def test_fullrunhappy_v2(debug=False, displayplots=False):
31
31
  os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
32
32
  os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
33
33
  os.path.join(get_test_temp_path(), "happyout2"),
34
- "--estmask",
34
+ "--estweights",
35
35
  os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
36
36
  "--projmask",
37
37
  os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
@@ -31,7 +31,7 @@ def test_fullrunhappy_v3(debug=False, displayplots=False):
31
31
  os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
32
32
  os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
33
33
  os.path.join(get_test_temp_path(), "happyout3"),
34
- "--estmask",
34
+ "--estweights",
35
35
  os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
36
36
  "--projmask",
37
37
  os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
@@ -31,7 +31,7 @@ def test_fullrunhappy_v4(debug=False, displayplots=False):
31
31
  os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
32
32
  os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
33
33
  os.path.join(get_test_temp_path(), "happyout4"),
34
- "--estmask",
34
+ "--estweights",
35
35
  os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
36
36
  "--projmask",
37
37
  os.path.join(get_examples_path(), "sub-HAPPYTEST_smallmask.nii.gz"),
@@ -39,6 +39,8 @@ def test_fullrunhappy_v4(debug=False, displayplots=False):
39
39
  "-1",
40
40
  "--model",
41
41
  "model_revised",
42
+ "--motionfile",
43
+ os.path.join(get_examples_path(), "sub-HAPPYTEST_mcf.par"),
42
44
  ]
43
45
  happy_workflow.happy_main(happy_parser.process_args(inputargs=inputargs))
44
46
 
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 2016-2024 Blaise Frederick
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ #
19
+ import os
20
+
21
+ import matplotlib as mpl
22
+
23
+ import rapidtide.workflows.happy as happy_workflow
24
+ import rapidtide.workflows.happy_parser as happy_parser
25
+ from rapidtide.tests.utils import get_examples_path, get_test_temp_path
26
+
27
+
28
+ def test_fullrunhappy_v4(debug=False, displayplots=False):
29
+ # run happy
30
+ inputargs = [
31
+ os.path.join(get_examples_path(), "sub-HAPPYTEST.nii.gz"),
32
+ os.path.join(get_examples_path(), "sub-HAPPYTEST.json"),
33
+ os.path.join(get_test_temp_path(), "happyout5"),
34
+ "--model",
35
+ "model_revised",
36
+ "--motionfile",
37
+ os.path.join(get_examples_path(), "sub-HAPPYTEST_mcf.par"),
38
+ "--nomotderiv",
39
+ "--nomotorthogonalize",
40
+ "--motfiltorder",
41
+ "2",
42
+ "--numskip",
43
+ "5",
44
+ "--motskip",
45
+ "5",
46
+ "--motionhp",
47
+ "0.01",
48
+ "--motionlp",
49
+ "2.0",
50
+ ]
51
+ happy_workflow.happy_main(happy_parser.process_args(inputargs=inputargs))
52
+
53
+
54
+ if __name__ == "__main__":
55
+ mpl.use("TkAgg")
56
+ test_fullrunhappy_v4(debug=True, displayplots=True)
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 RawArray, shared_memory
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
@@ -236,16 +236,23 @@ 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)
240
+ confoundregressors, confoundregressorlabels = tide_fit.calcexpandedregressors(
241
+ motiondict,
242
+ labels=["xtrans", "ytrans", "ztrans", "xrot", "yrot", "zrot"],
243
+ deriv=args.motfilt_deriv,
244
+ order=args.motfilt_order,
245
+ )
239
246
  (motionregressors, motionregressorlabels, filtereddata, confoundr2) = (
240
247
  tide_glmpass.confoundregress(
241
- args.motionfilename,
248
+ confoundregressors,
249
+ confoundregressorlabels,
242
250
  fmri_data[validprojvoxels, :],
243
251
  tr,
244
252
  orthogonalize=args.orthogonalize,
245
- motstart=args.motskip,
246
- motionhp=args.motionhp,
247
- motionlp=args.motionlp,
248
- deriv=args.motfilt_deriv,
253
+ tcstart=args.motskip,
254
+ tchp=args.motionhp,
255
+ tclp=args.motionlp,
249
256
  )
250
257
  )
251
258
  if confoundr2 is None:
@@ -279,10 +286,21 @@ def happy_main(argparsingfunc):
279
286
  timings.append(["Motion filtered data saved", time.time(), numspatiallocs, "voxels"])
280
287
 
281
288
  # get slice times
282
- slicetimes, normalizedtotr = tide_io.getslicetimesfromfile(slicetimename)
289
+ slicetimes, normalizedtotr, fileisbidsjson = tide_io.getslicetimesfromfile(slicetimename)
283
290
  if normalizedtotr and not args.slicetimesareinseconds:
284
291
  slicetimes *= tr
285
-
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
286
304
  timings.append(["Slice times determined", time.time(), None, None])
287
305
 
288
306
  # normalize the input data
@@ -312,30 +330,32 @@ def happy_main(argparsingfunc):
312
330
  tide_io.savetonifti(mads.reshape((xsize, ysize, numslices)), theheader, madsfilename)
313
331
 
314
332
  # read in estimation mask if present. Otherwise, otherwise use intensity mask.
315
- infodict["estmaskname"] = args.estmaskname
333
+ infodict["estweightsname"] = args.estweightsname
316
334
  if args.debug:
317
- print(args.estmaskname)
318
- if args.estmaskname is not None:
319
- tide_util.logmem("before reading in estmask")
320
- estmask = happy_support.readextmask(
321
- args.estmaskname, nim_hdr, xsize, ysize, numslices, args.debug
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
322
340
  )
323
- # * np.float64(mask_byslice)
324
- estmask_byslice = estmask.reshape(xsize * ysize, numslices)
325
- print("using estmask from file", args.estmaskname)
341
+ estweights_byslice = estweights.reshape(xsize * ysize, numslices)
342
+ print("using estweights from file", args.estweightsname)
326
343
  numpasses = 1
327
344
  else:
328
345
  # just fall back to the intensity mask
329
- estmask_byslice = mask_byslice.astype("float64")
346
+ estweights_byslice = mask_byslice.astype("float64")
330
347
  numpasses = 2
331
348
  print("Not using separate estimation mask - doing initial estimate using intensity mask")
332
- if args.fliparteries:
333
- # add another pass to refine the waveform after getting the new appflips
349
+
350
+ # add another pass to refine the waveform after getting the new appflips
351
+ if args.fliparteries or args.doaliasedcorrelation:
334
352
  numpasses += 1
335
- print("Adding a pass to regenerate cardiac waveform using better appflips")
353
+ print("Adding a pass to regenerate cardiac waveform using better vessel specification")
336
354
 
337
355
  # output mask size
338
- print(f"estmask has {len(np.where(estmask_byslice[:, :] > 0)[0])} voxels above threshold.")
356
+ print(
357
+ f"estweights has {len(np.where(estweights_byslice[:, :] > 0)[0])} voxels above threshold."
358
+ )
339
359
 
340
360
  infodict["numpasses"] = numpasses
341
361
 
@@ -364,7 +384,7 @@ def happy_main(argparsingfunc):
364
384
  slicenorms,
365
385
  ) = happy_support.cardiacfromimage(
366
386
  normdata_byslice,
367
- estmask_byslice,
387
+ estweights_byslice,
368
388
  numslices,
369
389
  timepoints,
370
390
  tr,
@@ -391,43 +411,15 @@ def happy_main(argparsingfunc):
391
411
  ]
392
412
  )
393
413
  infodict["cardfromfmri_normfac"] = cardfromfmri_normfac
394
- slicetimeaxis = np.linspace(
395
- 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
396
417
  )
397
418
  if (thispass == 0) and args.doupsampling:
398
- # allocate the upsampled image
399
- upsampleimage = np.zeros((xsize, ysize, numslices, numsteps * timepoints), dtype=float)
400
- upsampleimage_byslice = upsampleimage.reshape(
401
- xsize * ysize, numslices, numsteps * timepoints
419
+ happy_support.upsampleimage(
420
+ input_data, nim_hdr, numsteps, sliceoffsets, slicesamplerate, outputroot
402
421
  )
403
-
404
- # drop in the raw data
405
- for theslice in range(numslices):
406
- upsampleimage[
407
- :, :, theslice, sliceoffsets[theslice] : timepoints * numsteps : numsteps
408
- ] = fmri_data.reshape((xsize, ysize, numslices, timepoints))[:, :, theslice, :]
409
-
410
- # interpolate along the slice direction
411
- for thestep in range(numsteps):
412
- print(f"interpolating step {thestep}")
413
- thesrclocs = np.where(sliceoffsets == thestep)[0]
414
- print(f"sourcelocs: {thesrclocs}")
415
- thedstlocs = np.linspace(0, numslices, num=len(sliceoffsets), endpoint=False)
416
- print(f"len(destlocst), destlocs: {len(thedstlocs)}, {thedstlocs}")
417
- for thetimepoint in range(0, timepoints * numsteps):
418
- print(f"timepoint: {thetimepoint}")
419
- for thexyvoxel in range(xsize * ysize):
420
- theinterps = np.interp(
421
- thedstlocs,
422
- 1.0 * thesrclocs,
423
- upsampleimage_byslice[thexyvoxel, thesrclocs, thetimepoint],
424
- )
425
- upsampleimage_byslice[thexyvoxel, :, thetimepoint] = 1.0 * theinterps
426
-
427
- theheader = copy.deepcopy(nim_hdr)
428
- theheader["dim"][4] = timepoints * numsteps
429
- theheader["pixdim"][4] = 1.0 / slicesamplerate
430
- tide_io.savetonifti(upsampleimage, theheader, outputroot + "_upsampled")
422
+ sys.exit(0)
431
423
 
432
424
  if thispass == numpasses - 1:
433
425
  tide_io.writebidstsv(
@@ -1166,20 +1158,12 @@ def happy_main(argparsingfunc):
1166
1158
  # construct the destination arrays
1167
1159
  tide_util.logmem("before making destination arrays")
1168
1160
  app = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
1169
- app_byslice = app.reshape((xsize * ysize, numslices, args.destpoints))
1170
1161
  cine = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
1171
- cine_byslice = cine.reshape((xsize * ysize, numslices, args.destpoints))
1172
1162
  rawapp = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
1173
- rawapp_byslice = rawapp.reshape((xsize * ysize, numslices, args.destpoints))
1174
1163
  corrected_rawapp = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
1175
- corrected_rawapp_byslice = rawapp.reshape((xsize * ysize, numslices, args.destpoints))
1176
1164
  normapp = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
1177
- normapp_byslice = normapp.reshape((xsize * ysize, numslices, args.destpoints))
1178
1165
  weights = np.zeros((xsize, ysize, numslices, args.destpoints), dtype=np.float64)
1179
- weight_byslice = weights.reshape((xsize * ysize, numslices, args.destpoints))
1180
1166
  derivatives = np.zeros((xsize, ysize, numslices, 4), dtype=np.float64)
1181
- derivatives_byslice = derivatives.reshape((xsize * ysize, numslices, 4))
1182
-
1183
1167
  timings.append(["Output arrays allocated" + passstring, time.time(), None, None])
1184
1168
 
1185
1169
  if args.centric:
@@ -1193,6 +1177,42 @@ def happy_main(argparsingfunc):
1193
1177
  # now do the phase projection
1194
1178
  #
1195
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
+
1196
1216
  demeandata_byslice = demeandata.reshape((xsize * ysize, numslices, timepoints))
1197
1217
  means_byslice = means.reshape((xsize * ysize, numslices))
1198
1218
 
@@ -1211,7 +1231,7 @@ def happy_main(argparsingfunc):
1211
1231
  procpoints = np.where(censorpoints < 1)[0]
1212
1232
 
1213
1233
  # do phase averaging
1214
- app_bypoint, weight_bypoint = happy_support.cardiaccycleaverage(
1234
+ app_bypoint, weights_bypoint = happy_support.cardiaccycleaverage(
1215
1235
  instantaneous_cardiacphase,
1216
1236
  outphases,
1217
1237
  cardfromfmri_sliceres,
@@ -1233,7 +1253,7 @@ def happy_main(argparsingfunc):
1233
1253
  )
1234
1254
  tide_io.writebidstsv(
1235
1255
  outputroot + "_desc-cardiaccycleweightfromfmri_timeseries",
1236
- weight_bypoint,
1256
+ weights_bypoint,
1237
1257
  1.0 / (outphases[1] - outphases[0]),
1238
1258
  starttime=outphases[0],
1239
1259
  columns=["cardiaccycleweightfromfmri"],
@@ -1290,7 +1310,7 @@ def happy_main(argparsingfunc):
1290
1310
  outtimes = np.linspace(
1291
1311
  0.0, maxtime, num=int(maxtime / args.pulsereconstepsize), endpoint=False
1292
1312
  )
1293
- atp_bypoint, atpweight_bypoint = happy_support.cardiaccycleaverage(
1313
+ atp_bypoint, atpweights_bypoint = happy_support.cardiaccycleaverage(
1294
1314
  instantaneous_cardiactime,
1295
1315
  outtimes,
1296
1316
  cardfromfmri_sliceres,
@@ -1321,13 +1341,14 @@ def happy_main(argparsingfunc):
1321
1341
  appsmoothingfilter.setfreqs(0.0, 0.0, phaseFc, phaseFc)
1322
1342
 
1323
1343
  # setup for aliased correlation if we're going to do it
1324
- if args.doaliasedcorrelation and (thispass == numpasses - 1):
1344
+ if args.doaliasedcorrelation:
1325
1345
  if args.cardiacfilename and False:
1326
1346
  signal_sliceres = pleth_sliceres
1327
- # signal_stdres = pleth_stdres
1328
1347
  else:
1329
1348
  signal_sliceres = cardfromfmri_sliceres
1330
- # signal_stdres = dlfilteredcard_stdres
1349
+
1350
+ # zero out bad points
1351
+ signal_sliceres *= 1.0 - badpointlist
1331
1352
 
1332
1353
  theAliasedCorrelator = tide_corr.AliasedCorrelator(
1333
1354
  signal_sliceres,
@@ -1340,16 +1361,21 @@ def happy_main(argparsingfunc):
1340
1361
  )
1341
1362
  correndloc = tide_util.valtoindex(thealiasedcorrx, args.aliasedcorrelationwidth / 2.0)
1342
1363
  aliasedcorrelationpts = correndloc - corrstartloc + 1
1343
- thecorrfunc = np.zeros(
1344
- (xsize, ysize, numslices, aliasedcorrelationpts), dtype=np.float64
1345
- )
1346
- thecorrfunc_byslice = thecorrfunc.reshape(
1347
- (xsize * ysize, numslices, aliasedcorrelationpts)
1348
- )
1349
- wavedelay = np.zeros((xsize, ysize, numslices), dtype=np.float64)
1350
- wavedelay_byslice = wavedelay.reshape((xsize * ysize, numslices))
1351
- waveamp = np.zeros((xsize, ysize, numslices), dtype=np.float64)
1352
- waveamp_byslice = waveamp.reshape((xsize * ysize, numslices))
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
1353
1379
 
1354
1380
  # now project the data
1355
1381
  fmri_data_byslice = input_data.byslice()
@@ -1376,20 +1402,21 @@ def happy_main(argparsingfunc):
1376
1402
  cyclic=True,
1377
1403
  )
1378
1404
  for i in range(len(theindices)):
1379
- weight_byslice[validlocs, theslice, theindices[i]] += theweights[i]
1405
+ weights_byslice[validlocs, theslice, theindices[i]] += theweights[i]
1380
1406
  # rawapp_byslice[validlocs, theslice, theindices[i]] += (
1381
1407
  # theweights[i] * filteredmr
1382
1408
  # )
1383
1409
  rawapp_byslice[validlocs, theslice, theindices[i]] += filteredmr
1384
1410
  cine_byslice[validlocs, theslice, theindices[i]] += theweights[i] * cinemr
1385
1411
  for d in range(args.destpoints):
1386
- if weight_byslice[validlocs[0], theslice, d] == 0.0:
1387
- weight_byslice[validlocs, theslice, d] = 1.0
1412
+ if weights_byslice[validlocs[0], theslice, d] == 0.0:
1413
+ weights_byslice[validlocs, theslice, d] = 1.0
1388
1414
  rawapp_byslice[validlocs, theslice, :] = np.nan_to_num(
1389
- rawapp_byslice[validlocs, theslice, :] / weight_byslice[validlocs, theslice, :]
1415
+ rawapp_byslice[validlocs, theslice, :]
1416
+ / weights_byslice[validlocs, theslice, :]
1390
1417
  )
1391
1418
  cine_byslice[validlocs, theslice, :] = np.nan_to_num(
1392
- cine_byslice[validlocs, theslice, :] / weight_byslice[validlocs, theslice, :]
1419
+ cine_byslice[validlocs, theslice, :] / weights_byslice[validlocs, theslice, :]
1393
1420
  )
1394
1421
  else:
1395
1422
  rawapp_byslice[:, theslice, :] = 0.0
@@ -1414,7 +1441,7 @@ def happy_main(argparsingfunc):
1414
1441
  corrected_rawapp_byslice[validlocs, theslice, :] = (
1415
1442
  rawapp_byslice[validlocs, theslice, :] - timecoursemean
1416
1443
  ) * appflips_byslice[validlocs, theslice, None] + timecoursemean
1417
- if args.doaliasedcorrelation and (thispass == numpasses - 1):
1444
+ if args.doaliasedcorrelation and (thispass > 0):
1418
1445
  for theloc in validlocs:
1419
1446
  thecorrfunc_byslice[theloc, theslice, :] = theAliasedCorrelator.apply(
1420
1447
  -appflips_byslice[theloc, theslice]
@@ -1425,14 +1452,14 @@ def happy_main(argparsingfunc):
1425
1452
  wavedelay_byslice[theloc, theslice] = (
1426
1453
  thealiasedcorrx[corrstartloc : correndloc + 1]
1427
1454
  )[maxloc]
1428
- waveamp_byslice[theloc, theslice] = thecorrfunc_byslice[
1429
- theloc, theslice, maxloc
1430
- ]
1455
+ waveamp_byslice[theloc, theslice] = np.fabs(
1456
+ thecorrfunc_byslice[theloc, theslice, maxloc]
1457
+ )
1431
1458
  else:
1432
1459
  corrected_rawapp_byslice[validlocs, theslice, :] = rawapp_byslice[
1433
1460
  validlocs, theslice, :
1434
1461
  ]
1435
- if args.doaliasedcorrelation and (thispass == numpasses - 1):
1462
+ if args.doaliasedcorrelation and (thispass > 0):
1436
1463
  for theloc in validlocs:
1437
1464
  thecorrfunc_byslice[theloc, theslice, :] = theAliasedCorrelator.apply(
1438
1465
  -demeandata_byslice[theloc, theslice, :],
@@ -1442,9 +1469,9 @@ def happy_main(argparsingfunc):
1442
1469
  wavedelay_byslice[theloc, theslice] = (
1443
1470
  thealiasedcorrx[corrstartloc : correndloc + 1]
1444
1471
  )[maxloc]
1445
- waveamp_byslice[theloc, theslice] = thecorrfunc_byslice[
1446
- theloc, theslice, maxloc
1447
- ]
1472
+ waveamp_byslice[theloc, theslice] = np.fabs(
1473
+ thecorrfunc_byslice[theloc, theslice, maxloc]
1474
+ )
1448
1475
  timecoursemin = np.min(
1449
1476
  corrected_rawapp_byslice[validlocs, theslice, :], axis=1
1450
1477
  ).reshape((-1, 1))
@@ -1617,8 +1644,18 @@ def happy_main(argparsingfunc):
1617
1644
  tide_io.savetonifti(veins, theheader, veinmapfilename)
1618
1645
  timings.append(["Masks saved" + passstring, time.time(), None, None])
1619
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
+
1620
1654
  # now get ready to start again with a new mask
1621
- estmask_byslice = vesselmask.reshape((xsize * ysize, numslices)) + 0
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
1622
1659
 
1623
1660
  # save a vessel image
1624
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
  """
@@ -178,13 +179,6 @@ def _get_parser():
178
179
  ),
179
180
  default=True,
180
181
  )
181
- preprocessing_opts.add_argument(
182
- "--motpos",
183
- dest="motfilt_pos",
184
- action="store_true",
185
- help=("Include motion position regressors. "),
186
- default=False,
187
- )
188
182
  preprocessing_opts.add_argument(
189
183
  "--nomotderiv",
190
184
  dest="motfilt_deriv",
@@ -192,6 +186,17 @@ def _get_parser():
192
186
  help=("Do not use motion derivative regressors. "),
193
187
  default=True,
194
188
  )
189
+ preprocessing_opts.add_argument(
190
+ "--motfiltorder",
191
+ dest="motfilt_order",
192
+ action="store",
193
+ metavar="N",
194
+ type=lambda x: pf.is_int(parser, x),
195
+ help=(
196
+ "Include powers of each confound regressor up to order N. Default is 1 (no expansion). "
197
+ ),
198
+ default=1,
199
+ )
195
200
  preprocessing_opts.add_argument(
196
201
  "--discardmotionfiltered",
197
202
  dest="savemotionglmfilt",
@@ -203,10 +208,10 @@ def _get_parser():
203
208
  # Cardiac estimation tuning
204
209
  cardiac_est_tuning = parser.add_argument_group("Cardiac estimation tuning")
205
210
  cardiac_est_tuning.add_argument(
206
- "--estmask",
207
- dest="estmaskname",
211
+ "--estweights",
212
+ dest="estweightsname",
208
213
  action="store",
209
- metavar="MASKNAME",
214
+ metavar="WEIGHTSNAME",
210
215
  help=(
211
216
  "Generation of cardiac waveform from data will be restricted to "
212
217
  "voxels in MASKNAME and weighted by the mask intensity. If this is "
@@ -288,6 +293,15 @@ def _get_parser():
288
293
  ),
289
294
  default=False,
290
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
+ )
291
305
 
292
306
  # External cardiac waveform options
293
307
  external_cardiac_opts = parser.add_argument_group("External cardiac waveform options")
@@ -534,6 +548,15 @@ def _get_parser():
534
548
  help="Attempt to calculate absolute delay using an aliased correlation (experimental).",
535
549
  default=False,
536
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
+ )
537
560
  misc_opts.add_argument(
538
561
  "--upsample",
539
562
  dest="doupsampling",
@@ -662,23 +685,7 @@ def process_args(inputargs=None):
662
685
  """
663
686
  Compile arguments for rapidtide workflow.
664
687
  """
665
- if inputargs is None:
666
- print("processing command line arguments")
667
- # write out the command used
668
- try:
669
- args = _get_parser().parse_args()
670
- argstowrite = sys.argv
671
- except SystemExit:
672
- _get_parser().print_help()
673
- raise
674
- else:
675
- print("processing passed argument list:")
676
- try:
677
- args = _get_parser().parse_args(inputargs)
678
- argstowrite = inputargs
679
- except SystemExit:
680
- print("Use --help option for detailed information on options.")
681
- raise
688
+ args, argstowrite = pf.setargs(_get_parser, inputargs=inputargs)
682
689
 
683
690
  # save the raw and formatted command lines
684
691
  args.commandline = " ".join(argstowrite)
@@ -719,7 +726,6 @@ def process_args(inputargs=None):
719
726
  args.upsamplefac = 100
720
727
  args.centric = True
721
728
  args.pulsereconstepsize = 0.01
722
- args.aliasedcorrelationwidth = 3.0
723
729
  args.unnormvesselmap = True
724
730
  args.histlen = 100
725
731
  args.softvesselfrac = 0.4
@@ -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(args.slicetimefile)
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rapidtide
3
- Version: 3.0a5
3
+ Version: 3.0a7
4
4
  Summary: Tools for performing correlation analysis on fMRI data.
5
5
  Author: Taylor Salo, Daniel M. Drucker, Ph.D., Jeffrey N Stout, Yaroslav O. Halchenko, Derek Monroe
6
6
  Author-email: "Blaise deB. Frederick" <blaise.frederick@gmail.com>
@@ -33,14 +33,15 @@ Requires-Dist: nibabel
33
33
  Requires-Dist: nilearn
34
34
  Requires-Dist: matplotlib>=3.3.0
35
35
  Requires-Dist: pyqtgraph>=0.13.4
36
- Requires-Dist: pyqt5-sip
36
+ Requires-Dist: pyqt6-sip
37
+ Requires-Dist: pyqt6
37
38
  Requires-Dist: requests
38
39
  Requires-Dist: statsmodels
39
40
  Requires-Dist: pywavelets
40
- Requires-Dist: tomlkit
41
41
  Requires-Dist: tensorflow>=2.10.0
42
42
  Requires-Dist: tf-keras
43
43
  Requires-Dist: tqdm
44
+ Requires-Dist: versioneer
44
45
  Provides-Extra: tests
45
46
  Requires-Dist: codecov; extra == "tests"
46
47
  Requires-Dist: coverage; extra == "tests"
@@ -56,6 +57,7 @@ Requires-Dist: sphinx-gallery; extra == "doc"
56
57
  Requires-Dist: myst-parser; extra == "doc"
57
58
  Requires-Dist: numpydoc; extra == "doc"
58
59
  Requires-Dist: sphinxcontrib-bibtex; extra == "doc"
60
+ Requires-Dist: tomlkit; extra == "doc"
59
61
 
60
62
  The rapidtide package
61
63
  =====================
@@ -15,16 +15,16 @@ rapidtide/calcandfitcorrpairs.py,sha256=UmCp9eSU--HCYd7frdO9ctnMeDK32D1Eb53b1hdz
15
15
  rapidtide/calccoherence.py,sha256=SjSWcqbyATKu5Hya5LgRCTfq2w9l7G9L_kZbol802sk,4512
16
16
  rapidtide/calcnullsimfunc.py,sha256=_L5Gxr1CI0GKmGmEjHzrYNufAzDchDsruYCzboSgw3s,7150
17
17
  rapidtide/calcsimfunc.py,sha256=Jw_589HsH4ErYzI54jPezSRzBW7_xjxc71sstDbalng,5198
18
- rapidtide/correlate.py,sha256=FNkFEFaZsW13kG9O1LklBXD-t1G3WD81co5BP13lt9w,36186
18
+ rapidtide/correlate.py,sha256=iZzJa2QV7Le1_Vr9l8Zj2QS0_ZV-EXKtWkOAcICI8ec,36266
19
19
  rapidtide/dlfilter.py,sha256=8hmOCyGSMQqT2p_rAwOrvs2FaafqbQBEpvFkHAKlxew,55505
20
20
  rapidtide/externaltools.py,sha256=YhxuSn5z3v5E7PzB07yftXJGw95rs95Nmxbq4Wo2fhU,3965
21
21
  rapidtide/fMRIData_class.py,sha256=TrR-MyIBEzbUgUq8oQVmjkddnrhxeN_rHlX-En0p4Ao,5102
22
22
  rapidtide/filter.py,sha256=Ci62Vcw_qKX--Hzut9kb6XmBLjEe773JyGkGJtnH2g4,71773
23
23
  rapidtide/fit.py,sha256=lAzLc19VAhq3QJFSbaCbAWCNDefxSCsJfjW5WLHABMk,67130
24
24
  rapidtide/glmpass.py,sha256=Krdgj-pP2Vtelr6qYtMgh2u2C-9thJGwp2FKiEzo-7M,15681
25
- rapidtide/happy_supportfuncs.py,sha256=yYVmEmNYNjp3WluNWagVzdLNGSNgKfekgeL2zbkMH8I,44847
25
+ rapidtide/happy_supportfuncs.py,sha256=z1Tw6JEgffCQZCubgHYXDM9cZJjA5kZ-H_jZ0c7Wvnw,47032
26
26
  rapidtide/helper_classes.py,sha256=NBCmrxEqui-SnaKnJBISC3sJUJwZL45W5dTH9zDmKHY,50998
27
- rapidtide/io.py,sha256=TFOFsxqo-jor23T5aPy5dYAh-pHh_1lYTTGCIp7jn30,74319
27
+ rapidtide/io.py,sha256=CCb0IVGKfW-z2uaFyfVB8nDwN9JRVj62u1fZeXmrle8,74400
28
28
  rapidtide/makelaggedtcs.py,sha256=GsJ3svPSRJIHzJ9F5ZpT0eW3k6rIUCGXgq4o-sK4R-E,3889
29
29
  rapidtide/maskutil.py,sha256=noqFZzAvyAy0ZzEa1nmEIGzWA0zaPoNSIP3ck1cFKcE,6089
30
30
  rapidtide/miscmath.py,sha256=Wj3GXNkXbvGlsdxYGUMTZ3H5a3a1uhfTWZV73XtUYx4,14044
@@ -44,7 +44,7 @@ rapidtide/tidepoolTemplate_alt.ui,sha256=ruxCjdY3GQtLRYunqSyN9t2ye551fdTM3ZNLDDo
44
44
  rapidtide/tidepoolTemplate_alt_qt6.py,sha256=T4ZKrERqhT3OFWehiOUk-pfNYqKzecEfuYRofwSOoHg,52104
45
45
  rapidtide/tidepoolTemplate_qt6.py,sha256=NtwaX-sAnZC9fPPNVeL1tt6t_OYVorsTx_iBY93taS4,46333
46
46
  rapidtide/transformerdlfilter.py,sha256=oODhn4CVtlT7ua72ADWw0LYmkJznDfH8gB3YmlY_w00,4551
47
- rapidtide/util.py,sha256=ZKTlsUlSyUHow9ADv-TkFAowKouR6799BX7KJdnQv3Q,35962
47
+ rapidtide/util.py,sha256=Su9SUUR3_KVUzLyzTfCzXO9mDbdO-AD99MlIrn_YPoA,35926
48
48
  rapidtide/wiener.py,sha256=ls3jJvuTRlyJl1qL8SxYdct1vZD3yQ9Mhp8hb2lpx1E,4128
49
49
  rapidtide/wiener2.py,sha256=CSsNRqeSCrCJgD-FqOJ8RVoGKbdb-PW8e0cQfD3QyfY,3746
50
50
  rapidtide/data/examples/src/installtestdata,sha256=ummRjxxmArheODnzRHwb6DL9Sxhay6ulJpETEMVy-fs,205
@@ -64,7 +64,7 @@ rapidtide/data/examples/src/testfmridocker,sha256=jjL7bK29rrcog6uO9BtvcyAU3Sv8_5
64
64
  rapidtide/data/examples/src/testfrozen,sha256=K3qUWDRKPPiCXRgIFuPdwUUjUTzf4QBW8UUhR75NzDM,283
65
65
  rapidtide/data/examples/src/testfuncs,sha256=QmVJP8vjr-HqKCAaIz7McdADVZru6Nvwq16h5KPs9ek,1551
66
66
  rapidtide/data/examples/src/testglmfilt,sha256=LD2cTB-7yyCc31jAr8UtYksf-Cn-YLC3ScnV3olvpFE,3333
67
- rapidtide/data/examples/src/testhappy,sha256=vFBrhcXOltLLwPSWJVw4XTqxAyHv1a_Abko5rh_5GfE,1798
67
+ rapidtide/data/examples/src/testhappy,sha256=Qo-hNofuIYOj522PPtqR_5pePTTTyJTaOdAA18G3bkg,1817
68
68
  rapidtide/data/examples/src/testlinfit,sha256=oPnkHJ6lcwsuJhnSMMK7Gx3DHSCf6JK7CIYuIMHbyNA,471
69
69
  rapidtide/data/examples/src/testlocalflow,sha256=hEwstisbWVuALr_29fBJ2nHETKkEF_9qK8wJ4kzuiJk,596
70
70
  rapidtide/data/examples/src/testnoiseamp,sha256=ZRu3GstBhdnwZmDF7ExZynOXFFMElWiZuod8LbUKa-I,612
@@ -210,12 +210,13 @@ rapidtide/tests/test_corrpass.py,sha256=eBNw1KBvjo9WgorR-7aPga3WIeQxckTGjPwv-kn6
210
210
  rapidtide/tests/test_delayestimation.py,sha256=2AeQcT_cFvvNvH0R-K9WNDDp66S-UjybfAqdfG0REYU,13460
211
211
  rapidtide/tests/test_doresample.py,sha256=ILQxH6UXtHZ9OwgTpbZE_bek_QKYGmmA6D70r6NqAoc,2716
212
212
  rapidtide/tests/test_fastresampler.py,sha256=UOWk2_GXEp0xT_gOkVnvg7yuQbbkZGHdljB6zh28OJQ,3763
213
- rapidtide/tests/test_filter.py,sha256=gVo9I_i7pH0waMAUkhNXrFmBT3YRK4G_w-8y_B43aqY,10891
213
+ rapidtide/tests/test_filter.py,sha256=_xhk3rbYFtuKgrDdgrrrlITtmQhOUUi5EhFcnxVUioA,10891
214
214
  rapidtide/tests/test_findmaxlag.py,sha256=x9mKQ8TmWW4jq8CrlfrX8zwO3n4pYa7aPgF3F1e0aPc,11551
215
215
  rapidtide/tests/test_fullrunhappy_v1.py,sha256=XuK90R4Ef7PIvJfyyXHqL__SvRjJUHtHX8PZYuJjEKo,1502
216
- rapidtide/tests/test_fullrunhappy_v2.py,sha256=4S61nuz_S-chlI8zScby3R0RpJdoFcIS0eFH9Ed5LU4,1932
217
- rapidtide/tests/test_fullrunhappy_v3.py,sha256=JrfMW4gqSxd01mnvKuImMToyhzqQl1R_mtQpLG67EVw,1740
218
- rapidtide/tests/test_fullrunhappy_v4.py,sha256=QaWkK8bZppz9i97g31K25Yg0HKnsdnCWbfzCTzsbCRU,1626
216
+ rapidtide/tests/test_fullrunhappy_v2.py,sha256=9_1sjtTP-4YVv-d86iL0hkm8T8ODQ1Ckumu-iFu2W8s,1935
217
+ rapidtide/tests/test_fullrunhappy_v3.py,sha256=sEWV-Qf_13gJ9BnUmgIu-JtMAh1Jp0Qn8EhTEBU4YmU,1743
218
+ rapidtide/tests/test_fullrunhappy_v4.py,sha256=_8ax0oEEdaSSRa-N-lGquWP4MfLj6DR-xy-NUZ3kuhM,1721
219
+ rapidtide/tests/test_fullrunhappy_v5.py,sha256=1otOjGN7PADurvB3PUqHq_FxCpd5vr3Q1KD8FrPGXlU,1721
219
220
  rapidtide/tests/test_fullrunrapidtide_v1.py,sha256=jO2PyPTvxfIYyzydQgxD812DRuzotCTFmnBqShRpa0M,2864
220
221
  rapidtide/tests/test_fullrunrapidtide_v2.py,sha256=RsMCrq-A4WzVzQxFnyvuotKCT4ipfyepM1RxGBpmMys,2881
221
222
  rapidtide/tests/test_fullrunrapidtide_v3.py,sha256=xdwJJyAzup2Jimidb0y-l2Sw7Kwq2WBL6Tw-BQdyzBg,2223
@@ -281,9 +282,9 @@ rapidtide/workflows/fixtr.py,sha256=UuePpVA01YmU4sGiiRcBzMZG1jfNM8TA6xkFyBJdMc8,
281
282
  rapidtide/workflows/glmfilt.py,sha256=ys37_Xpo-LUaOzif9t2BSH-AJlxWkYtYm54REdxFsjg,9995
282
283
  rapidtide/workflows/glmfrommaps.py,sha256=bajR4JBaLaA6REPwBd9S421-0G3ozgaD-gHERxLbEEU,6006
283
284
  rapidtide/workflows/gmscalc.py,sha256=Vz5GnK2WM1PXkFkQSV8KFc1kKJoJ0Q4XW8srLKpsAUg,6258
284
- rapidtide/workflows/happy.py,sha256=ePSZGtBOE_4p3IwQG337aM9aCeBpL95BRdbaOguf1Qc,76812
285
+ rapidtide/workflows/happy.py,sha256=znW3IVNjaQVPTUsILYFjOMEawA3o1_zldCNFHmloE8A,77412
285
286
  rapidtide/workflows/happy2std.py,sha256=aLr8j7qODB_laLNozmI_txKXqGZsuFZp-De8USEiSWE,8132
286
- rapidtide/workflows/happy_parser.py,sha256=jo6CDHFd5K6GurorqqYd_kcQrVAcx4B6DWlVbGA5lno,24973
287
+ rapidtide/workflows/happy_parser.py,sha256=4wVkuqMvA8YbgsanMMbNppKFbmlHMJyLpjZgJaCQO20,25283
287
288
  rapidtide/workflows/histnifti.py,sha256=DtRWkN43GPIuXRCgvCvLrIoeVAjo0AIk1qmrBRBQjJI,11197
288
289
  rapidtide/workflows/histtc.py,sha256=rlTUsiXB1rBv4noNmjKmHajonuhkqSicp98k2JxiPj0,4561
289
290
  rapidtide/workflows/localflow.py,sha256=TvdoUdz_1zIn79UsaPWDPCgrRzy_Yp8wHi7ASdVA1XY,23542
@@ -314,7 +315,7 @@ rapidtide/workflows/showstxcorr.py,sha256=GbOvoKCqyTaGl5EMPpNTyejnBb5mUYbsdyV7lR
314
315
  rapidtide/workflows/showtc.py,sha256=h2eKhJXn30_lDpiBgWF6TZG60L-WZn931_SSjVZpM_M,18835
315
316
  rapidtide/workflows/showxcorrx.py,sha256=-KIv1nqf7knHyxgrEsDvHfhRInDRrdhXGjvWrNJAzmw,31370
316
317
  rapidtide/workflows/showxy.py,sha256=4eq1Ft8z9V-JTgjcnhWqGhFKR-dsXTeU0cArJmiWmVg,10532
317
- rapidtide/workflows/simdata.py,sha256=54Fq95y7-WYnONfWgP7EWZEdRp6NnJSw4cnebD-F3OQ,13894
318
+ rapidtide/workflows/simdata.py,sha256=hd-A8bvmPX1Zn5EX6vYz40s64mYDtWzLRljYN23gcIA,13920
318
319
  rapidtide/workflows/spatialfit.py,sha256=AHwXlqxD6FsjpIVGYaF2ONyZ_AJdwuWwFPoiSxfLH20,9136
319
320
  rapidtide/workflows/spatialmi.py,sha256=m_gafDOAJOyRjXV-LO9UTckU_07MkdadPGcsKU3fzAw,13407
320
321
  rapidtide/workflows/spectrogram.py,sha256=ATe6baNL-Rv6rvV6rCcxcBO2naFu0v4UDJ2hX6T8BrA,6452
@@ -324,9 +325,9 @@ rapidtide/workflows/tcfrom3col.py,sha256=6tV2lGEtXpI4dn_8kcTCVzZxpJzmopuDwpXvOIE
324
325
  rapidtide/workflows/tidepool.py,sha256=7_MK2Sx72-MvkCnTh_Cg_jBaJpNnVdDjTLgdoKlpvdY,78516
325
326
  rapidtide/workflows/utils.py,sha256=k2m2F1-tWxhcUYvk5geO1yl-c5bKcDX7Jv7ohvJZaOk,5379
326
327
  rapidtide/workflows/variabilityizer.py,sha256=yQFDTBcGehxW44R_FQHeeKrTpeYrrh96xcW1uWbPtYo,3167
327
- rapidtide-3.0a5.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
328
- rapidtide-3.0a5.dist-info/METADATA,sha256=mhGD0aiVKnS68pwTAYs29mPmsT0kisgJBHuyKTvEcNM,15560
329
- rapidtide-3.0a5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
330
- rapidtide-3.0a5.dist-info/entry_points.txt,sha256=76O4RdCVLd7YrASvmgJQWaRUlgmBzMDU5_XkGIlmuTk,3260
331
- rapidtide-3.0a5.dist-info/top_level.txt,sha256=MnNXGfbrIBc9RnAqzBHOWd3GQO-aIUDnRTz4_5VjH5g,16
332
- rapidtide-3.0a5.dist-info/RECORD,,
328
+ rapidtide-3.0a7.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
329
+ rapidtide-3.0a7.dist-info/METADATA,sha256=DcwlmKrFI6NBhf0V7wF8cjTILWsKVAbQh-6r6P0nhh8,15623
330
+ rapidtide-3.0a7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
331
+ rapidtide-3.0a7.dist-info/entry_points.txt,sha256=76O4RdCVLd7YrASvmgJQWaRUlgmBzMDU5_XkGIlmuTk,3260
332
+ rapidtide-3.0a7.dist-info/top_level.txt,sha256=MnNXGfbrIBc9RnAqzBHOWd3GQO-aIUDnRTz4_5VjH5g,16
333
+ rapidtide-3.0a7.dist-info/RECORD,,