rapidtide 3.0.11__py3-none-any.whl → 3.1.1__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/Colortables.py +492 -27
- rapidtide/OrthoImageItem.py +1049 -46
- rapidtide/RapidtideDataset.py +1533 -86
- rapidtide/_version.py +3 -3
- rapidtide/calccoherence.py +196 -29
- rapidtide/calcnullsimfunc.py +188 -40
- rapidtide/calcsimfunc.py +242 -42
- rapidtide/correlate.py +1203 -383
- rapidtide/data/examples/src/testLD +56 -0
- rapidtide/data/examples/src/testalign +1 -1
- rapidtide/data/examples/src/testdelayvar +0 -1
- rapidtide/data/examples/src/testfmri +53 -3
- rapidtide/data/examples/src/testglmfilt +5 -5
- rapidtide/data/examples/src/testhappy +29 -7
- rapidtide/data/examples/src/testppgproc +17 -0
- rapidtide/data/examples/src/testrolloff +11 -0
- rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
- rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
- rapidtide/decorators.py +91 -0
- rapidtide/dlfilter.py +2226 -110
- rapidtide/dlfiltertorch.py +4842 -0
- rapidtide/externaltools.py +327 -12
- rapidtide/fMRIData_class.py +79 -40
- rapidtide/filter.py +1899 -810
- rapidtide/fit.py +2011 -581
- rapidtide/genericmultiproc.py +93 -18
- rapidtide/happy_supportfuncs.py +2047 -172
- rapidtide/helper_classes.py +584 -43
- rapidtide/io.py +2370 -372
- rapidtide/linfitfiltpass.py +346 -99
- rapidtide/makelaggedtcs.py +210 -24
- rapidtide/maskutil.py +448 -62
- rapidtide/miscmath.py +827 -121
- rapidtide/multiproc.py +210 -22
- rapidtide/patchmatch.py +242 -42
- rapidtide/peakeval.py +31 -31
- rapidtide/ppgproc.py +2203 -0
- rapidtide/qualitycheck.py +352 -39
- rapidtide/refinedelay.py +431 -57
- rapidtide/refineregressor.py +494 -189
- rapidtide/resample.py +671 -185
- rapidtide/scripts/applyppgproc.py +28 -0
- rapidtide/scripts/showxcorr_legacy.py +7 -7
- rapidtide/scripts/stupidramtricks.py +15 -17
- rapidtide/simFuncClasses.py +1052 -77
- rapidtide/simfuncfit.py +269 -69
- rapidtide/stats.py +540 -238
- rapidtide/tests/happycomp +9 -0
- rapidtide/tests/test_cleanregressor.py +1 -2
- rapidtide/tests/test_dlfiltertorch.py +627 -0
- rapidtide/tests/test_findmaxlag.py +24 -8
- rapidtide/tests/test_fullrunhappy_v1.py +0 -2
- rapidtide/tests/test_fullrunhappy_v2.py +0 -2
- rapidtide/tests/test_fullrunhappy_v3.py +11 -4
- rapidtide/tests/test_fullrunhappy_v4.py +10 -2
- rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
- rapidtide/tests/test_getparsers.py +11 -3
- rapidtide/tests/test_refinedelay.py +0 -1
- rapidtide/tests/test_simroundtrip.py +16 -8
- rapidtide/tests/test_stcorrelate.py +3 -1
- rapidtide/tests/utils.py +9 -8
- rapidtide/tidepoolTemplate.py +142 -38
- rapidtide/tidepoolTemplate_alt.py +165 -44
- rapidtide/tidepoolTemplate_big.py +189 -52
- rapidtide/util.py +1217 -118
- rapidtide/voxelData.py +684 -37
- rapidtide/wiener.py +136 -23
- rapidtide/wiener2.py +113 -7
- rapidtide/workflows/adjustoffset.py +105 -3
- rapidtide/workflows/aligntcs.py +85 -2
- rapidtide/workflows/applydlfilter.py +87 -10
- rapidtide/workflows/applyppgproc.py +540 -0
- rapidtide/workflows/atlasaverage.py +210 -47
- rapidtide/workflows/atlastool.py +100 -3
- rapidtide/workflows/calcSimFuncMap.py +288 -69
- rapidtide/workflows/calctexticc.py +201 -9
- rapidtide/workflows/ccorrica.py +101 -6
- rapidtide/workflows/cleanregressor.py +165 -31
- rapidtide/workflows/delayvar.py +171 -23
- rapidtide/workflows/diffrois.py +81 -3
- rapidtide/workflows/endtidalproc.py +144 -4
- rapidtide/workflows/fdica.py +195 -15
- rapidtide/workflows/filtnifti.py +70 -3
- rapidtide/workflows/filttc.py +74 -3
- rapidtide/workflows/fitSimFuncMap.py +202 -51
- rapidtide/workflows/fixtr.py +73 -3
- rapidtide/workflows/gmscalc.py +113 -3
- rapidtide/workflows/happy.py +801 -199
- rapidtide/workflows/happy2std.py +144 -12
- rapidtide/workflows/happy_parser.py +163 -23
- rapidtide/workflows/histnifti.py +118 -2
- rapidtide/workflows/histtc.py +84 -3
- rapidtide/workflows/linfitfilt.py +117 -4
- rapidtide/workflows/localflow.py +328 -28
- rapidtide/workflows/mergequality.py +79 -3
- rapidtide/workflows/niftidecomp.py +322 -18
- rapidtide/workflows/niftistats.py +174 -4
- rapidtide/workflows/pairproc.py +98 -4
- rapidtide/workflows/pairwisemergenifti.py +85 -2
- rapidtide/workflows/parser_funcs.py +1421 -40
- rapidtide/workflows/physiofreq.py +137 -11
- rapidtide/workflows/pixelcomp.py +207 -5
- rapidtide/workflows/plethquality.py +103 -21
- rapidtide/workflows/polyfitim.py +151 -11
- rapidtide/workflows/proj2flow.py +75 -2
- rapidtide/workflows/rankimage.py +111 -4
- rapidtide/workflows/rapidtide.py +368 -76
- rapidtide/workflows/rapidtide2std.py +98 -2
- rapidtide/workflows/rapidtide_parser.py +109 -9
- rapidtide/workflows/refineDelayMap.py +144 -33
- rapidtide/workflows/refineRegressor.py +675 -96
- rapidtide/workflows/regressfrommaps.py +161 -37
- rapidtide/workflows/resamplenifti.py +85 -3
- rapidtide/workflows/resampletc.py +91 -3
- rapidtide/workflows/retrolagtcs.py +99 -9
- rapidtide/workflows/retroregress.py +176 -26
- rapidtide/workflows/roisummarize.py +174 -5
- rapidtide/workflows/runqualitycheck.py +71 -3
- rapidtide/workflows/showarbcorr.py +149 -6
- rapidtide/workflows/showhist.py +86 -2
- rapidtide/workflows/showstxcorr.py +160 -3
- rapidtide/workflows/showtc.py +159 -3
- rapidtide/workflows/showxcorrx.py +190 -10
- rapidtide/workflows/showxy.py +185 -15
- rapidtide/workflows/simdata.py +264 -38
- rapidtide/workflows/spatialfit.py +77 -2
- rapidtide/workflows/spatialmi.py +250 -27
- rapidtide/workflows/spectrogram.py +305 -32
- rapidtide/workflows/synthASL.py +154 -3
- rapidtide/workflows/tcfrom2col.py +76 -2
- rapidtide/workflows/tcfrom3col.py +74 -2
- rapidtide/workflows/tidepool.py +2971 -130
- rapidtide/workflows/utils.py +19 -14
- rapidtide/workflows/utils_doc.py +293 -0
- rapidtide/workflows/variabilityizer.py +116 -3
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/METADATA +10 -8
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/RECORD +144 -128
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/entry_points.txt +1 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/WHEEL +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/top_level.txt +0 -0
rapidtide/RapidtideDataset.py
CHANGED
|
@@ -19,9 +19,11 @@
|
|
|
19
19
|
import copy
|
|
20
20
|
import os
|
|
21
21
|
import sys
|
|
22
|
+
from typing import Any, Callable
|
|
22
23
|
|
|
23
24
|
import nibabel as nib
|
|
24
25
|
import numpy as np
|
|
26
|
+
from numpy.typing import NDArray
|
|
25
27
|
|
|
26
28
|
import rapidtide.filter as tide_filt
|
|
27
29
|
import rapidtide.io as tide_io
|
|
@@ -39,7 +41,42 @@ atlases = {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
|
|
42
|
-
def check_rt_spatialmatch(dataset1, dataset2):
|
|
44
|
+
def check_rt_spatialmatch(dataset1: Any, dataset2: Any) -> tuple[bool, bool, bool, bool]:
|
|
45
|
+
"""
|
|
46
|
+
Check spatial matching between two datasets for dimension, size, space, and affine properties.
|
|
47
|
+
|
|
48
|
+
This function compares four key spatial attributes between two datasets to determine
|
|
49
|
+
if they are spatially compatible for further processing or analysis.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
dataset1 : Any
|
|
54
|
+
First dataset object containing spatial attributes xdim, ydim, zdim, xsize, ysize,
|
|
55
|
+
zsize, space, and affine.
|
|
56
|
+
dataset2 : Any
|
|
57
|
+
Second dataset object containing the same spatial attributes as dataset1.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
tuple[bool, bool, bool, bool]
|
|
62
|
+
A tuple of four boolean values representing:
|
|
63
|
+
- dimmatch: True if all spatial dimensions (xdim, ydim, zdim) match
|
|
64
|
+
- sizematch: True if all spatial sizes (xsize, ysize, zsize) match
|
|
65
|
+
- spacematch: True if spatial coordinate systems (space) match
|
|
66
|
+
- affinematch: True if affine transformation matrices (affine) match
|
|
67
|
+
|
|
68
|
+
Notes
|
|
69
|
+
-----
|
|
70
|
+
The function performs element-wise comparison of spatial attributes. For affine matrices,
|
|
71
|
+
the comparison uses Python's default equality operator, which may be sensitive to
|
|
72
|
+
floating-point precision differences.
|
|
73
|
+
|
|
74
|
+
Examples
|
|
75
|
+
--------
|
|
76
|
+
>>> dimmatch, sizematch, spacematch, affinematch = check_rt_spatialmatch(dataset1, dataset2)
|
|
77
|
+
>>> if dimmatch and sizematch:
|
|
78
|
+
... print("Datasets have matching dimensions and sizes")
|
|
79
|
+
"""
|
|
43
80
|
if (
|
|
44
81
|
(dataset1.xdim == dataset2.xdim)
|
|
45
82
|
and (dataset1.ydim == dataset2.ydim)
|
|
@@ -72,18 +109,72 @@ class Timecourse:
|
|
|
72
109
|
|
|
73
110
|
def __init__(
|
|
74
111
|
self,
|
|
75
|
-
name,
|
|
76
|
-
filename,
|
|
77
|
-
namebase,
|
|
78
|
-
samplerate,
|
|
79
|
-
displaysamplerate,
|
|
80
|
-
starttime=0.0,
|
|
81
|
-
label=None,
|
|
82
|
-
report=False,
|
|
83
|
-
isbids=False,
|
|
84
|
-
limits=None,
|
|
85
|
-
verbose=0,
|
|
86
|
-
):
|
|
112
|
+
name: str,
|
|
113
|
+
filename: str,
|
|
114
|
+
namebase: str,
|
|
115
|
+
samplerate: float,
|
|
116
|
+
displaysamplerate: float,
|
|
117
|
+
starttime: float = 0.0,
|
|
118
|
+
label: str | None = None,
|
|
119
|
+
report: bool = False,
|
|
120
|
+
isbids: bool = False,
|
|
121
|
+
limits: tuple[float, float] | None = None,
|
|
122
|
+
verbose: int = 0,
|
|
123
|
+
) -> None:
|
|
124
|
+
"""
|
|
125
|
+
Initialize a Timecourse object for reading and managing time series data.
|
|
126
|
+
|
|
127
|
+
This constructor sets up the basic properties of a timecourse and reads the
|
|
128
|
+
time series data from the specified file.
|
|
129
|
+
|
|
130
|
+
Parameters
|
|
131
|
+
----------
|
|
132
|
+
name : str
|
|
133
|
+
The name of the timecourse, used for identification
|
|
134
|
+
filename : str
|
|
135
|
+
The full path to the data file containing the time series
|
|
136
|
+
namebase : str
|
|
137
|
+
The base name of the file (without path)
|
|
138
|
+
samplerate : float
|
|
139
|
+
The sampling rate of the time series data in Hz
|
|
140
|
+
displaysamplerate : float
|
|
141
|
+
The sampling rate used for display purposes in Hz
|
|
142
|
+
starttime : float, default=0.0
|
|
143
|
+
The start time of the time series in seconds
|
|
144
|
+
label : str, optional
|
|
145
|
+
The label to use for display. If None, defaults to the name parameter
|
|
146
|
+
report : bool, default=False
|
|
147
|
+
Whether to generate a report during initialization
|
|
148
|
+
isbids : bool, default=False
|
|
149
|
+
Whether the data follows BIDS (Brain Imaging Data Structure) format
|
|
150
|
+
limits : tuple of float, optional
|
|
151
|
+
The (min, max) value limits for the time series data
|
|
152
|
+
verbose : int, default=0
|
|
153
|
+
Verbosity level for logging output (0 = quiet, higher values = more verbose)
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
None
|
|
158
|
+
This method initializes the object and does not return any value
|
|
159
|
+
|
|
160
|
+
Notes
|
|
161
|
+
-----
|
|
162
|
+
The method automatically reads the time series data using the readTimeData method
|
|
163
|
+
after setting all the internal attributes. If verbose level is greater than 1,
|
|
164
|
+
a message is printed indicating the file being read.
|
|
165
|
+
|
|
166
|
+
Examples
|
|
167
|
+
--------
|
|
168
|
+
>>> tc = Timecourse(
|
|
169
|
+
... name="ECG",
|
|
170
|
+
... filename="/data/ecg_data.dat",
|
|
171
|
+
... namebase="ecg_data",
|
|
172
|
+
... samplerate=1000.0,
|
|
173
|
+
... displaysamplerate=100.0,
|
|
174
|
+
... starttime=0.0,
|
|
175
|
+
... label="Electrocardiogram"
|
|
176
|
+
... )
|
|
177
|
+
"""
|
|
87
178
|
self.verbose = verbose
|
|
88
179
|
self.name = name
|
|
89
180
|
self.filename = filename
|
|
@@ -103,7 +194,45 @@ class Timecourse:
|
|
|
103
194
|
print("reading Timecourse ", self.name, " from ", self.filename, "...")
|
|
104
195
|
self.readTimeData(self.label)
|
|
105
196
|
|
|
106
|
-
def readTimeData(self, thename):
|
|
197
|
+
def readTimeData(self, thename: str) -> None:
|
|
198
|
+
"""
|
|
199
|
+
Read time series data from a file and compute associated statistics and spectral properties.
|
|
200
|
+
|
|
201
|
+
This function reads time series data either from a BIDS-compatible TSV file or a vector file,
|
|
202
|
+
depending on whether the object is configured to use BIDS format. It computes the time axis,
|
|
203
|
+
spectral data, and statistical measures (kurtosis and skewness) for the selected column or
|
|
204
|
+
the entire dataset.
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
thename : str
|
|
209
|
+
The name of the column to extract from the BIDS TSV file. Ignored if not using BIDS format.
|
|
210
|
+
|
|
211
|
+
Returns
|
|
212
|
+
-------
|
|
213
|
+
None
|
|
214
|
+
This function does not return a value but updates the following attributes of the object:
|
|
215
|
+
- `timedata`: The time series data as a numpy array.
|
|
216
|
+
- `length`: The length of the time series.
|
|
217
|
+
- `timeaxis`: The time axis corresponding to the data.
|
|
218
|
+
- `specaxis`: The frequency axis for the power spectrum.
|
|
219
|
+
- `specdata`: The power spectrum of the time series.
|
|
220
|
+
- `kurtosis`, `kurtosis_z`, `kurtosis_p`: Kurtosis statistics.
|
|
221
|
+
- `skewness`, `skewness_z`, `skewness_p`: Skewness statistics.
|
|
222
|
+
|
|
223
|
+
Notes
|
|
224
|
+
-----
|
|
225
|
+
If the `thename` column is not found in a BIDS TSV file, the function sets `timedata` to `None`
|
|
226
|
+
and returns early. The function uses `tide_io.readbidstsv` for BIDS files and `tide_io.readvec`
|
|
227
|
+
for non-BIDS files. Spectral analysis and statistical computations are performed using
|
|
228
|
+
`tide_filt.spectrum`, `tide_math.corrnormalize`, and `tide_stats.kurtosisstats`/`skewnessstats`.
|
|
229
|
+
|
|
230
|
+
Examples
|
|
231
|
+
--------
|
|
232
|
+
>>> obj.readTimeData('signal')
|
|
233
|
+
>>> print(obj.timedata)
|
|
234
|
+
>>> print(obj.specdata)
|
|
235
|
+
"""
|
|
107
236
|
if self.isbids:
|
|
108
237
|
dummy, dummy, columns, indata, dummy, dummy = tide_io.readbidstsv(self.filename)
|
|
109
238
|
try:
|
|
@@ -146,7 +275,54 @@ class Timecourse:
|
|
|
146
275
|
|
|
147
276
|
print()
|
|
148
277
|
|
|
149
|
-
def summarize(self):
|
|
278
|
+
def summarize(self) -> None:
|
|
279
|
+
"""
|
|
280
|
+
Print a summary of the timecourse properties.
|
|
281
|
+
|
|
282
|
+
This method outputs a formatted summary of various properties associated with
|
|
283
|
+
the timecourse object, including name, label, file information, sampling rate,
|
|
284
|
+
length, and statistical measures.
|
|
285
|
+
|
|
286
|
+
Parameters
|
|
287
|
+
----------
|
|
288
|
+
self : object
|
|
289
|
+
The timecourse object instance containing the properties to be summarized.
|
|
290
|
+
Expected attributes include:
|
|
291
|
+
- name: str, the name of the timecourse
|
|
292
|
+
- label: str, the label associated with the timecourse
|
|
293
|
+
- filename: str, the filename of the timecourse data
|
|
294
|
+
- namebase: str, the base name of the file
|
|
295
|
+
- samplerate: float, the sampling rate of the timecourse
|
|
296
|
+
- length: int, the length of the timecourse
|
|
297
|
+
- kurtosis: float, the kurtosis value of the timecourse
|
|
298
|
+
- kurtosis_z: float, the z-score of the kurtosis
|
|
299
|
+
- kurtosis_p: float, the p-value of the kurtosis
|
|
300
|
+
|
|
301
|
+
Returns
|
|
302
|
+
-------
|
|
303
|
+
None
|
|
304
|
+
This method prints the summary information to stdout and does not return any value.
|
|
305
|
+
|
|
306
|
+
Notes
|
|
307
|
+
-----
|
|
308
|
+
The output is formatted for readability with consistent indentation and
|
|
309
|
+
descriptive labels for each property. This method is typically used for
|
|
310
|
+
debugging and quick inspection of timecourse properties.
|
|
311
|
+
|
|
312
|
+
Examples
|
|
313
|
+
--------
|
|
314
|
+
>>> timecourse = Timecourse(name="test_signal", label="test", filename="test.csv")
|
|
315
|
+
>>> timecourse.summarize()
|
|
316
|
+
Timecourse name: test_signal
|
|
317
|
+
label: test
|
|
318
|
+
filename: test.csv
|
|
319
|
+
namebase: test
|
|
320
|
+
samplerate: 100.0
|
|
321
|
+
length: 1000
|
|
322
|
+
kurtosis: 0.5
|
|
323
|
+
kurtosis_z: 1.2
|
|
324
|
+
kurtosis_p: 0.23
|
|
325
|
+
"""
|
|
150
326
|
print()
|
|
151
327
|
print("Timecourse name: ", self.name)
|
|
152
328
|
print(" label: ", self.label)
|
|
@@ -166,22 +342,86 @@ class Overlay:
|
|
|
166
342
|
|
|
167
343
|
def __init__(
|
|
168
344
|
self,
|
|
169
|
-
name,
|
|
170
|
-
filespec,
|
|
171
|
-
namebase,
|
|
172
|
-
funcmask=None,
|
|
173
|
-
geommask=None,
|
|
174
|
-
label=None,
|
|
175
|
-
report=False,
|
|
176
|
-
lut_state=gen_gray_state(),
|
|
177
|
-
alpha=128,
|
|
178
|
-
endalpha=0,
|
|
179
|
-
display_state=True,
|
|
180
|
-
invertonload=False,
|
|
181
|
-
isaMask=False,
|
|
182
|
-
init_LUT=True,
|
|
183
|
-
verbose=1,
|
|
184
|
-
):
|
|
345
|
+
name: str,
|
|
346
|
+
filespec: str,
|
|
347
|
+
namebase: str,
|
|
348
|
+
funcmask: NDArray | None = None,
|
|
349
|
+
geommask: NDArray | None = None,
|
|
350
|
+
label: str | None = None,
|
|
351
|
+
report: bool = False,
|
|
352
|
+
lut_state: dict = gen_gray_state(),
|
|
353
|
+
alpha: int = 128,
|
|
354
|
+
endalpha: int = 0,
|
|
355
|
+
display_state: bool = True,
|
|
356
|
+
invertonload: bool = False,
|
|
357
|
+
isaMask: bool = False,
|
|
358
|
+
init_LUT: bool = True,
|
|
359
|
+
verbose: int = 1,
|
|
360
|
+
) -> None:
|
|
361
|
+
"""
|
|
362
|
+
Initialize an overlay object for rapidtide image data visualization.
|
|
363
|
+
|
|
364
|
+
This constructor initializes an overlay by loading image data from a file,
|
|
365
|
+
applying functional and geometric masks, and setting up display properties
|
|
366
|
+
including lookup tables and affine transformations.
|
|
367
|
+
|
|
368
|
+
Parameters
|
|
369
|
+
----------
|
|
370
|
+
name : str
|
|
371
|
+
Name of the overlay.
|
|
372
|
+
filespec : str
|
|
373
|
+
File specification string used to locate and load the image data.
|
|
374
|
+
namebase : str
|
|
375
|
+
Base name for the overlay, used in file naming and labeling.
|
|
376
|
+
funcmask : NDArray | None, optional
|
|
377
|
+
Functional mask to apply to the data. Default is None.
|
|
378
|
+
geommask : NDArray | None, optional
|
|
379
|
+
Geometric mask to apply to the data. Default is None.
|
|
380
|
+
label : str | None, optional
|
|
381
|
+
Label for the overlay. If None, defaults to the value of `name`. Default is None.
|
|
382
|
+
report : bool, optional
|
|
383
|
+
If True, enables reporting mode. Default is False.
|
|
384
|
+
lut_state : dict, optional
|
|
385
|
+
Lookup table state dictionary. Default is ``gen_gray_state()``.
|
|
386
|
+
alpha : int, optional
|
|
387
|
+
Initial alpha value for display. Default is 128.
|
|
388
|
+
endalpha : int, optional
|
|
389
|
+
End alpha value for display. Default is 0.
|
|
390
|
+
display_state : bool, optional
|
|
391
|
+
If True, initializes display state. Default is True.
|
|
392
|
+
invertonload : bool, optional
|
|
393
|
+
If True, inverts the data on load. Default is False.
|
|
394
|
+
isaMask : bool, optional
|
|
395
|
+
If True, treats the data as a mask. Default is False.
|
|
396
|
+
init_LUT : bool, optional
|
|
397
|
+
If True, initializes the lookup table. Default is True.
|
|
398
|
+
verbose : int, optional
|
|
399
|
+
Verbosity level. Default is 1.
|
|
400
|
+
|
|
401
|
+
Returns
|
|
402
|
+
-------
|
|
403
|
+
None
|
|
404
|
+
This method initializes the object in-place and does not return a value.
|
|
405
|
+
|
|
406
|
+
Notes
|
|
407
|
+
-----
|
|
408
|
+
The constructor performs the following steps:
|
|
409
|
+
1. Loads image data using `tide_io.processnamespec`.
|
|
410
|
+
2. Applies functional and geometric masks.
|
|
411
|
+
3. Sets up display parameters such as `dispmin` and `dispmax`.
|
|
412
|
+
4. Initializes lookup table if `init_LUT` is True.
|
|
413
|
+
5. Determines the spatial coordinate system and affine transformation matrix.
|
|
414
|
+
6. Determines the orientation (neurological or radiological) based on the affine matrix.
|
|
415
|
+
|
|
416
|
+
Examples
|
|
417
|
+
--------
|
|
418
|
+
>>> overlay = Overlay(
|
|
419
|
+
... name="my_overlay",
|
|
420
|
+
... filespec="/path/to/image.nii",
|
|
421
|
+
... namebase="overlay_base",
|
|
422
|
+
... verbose=2
|
|
423
|
+
... )
|
|
424
|
+
"""
|
|
185
425
|
self.verbose = verbose
|
|
186
426
|
self.name = name
|
|
187
427
|
if label is None:
|
|
@@ -266,7 +506,41 @@ class Overlay:
|
|
|
266
506
|
if self.verbose > 0:
|
|
267
507
|
self.summarize()
|
|
268
508
|
|
|
269
|
-
def duplicate(self, newname, newlabel, init_LUT=True):
|
|
509
|
+
def duplicate(self, newname: str, newlabel: str, init_LUT: bool = True) -> Any:
|
|
510
|
+
"""
|
|
511
|
+
Create a duplicate of the current overlay with new name and label.
|
|
512
|
+
|
|
513
|
+
Parameters
|
|
514
|
+
----------
|
|
515
|
+
newname : str
|
|
516
|
+
The name for the new overlay instance.
|
|
517
|
+
newlabel : str
|
|
518
|
+
The label for the new overlay instance.
|
|
519
|
+
init_LUT : bool, optional
|
|
520
|
+
Whether to initialize the lookup table for the new overlay.
|
|
521
|
+
Default is True.
|
|
522
|
+
|
|
523
|
+
Returns
|
|
524
|
+
-------
|
|
525
|
+
Any
|
|
526
|
+
A new Overlay instance with the specified name and label,
|
|
527
|
+
inheriting all properties from the current overlay.
|
|
528
|
+
|
|
529
|
+
Notes
|
|
530
|
+
-----
|
|
531
|
+
This method creates a shallow copy of the current overlay with
|
|
532
|
+
updated name and label attributes. The new overlay maintains
|
|
533
|
+
references to the original data files and masks.
|
|
534
|
+
|
|
535
|
+
Examples
|
|
536
|
+
--------
|
|
537
|
+
>>> overlay = Overlay("original", "file.nii", "base")
|
|
538
|
+
>>> new_overlay = overlay.duplicate("copy", "Copy Label")
|
|
539
|
+
>>> print(new_overlay.name)
|
|
540
|
+
'copy'
|
|
541
|
+
>>> print(new_overlay.label)
|
|
542
|
+
'Copy Label'
|
|
543
|
+
"""
|
|
270
544
|
return Overlay(
|
|
271
545
|
newname,
|
|
272
546
|
self.filename,
|
|
@@ -279,7 +553,39 @@ class Overlay:
|
|
|
279
553
|
verbose=self.verbose,
|
|
280
554
|
)
|
|
281
555
|
|
|
282
|
-
def updateStats(self):
|
|
556
|
+
def updateStats(self) -> None:
|
|
557
|
+
"""
|
|
558
|
+
Update statistical properties of the masked data.
|
|
559
|
+
|
|
560
|
+
This method calculates various statistical measures from the masked data,
|
|
561
|
+
including min/max values, quartiles, robust statistics, and histogram data.
|
|
562
|
+
The results are stored as instance attributes for later use.
|
|
563
|
+
|
|
564
|
+
Parameters
|
|
565
|
+
----------
|
|
566
|
+
None
|
|
567
|
+
|
|
568
|
+
Returns
|
|
569
|
+
-------
|
|
570
|
+
None
|
|
571
|
+
This method does not return a value but updates instance attributes
|
|
572
|
+
with statistical calculations.
|
|
573
|
+
|
|
574
|
+
Notes
|
|
575
|
+
-----
|
|
576
|
+
The method uses the mask to filter data points where mask != 0.
|
|
577
|
+
Statistical calculations include:
|
|
578
|
+
- Minimum and maximum values
|
|
579
|
+
- Robust statistics (0.02, 0.25, 0.5, 0.75, 0.98 percentiles)
|
|
580
|
+
- Histogram data with 200 bins
|
|
581
|
+
- Quartiles (25th, 50th, 75th percentiles)
|
|
582
|
+
|
|
583
|
+
Examples
|
|
584
|
+
--------
|
|
585
|
+
>>> obj.updateStats()
|
|
586
|
+
>>> print(obj.minval, obj.maxval)
|
|
587
|
+
>>> print(obj.quartiles)
|
|
588
|
+
"""
|
|
283
589
|
calcmaskeddata = self.data[np.where(self.mask != 0)]
|
|
284
590
|
|
|
285
591
|
self.minval = calcmaskeddata.min()
|
|
@@ -307,14 +613,87 @@ class Overlay:
|
|
|
307
613
|
self.quartiles,
|
|
308
614
|
)
|
|
309
615
|
|
|
310
|
-
def setData(self, data, isaMask=False):
|
|
616
|
+
def setData(self, data: NDArray, isaMask: bool = False) -> None:
|
|
617
|
+
"""
|
|
618
|
+
Set the data array and optionally convert it to a binary mask.
|
|
619
|
+
|
|
620
|
+
This method assigns the provided data array to the internal data attribute
|
|
621
|
+
and optionally converts it to a binary mask where values less than 0.5
|
|
622
|
+
are set to 0.0 and values greater than 0.5 are set to 1.0.
|
|
623
|
+
|
|
624
|
+
Parameters
|
|
625
|
+
----------
|
|
626
|
+
data : NDArray
|
|
627
|
+
The input data array to be set. A copy of this array is stored internally.
|
|
628
|
+
isaMask : bool, optional
|
|
629
|
+
If True, converts the data to a binary mask. Values less than 0.5 become 0.0,
|
|
630
|
+
and values greater than 0.5 become 1.0. Default is False.
|
|
631
|
+
|
|
632
|
+
Returns
|
|
633
|
+
-------
|
|
634
|
+
None
|
|
635
|
+
This method does not return any value.
|
|
636
|
+
|
|
637
|
+
Notes
|
|
638
|
+
-----
|
|
639
|
+
The data is stored as a copy to prevent external modifications from affecting
|
|
640
|
+
the internal state. The mask conversion is performed using numpy's where function
|
|
641
|
+
for efficient element-wise operations.
|
|
642
|
+
|
|
643
|
+
Examples
|
|
644
|
+
--------
|
|
645
|
+
>>> obj.setData(np.array([0.2, 0.7, 0.3, 0.8]))
|
|
646
|
+
>>> obj.setData(np.array([0.2, 0.7, 0.3, 0.8]), isaMask=True)
|
|
647
|
+
"""
|
|
311
648
|
self.data = data.copy()
|
|
312
649
|
if isaMask:
|
|
313
650
|
self.data[np.where(self.data < 0.5)] = 0.0
|
|
314
651
|
self.data[np.where(self.data > 0.5)] = 1.0
|
|
315
652
|
self.updateStats()
|
|
316
653
|
|
|
317
|
-
def readImageData(self, isaMask=False):
|
|
654
|
+
def readImageData(self, isaMask: bool = False) -> None:
|
|
655
|
+
"""
|
|
656
|
+
Read image data from a NIfTI file and process it based on specified flags.
|
|
657
|
+
|
|
658
|
+
This function loads image data from a NIfTI file using `tide_io.readfromnifti`,
|
|
659
|
+
applies optional inversion and masking operations, and extracts dimension and
|
|
660
|
+
spacing information from the header.
|
|
661
|
+
|
|
662
|
+
Parameters
|
|
663
|
+
----------
|
|
664
|
+
isaMask : bool, optional
|
|
665
|
+
If True, process the data as a binary mask. For non-mask files, values
|
|
666
|
+
less than 0.5 are set to 0, and values greater than 0.5 are set to 1.
|
|
667
|
+
For mask files with `filevals` defined, the data is converted to a binary
|
|
668
|
+
mask based on matching values in `filevals`. Default is False.
|
|
669
|
+
|
|
670
|
+
Returns
|
|
671
|
+
-------
|
|
672
|
+
None
|
|
673
|
+
This function does not return a value but updates the instance attributes
|
|
674
|
+
`nim`, `data`, `header`, `dims`, `sizes`, `xdim`, `ydim`, `zdim`, `tdim`,
|
|
675
|
+
`xsize`, `ysize`, `zsize`, `tr`, and `toffset`.
|
|
676
|
+
|
|
677
|
+
Notes
|
|
678
|
+
-----
|
|
679
|
+
- If `invertonload` is True, the data is multiplied by -1.0.
|
|
680
|
+
- The function prints data range and header information if `verbose > 1`.
|
|
681
|
+
- Dimension and spacing information is parsed using `tide_io.parseniftidims` and
|
|
682
|
+
`tide_io.parseniftisizes`.
|
|
683
|
+
|
|
684
|
+
Examples
|
|
685
|
+
--------
|
|
686
|
+
>>> reader = ImageReader()
|
|
687
|
+
>>> reader.filename = "example.nii"
|
|
688
|
+
>>> reader.invertonload = True
|
|
689
|
+
>>> reader.verbose = 2
|
|
690
|
+
>>> reader.readImageData(isaMask=True)
|
|
691
|
+
Overlay data range: -1.0 1.0
|
|
692
|
+
header {'toffset': 0.0, ...}
|
|
693
|
+
Overlay dims: 64 64 32 1
|
|
694
|
+
Overlay sizes: 3.0 3.0 3.0 2.0
|
|
695
|
+
Overlay toffset: 0.0
|
|
696
|
+
"""
|
|
318
697
|
self.nim, self.data, self.header, self.dims, self.sizes = tide_io.readfromnifti(
|
|
319
698
|
self.filename
|
|
320
699
|
)
|
|
@@ -340,16 +719,97 @@ class Overlay:
|
|
|
340
719
|
print("Overlay sizes:", self.xsize, self.ysize, self.zsize, self.tr)
|
|
341
720
|
print("Overlay toffset:", self.toffset)
|
|
342
721
|
|
|
343
|
-
def setLabel(self, label):
|
|
722
|
+
def setLabel(self, label: str) -> None:
|
|
723
|
+
"""
|
|
724
|
+
Set the label for the object.
|
|
725
|
+
|
|
726
|
+
Parameters
|
|
727
|
+
----------
|
|
728
|
+
label : str
|
|
729
|
+
The label to assign to the object.
|
|
730
|
+
|
|
731
|
+
Returns
|
|
732
|
+
-------
|
|
733
|
+
None
|
|
734
|
+
This method does not return any value.
|
|
735
|
+
|
|
736
|
+
Notes
|
|
737
|
+
-----
|
|
738
|
+
This method directly assigns the provided label to the object's label attribute.
|
|
739
|
+
The label is typically used for identification or display purposes.
|
|
740
|
+
|
|
741
|
+
Examples
|
|
742
|
+
--------
|
|
743
|
+
>>> obj = MyClass()
|
|
744
|
+
>>> obj.setLabel("New Label")
|
|
745
|
+
>>> print(obj.label)
|
|
746
|
+
'New Label'
|
|
747
|
+
"""
|
|
344
748
|
self.label = label
|
|
345
749
|
|
|
346
|
-
def real2tr(self, time):
|
|
750
|
+
def real2tr(self, time: float) -> float:
|
|
751
|
+
"""
|
|
752
|
+
Convert real time to trigger time.
|
|
753
|
+
|
|
754
|
+
Convert a real time value to its corresponding trigger time value by applying
|
|
755
|
+
the time offset and trigger period parameters.
|
|
756
|
+
|
|
757
|
+
Parameters
|
|
758
|
+
----------
|
|
759
|
+
time : float
|
|
760
|
+
The real time value to be converted to trigger time.
|
|
761
|
+
|
|
762
|
+
Returns
|
|
763
|
+
-------
|
|
764
|
+
float
|
|
765
|
+
The converted trigger time value, rounded to the nearest integer.
|
|
766
|
+
|
|
767
|
+
Notes
|
|
768
|
+
-----
|
|
769
|
+
The conversion is performed using the formula: ``round((time - toffset) / tr)``
|
|
770
|
+
where ``toffset`` is the time offset and ``tr`` is the trigger period.
|
|
771
|
+
|
|
772
|
+
Examples
|
|
773
|
+
--------
|
|
774
|
+
>>> obj.real2tr(10.5)
|
|
775
|
+
2.0
|
|
776
|
+
>>> obj.real2tr(5.0)
|
|
777
|
+
0.0
|
|
778
|
+
"""
|
|
347
779
|
return np.round((time - self.toffset) / self.tr, 0)
|
|
348
780
|
|
|
349
|
-
def tr2real(self, tpos):
|
|
781
|
+
def tr2real(self, tpos: int) -> float:
|
|
350
782
|
return self.toffset + self.tr * tpos
|
|
351
783
|
|
|
352
|
-
def real2vox(
|
|
784
|
+
def real2vox(
|
|
785
|
+
self, xcoord: float, ycoord: float, zcoord: float, time: float
|
|
786
|
+
) -> tuple[int, int, int, int]:
|
|
787
|
+
"""
|
|
788
|
+
Convert a time position to a real time value.
|
|
789
|
+
|
|
790
|
+
Parameters
|
|
791
|
+
----------
|
|
792
|
+
tpos : int
|
|
793
|
+
Time position index to convert to real time value.
|
|
794
|
+
|
|
795
|
+
Returns
|
|
796
|
+
-------
|
|
797
|
+
float
|
|
798
|
+
The corresponding real time value calculated as `toffset + tr * tpos`.
|
|
799
|
+
|
|
800
|
+
Notes
|
|
801
|
+
-----
|
|
802
|
+
This function performs a linear transformation from discrete time positions
|
|
803
|
+
to continuous time values using the instance's time offset and time rate
|
|
804
|
+
parameters.
|
|
805
|
+
|
|
806
|
+
Examples
|
|
807
|
+
--------
|
|
808
|
+
>>> obj.tr2real(0)
|
|
809
|
+
10.0
|
|
810
|
+
>>> obj.tr2real(5)
|
|
811
|
+
15.0
|
|
812
|
+
"""
|
|
353
813
|
x, y, z = nib.apply_affine(self.invaffine, [xcoord, ycoord, zcoord])
|
|
354
814
|
t = self.real2tr(time)
|
|
355
815
|
return (
|
|
@@ -359,30 +819,183 @@ class Overlay:
|
|
|
359
819
|
int(np.round(t, 0)),
|
|
360
820
|
)
|
|
361
821
|
|
|
362
|
-
def vox2real(self, xpos, ypos, zpos, tpos):
|
|
822
|
+
def vox2real(self, xpos: int, ypos: int, zpos: int, tpos: int) -> NDArray:
|
|
823
|
+
"""
|
|
824
|
+
Convert voxel coordinates to real-world coordinates.
|
|
825
|
+
|
|
826
|
+
This function transforms voxel coordinates (x, y, z, t) to real-world coordinates
|
|
827
|
+
using the affine transformation matrix and temporal transformation.
|
|
828
|
+
|
|
829
|
+
Parameters
|
|
830
|
+
----------
|
|
831
|
+
xpos : int
|
|
832
|
+
X coordinate in voxel space
|
|
833
|
+
ypos : int
|
|
834
|
+
Y coordinate in voxel space
|
|
835
|
+
zpos : int
|
|
836
|
+
Z coordinate in voxel space
|
|
837
|
+
tpos : int
|
|
838
|
+
T coordinate in voxel space (temporal dimension)
|
|
839
|
+
|
|
840
|
+
Returns
|
|
841
|
+
-------
|
|
842
|
+
NDArray
|
|
843
|
+
Array containing real-world coordinates [x_real, y_real, z_real, t_real]
|
|
844
|
+
|
|
845
|
+
Notes
|
|
846
|
+
-----
|
|
847
|
+
The conversion uses nibabel's apply_affine function for spatial transformation
|
|
848
|
+
and self.tr2real for temporal transformation. The result includes both
|
|
849
|
+
spatial and temporal coordinates in real-world units.
|
|
850
|
+
|
|
851
|
+
Examples
|
|
852
|
+
--------
|
|
853
|
+
>>> vox2real(10, 20, 30, 5)
|
|
854
|
+
array([12.5, 25.0, 37.5, 2.5])
|
|
855
|
+
"""
|
|
363
856
|
return np.concatenate(
|
|
364
857
|
(nib.apply_affine(self.affine, [xpos, ypos, zpos]), [self.tr2real(tpos)]),
|
|
365
858
|
axis=0,
|
|
366
859
|
)
|
|
367
860
|
|
|
368
|
-
def setXYZpos(self, xpos, ypos, zpos):
|
|
861
|
+
def setXYZpos(self, xpos: int, ypos: int, zpos: int) -> None:
|
|
862
|
+
"""
|
|
863
|
+
Set the 3D position coordinates of the object.
|
|
864
|
+
|
|
865
|
+
Parameters
|
|
866
|
+
----------
|
|
867
|
+
xpos : int
|
|
868
|
+
The x-coordinate position value.
|
|
869
|
+
ypos : int
|
|
870
|
+
The y-coordinate position value.
|
|
871
|
+
zpos : int
|
|
872
|
+
The z-coordinate position value.
|
|
873
|
+
|
|
874
|
+
Returns
|
|
875
|
+
-------
|
|
876
|
+
None
|
|
877
|
+
This method does not return any value.
|
|
878
|
+
|
|
879
|
+
Notes
|
|
880
|
+
-----
|
|
881
|
+
All position values are converted to integers before assignment.
|
|
882
|
+
|
|
883
|
+
Examples
|
|
884
|
+
--------
|
|
885
|
+
>>> obj = MyClass()
|
|
886
|
+
>>> obj.setXYZpos(10, 20, 30)
|
|
887
|
+
>>> print(obj.xpos, obj.ypos, obj.zpos)
|
|
888
|
+
10 20 30
|
|
889
|
+
"""
|
|
369
890
|
self.xpos = int(xpos)
|
|
370
891
|
self.ypos = int(ypos)
|
|
371
892
|
self.zpos = int(zpos)
|
|
372
893
|
|
|
373
|
-
def setTpos(self, tpos):
|
|
894
|
+
def setTpos(self, tpos: int) -> None:
|
|
895
|
+
"""
|
|
896
|
+
Set the temporal position attribute with bounds checking.
|
|
897
|
+
|
|
898
|
+
Parameters
|
|
899
|
+
----------
|
|
900
|
+
tpos : int
|
|
901
|
+
The temporal position to set. If greater than self.tdim - 1,
|
|
902
|
+
it will be clamped to self.tdim - 1.
|
|
903
|
+
|
|
904
|
+
Returns
|
|
905
|
+
-------
|
|
906
|
+
None
|
|
907
|
+
This method modifies the instance in-place and does not return a value.
|
|
908
|
+
|
|
909
|
+
Notes
|
|
910
|
+
-----
|
|
911
|
+
The temporal position is bounded by the dimensionality of the temporal
|
|
912
|
+
space (self.tdim). If the input tpos exceeds this limit, it will be
|
|
913
|
+
automatically adjusted to the maximum valid position (self.tdim - 1).
|
|
914
|
+
|
|
915
|
+
Examples
|
|
916
|
+
--------
|
|
917
|
+
>>> obj = MyClass()
|
|
918
|
+
>>> obj.tdim = 5
|
|
919
|
+
>>> obj.setTpos(3)
|
|
920
|
+
>>> obj.tpos
|
|
921
|
+
3
|
|
922
|
+
>>> obj.setTpos(10)
|
|
923
|
+
>>> obj.tpos
|
|
924
|
+
4
|
|
925
|
+
"""
|
|
374
926
|
if tpos > self.tdim - 1:
|
|
375
927
|
self.tpos = int(self.tdim - 1)
|
|
376
928
|
else:
|
|
377
929
|
self.tpos = int(tpos)
|
|
378
930
|
|
|
379
|
-
def getFocusVal(self):
|
|
931
|
+
def getFocusVal(self) -> float:
|
|
932
|
+
"""
|
|
933
|
+
Get the focus value at the current position.
|
|
934
|
+
|
|
935
|
+
This method retrieves the data value from the masked data array at the
|
|
936
|
+
current position coordinates. The method handles both 3D and 4D data arrays
|
|
937
|
+
by checking the time dimension.
|
|
938
|
+
|
|
939
|
+
Parameters
|
|
940
|
+
----------
|
|
941
|
+
self : object
|
|
942
|
+
The instance of the class containing the masked data and position
|
|
943
|
+
coordinates.
|
|
944
|
+
|
|
945
|
+
Returns
|
|
946
|
+
-------
|
|
947
|
+
float
|
|
948
|
+
The data value at the current position. For 4D data (tdim > 1), returns
|
|
949
|
+
the value at [xpos, ypos, zpos, tpos]. For 3D data (tdim <= 1), returns
|
|
950
|
+
the value at [xpos, ypos, zpos].
|
|
951
|
+
|
|
952
|
+
Notes
|
|
953
|
+
-----
|
|
954
|
+
The method assumes that the instance has the following attributes:
|
|
955
|
+
- maskeddata: numpy array containing the data
|
|
956
|
+
- xpos, ypos, zpos, tpos: integer coordinates
|
|
957
|
+
- tdim: integer representing the time dimension
|
|
958
|
+
|
|
959
|
+
Examples
|
|
960
|
+
--------
|
|
961
|
+
>>> value = obj.getFocusVal()
|
|
962
|
+
>>> print(value)
|
|
963
|
+
0.5
|
|
964
|
+
"""
|
|
380
965
|
if self.tdim > 1:
|
|
381
966
|
return self.maskeddata[self.xpos, self.ypos, self.zpos, self.tpos]
|
|
382
967
|
else:
|
|
383
968
|
return self.maskeddata[self.xpos, self.ypos, self.zpos]
|
|
384
969
|
|
|
385
|
-
def setFuncMask(self, funcmask, maskdata=True):
|
|
970
|
+
def setFuncMask(self, funcmask: NDArray | None, maskdata: bool = True) -> None:
|
|
971
|
+
"""
|
|
972
|
+
Set the functional mask for the object.
|
|
973
|
+
|
|
974
|
+
Parameters
|
|
975
|
+
----------
|
|
976
|
+
funcmask : array-like, optional
|
|
977
|
+
The functional mask to be set. If None, a default mask is created based on
|
|
978
|
+
the dimensionality of the data. If provided, a copy of the mask is stored.
|
|
979
|
+
maskdata : bool, default=True
|
|
980
|
+
If True, calls maskData() method after setting the functional mask.
|
|
981
|
+
|
|
982
|
+
Returns
|
|
983
|
+
-------
|
|
984
|
+
None
|
|
985
|
+
This method modifies the object in-place and does not return any value.
|
|
986
|
+
|
|
987
|
+
Notes
|
|
988
|
+
-----
|
|
989
|
+
When funcmask is None, the method creates a default mask:
|
|
990
|
+
- For 1D data (tdim == 1): creates a mask with the same shape as self.data
|
|
991
|
+
- For higher dimensional data: creates a mask with shape (self.data.shape[0], self.data.shape[1], self.data.shape[2], 1)
|
|
992
|
+
|
|
993
|
+
Examples
|
|
994
|
+
--------
|
|
995
|
+
>>> obj.setFuncMask(None)
|
|
996
|
+
>>> obj.setFuncMask(np.ones((10, 10)))
|
|
997
|
+
>>> obj.setFuncMask(None, maskdata=False)
|
|
998
|
+
"""
|
|
386
999
|
self.funcmask = funcmask
|
|
387
1000
|
if self.funcmask is None:
|
|
388
1001
|
if self.tdim == 1:
|
|
@@ -394,7 +1007,35 @@ class Overlay:
|
|
|
394
1007
|
if maskdata:
|
|
395
1008
|
self.maskData()
|
|
396
1009
|
|
|
397
|
-
def setGeomMask(self, geommask, maskdata=True):
|
|
1010
|
+
def setGeomMask(self, geommask: NDArray | None, maskdata: bool = True) -> None:
|
|
1011
|
+
"""
|
|
1012
|
+
Set the geometric mask for the object and optionally mask the data.
|
|
1013
|
+
|
|
1014
|
+
Parameters
|
|
1015
|
+
----------
|
|
1016
|
+
geommask : ndarray or None
|
|
1017
|
+
Geometric mask array. If None, a default mask is created based on the
|
|
1018
|
+
object's dimensions. If not None, the provided mask is copied and used.
|
|
1019
|
+
maskdata : bool, default=True
|
|
1020
|
+
If True, applies the mask to the data by calling maskData() method.
|
|
1021
|
+
If False, only sets the geometric mask without masking the data.
|
|
1022
|
+
|
|
1023
|
+
Returns
|
|
1024
|
+
-------
|
|
1025
|
+
None
|
|
1026
|
+
This method modifies the object in-place and does not return any value.
|
|
1027
|
+
|
|
1028
|
+
Notes
|
|
1029
|
+
-----
|
|
1030
|
+
When geommask is None and tdim == 1, a mask of ones with the same shape as
|
|
1031
|
+
self.data is created. Otherwise, a mask of ones with the shape of
|
|
1032
|
+
self.data[:, :, :, 0] is created.
|
|
1033
|
+
|
|
1034
|
+
Examples
|
|
1035
|
+
--------
|
|
1036
|
+
>>> obj.setGeomMask(None)
|
|
1037
|
+
>>> obj.setGeomMask(mask_array, maskdata=False)
|
|
1038
|
+
"""
|
|
398
1039
|
self.geommask = geommask
|
|
399
1040
|
if self.geommask is None:
|
|
400
1041
|
if self.tdim == 1:
|
|
@@ -406,7 +1047,36 @@ class Overlay:
|
|
|
406
1047
|
if maskdata:
|
|
407
1048
|
self.maskData()
|
|
408
1049
|
|
|
409
|
-
def maskData(self):
|
|
1050
|
+
def maskData(self) -> None:
|
|
1051
|
+
"""
|
|
1052
|
+
Apply mask to data and update statistics if mask has changed.
|
|
1053
|
+
|
|
1054
|
+
This method combines geometric and functional masks to create a final mask,
|
|
1055
|
+
then checks if the mask has changed since the last update. If the mask has
|
|
1056
|
+
changed, it applies the mask to the data, sets masked values to zero, and
|
|
1057
|
+
updates the statistics.
|
|
1058
|
+
|
|
1059
|
+
Parameters
|
|
1060
|
+
----------
|
|
1061
|
+
None
|
|
1062
|
+
|
|
1063
|
+
Returns
|
|
1064
|
+
-------
|
|
1065
|
+
None
|
|
1066
|
+
This method modifies the instance in-place and does not return any value.
|
|
1067
|
+
|
|
1068
|
+
Notes
|
|
1069
|
+
-----
|
|
1070
|
+
The method uses a hash-based approach to efficiently detect when the mask
|
|
1071
|
+
has changed, avoiding expensive operations when the mask remains the same.
|
|
1072
|
+
The mask is applied by setting values to zero where the combined mask is
|
|
1073
|
+
less than 0.5.
|
|
1074
|
+
|
|
1075
|
+
Examples
|
|
1076
|
+
--------
|
|
1077
|
+
>>> obj.maskData()
|
|
1078
|
+
# Applies mask and updates statistics if mask has changed
|
|
1079
|
+
"""
|
|
410
1080
|
self.mask = self.geommask * self.funcmask
|
|
411
1081
|
maskhash = hash(self.mask.tobytes())
|
|
412
1082
|
# these operations are expensive, so only do them if the mask is changed
|
|
@@ -420,16 +1090,137 @@ class Overlay:
|
|
|
420
1090
|
self.updateStats()
|
|
421
1091
|
self.maskhash = maskhash
|
|
422
1092
|
|
|
423
|
-
def setReport(self, report):
|
|
1093
|
+
def setReport(self, report: bool) -> None:
|
|
1094
|
+
"""
|
|
1095
|
+
Set the report flag for the object.
|
|
1096
|
+
|
|
1097
|
+
Parameters
|
|
1098
|
+
----------
|
|
1099
|
+
report : bool
|
|
1100
|
+
Flag indicating whether reporting is enabled or disabled.
|
|
1101
|
+
|
|
1102
|
+
Returns
|
|
1103
|
+
-------
|
|
1104
|
+
None
|
|
1105
|
+
This method does not return any value.
|
|
1106
|
+
|
|
1107
|
+
Notes
|
|
1108
|
+
-----
|
|
1109
|
+
This method assigns the provided boolean value to the internal `report` attribute
|
|
1110
|
+
of the object. The attribute can be accessed later to check the current reporting state.
|
|
1111
|
+
|
|
1112
|
+
Examples
|
|
1113
|
+
--------
|
|
1114
|
+
>>> obj = MyClass()
|
|
1115
|
+
>>> obj.setReport(True)
|
|
1116
|
+
>>> obj.report
|
|
1117
|
+
True
|
|
1118
|
+
>>> obj.setReport(False)
|
|
1119
|
+
>>> obj.report
|
|
1120
|
+
False
|
|
1121
|
+
"""
|
|
424
1122
|
self.report = report
|
|
425
1123
|
|
|
426
|
-
def setTR(self, trval):
|
|
1124
|
+
def setTR(self, trval: float) -> None:
|
|
1125
|
+
"""
|
|
1126
|
+
Set the TR (repetition time) value for the object.
|
|
1127
|
+
|
|
1128
|
+
Parameters
|
|
1129
|
+
----------
|
|
1130
|
+
trval : float
|
|
1131
|
+
The repetition time value to be set. This parameter represents the
|
|
1132
|
+
time interval between successive MRI pulse sequences in seconds.
|
|
1133
|
+
|
|
1134
|
+
Returns
|
|
1135
|
+
-------
|
|
1136
|
+
None
|
|
1137
|
+
This method does not return any value.
|
|
1138
|
+
|
|
1139
|
+
Notes
|
|
1140
|
+
-----
|
|
1141
|
+
This method directly assigns the provided value to the internal `tr` attribute
|
|
1142
|
+
of the object. The TR value is commonly used in MRI data processing and
|
|
1143
|
+
represents the time between the start of one pulse sequence and the start
|
|
1144
|
+
of the next.
|
|
1145
|
+
|
|
1146
|
+
Examples
|
|
1147
|
+
--------
|
|
1148
|
+
>>> obj = MyClass()
|
|
1149
|
+
>>> obj.setTR(2.0)
|
|
1150
|
+
>>> print(obj.tr)
|
|
1151
|
+
2.0
|
|
1152
|
+
"""
|
|
427
1153
|
self.tr = trval
|
|
428
1154
|
|
|
429
|
-
def settoffset(self, toffset):
|
|
1155
|
+
def settoffset(self, toffset: float) -> None:
|
|
1156
|
+
"""
|
|
1157
|
+
Set the time offset value.
|
|
1158
|
+
|
|
1159
|
+
Parameters
|
|
1160
|
+
----------
|
|
1161
|
+
toffset : float
|
|
1162
|
+
The time offset value to set.
|
|
1163
|
+
|
|
1164
|
+
Returns
|
|
1165
|
+
-------
|
|
1166
|
+
None
|
|
1167
|
+
This method does not return any value.
|
|
1168
|
+
|
|
1169
|
+
Notes
|
|
1170
|
+
-----
|
|
1171
|
+
This method assigns the provided time offset value to the instance variable
|
|
1172
|
+
`self.toffset`. The time offset is typically used to adjust timing references
|
|
1173
|
+
in time-series data processing or temporal calculations.
|
|
1174
|
+
|
|
1175
|
+
Examples
|
|
1176
|
+
--------
|
|
1177
|
+
>>> obj = MyClass()
|
|
1178
|
+
>>> obj.settoffset(5.0)
|
|
1179
|
+
>>> print(obj.toffset)
|
|
1180
|
+
5.0
|
|
1181
|
+
"""
|
|
430
1182
|
self.toffset = toffset
|
|
431
1183
|
|
|
432
|
-
def setLUT(self, lut_state, alpha=255, endalpha=128):
|
|
1184
|
+
def setLUT(self, lut_state: dict, alpha: int = 255, endalpha: int = 128) -> None:
|
|
1185
|
+
"""
|
|
1186
|
+
Set the lookup table (LUT) state with optional alpha blending adjustments.
|
|
1187
|
+
|
|
1188
|
+
This function configures the lookup table state for gradient visualization,
|
|
1189
|
+
applying alpha transparency adjustments to the color ticks and restoring
|
|
1190
|
+
the gradient state with the updated LUT.
|
|
1191
|
+
|
|
1192
|
+
Parameters
|
|
1193
|
+
----------
|
|
1194
|
+
lut_state : dict
|
|
1195
|
+
Dictionary containing the lookup table state with keys:
|
|
1196
|
+
- "ticks": list of tuples representing color stops
|
|
1197
|
+
- "mode": color mapping mode
|
|
1198
|
+
- "name": name of the LUT
|
|
1199
|
+
alpha : int, optional
|
|
1200
|
+
Alpha value (0-255) to apply to intermediate color ticks, by default 255
|
|
1201
|
+
endalpha : int, optional
|
|
1202
|
+
Alpha value (0-255) to apply to the end color ticks, by default 128
|
|
1203
|
+
|
|
1204
|
+
Returns
|
|
1205
|
+
-------
|
|
1206
|
+
None
|
|
1207
|
+
This function modifies the instance state in-place and does not return anything.
|
|
1208
|
+
|
|
1209
|
+
Notes
|
|
1210
|
+
-----
|
|
1211
|
+
The function applies alpha blending to intermediate color ticks while preserving
|
|
1212
|
+
the original alpha values of the first and last ticks. When verbose mode is enabled
|
|
1213
|
+
(verbose > 1), the modified tick values are printed to the console.
|
|
1214
|
+
|
|
1215
|
+
Examples
|
|
1216
|
+
--------
|
|
1217
|
+
>>> lut_state = {
|
|
1218
|
+
... "ticks": [(0, (0, 0, 0, 255)), (128, (128, 128, 128, 255)), (255, (255, 255, 255, 255))],
|
|
1219
|
+
... "mode": "RGB",
|
|
1220
|
+
... "name": "grayscale"
|
|
1221
|
+
... }
|
|
1222
|
+
>>> setLUT(lut_state, alpha=128, endalpha=64)
|
|
1223
|
+
"""
|
|
433
1224
|
if alpha is not None:
|
|
434
1225
|
theticks = [lut_state["ticks"][0]]
|
|
435
1226
|
for theelement in lut_state["ticks"][1:-1]:
|
|
@@ -449,10 +1240,80 @@ class Overlay:
|
|
|
449
1240
|
self.theLUT = self.gradient.getLookupTable(512, alpha=True)
|
|
450
1241
|
self.LUTname = lut_state["name"]
|
|
451
1242
|
|
|
452
|
-
def setisdisplayed(self, display_state):
|
|
1243
|
+
def setisdisplayed(self, display_state: bool) -> None:
|
|
1244
|
+
"""
|
|
1245
|
+
Set the display state of the object.
|
|
1246
|
+
|
|
1247
|
+
Parameters
|
|
1248
|
+
----------
|
|
1249
|
+
display_state : bool
|
|
1250
|
+
The display state to set. True indicates the object should be displayed,
|
|
1251
|
+
False indicates it should be hidden.
|
|
1252
|
+
|
|
1253
|
+
Returns
|
|
1254
|
+
-------
|
|
1255
|
+
None
|
|
1256
|
+
This method does not return any value.
|
|
1257
|
+
|
|
1258
|
+
Notes
|
|
1259
|
+
-----
|
|
1260
|
+
This method directly assigns the provided display state to the internal
|
|
1261
|
+
`display_state` attribute of the object. The display state controls whether
|
|
1262
|
+
the object is visible in the user interface or not.
|
|
1263
|
+
|
|
1264
|
+
Examples
|
|
1265
|
+
--------
|
|
1266
|
+
>>> obj = MyClass()
|
|
1267
|
+
>>> obj.setisdisplayed(True)
|
|
1268
|
+
>>> print(obj.display_state)
|
|
1269
|
+
True
|
|
1270
|
+
>>> obj.setisdisplayed(False)
|
|
1271
|
+
>>> print(obj.display_state)
|
|
1272
|
+
False
|
|
1273
|
+
"""
|
|
453
1274
|
self.display_state = display_state
|
|
454
1275
|
|
|
455
|
-
def summarize(self):
|
|
1276
|
+
def summarize(self) -> None:
|
|
1277
|
+
"""
|
|
1278
|
+
Print a summary of the overlay's properties and metadata.
|
|
1279
|
+
|
|
1280
|
+
This method outputs a formatted summary of the overlay's key attributes,
|
|
1281
|
+
including name, label, file information, dimensions, orientation, and
|
|
1282
|
+
data statistics. It also indicates whether geometric and functional masks
|
|
1283
|
+
are set.
|
|
1284
|
+
|
|
1285
|
+
Notes
|
|
1286
|
+
-----
|
|
1287
|
+
The output is printed directly to the console and does not return any value.
|
|
1288
|
+
This method is intended for debugging or inspection purposes.
|
|
1289
|
+
|
|
1290
|
+
Examples
|
|
1291
|
+
--------
|
|
1292
|
+
>>> overlay = Overlay(...)
|
|
1293
|
+
>>> overlay.summarize()
|
|
1294
|
+
Overlay name: my_overlay
|
|
1295
|
+
label: My Overlay
|
|
1296
|
+
filename: /path/to/my_overlay.nii
|
|
1297
|
+
namebase: my_overlay
|
|
1298
|
+
xdim: 64
|
|
1299
|
+
ydim: 64
|
|
1300
|
+
zdim: 32
|
|
1301
|
+
tdim: 100
|
|
1302
|
+
space: MNI
|
|
1303
|
+
orientation: radiological
|
|
1304
|
+
toffset: 0.0
|
|
1305
|
+
tr: 2.0
|
|
1306
|
+
min: -1.5
|
|
1307
|
+
max: 2.0
|
|
1308
|
+
robustmin: -1.0
|
|
1309
|
+
robustmax: 1.5
|
|
1310
|
+
dispmin: -1.5
|
|
1311
|
+
dispmax: 2.0
|
|
1312
|
+
data shape: (64, 64, 32, 100)
|
|
1313
|
+
masked data shape: (64, 64, 32, 100)
|
|
1314
|
+
geometric mask is set
|
|
1315
|
+
functional mask not set
|
|
1316
|
+
"""
|
|
456
1317
|
print()
|
|
457
1318
|
print("Overlay name: ", self.name)
|
|
458
1319
|
print(" label: ", self.label)
|
|
@@ -517,24 +1378,89 @@ class RapidtideDataset:
|
|
|
517
1378
|
|
|
518
1379
|
def __init__(
|
|
519
1380
|
self,
|
|
520
|
-
name,
|
|
521
|
-
fileroot,
|
|
522
|
-
anatname=None,
|
|
523
|
-
geommaskname=None,
|
|
524
|
-
funcmaskname=None,
|
|
525
|
-
graymaskspec=None,
|
|
526
|
-
whitemaskspec=None,
|
|
527
|
-
userise=False,
|
|
528
|
-
usecorrout=False,
|
|
529
|
-
useatlas=False,
|
|
530
|
-
minimal=False,
|
|
531
|
-
forcetr=False,
|
|
532
|
-
forceoffset=False,
|
|
533
|
-
coordinatespace="unspecified",
|
|
534
|
-
offsettime=0.0,
|
|
535
|
-
init_LUT=True,
|
|
536
|
-
verbose=0,
|
|
537
|
-
):
|
|
1381
|
+
name: str,
|
|
1382
|
+
fileroot: str,
|
|
1383
|
+
anatname: str | None = None,
|
|
1384
|
+
geommaskname: str | None = None,
|
|
1385
|
+
funcmaskname: str | None = None,
|
|
1386
|
+
graymaskspec: str | None = None,
|
|
1387
|
+
whitemaskspec: str | None = None,
|
|
1388
|
+
userise: bool = False,
|
|
1389
|
+
usecorrout: bool = False,
|
|
1390
|
+
useatlas: bool = False,
|
|
1391
|
+
minimal: bool = False,
|
|
1392
|
+
forcetr: bool = False,
|
|
1393
|
+
forceoffset: bool = False,
|
|
1394
|
+
coordinatespace: str = "unspecified",
|
|
1395
|
+
offsettime: float = 0.0,
|
|
1396
|
+
init_LUT: bool = True,
|
|
1397
|
+
verbose: int = 0,
|
|
1398
|
+
) -> None:
|
|
1399
|
+
"""
|
|
1400
|
+
Initialize a RapidtideDataset object for processing neuroimaging data.
|
|
1401
|
+
|
|
1402
|
+
This constructor sets up the dataset configuration based on provided parameters,
|
|
1403
|
+
determines the naming convention used by the dataset (BIDS or legacy), and
|
|
1404
|
+
initializes internal structures for regressor and overlay handling.
|
|
1405
|
+
|
|
1406
|
+
Parameters
|
|
1407
|
+
----------
|
|
1408
|
+
name : str
|
|
1409
|
+
Name of the dataset.
|
|
1410
|
+
fileroot : str
|
|
1411
|
+
Root path to the dataset files.
|
|
1412
|
+
anatname : str, optional
|
|
1413
|
+
Path to the anatomical image file. Default is None.
|
|
1414
|
+
geommaskname : str, optional
|
|
1415
|
+
Path to the geometric mask file. Default is None.
|
|
1416
|
+
funcmaskname : str, optional
|
|
1417
|
+
Path to the functional mask file. Default is None.
|
|
1418
|
+
graymaskspec : str, optional
|
|
1419
|
+
Specification for gray matter mask. Default is None.
|
|
1420
|
+
whitemaskspec : str, optional
|
|
1421
|
+
Specification for white matter mask. Default is None.
|
|
1422
|
+
userise : bool, optional
|
|
1423
|
+
Whether to use RISE (reconstruction of instantaneous signal estimates). Default is False.
|
|
1424
|
+
usecorrout : bool, optional
|
|
1425
|
+
Whether to use corrected output. Default is False.
|
|
1426
|
+
useatlas : bool, optional
|
|
1427
|
+
Whether to use atlas-based processing. Default is False.
|
|
1428
|
+
minimal : bool, optional
|
|
1429
|
+
Whether to run in minimal mode. Default is False.
|
|
1430
|
+
forcetr : bool, optional
|
|
1431
|
+
Whether to force TR (repetition time) correction. Default is False.
|
|
1432
|
+
forceoffset : bool, optional
|
|
1433
|
+
Whether to force offset correction. Default is False.
|
|
1434
|
+
coordinatespace : str, optional
|
|
1435
|
+
Coordinate space of the data. Default is "unspecified".
|
|
1436
|
+
offsettime : float, optional
|
|
1437
|
+
Time offset to apply. Default is 0.0.
|
|
1438
|
+
init_LUT : bool, optional
|
|
1439
|
+
Whether to initialize lookup tables. Default is True.
|
|
1440
|
+
verbose : int, optional
|
|
1441
|
+
Verbosity level. Default is 0.
|
|
1442
|
+
|
|
1443
|
+
Returns
|
|
1444
|
+
-------
|
|
1445
|
+
None
|
|
1446
|
+
This method initializes the object and does not return any value.
|
|
1447
|
+
|
|
1448
|
+
Notes
|
|
1449
|
+
-----
|
|
1450
|
+
The function automatically detects whether the dataset uses BIDS-style naming
|
|
1451
|
+
conventions by checking for the presence of specific files like
|
|
1452
|
+
``<fileroot>desc-maxtime_map.nii.gz``. If not found, it checks for legacy naming
|
|
1453
|
+
patterns such as ``<fileroot>fitmask.nii.gz``.
|
|
1454
|
+
|
|
1455
|
+
Examples
|
|
1456
|
+
--------
|
|
1457
|
+
>>> dataset = RapidtideDataset(
|
|
1458
|
+
... name="test_dataset",
|
|
1459
|
+
... fileroot="/path/to/data",
|
|
1460
|
+
... anatname="/path/to/anat.nii.gz",
|
|
1461
|
+
... verbose=1
|
|
1462
|
+
... )
|
|
1463
|
+
"""
|
|
538
1464
|
self.verbose = verbose
|
|
539
1465
|
self.name = name
|
|
540
1466
|
self.fileroot = fileroot
|
|
@@ -574,7 +1500,47 @@ class RapidtideDataset:
|
|
|
574
1500
|
self.setupregressors()
|
|
575
1501
|
self.setupoverlays()
|
|
576
1502
|
|
|
577
|
-
def _loadregressors(self):
|
|
1503
|
+
def _loadregressors(self) -> None:
|
|
1504
|
+
"""
|
|
1505
|
+
Load regressor timecourses from specified files.
|
|
1506
|
+
|
|
1507
|
+
This method iterates through the list of regressor specifications (`self.regressorspecs`)
|
|
1508
|
+
and attempts to load each regressor from the corresponding file. If a file exists, it is
|
|
1509
|
+
read into a `Timecourse` object and stored in `self.regressors`. If no regressor is
|
|
1510
|
+
successfully loaded, the first one in the list is set as the focus regressor.
|
|
1511
|
+
|
|
1512
|
+
Parameters
|
|
1513
|
+
----------
|
|
1514
|
+
self : object
|
|
1515
|
+
The instance of the class containing the method. Expected to have the following
|
|
1516
|
+
attributes:
|
|
1517
|
+
- `regressorspecs`: list of tuples specifying regressor files and parameters.
|
|
1518
|
+
- `fileroot`: string, base path for regressor files.
|
|
1519
|
+
- `regressors`: dict, to store loaded regressors.
|
|
1520
|
+
- `focusregressor`: str, name of the currently focused regressor.
|
|
1521
|
+
- `verbose`: int, level of verbosity for logging.
|
|
1522
|
+
- `bidsformat`: bool, flag indicating BIDS format usage.
|
|
1523
|
+
- `regressorsimcalclimits`: tuple, limits for regressor calculation.
|
|
1524
|
+
- `isbids`: bool, flag indicating BIDS format usage (likely a typo for `bidsformat`).
|
|
1525
|
+
|
|
1526
|
+
Returns
|
|
1527
|
+
-------
|
|
1528
|
+
None
|
|
1529
|
+
This method modifies the instance's attributes in place and does not return any value.
|
|
1530
|
+
|
|
1531
|
+
Notes
|
|
1532
|
+
-----
|
|
1533
|
+
- If a regressor file does not exist and the corresponding flag in `regressorspecs` is True,
|
|
1534
|
+
a `FileNotFoundError` is raised.
|
|
1535
|
+
- If a regressor file does not exist and the flag is False, the file is skipped with a message.
|
|
1536
|
+
- The first successfully loaded regressor is set as the `focusregressor` if none is already set.
|
|
1537
|
+
|
|
1538
|
+
Examples
|
|
1539
|
+
--------
|
|
1540
|
+
>>> loader = MyLoader()
|
|
1541
|
+
>>> loader._loadregressors()
|
|
1542
|
+
# Loads regressors specified in `loader.regressorspecs` into `loader.regressors`.
|
|
1543
|
+
"""
|
|
578
1544
|
self.focusregressor = None
|
|
579
1545
|
for thisregressor in self.regressorspecs:
|
|
580
1546
|
if os.path.isfile(self.fileroot + thisregressor[2]):
|
|
@@ -601,7 +1567,9 @@ class RapidtideDataset:
|
|
|
601
1567
|
self.focusregressor = thisregressor[0]
|
|
602
1568
|
else:
|
|
603
1569
|
if thisregressor[6]:
|
|
604
|
-
raise FileNotFoundError(
|
|
1570
|
+
raise FileNotFoundError(
|
|
1571
|
+
f"regressor file {self.fileroot + thisregressor[2]} does not exist"
|
|
1572
|
+
)
|
|
605
1573
|
else:
|
|
606
1574
|
if self.verbose > 1:
|
|
607
1575
|
print(
|
|
@@ -610,7 +1578,46 @@ class RapidtideDataset:
|
|
|
610
1578
|
" does not exist - skipping...",
|
|
611
1579
|
)
|
|
612
1580
|
|
|
613
|
-
def _loadfuncmaps(self):
|
|
1581
|
+
def _loadfuncmaps(self) -> None:
|
|
1582
|
+
"""
|
|
1583
|
+
Load functional maps from NIfTI files and initialize overlays.
|
|
1584
|
+
|
|
1585
|
+
This function iterates through the list of functional maps specified in
|
|
1586
|
+
`self.funcmaps`, loads each map from a NIfTI file (if it exists), and
|
|
1587
|
+
initializes an `Overlay` object for each. It ensures that all loaded
|
|
1588
|
+
maps have consistent dimensions and voxel sizes. If a map is listed in
|
|
1589
|
+
`mapstoinvert`, it will be inverted upon loading.
|
|
1590
|
+
|
|
1591
|
+
Parameters
|
|
1592
|
+
----------
|
|
1593
|
+
None
|
|
1594
|
+
|
|
1595
|
+
Returns
|
|
1596
|
+
-------
|
|
1597
|
+
None
|
|
1598
|
+
This function does not return a value but updates the following
|
|
1599
|
+
instance attributes:
|
|
1600
|
+
- `self.overlays`: Dictionary mapping map names to `Overlay` objects.
|
|
1601
|
+
- `self.loadedfuncmaps`: List of successfully loaded map names.
|
|
1602
|
+
|
|
1603
|
+
Notes
|
|
1604
|
+
-----
|
|
1605
|
+
- The function checks for the existence of `.nii.gz` files before attempting
|
|
1606
|
+
to load them.
|
|
1607
|
+
- If dimensions or voxel sizes of the loaded maps do not match, the program
|
|
1608
|
+
will exit with an error message.
|
|
1609
|
+
- Map names in `mapstoinvert` (currently only "varChange") will be inverted
|
|
1610
|
+
during loading.
|
|
1611
|
+
|
|
1612
|
+
Examples
|
|
1613
|
+
--------
|
|
1614
|
+
Assuming `self.funcmaps` contains entries like:
|
|
1615
|
+
[("varChange", "varchange_map"), ("tstat", "tstat_map")]
|
|
1616
|
+
|
|
1617
|
+
And the corresponding files exist, this function will load these maps and
|
|
1618
|
+
store them in `self.overlays` with appropriate inversion applied where
|
|
1619
|
+
needed.
|
|
1620
|
+
"""
|
|
614
1621
|
mapstoinvert = ["varChange"]
|
|
615
1622
|
self.loadedfuncmaps = []
|
|
616
1623
|
xdim = 0
|
|
@@ -671,7 +1678,53 @@ class RapidtideDataset:
|
|
|
671
1678
|
if self.verbose > 1:
|
|
672
1679
|
print("functional maps loaded:", self.loadedfuncmaps)
|
|
673
1680
|
|
|
674
|
-
def _loadfuncmasks(self):
|
|
1681
|
+
def _loadfuncmasks(self) -> None:
|
|
1682
|
+
"""
|
|
1683
|
+
Load functional masks from specified files and create overlay objects.
|
|
1684
|
+
|
|
1685
|
+
This method iterates through the functional masks defined in `self.funcmasks`
|
|
1686
|
+
and attempts to load each mask file. If a mask file exists, it creates an
|
|
1687
|
+
Overlay object and stores it in `self.overlays` with the mask name as key.
|
|
1688
|
+
|
|
1689
|
+
Parameters
|
|
1690
|
+
----------
|
|
1691
|
+
self : object
|
|
1692
|
+
The instance containing the following attributes:
|
|
1693
|
+
- funcmasks : list of tuples
|
|
1694
|
+
List of (maskname, maskfilename) pairs to load
|
|
1695
|
+
- fileroot : str
|
|
1696
|
+
Root directory path for mask files
|
|
1697
|
+
- overlays : dict
|
|
1698
|
+
Dictionary to store loaded overlay objects
|
|
1699
|
+
- verbose : int
|
|
1700
|
+
Verbosity level for printing status messages
|
|
1701
|
+
- init_LUT : bool, optional
|
|
1702
|
+
Flag to initialize lookup table for overlays
|
|
1703
|
+
- loadedfuncmasks : list
|
|
1704
|
+
List to store names of successfully loaded masks
|
|
1705
|
+
|
|
1706
|
+
Returns
|
|
1707
|
+
-------
|
|
1708
|
+
None
|
|
1709
|
+
This method modifies instance attributes in-place and does not return a value.
|
|
1710
|
+
|
|
1711
|
+
Notes
|
|
1712
|
+
-----
|
|
1713
|
+
- Mask files are expected to have .nii.gz extension
|
|
1714
|
+
- Only masks that exist at the constructed file path are loaded
|
|
1715
|
+
- Progress information is printed based on verbosity level
|
|
1716
|
+
- Successfully loaded mask names are stored in `self.loadedfuncmasks`
|
|
1717
|
+
|
|
1718
|
+
Examples
|
|
1719
|
+
--------
|
|
1720
|
+
>>> # Assuming self.funcmasks = [('mask1', 'mask1_file'), ('mask2', 'mask2_file')]
|
|
1721
|
+
>>> # and mask files exist at self.fileroot + maskfilename + ".nii.gz"
|
|
1722
|
+
>>> _loadfuncmasks()
|
|
1723
|
+
>>> print(self.loadedfuncmasks)
|
|
1724
|
+
['mask1', 'mask2']
|
|
1725
|
+
>>> print(self.overlays['mask1'])
|
|
1726
|
+
<Overlay object at 0x...>
|
|
1727
|
+
"""
|
|
675
1728
|
self.loadedfuncmasks = []
|
|
676
1729
|
for maskname, maskfilename in self.funcmasks:
|
|
677
1730
|
if self.verbose > 1:
|
|
@@ -697,7 +1750,41 @@ class RapidtideDataset:
|
|
|
697
1750
|
if self.verbose > 1:
|
|
698
1751
|
print(self.loadedfuncmasks)
|
|
699
1752
|
|
|
700
|
-
def _genpmasks(self, pvals=[0.05, 0.01, 0.005, 0.001]):
|
|
1753
|
+
def _genpmasks(self, pvals: list[float] = [0.05, 0.01, 0.005, 0.001]) -> None:
|
|
1754
|
+
"""
|
|
1755
|
+
Generate binary masks for specified p-value thresholds from negative log10 p-values.
|
|
1756
|
+
|
|
1757
|
+
This function creates binary masks based on negative log10 p-values stored in
|
|
1758
|
+
self.overlays["neglog10p"]. Each mask represents regions where the negative
|
|
1759
|
+
log10 p-values exceed the specified threshold.
|
|
1760
|
+
|
|
1761
|
+
Parameters
|
|
1762
|
+
----------
|
|
1763
|
+
pvals : list of float, optional
|
|
1764
|
+
List of p-value thresholds for mask generation. Default is [0.05, 0.01, 0.005, 0.001].
|
|
1765
|
+
Each threshold is converted to a mask name format "p_lt_{threshold}_mask".
|
|
1766
|
+
|
|
1767
|
+
Returns
|
|
1768
|
+
-------
|
|
1769
|
+
None
|
|
1770
|
+
This function modifies the instance's overlays and loadedfuncmasks attributes
|
|
1771
|
+
in-place and does not return any value.
|
|
1772
|
+
|
|
1773
|
+
Notes
|
|
1774
|
+
-----
|
|
1775
|
+
- Mask names are formatted to replace "0.0" with "0p0" (e.g., "0.05" becomes "0p05")
|
|
1776
|
+
- The function uses the last loaded functional mask as the base for duplication
|
|
1777
|
+
- Generated masks are stored in self.overlays dictionary with corresponding names
|
|
1778
|
+
- The function updates self.loadedfuncmasks with the names of newly created masks
|
|
1779
|
+
|
|
1780
|
+
Examples
|
|
1781
|
+
--------
|
|
1782
|
+
>>> _genpmasks([0.05, 0.01])
|
|
1783
|
+
# Generates masks for p-values 0.05 and 0.01 based on neglog10p data
|
|
1784
|
+
|
|
1785
|
+
>>> _genpmasks()
|
|
1786
|
+
# Generates masks for default p-values [0.05, 0.01, 0.005, 0.001]
|
|
1787
|
+
"""
|
|
701
1788
|
for thepval in pvals:
|
|
702
1789
|
maskname = f"p_lt_{thepval:.3f}_mask".replace("0.0", "0p0")
|
|
703
1790
|
nlpthresh = -np.log10(thepval)
|
|
@@ -713,7 +1800,41 @@ class RapidtideDataset:
|
|
|
713
1800
|
if self.verbose > 1:
|
|
714
1801
|
print(self.loadedfuncmasks)
|
|
715
1802
|
|
|
716
|
-
def _loadgeommask(self):
|
|
1803
|
+
def _loadgeommask(self) -> bool:
|
|
1804
|
+
"""
|
|
1805
|
+
Load a geometric mask based on configuration settings and available files.
|
|
1806
|
+
|
|
1807
|
+
This function attempts to load a geometric mask either from a user-specified
|
|
1808
|
+
file or from a default location based on the coordinate space and voxel size.
|
|
1809
|
+
The mask is stored in `self.overlays["geommask"]` if successfully loaded.
|
|
1810
|
+
|
|
1811
|
+
Returns
|
|
1812
|
+
-------
|
|
1813
|
+
bool
|
|
1814
|
+
True if a geometric mask was successfully loaded, False otherwise.
|
|
1815
|
+
|
|
1816
|
+
Notes
|
|
1817
|
+
-----
|
|
1818
|
+
- If `self.geommaskname` is set, the function attempts to load the mask from that file.
|
|
1819
|
+
- If `self.coordinatespace` is "MNI152", the function searches for a default mask
|
|
1820
|
+
based on the voxel size (`xsize`, `ysize`, `zsize`).
|
|
1821
|
+
- The function uses the FSL directory to locate default masks when available.
|
|
1822
|
+
- Verbose output is printed if `self.verbose` is greater than 1.
|
|
1823
|
+
|
|
1824
|
+
Examples
|
|
1825
|
+
--------
|
|
1826
|
+
>>> loader = SomeClass()
|
|
1827
|
+
>>> loader.geommaskname = "/path/to/custom_mask.nii.gz"
|
|
1828
|
+
>>> loader._loadgeommask()
|
|
1829
|
+
True
|
|
1830
|
+
|
|
1831
|
+
>>> loader.coordinatespace = "MNI152"
|
|
1832
|
+
>>> loader.xsize = 2.0
|
|
1833
|
+
>>> loader.ysize = 2.0
|
|
1834
|
+
>>> loader.zsize = 2.0
|
|
1835
|
+
>>> loader._loadgeommask()
|
|
1836
|
+
True # if default mask is found
|
|
1837
|
+
"""
|
|
717
1838
|
if self.geommaskname is not None:
|
|
718
1839
|
if os.path.isfile(self.geommaskname):
|
|
719
1840
|
thepath, thebase = os.path.split(self.geommaskname)
|
|
@@ -768,7 +1889,46 @@ class RapidtideDataset:
|
|
|
768
1889
|
print("no geometric mask loaded")
|
|
769
1890
|
return False
|
|
770
1891
|
|
|
771
|
-
def _loadanatomics(self):
|
|
1892
|
+
def _loadanatomics(self) -> bool:
|
|
1893
|
+
"""
|
|
1894
|
+
Load anatomic image data based on available files and coordinate space settings.
|
|
1895
|
+
|
|
1896
|
+
This method attempts to load anatomic images from various possible sources,
|
|
1897
|
+
prioritizing user-specified files, high-resolution templates, MNI templates,
|
|
1898
|
+
and mean-based images. The loaded image is stored in `self.overlays["anatomic"]`.
|
|
1899
|
+
|
|
1900
|
+
Returns
|
|
1901
|
+
-------
|
|
1902
|
+
bool
|
|
1903
|
+
True if anatomic image was successfully loaded, False otherwise.
|
|
1904
|
+
|
|
1905
|
+
Notes
|
|
1906
|
+
-----
|
|
1907
|
+
The method checks for the following files in order:
|
|
1908
|
+
1. User-specified anatomic file (`self.anatname`)
|
|
1909
|
+
2. High-resolution head image: `highres_head.nii.gz`
|
|
1910
|
+
3. High-resolution image: `highres.nii.gz`
|
|
1911
|
+
4. MNI152 template based on resolution (`xsize`, `ysize`, `zsize`)
|
|
1912
|
+
5. MNI152NLin2009cAsym template based on resolution
|
|
1913
|
+
6. Mean image: `mean.nii.gz`
|
|
1914
|
+
7. Mean value image: `meanvalue.nii.gz`
|
|
1915
|
+
8. Described mean image: `desc-unfiltmean_map.nii.gz`
|
|
1916
|
+
9. Described mean image: `desc-mean_map.nii.gz`
|
|
1917
|
+
|
|
1918
|
+
If `FSLDIR` environment variable is set, it is used to locate MNI152 templates
|
|
1919
|
+
with 2mm resolution.
|
|
1920
|
+
|
|
1921
|
+
Examples
|
|
1922
|
+
--------
|
|
1923
|
+
>>> loader = MyLoader()
|
|
1924
|
+
>>> loader.fileroot = "/path/to/data/"
|
|
1925
|
+
>>> loader.coordinatespace = "MNI152"
|
|
1926
|
+
>>> loader.xsize = 2.0
|
|
1927
|
+
>>> loader.ysize = 2.0
|
|
1928
|
+
>>> loader.zsize = 2.0
|
|
1929
|
+
>>> loader._loadanatomics()
|
|
1930
|
+
True
|
|
1931
|
+
"""
|
|
772
1932
|
try:
|
|
773
1933
|
fsldir = os.environ["FSLDIR"]
|
|
774
1934
|
except KeyError:
|
|
@@ -945,7 +2105,33 @@ class RapidtideDataset:
|
|
|
945
2105
|
print("no anatomic image loaded")
|
|
946
2106
|
return False
|
|
947
2107
|
|
|
948
|
-
def _loadgraymask(self):
|
|
2108
|
+
def _loadgraymask(self) -> bool:
|
|
2109
|
+
"""
|
|
2110
|
+
Load gray matter mask from specification.
|
|
2111
|
+
|
|
2112
|
+
Load a gray matter mask from the file specification stored in `self.graymaskspec`.
|
|
2113
|
+
If successful, the mask is stored in `self.overlays["graymask"]` and the function
|
|
2114
|
+
returns True. If no mask specification is provided or the file doesn't exist,
|
|
2115
|
+
the function returns False.
|
|
2116
|
+
|
|
2117
|
+
Returns
|
|
2118
|
+
-------
|
|
2119
|
+
bool
|
|
2120
|
+
True if gray matter mask was successfully loaded, False otherwise.
|
|
2121
|
+
|
|
2122
|
+
Notes
|
|
2123
|
+
-----
|
|
2124
|
+
This function checks if `self.graymaskspec` is not None and if the specified
|
|
2125
|
+
file exists. If both conditions are met, it creates an Overlay object for the
|
|
2126
|
+
gray mask and stores it in `self.overlays["graymask"]`. The function also
|
|
2127
|
+
prints verbose messages when loading or skipping the mask.
|
|
2128
|
+
|
|
2129
|
+
Examples
|
|
2130
|
+
--------
|
|
2131
|
+
>>> loaded = self._loadgraymask()
|
|
2132
|
+
>>> print(loaded)
|
|
2133
|
+
True
|
|
2134
|
+
"""
|
|
949
2135
|
if self.graymaskspec is not None:
|
|
950
2136
|
filename, dummy = tide_io.parsefilespec(self.graymaskspec)
|
|
951
2137
|
if os.path.isfile(filename):
|
|
@@ -967,7 +2153,39 @@ class RapidtideDataset:
|
|
|
967
2153
|
print("no gray mask loaded")
|
|
968
2154
|
return False
|
|
969
2155
|
|
|
970
|
-
def _loadwhitemask(self):
|
|
2156
|
+
def _loadwhitemask(self) -> bool:
|
|
2157
|
+
"""
|
|
2158
|
+
Load white matter mask from specification if available.
|
|
2159
|
+
|
|
2160
|
+
This method attempts to load a white matter mask from the specification
|
|
2161
|
+
stored in `self.whitemaskspec`. If the specification is valid and the
|
|
2162
|
+
corresponding file exists, it creates an Overlay object for the white
|
|
2163
|
+
matter mask and stores it in `self.overlays["whitemask"]`.
|
|
2164
|
+
|
|
2165
|
+
Parameters
|
|
2166
|
+
----------
|
|
2167
|
+
self : object
|
|
2168
|
+
The instance containing the white matter mask specification and
|
|
2169
|
+
overlay storage.
|
|
2170
|
+
|
|
2171
|
+
Returns
|
|
2172
|
+
-------
|
|
2173
|
+
bool
|
|
2174
|
+
True if white matter mask was successfully loaded, False otherwise.
|
|
2175
|
+
|
|
2176
|
+
Notes
|
|
2177
|
+
-----
|
|
2178
|
+
The method checks if `self.whitemaskspec` is not None and if the
|
|
2179
|
+
specified file exists before attempting to load it. If successful,
|
|
2180
|
+
the mask is stored in `self.overlays["whitemask"]` and a verbose
|
|
2181
|
+
message is printed if `self.verbose` is greater than 1.
|
|
2182
|
+
|
|
2183
|
+
Examples
|
|
2184
|
+
--------
|
|
2185
|
+
>>> loaded = self._loadwhitemask()
|
|
2186
|
+
>>> print(loaded)
|
|
2187
|
+
True
|
|
2188
|
+
"""
|
|
971
2189
|
if self.whitemaskspec is not None:
|
|
972
2190
|
filename, dummy = tide_io.parsefilespec(self.whitemaskspec)
|
|
973
2191
|
if os.path.isfile(filename):
|
|
@@ -989,7 +2207,42 @@ class RapidtideDataset:
|
|
|
989
2207
|
print("no white mask loaded")
|
|
990
2208
|
return False
|
|
991
2209
|
|
|
992
|
-
def setupregressors(self):
|
|
2210
|
+
def setupregressors(self) -> None:
|
|
2211
|
+
"""
|
|
2212
|
+
Set up regressor specifications and load regressor data.
|
|
2213
|
+
|
|
2214
|
+
This method initializes the regressor specifications based on the BIDS format
|
|
2215
|
+
and the run options, and loads the corresponding regressor data. It handles
|
|
2216
|
+
various configuration parameters such as filter limits, sampling frequencies,
|
|
2217
|
+
and similarity metrics, and prepares a list of regressor specifications for
|
|
2218
|
+
use in subsequent processing steps.
|
|
2219
|
+
|
|
2220
|
+
Parameters
|
|
2221
|
+
----------
|
|
2222
|
+
None
|
|
2223
|
+
|
|
2224
|
+
Returns
|
|
2225
|
+
-------
|
|
2226
|
+
None
|
|
2227
|
+
This method does not return any value but updates the instance attributes
|
|
2228
|
+
`regressors`, `regressorfilterlimits`, `fmrifreq`, `inputfreq`,
|
|
2229
|
+
`inputstarttime`, `oversampfactor`, `similaritymetric`, `regressorsimcalclimits`,
|
|
2230
|
+
`numberofpasses`, and `regressorspecs`.
|
|
2231
|
+
|
|
2232
|
+
Notes
|
|
2233
|
+
-----
|
|
2234
|
+
- The method reads run options from a file specified by `self.fileroot + "desc-runoptions_info"`.
|
|
2235
|
+
- If `self.bidsformat` is True, the regressor files are named according to BIDS conventions.
|
|
2236
|
+
- The method determines the number of passes and sets up the regressor specifications accordingly.
|
|
2237
|
+
- The `regressorspecs` list contains information for loading regressors at different stages:
|
|
2238
|
+
pre-filtered, post-filtered, and multiple passes, with associated file names, frequencies,
|
|
2239
|
+
and time offsets.
|
|
2240
|
+
|
|
2241
|
+
Examples
|
|
2242
|
+
--------
|
|
2243
|
+
>>> setupregressors()
|
|
2244
|
+
# Updates instance attributes with regressor configurations and loads data.
|
|
2245
|
+
"""
|
|
993
2246
|
# load the regressors
|
|
994
2247
|
self.regressors = {}
|
|
995
2248
|
self.therunoptions = tide_io.readoptionsfile(self.fileroot + "desc-runoptions_info")
|
|
@@ -1157,17 +2410,134 @@ class RapidtideDataset:
|
|
|
1157
2410
|
]
|
|
1158
2411
|
self._loadregressors()
|
|
1159
2412
|
|
|
1160
|
-
def getregressors(self):
|
|
2413
|
+
def getregressors(self) -> dict:
|
|
2414
|
+
"""
|
|
2415
|
+
Return the regressors stored in the object.
|
|
2416
|
+
|
|
2417
|
+
Returns
|
|
2418
|
+
-------
|
|
2419
|
+
dict
|
|
2420
|
+
A dictionary containing the regressors. The keys are typically
|
|
2421
|
+
regressor names and the values are the corresponding regressor objects.
|
|
2422
|
+
|
|
2423
|
+
Notes
|
|
2424
|
+
-----
|
|
2425
|
+
This method provides access to the internal regressors dictionary
|
|
2426
|
+
that stores all regression models used by the object.
|
|
2427
|
+
|
|
2428
|
+
Examples
|
|
2429
|
+
--------
|
|
2430
|
+
>>> model = MyRegressionModel()
|
|
2431
|
+
>>> regressors = model.getregressors()
|
|
2432
|
+
>>> print(regressors)
|
|
2433
|
+
{'linear_reg': LinearRegression(), 'ridge_reg': Ridge()}
|
|
2434
|
+
"""
|
|
1161
2435
|
return self.regressors
|
|
1162
2436
|
|
|
1163
|
-
def setfocusregressor(self, whichregressor):
|
|
2437
|
+
def setfocusregressor(self, whichregressor: str) -> None:
|
|
2438
|
+
"""
|
|
2439
|
+
Set the focus regressor for the current instance.
|
|
2440
|
+
|
|
2441
|
+
This method sets the focus regressor to the specified regressor name if it exists
|
|
2442
|
+
in the regressors dictionary. If the specified regressor does not exist, it defaults
|
|
2443
|
+
to "prefilt".
|
|
2444
|
+
|
|
2445
|
+
Parameters
|
|
2446
|
+
----------
|
|
2447
|
+
whichregressor : str
|
|
2448
|
+
The name of the regressor to set as the focus regressor. This should be a key
|
|
2449
|
+
present in the instance's regressors dictionary.
|
|
2450
|
+
|
|
2451
|
+
Returns
|
|
2452
|
+
-------
|
|
2453
|
+
None
|
|
2454
|
+
This method does not return any value.
|
|
2455
|
+
|
|
2456
|
+
Notes
|
|
2457
|
+
-----
|
|
2458
|
+
If the specified regressor name is not found in self.regressors, the method will
|
|
2459
|
+
automatically fall back to setting the focus regressor to "prefilt".
|
|
2460
|
+
|
|
2461
|
+
Examples
|
|
2462
|
+
--------
|
|
2463
|
+
>>> instance.setfocusregressor("regressor1")
|
|
2464
|
+
>>> print(instance.focusregressor)
|
|
2465
|
+
'regressor1'
|
|
2466
|
+
|
|
2467
|
+
>>> instance.setfocusregressor("nonexistent")
|
|
2468
|
+
>>> print(instance.focusregressor)
|
|
2469
|
+
'prefilt'
|
|
2470
|
+
"""
|
|
1164
2471
|
try:
|
|
1165
2472
|
testregressor = self.regressors[whichregressor]
|
|
1166
2473
|
self.focusregressor = whichregressor
|
|
1167
2474
|
except KeyError:
|
|
1168
2475
|
self.focusregressor = "prefilt"
|
|
1169
2476
|
|
|
1170
|
-
def setupoverlays(self):
|
|
2477
|
+
def setupoverlays(self) -> None:
|
|
2478
|
+
"""
|
|
2479
|
+
Set up and load all overlays for functional and anatomical data.
|
|
2480
|
+
|
|
2481
|
+
This function initializes the overlays dictionary and loads various functional
|
|
2482
|
+
maps, masks, and anatomical data based on the configuration parameters such as
|
|
2483
|
+
BIDS format, use of correlation outputs, and coordinate space. It also handles
|
|
2484
|
+
setting TR and time offset values for the loaded maps, and loads additional
|
|
2485
|
+
data such as atlases and tissue masks if applicable.
|
|
2486
|
+
|
|
2487
|
+
Parameters
|
|
2488
|
+
----------
|
|
2489
|
+
self : object
|
|
2490
|
+
The instance of the class containing this method. Expected to have the
|
|
2491
|
+
following attributes:
|
|
2492
|
+
|
|
2493
|
+
- bidsformat : bool
|
|
2494
|
+
Indicates whether the data is in BIDS format.
|
|
2495
|
+
- usecorrout : bool
|
|
2496
|
+
Whether to include correlation output maps.
|
|
2497
|
+
- newstylenames : bool
|
|
2498
|
+
Whether to use new-style naming conventions for maps.
|
|
2499
|
+
- userise : bool
|
|
2500
|
+
Whether to include rise time-related maps.
|
|
2501
|
+
- forcetr : bool
|
|
2502
|
+
Whether to force TR value for loaded maps.
|
|
2503
|
+
- forceoffset : bool
|
|
2504
|
+
Whether to force time offset for loaded maps.
|
|
2505
|
+
- trval : float
|
|
2506
|
+
The TR value to be set if `forcetr` is True.
|
|
2507
|
+
- offsettime : float
|
|
2508
|
+
The time offset to be set if `forceoffset` is True.
|
|
2509
|
+
- verbose : int
|
|
2510
|
+
Verbosity level for output messages.
|
|
2511
|
+
- referencedir : str
|
|
2512
|
+
Directory containing reference data such as atlases.
|
|
2513
|
+
- init_LUT : bool
|
|
2514
|
+
Whether to initialize lookup tables for overlays.
|
|
2515
|
+
- useatlas : bool
|
|
2516
|
+
Whether to load atlas data.
|
|
2517
|
+
- coordinatespace : str
|
|
2518
|
+
The coordinate space of the data (e.g., "MNI152", "MNI152NLin2009cAsym").
|
|
2519
|
+
|
|
2520
|
+
Returns
|
|
2521
|
+
-------
|
|
2522
|
+
None
|
|
2523
|
+
This function does not return any value. It modifies the instance's
|
|
2524
|
+
attributes in place.
|
|
2525
|
+
|
|
2526
|
+
Notes
|
|
2527
|
+
-----
|
|
2528
|
+
- Functional maps are loaded based on the BIDS format and naming conventions.
|
|
2529
|
+
- The function dynamically builds lists of functional maps and masks depending
|
|
2530
|
+
on the configuration.
|
|
2531
|
+
- If an atlas is to be used and the coordinate space is compatible, it will be
|
|
2532
|
+
loaded and added to the overlays.
|
|
2533
|
+
- The function sets up several instance variables such as `xdim`, `ydim`, `zdim`,
|
|
2534
|
+
`tdim`, `xsize`, `ysize`, `zsize`, and `tr` from the focus map.
|
|
2535
|
+
|
|
2536
|
+
Examples
|
|
2537
|
+
--------
|
|
2538
|
+
>>> setupoverlays()
|
|
2539
|
+
# Loads all overlays and sets up the instance for further processing.
|
|
2540
|
+
"""
|
|
1171
2541
|
# load the overlays
|
|
1172
2542
|
self.overlays = {}
|
|
1173
2543
|
|
|
@@ -1397,15 +2767,92 @@ class RapidtideDataset:
|
|
|
1397
2767
|
if self.verbose > 1:
|
|
1398
2768
|
print("done")
|
|
1399
2769
|
|
|
1400
|
-
def getoverlays(self):
|
|
2770
|
+
def getoverlays(self) -> dict:
|
|
2771
|
+
"""
|
|
2772
|
+
Return the overlays dictionary.
|
|
2773
|
+
|
|
2774
|
+
Returns
|
|
2775
|
+
-------
|
|
2776
|
+
dict
|
|
2777
|
+
A dictionary containing the overlays data.
|
|
2778
|
+
|
|
2779
|
+
Notes
|
|
2780
|
+
-----
|
|
2781
|
+
This method provides access to the internal overlays attribute.
|
|
2782
|
+
The returned dictionary contains all overlay data managed by this instance.
|
|
2783
|
+
|
|
2784
|
+
Examples
|
|
2785
|
+
--------
|
|
2786
|
+
>>> overlays = obj.getoverlays()
|
|
2787
|
+
>>> print(overlays)
|
|
2788
|
+
{'overlay1': <OverlayObject>, 'overlay2': <OverlayObject>}
|
|
2789
|
+
"""
|
|
1401
2790
|
return self.overlays
|
|
1402
2791
|
|
|
1403
|
-
def setfocusmap(self, whichmap):
|
|
2792
|
+
def setfocusmap(self, whichmap: str) -> None:
|
|
2793
|
+
"""
|
|
2794
|
+
Set the focus map to the specified map name.
|
|
2795
|
+
|
|
2796
|
+
This method sets the current focus map to the specified map name if it exists
|
|
2797
|
+
in the overlays dictionary. If the specified map does not exist, it defaults
|
|
2798
|
+
to setting the focus map to "lagtimes".
|
|
2799
|
+
|
|
2800
|
+
Parameters
|
|
2801
|
+
----------
|
|
2802
|
+
whichmap : str
|
|
2803
|
+
The name of the map to set as the focus map. This should correspond to
|
|
2804
|
+
a key in the self.overlays dictionary.
|
|
2805
|
+
|
|
2806
|
+
Returns
|
|
2807
|
+
-------
|
|
2808
|
+
None
|
|
2809
|
+
This method does not return any value.
|
|
2810
|
+
|
|
2811
|
+
Notes
|
|
2812
|
+
-----
|
|
2813
|
+
If the specified `whichmap` is not found in `self.overlays`, the method
|
|
2814
|
+
will automatically fall back to setting the focus map to "lagtimes".
|
|
2815
|
+
|
|
2816
|
+
Examples
|
|
2817
|
+
--------
|
|
2818
|
+
>>> obj.setfocusmap("temperature")
|
|
2819
|
+
>>> obj.focusmap
|
|
2820
|
+
'temperature'
|
|
2821
|
+
|
|
2822
|
+
>>> obj.setfocusmap("nonexistent")
|
|
2823
|
+
>>> obj.focusmap
|
|
2824
|
+
'lagtimes'
|
|
2825
|
+
"""
|
|
1404
2826
|
try:
|
|
1405
2827
|
testmap = self.overlays[whichmap]
|
|
1406
2828
|
self.focusmap = whichmap
|
|
1407
2829
|
except KeyError:
|
|
1408
2830
|
self.focusmap = "lagtimes"
|
|
1409
2831
|
|
|
1410
|
-
def setFuncMaskName(self, maskname):
|
|
2832
|
+
def setFuncMaskName(self, maskname: str) -> None:
|
|
2833
|
+
"""
|
|
2834
|
+
Set the function mask name attribute.
|
|
2835
|
+
|
|
2836
|
+
Parameters
|
|
2837
|
+
----------
|
|
2838
|
+
maskname : str
|
|
2839
|
+
The name to assign to the function mask attribute.
|
|
2840
|
+
|
|
2841
|
+
Returns
|
|
2842
|
+
-------
|
|
2843
|
+
None
|
|
2844
|
+
This method does not return any value.
|
|
2845
|
+
|
|
2846
|
+
Notes
|
|
2847
|
+
-----
|
|
2848
|
+
This method assigns the provided mask name to the internal `funcmaskname` attribute
|
|
2849
|
+
of the object instance.
|
|
2850
|
+
|
|
2851
|
+
Examples
|
|
2852
|
+
--------
|
|
2853
|
+
>>> obj = MyClass()
|
|
2854
|
+
>>> obj.setFuncMaskName("my_mask")
|
|
2855
|
+
>>> print(obj.funcmaskname)
|
|
2856
|
+
'my_mask'
|
|
2857
|
+
"""
|
|
1411
2858
|
self.funcmaskname = maskname
|