rapidtide 3.0.1__py3-none-any.whl → 3.0.2__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/voxelData.py CHANGED
@@ -16,14 +16,78 @@
16
16
  # limitations under the License.
17
17
  #
18
18
  #
19
+ import copy
20
+
19
21
  import numpy as np
20
- from tf_keras.src.layers.preprocessing.benchmarks.index_lookup_forward_benchmark import (
21
- get_vocab,
22
- )
23
22
  from tqdm import tqdm
24
23
 
25
24
  import rapidtide.filter as tide_filt
26
25
  import rapidtide.io as tide_io
26
+ import rapidtide.util as tide_util
27
+
28
+
29
+ class dataVolume:
30
+ xsize = None
31
+ ysize = None
32
+ numslices = None
33
+ numspatiallocs = None
34
+ timepoints = None
35
+ dtype = None
36
+ dimensions = None
37
+ data = None
38
+ data_shm = None
39
+ thepid = None
40
+
41
+ def __init__(
42
+ self,
43
+ shape,
44
+ shared=False,
45
+ dtype=np.float64,
46
+ thepid=0,
47
+ ):
48
+ if len(shape) == 3:
49
+ self.xsize = int(shape[0])
50
+ self.ysize = int(shape[1])
51
+ self.numslices = int(shape[2])
52
+ self.timepoints = 1
53
+ self.dimensions = 3
54
+ elif len(shape) == 4:
55
+ self.xsize = int(shape[0])
56
+ self.ysize = int(shape[1])
57
+ self.numslices = int(shape[2])
58
+ self.timepoints = int(shape[3])
59
+ self.dimensions = 4
60
+ else:
61
+ print(f"illegal shape: {shape}")
62
+ self.numspatiallocs = self.xsize * self.ysize * self.numslices
63
+ self.dtype = dtype
64
+ if not shared:
65
+ self.data = np.zeros(shape, dtype=dtype)
66
+ else:
67
+ self.data, self.data_shm = tide_util.allocshared(
68
+ shape, self.dtype, name=f"filtereddata_{thepid}"
69
+ )
70
+ return self.data
71
+
72
+ def byvol(self):
73
+ return self.data
74
+
75
+ def byslice(self):
76
+ if self.dimensions == 3:
77
+ return self.data.reshape(self.xsize * self.ysize, -1)
78
+ else:
79
+ return self.data.reshape(self.xsize * self.ysize, self.numslices, -1)
80
+
81
+ def byvoxel(self):
82
+ if self.dimensions == 3:
83
+ return self.data.reshape(self.numspatiallocs)
84
+ else:
85
+ return self.data.reshape(self.numspatiallocs, -1)
86
+
87
+ def destroy(self):
88
+ del self.data
89
+ if self.data_shm is not None:
90
+ tide_util.cleanup_shm(self.data_shm)
27
91
 
28
92
 
29
93
  class VoxelData:
@@ -36,14 +100,17 @@ class VoxelData:
36
100
  ysize = None
37
101
  numslices = None
38
102
  timepoints = None
103
+ realtimepoints = None
39
104
  xdim = None
40
105
  ydim = None
41
106
  slicethickness = None
42
107
  timestep = None
43
108
  thesizes = None
44
109
  thedims = None
110
+ numslicelocs = None
45
111
  numspatiallocs = None
46
112
  nativespaceshape = None
113
+ nativefmrishape = None
47
114
  validvoxels = None
48
115
  cifti_hdr = None
49
116
  filetype = None
@@ -71,7 +138,8 @@ class VoxelData:
71
138
  self.xsize = self.theshape[0]
72
139
  self.ysize = 1
73
140
  self.numslices = 1
74
- self.timepoints = self.theshape[1]
141
+ self.numslicelocs = None
142
+ self.timepoints = int(self.theshape[1])
75
143
  self.thesizes = [0, int(self.xsize), 1, 1, int(self.timepoints)]
76
144
  self.toffset = 0.0
77
145
  self.numspatiallocs = int(self.xsize)
@@ -81,7 +149,8 @@ class VoxelData:
81
149
  if tide_io.checkifcifti(self.filename):
82
150
  self.filetype = "cifti"
83
151
  self.nim_affine = None
84
- self.timepoints = self.nim_data.shape[1]
152
+ self.numslicelocs = None
153
+ self.timepoints = int(self.nim_data.shape[1])
85
154
  self.numspatiallocs = self.nim_data.shape[0]
86
155
  self.nativespaceshape = (1, 1, 1, 1, self.numspatiallocs)
87
156
  else:
@@ -90,6 +159,7 @@ class VoxelData:
90
159
  self.xsize, self.ysize, self.numslices, self.timepoints = tide_io.parseniftidims(
91
160
  self.thedims
92
161
  )
162
+ self.numslicelocs = int(self.xsize) * int(self.ysize)
93
163
  self.numspatiallocs = int(self.xsize) * int(self.ysize) * int(self.numslices)
94
164
  self.cifti_hdr = None
95
165
  self.nativespaceshape = (self.xsize, self.ysize, self.numslices)
@@ -120,6 +190,30 @@ class VoxelData:
120
190
  self.setvalidtimes(validstart, validend)
121
191
  self.resident = True
122
192
 
193
+ def copyheader(self, numtimepoints=None, tr=None, toffset=None):
194
+ if self.filetype == "text":
195
+ return None
196
+ else:
197
+ thisheader = copy.deepcopy(self.nim_hdr)
198
+ if self.filetype == "cifti":
199
+ timeindex = thisheader["dim"][0] - 1
200
+ spaceindex = thisheader["dim"][0]
201
+ thisheader["dim"][timeindex] = numtimepoints
202
+ thisheader["dim"][spaceindex] = self.numspatiallocs
203
+ else:
204
+ if numtimepoints is not None:
205
+ thisheader["dim"][4] = numtimepoints
206
+ if numtimepoints > 1:
207
+ thisheader["dim"][0] = 4
208
+ else:
209
+ thisheader["dim"][0] = 3
210
+ thisheader["pixdim"][4] = 1.0
211
+ if toffset is not None:
212
+ thisheader["toffset"] = toffset
213
+ if tr is not None:
214
+ thisheader["pixdim"][4] = tr
215
+ return thisheader
216
+
123
217
  def getsizes(self):
124
218
  return self.xdim, self.ydim, self.slicethickness, self.timestep
125
219
 
@@ -167,32 +261,48 @@ class VoxelData:
167
261
  self.validend = self.timepoints - 1
168
262
  else:
169
263
  self.validend = validend
264
+ self.realtimepoints = self.validend - self.validstart + 1
265
+ if self.filetype == "nifti":
266
+ self.nativefmrishape = (self.xsize, self.ysize, self.numslices, self.realtimepoints)
267
+ elif self.filetype == "cifti":
268
+ self.nativefmrishape = (1, 1, 1, self.realtimepoints, self.numspatiallocs)
269
+ else:
270
+ self.nativefmrishape = (self.xsize, self.realtimepoints)
170
271
 
171
272
  def setvalidvoxels(self, validvoxels):
172
273
  self.validvoxels = validvoxels
173
274
  self.numvalidspatiallocs = np.shape(self.validvoxels)[0]
174
275
 
175
- def native(self):
276
+ def byvol(self):
176
277
  if not self.resident:
177
278
  self.load()
178
279
  return self.nim_data
179
280
 
180
- def nativetrimmed(self):
281
+ def byvoltrimmed(self):
181
282
  if not self.resident:
182
283
  self.load()
183
284
  if self.filetype == "nifti":
184
285
  return self.nim_data[:, :, :, self.validstart : self.validend + 1]
185
286
  else:
186
- return self.nim_data[:, self.validstart: self.validend + 1]
287
+ return self.nim_data[:, self.validstart : self.validend + 1]
288
+
289
+ def byvoxel(self):
290
+ return self.byvoltrimmed().reshape(self.numspatiallocs, -1)
187
291
 
188
- def voxelbytime(self):
189
- return self.nativetrimmed().reshape(self.numspatiallocs, -1)
292
+ def byslice(self):
293
+ return self.byvoltrimmed().reshape(self.numslicelocs, self.numslices, -1)
190
294
 
191
- def getvalidvoxels(self):
295
+ def validdata(self):
192
296
  if self.validvoxels is None:
193
- return self.voxelbytime()
297
+ return self.byvoxel()
194
298
  else:
195
- return self.voxelbytime()[self.validvoxels, :]
299
+ return self.byvoxel()[self.validvoxels, :]
300
+
301
+ # def validdatabyslice(self):
302
+ # if self.validvoxels is None:
303
+ # return self.byslice()
304
+ # else:
305
+ # return self.byvoxel()[self.validvoxels, :].reshape(self.numslicelocs, self.numslices, -1)
196
306
 
197
307
  def smooth(
198
308
  self,
@@ -241,7 +351,7 @@ class VoxelData:
241
351
  f"applying gaussian spatial filter to timepoints {self.validstart} "
242
352
  f"to {self.validend} with sigma={gausssigma}"
243
353
  )
244
- sourcedata = self.native()
354
+ sourcedata = self.byvol()
245
355
  for i in tqdm(
246
356
  range(self.validstart, self.validend + 1),
247
357
  desc="Timepoint",
@@ -271,6 +381,7 @@ class VoxelData:
271
381
  print(f"\t{self.timestep=}")
272
382
  print(f"\t{self.thesizes=}")
273
383
  print(f"\t{self.thedims=}")
384
+ print(f"\t{self.numslicelocs=}")
274
385
  print(f"\t{self.numspatiallocs=}")
275
386
  print(f"\t{self.nativespaceshape=}")
276
387
  print(f"\t{self.cifti_hdr=}")
@@ -130,7 +130,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
130
130
  if optiondict["checkpoint"]:
131
131
  outcorrarray[:, :] = 0.0
132
132
  outcorrarray[validvoxels, :] = corrout[:, :]
133
- if optiondict["textio"]:
133
+ if theinputdata.filetype == "text":
134
134
  tide_io.writenpvecs(
135
135
  outcorrarray.reshape(nativecorrshape),
136
136
  f"{outputname}_corrout_prefit_pass" + str(thepass) + ".txt",
@@ -320,8 +320,8 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
320
320
  if optiondict["savedespecklemasks"] and (optiondict["despeckle_passes"] > 0):
321
321
  despecklesavemask = np.where(internaldespeckleincludemask[validvoxels] == 0.0, 0, 1)
322
322
  if thepass == optiondict["passes"]:
323
- if not optiondict["textio"]:
324
- if fileiscifti:
323
+ if theinputdata.filetype != "text":
324
+ if theinputdata.filetype == "cifti":
325
325
  timeindex = theheader["dim"][0] - 1
326
326
  spaceindex = theheader["dim"][0]
327
327
  theheader["dim"][timeindex] = 1
@@ -346,8 +346,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
346
346
  nativespaceshape,
347
347
  theheader,
348
348
  bidsbasedict,
349
- textio=optiondict["textio"],
350
- fileiscifti=fileiscifti,
349
+ filetype=theinputdata.filetype,
351
350
  rt_floattype=rt_floattype,
352
351
  cifti_hdr=cifti_hdr,
353
352
  )
@@ -384,8 +383,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
384
383
  nativespaceshape,
385
384
  theheader,
386
385
  bidsbasedict,
387
- textio=optiondict["textio"],
388
- fileiscifti=fileiscifti,
386
+ filetype=theinputdata.filetype,
389
387
  rt_floattype=rt_floattype,
390
388
  cifti_hdr=cifti_hdr,
391
389
  )
@@ -417,8 +415,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
417
415
  nativespaceshape,
418
416
  theheader,
419
417
  bidsbasedict,
420
- textio=optiondict["textio"],
421
- fileiscifti=fileiscifti,
418
+ filetype=theinputdata.filetype,
422
419
  rt_floattype=rt_floattype,
423
420
  cifti_hdr=cifti_hdr,
424
421
  )
@@ -442,8 +439,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
442
439
  nativespaceshape,
443
440
  theheader,
444
441
  bidsbasedict,
445
- textio=optiondict["textio"],
446
- fileiscifti=fileiscifti,
442
+ filetype=theinputdata.filetype,
447
443
  rt_floattype=rt_floattype,
448
444
  cifti_hdr=cifti_hdr,
449
445
  )
@@ -478,8 +474,7 @@ def estimateDelay(voxeldata, datatimeaxis, osdatatimeaxis, theMutualInformationa
478
474
  nativespaceshape,
479
475
  theheader,
480
476
  bidsbasedict,
481
- textio=optiondict["textio"],
482
- fileiscifti=fileiscifti,
477
+ filetype=theinputdata.filetype,
483
478
  rt_floattype=rt_floattype,
484
479
  cifti_hdr=cifti_hdr,
485
480
  )
@@ -36,6 +36,7 @@ import rapidtide.refinedelay as tide_refinedelay
36
36
  import rapidtide.resample as tide_resample
37
37
  import rapidtide.stats as tide_stats
38
38
  import rapidtide.util as tide_util
39
+ import rapidtide.voxelData as tide_voxelData
39
40
  import rapidtide.workflows.parser_funcs as pf
40
41
  import rapidtide.workflows.regressfrommaps as tide_regressfrommaps
41
42
 
@@ -381,19 +382,19 @@ def delayvar(args):
381
382
 
382
383
  # read the fmri input files
383
384
  print("reading fmrifile")
384
- fmri_input, fmri_data, fmri_header, fmri_dims, fmri_sizes = tide_io.readfromnifti(
385
- args.fmrifile
386
- )
385
+ theinputdata = tide_voxelData.VoxelData(args.fmrifile)
386
+ xsize, ysize, numslices, timepoints = theinputdata.getdims()
387
+ xdim, ydim, slicethickness, fmritr = theinputdata.getsizes()
388
+ fmri_header = theinputdata.copyheader()
389
+ fmri_data = theinputdata.byvol()
390
+ numspatiallocs = theinputdata.numspatiallocs
387
391
 
388
392
  # create the canary file
389
393
  Path(f"{outputname}_DELAYVARISRUNNING.txt").touch()
390
394
 
391
395
  if args.debug:
392
396
  print(f"{fmri_data.shape=}")
393
- xdim, ydim, slicedim, fmritr = tide_io.parseniftisizes(fmri_sizes)
394
- xsize, ysize, numslices, timepoints = tide_io.parseniftidims(fmri_dims)
395
- numspatiallocs = int(xsize) * int(ysize) * int(numslices)
396
- fmri_data_spacebytime = fmri_data.reshape((numspatiallocs, timepoints))
397
+ fmri_data_spacebytime = theinputdata.byvoxel()
397
398
  if args.debug:
398
399
  print(f"{fmri_data_spacebytime.shape=}")
399
400
 
@@ -530,7 +531,7 @@ def delayvar(args):
530
531
 
531
532
  if args.windelayoffsetgausssigma < 0.0:
532
533
  # set gausssigma automatically
533
- args.windelayoffsetgausssigma = np.mean([xdim, ydim, slicedim]) / 2.0
534
+ args.windelayoffsetgausssigma = np.mean([xdim, ydim, slicethickness]) / 2.0
534
535
 
535
536
  wintrs = int(np.round(args.windowsize / fmritr, 0))
536
537
  wintrs += wintrs % 2
@@ -590,8 +591,7 @@ def delayvar(args):
590
591
  (xsize, ysize, numslices, validtimepoints),
591
592
  theheader,
592
593
  bidsbasedict,
593
- textio=therunoptions["textio"],
594
- fileiscifti=False,
594
+ filetype=theinputdata.filetype,
595
595
  rt_floattype=rt_floattype,
596
596
  cifti_hdr=None,
597
597
  )
@@ -737,11 +737,9 @@ def delayvar(args):
737
737
  windowedregressderivratios[:, thewin],
738
738
  (xsize, ysize, numslices),
739
739
  validvoxels,
740
- (xdim, ydim, slicedim),
740
+ (xdim, ydim, slicethickness),
741
741
  gausssigma=args.windelayoffsetgausssigma,
742
742
  patchthresh=args.delaypatchthresh,
743
- fileiscifti=False,
744
- textio=False,
745
743
  rt_floattype=rt_floattype,
746
744
  verbose=args.verbose,
747
745
  debug=args.debug,