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.
Files changed (144) hide show
  1. rapidtide/Colortables.py +492 -27
  2. rapidtide/OrthoImageItem.py +1049 -46
  3. rapidtide/RapidtideDataset.py +1533 -86
  4. rapidtide/_version.py +3 -3
  5. rapidtide/calccoherence.py +196 -29
  6. rapidtide/calcnullsimfunc.py +188 -40
  7. rapidtide/calcsimfunc.py +242 -42
  8. rapidtide/correlate.py +1203 -383
  9. rapidtide/data/examples/src/testLD +56 -0
  10. rapidtide/data/examples/src/testalign +1 -1
  11. rapidtide/data/examples/src/testdelayvar +0 -1
  12. rapidtide/data/examples/src/testfmri +53 -3
  13. rapidtide/data/examples/src/testglmfilt +5 -5
  14. rapidtide/data/examples/src/testhappy +29 -7
  15. rapidtide/data/examples/src/testppgproc +17 -0
  16. rapidtide/data/examples/src/testrolloff +11 -0
  17. rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
  18. rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
  19. rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
  20. rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
  21. rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
  22. rapidtide/decorators.py +91 -0
  23. rapidtide/dlfilter.py +2226 -110
  24. rapidtide/dlfiltertorch.py +4842 -0
  25. rapidtide/externaltools.py +327 -12
  26. rapidtide/fMRIData_class.py +79 -40
  27. rapidtide/filter.py +1899 -810
  28. rapidtide/fit.py +2011 -581
  29. rapidtide/genericmultiproc.py +93 -18
  30. rapidtide/happy_supportfuncs.py +2047 -172
  31. rapidtide/helper_classes.py +584 -43
  32. rapidtide/io.py +2370 -372
  33. rapidtide/linfitfiltpass.py +346 -99
  34. rapidtide/makelaggedtcs.py +210 -24
  35. rapidtide/maskutil.py +448 -62
  36. rapidtide/miscmath.py +827 -121
  37. rapidtide/multiproc.py +210 -22
  38. rapidtide/patchmatch.py +242 -42
  39. rapidtide/peakeval.py +31 -31
  40. rapidtide/ppgproc.py +2203 -0
  41. rapidtide/qualitycheck.py +352 -39
  42. rapidtide/refinedelay.py +431 -57
  43. rapidtide/refineregressor.py +494 -189
  44. rapidtide/resample.py +671 -185
  45. rapidtide/scripts/applyppgproc.py +28 -0
  46. rapidtide/scripts/showxcorr_legacy.py +7 -7
  47. rapidtide/scripts/stupidramtricks.py +15 -17
  48. rapidtide/simFuncClasses.py +1052 -77
  49. rapidtide/simfuncfit.py +269 -69
  50. rapidtide/stats.py +540 -238
  51. rapidtide/tests/happycomp +9 -0
  52. rapidtide/tests/test_cleanregressor.py +1 -2
  53. rapidtide/tests/test_dlfiltertorch.py +627 -0
  54. rapidtide/tests/test_findmaxlag.py +24 -8
  55. rapidtide/tests/test_fullrunhappy_v1.py +0 -2
  56. rapidtide/tests/test_fullrunhappy_v2.py +0 -2
  57. rapidtide/tests/test_fullrunhappy_v3.py +11 -4
  58. rapidtide/tests/test_fullrunhappy_v4.py +10 -2
  59. rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
  60. rapidtide/tests/test_getparsers.py +11 -3
  61. rapidtide/tests/test_refinedelay.py +0 -1
  62. rapidtide/tests/test_simroundtrip.py +16 -8
  63. rapidtide/tests/test_stcorrelate.py +3 -1
  64. rapidtide/tests/utils.py +9 -8
  65. rapidtide/tidepoolTemplate.py +142 -38
  66. rapidtide/tidepoolTemplate_alt.py +165 -44
  67. rapidtide/tidepoolTemplate_big.py +189 -52
  68. rapidtide/util.py +1217 -118
  69. rapidtide/voxelData.py +684 -37
  70. rapidtide/wiener.py +136 -23
  71. rapidtide/wiener2.py +113 -7
  72. rapidtide/workflows/adjustoffset.py +105 -3
  73. rapidtide/workflows/aligntcs.py +85 -2
  74. rapidtide/workflows/applydlfilter.py +87 -10
  75. rapidtide/workflows/applyppgproc.py +540 -0
  76. rapidtide/workflows/atlasaverage.py +210 -47
  77. rapidtide/workflows/atlastool.py +100 -3
  78. rapidtide/workflows/calcSimFuncMap.py +288 -69
  79. rapidtide/workflows/calctexticc.py +201 -9
  80. rapidtide/workflows/ccorrica.py +101 -6
  81. rapidtide/workflows/cleanregressor.py +165 -31
  82. rapidtide/workflows/delayvar.py +171 -23
  83. rapidtide/workflows/diffrois.py +81 -3
  84. rapidtide/workflows/endtidalproc.py +144 -4
  85. rapidtide/workflows/fdica.py +195 -15
  86. rapidtide/workflows/filtnifti.py +70 -3
  87. rapidtide/workflows/filttc.py +74 -3
  88. rapidtide/workflows/fitSimFuncMap.py +202 -51
  89. rapidtide/workflows/fixtr.py +73 -3
  90. rapidtide/workflows/gmscalc.py +113 -3
  91. rapidtide/workflows/happy.py +801 -199
  92. rapidtide/workflows/happy2std.py +144 -12
  93. rapidtide/workflows/happy_parser.py +163 -23
  94. rapidtide/workflows/histnifti.py +118 -2
  95. rapidtide/workflows/histtc.py +84 -3
  96. rapidtide/workflows/linfitfilt.py +117 -4
  97. rapidtide/workflows/localflow.py +328 -28
  98. rapidtide/workflows/mergequality.py +79 -3
  99. rapidtide/workflows/niftidecomp.py +322 -18
  100. rapidtide/workflows/niftistats.py +174 -4
  101. rapidtide/workflows/pairproc.py +98 -4
  102. rapidtide/workflows/pairwisemergenifti.py +85 -2
  103. rapidtide/workflows/parser_funcs.py +1421 -40
  104. rapidtide/workflows/physiofreq.py +137 -11
  105. rapidtide/workflows/pixelcomp.py +207 -5
  106. rapidtide/workflows/plethquality.py +103 -21
  107. rapidtide/workflows/polyfitim.py +151 -11
  108. rapidtide/workflows/proj2flow.py +75 -2
  109. rapidtide/workflows/rankimage.py +111 -4
  110. rapidtide/workflows/rapidtide.py +368 -76
  111. rapidtide/workflows/rapidtide2std.py +98 -2
  112. rapidtide/workflows/rapidtide_parser.py +109 -9
  113. rapidtide/workflows/refineDelayMap.py +144 -33
  114. rapidtide/workflows/refineRegressor.py +675 -96
  115. rapidtide/workflows/regressfrommaps.py +161 -37
  116. rapidtide/workflows/resamplenifti.py +85 -3
  117. rapidtide/workflows/resampletc.py +91 -3
  118. rapidtide/workflows/retrolagtcs.py +99 -9
  119. rapidtide/workflows/retroregress.py +176 -26
  120. rapidtide/workflows/roisummarize.py +174 -5
  121. rapidtide/workflows/runqualitycheck.py +71 -3
  122. rapidtide/workflows/showarbcorr.py +149 -6
  123. rapidtide/workflows/showhist.py +86 -2
  124. rapidtide/workflows/showstxcorr.py +160 -3
  125. rapidtide/workflows/showtc.py +159 -3
  126. rapidtide/workflows/showxcorrx.py +190 -10
  127. rapidtide/workflows/showxy.py +185 -15
  128. rapidtide/workflows/simdata.py +264 -38
  129. rapidtide/workflows/spatialfit.py +77 -2
  130. rapidtide/workflows/spatialmi.py +250 -27
  131. rapidtide/workflows/spectrogram.py +305 -32
  132. rapidtide/workflows/synthASL.py +154 -3
  133. rapidtide/workflows/tcfrom2col.py +76 -2
  134. rapidtide/workflows/tcfrom3col.py +74 -2
  135. rapidtide/workflows/tidepool.py +2971 -130
  136. rapidtide/workflows/utils.py +19 -14
  137. rapidtide/workflows/utils_doc.py +293 -0
  138. rapidtide/workflows/variabilityizer.py +116 -3
  139. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/METADATA +10 -8
  140. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/RECORD +144 -128
  141. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/entry_points.txt +1 -0
  142. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/WHEEL +0 -0
  143. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/licenses/LICENSE +0 -0
  144. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/top_level.txt +0 -0
@@ -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(self, xcoord, ycoord, zcoord, time):
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(f"regressor file {self.fileroot + thisregressor[2]} does not exist")
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