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