rapidtide 3.0.10__py3-none-any.whl → 3.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 (141) hide show
  1. rapidtide/Colortables.py +492 -27
  2. rapidtide/OrthoImageItem.py +1053 -47
  3. rapidtide/RapidtideDataset.py +1533 -86
  4. rapidtide/_version.py +3 -3
  5. rapidtide/calccoherence.py +196 -29
  6. rapidtide/calcnullsimfunc.py +191 -40
  7. rapidtide/calcsimfunc.py +245 -42
  8. rapidtide/correlate.py +1210 -393
  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 +19 -1
  13. rapidtide/data/examples/src/testglmfilt +5 -5
  14. rapidtide/data/examples/src/testhappy +30 -1
  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/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm.nii.gz +0 -0
  23. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm_mask.nii.gz +0 -0
  24. rapidtide/decorators.py +91 -0
  25. rapidtide/dlfilter.py +2225 -108
  26. rapidtide/dlfiltertorch.py +4843 -0
  27. rapidtide/externaltools.py +327 -12
  28. rapidtide/fMRIData_class.py +79 -40
  29. rapidtide/filter.py +1899 -810
  30. rapidtide/fit.py +2004 -574
  31. rapidtide/genericmultiproc.py +93 -18
  32. rapidtide/happy_supportfuncs.py +2044 -171
  33. rapidtide/helper_classes.py +584 -43
  34. rapidtide/io.py +2363 -370
  35. rapidtide/linfitfiltpass.py +341 -75
  36. rapidtide/makelaggedtcs.py +211 -20
  37. rapidtide/maskutil.py +423 -53
  38. rapidtide/miscmath.py +827 -121
  39. rapidtide/multiproc.py +210 -22
  40. rapidtide/patchmatch.py +234 -33
  41. rapidtide/peakeval.py +32 -30
  42. rapidtide/ppgproc.py +2203 -0
  43. rapidtide/qualitycheck.py +352 -39
  44. rapidtide/refinedelay.py +422 -57
  45. rapidtide/refineregressor.py +498 -184
  46. rapidtide/resample.py +671 -185
  47. rapidtide/scripts/applyppgproc.py +28 -0
  48. rapidtide/simFuncClasses.py +1052 -77
  49. rapidtide/simfuncfit.py +260 -46
  50. rapidtide/stats.py +540 -238
  51. rapidtide/tests/happycomp +9 -0
  52. rapidtide/tests/test_dlfiltertorch.py +627 -0
  53. rapidtide/tests/test_findmaxlag.py +24 -8
  54. rapidtide/tests/test_fullrunhappy_v1.py +0 -2
  55. rapidtide/tests/test_fullrunhappy_v2.py +0 -2
  56. rapidtide/tests/test_fullrunhappy_v3.py +1 -0
  57. rapidtide/tests/test_fullrunhappy_v4.py +2 -2
  58. rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
  59. rapidtide/tests/test_simroundtrip.py +8 -8
  60. rapidtide/tests/utils.py +9 -8
  61. rapidtide/tidepoolTemplate.py +142 -38
  62. rapidtide/tidepoolTemplate_alt.py +165 -44
  63. rapidtide/tidepoolTemplate_big.py +189 -52
  64. rapidtide/util.py +1217 -118
  65. rapidtide/voxelData.py +684 -37
  66. rapidtide/wiener.py +19 -12
  67. rapidtide/wiener2.py +113 -7
  68. rapidtide/wiener_doc.py +255 -0
  69. rapidtide/workflows/adjustoffset.py +105 -3
  70. rapidtide/workflows/aligntcs.py +85 -2
  71. rapidtide/workflows/applydlfilter.py +87 -10
  72. rapidtide/workflows/applyppgproc.py +522 -0
  73. rapidtide/workflows/atlasaverage.py +210 -47
  74. rapidtide/workflows/atlastool.py +100 -3
  75. rapidtide/workflows/calcSimFuncMap.py +294 -64
  76. rapidtide/workflows/calctexticc.py +201 -9
  77. rapidtide/workflows/ccorrica.py +97 -4
  78. rapidtide/workflows/cleanregressor.py +168 -29
  79. rapidtide/workflows/delayvar.py +163 -10
  80. rapidtide/workflows/diffrois.py +81 -3
  81. rapidtide/workflows/endtidalproc.py +144 -4
  82. rapidtide/workflows/fdica.py +195 -15
  83. rapidtide/workflows/filtnifti.py +70 -3
  84. rapidtide/workflows/filttc.py +74 -3
  85. rapidtide/workflows/fitSimFuncMap.py +206 -48
  86. rapidtide/workflows/fixtr.py +73 -3
  87. rapidtide/workflows/gmscalc.py +113 -3
  88. rapidtide/workflows/happy.py +813 -201
  89. rapidtide/workflows/happy2std.py +144 -12
  90. rapidtide/workflows/happy_parser.py +149 -8
  91. rapidtide/workflows/histnifti.py +118 -2
  92. rapidtide/workflows/histtc.py +84 -3
  93. rapidtide/workflows/linfitfilt.py +117 -4
  94. rapidtide/workflows/localflow.py +328 -28
  95. rapidtide/workflows/mergequality.py +79 -3
  96. rapidtide/workflows/niftidecomp.py +322 -18
  97. rapidtide/workflows/niftistats.py +174 -4
  98. rapidtide/workflows/pairproc.py +88 -2
  99. rapidtide/workflows/pairwisemergenifti.py +85 -2
  100. rapidtide/workflows/parser_funcs.py +1421 -40
  101. rapidtide/workflows/physiofreq.py +137 -11
  102. rapidtide/workflows/pixelcomp.py +208 -5
  103. rapidtide/workflows/plethquality.py +103 -21
  104. rapidtide/workflows/polyfitim.py +151 -11
  105. rapidtide/workflows/proj2flow.py +75 -2
  106. rapidtide/workflows/rankimage.py +111 -4
  107. rapidtide/workflows/rapidtide.py +272 -15
  108. rapidtide/workflows/rapidtide2std.py +98 -2
  109. rapidtide/workflows/rapidtide_parser.py +109 -9
  110. rapidtide/workflows/refineDelayMap.py +143 -33
  111. rapidtide/workflows/refineRegressor.py +682 -93
  112. rapidtide/workflows/regressfrommaps.py +152 -31
  113. rapidtide/workflows/resamplenifti.py +85 -3
  114. rapidtide/workflows/resampletc.py +91 -3
  115. rapidtide/workflows/retrolagtcs.py +98 -6
  116. rapidtide/workflows/retroregress.py +165 -9
  117. rapidtide/workflows/roisummarize.py +173 -5
  118. rapidtide/workflows/runqualitycheck.py +71 -3
  119. rapidtide/workflows/showarbcorr.py +147 -4
  120. rapidtide/workflows/showhist.py +86 -2
  121. rapidtide/workflows/showstxcorr.py +160 -3
  122. rapidtide/workflows/showtc.py +159 -3
  123. rapidtide/workflows/showxcorrx.py +184 -4
  124. rapidtide/workflows/showxy.py +185 -15
  125. rapidtide/workflows/simdata.py +262 -36
  126. rapidtide/workflows/spatialfit.py +77 -2
  127. rapidtide/workflows/spatialmi.py +251 -27
  128. rapidtide/workflows/spectrogram.py +305 -32
  129. rapidtide/workflows/synthASL.py +154 -3
  130. rapidtide/workflows/tcfrom2col.py +76 -2
  131. rapidtide/workflows/tcfrom3col.py +74 -2
  132. rapidtide/workflows/tidepool.py +2972 -133
  133. rapidtide/workflows/utils.py +19 -14
  134. rapidtide/workflows/utils_doc.py +293 -0
  135. rapidtide/workflows/variabilityizer.py +116 -3
  136. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/METADATA +10 -9
  137. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/RECORD +141 -122
  138. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/entry_points.txt +1 -0
  139. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/WHEEL +0 -0
  140. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/licenses/LICENSE +0 -0
  141. {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/top_level.txt +0 -0
@@ -17,18 +17,13 @@
17
17
  #
18
18
  #
19
19
  import sys
20
- import warnings
20
+ from typing import Any
21
21
 
22
22
  import matplotlib.pyplot as plt
23
23
  import numpy as np
24
24
  import scipy as sp
25
- from numpy.polynomial import Polynomial
26
- from scipy.optimize import curve_fit
27
- from statsmodels.robust import mad
25
+ from numpy.typing import NDArray
28
26
 
29
- import rapidtide.correlate as tide_corr
30
- import rapidtide.filter as tide_filt
31
- import rapidtide.fit as tide_fit
32
27
  import rapidtide.miscmath as tide_math
33
28
  import rapidtide.util as tide_util
34
29
 
@@ -46,7 +41,44 @@ class fMRIDataset:
46
41
  numskip = 0
47
42
  validvoxels = None
48
43
 
49
- def __init__(self, thedata, zerodata=False, copydata=False, numskip=0):
44
+ def __init__(
45
+ self, thedata: NDArray, zerodata: bool = False, copydata: bool = False, numskip: int = 0
46
+ ) -> None:
47
+ """
48
+ Initialize the fMRIDataset with data and configuration parameters.
49
+
50
+ Parameters
51
+ ----------
52
+ thedata : NDArray
53
+ The input data array to be stored in the object.
54
+ zerodata : bool, optional
55
+ If True, initializes the data with zeros instead of copying the input data.
56
+ Default is False.
57
+ copydata : bool, optional
58
+ If True and zerodata is False, creates a copy of the input data.
59
+ If False and zerodata is False, uses the input data directly.
60
+ Default is False.
61
+ numskip : int, optional
62
+ Number of elements to skip during processing. Default is 0.
63
+
64
+ Returns
65
+ -------
66
+ None
67
+ This method does not return any value.
68
+
69
+ Notes
70
+ -----
71
+ The initialization process involves:
72
+ 1. Setting the data based on the zerodata and copydata parameters
73
+ 2. Calling getsizes() to determine data dimensions
74
+ 3. Calling setnumskip() to configure the skip parameter
75
+
76
+ Examples
77
+ --------
78
+ >>> obj = MyClass(data_array)
79
+ >>> obj = MyClass(data_array, zerodata=True)
80
+ >>> obj = MyClass(data_array, copydata=True, numskip=5)
81
+ """
50
82
  if zerodata:
51
83
  self.thedata = thedata * 0.0
52
84
  else:
@@ -57,7 +89,56 @@ class fMRIDataset:
57
89
  self.getsizes()
58
90
  self.setnumskip(numskip)
59
91
 
60
- def getsizes(self):
92
+ def getsizes(self) -> None:
93
+ """
94
+ Calculate and store various size parameters from data shape.
95
+
96
+ This method extracts dimensional information from the data shape and computes
97
+ derived quantities such as slice size and total number of voxels. It handles
98
+ both 3D and 4D data arrays by checking for the presence of a fourth dimension.
99
+
100
+ Parameters
101
+ ----------
102
+ self : object
103
+ The instance containing the data array in `thedata` attribute.
104
+ The `thedata` attribute should be a numpy array with shape (xsize, ysize, numslices, [realtimepoints])
105
+
106
+ Returns
107
+ -------
108
+ None
109
+ This method does not return any value but modifies the instance attributes.
110
+
111
+ Notes
112
+ -----
113
+ The method assumes `thedata` is a numpy array with at least 2 dimensions.
114
+ If the fourth dimension is not present, `realtimepoints` is set to 1.
115
+
116
+ Attributes Modified
117
+ -------------------
118
+ theshape : tuple
119
+ The shape of the data array
120
+ xsize : int
121
+ Size of the first dimension (x-axis)
122
+ ysize : int
123
+ Size of the second dimension (y-axis)
124
+ numslices : int
125
+ Number of slices (third dimension)
126
+ realtimepoints : int
127
+ Number of real-time points (fourth dimension, default 1)
128
+ slicesize : int
129
+ Product of xsize and ysize (number of pixels per slice)
130
+ numvox : int
131
+ Total number of voxels (slicesize * numslices)
132
+
133
+ Examples
134
+ --------
135
+ >>> # Assuming self.thedata has shape (64, 64, 30, 100)
136
+ >>> getsizes(self)
137
+ >>> print(self.xsize, self.ysize, self.numslices, self.realtimepoints)
138
+ 64 64 30 100
139
+ >>> print(self.slicesize, self.numvox)
140
+ 4096 122880
141
+ """
61
142
  self.theshape = self.thedata.shape
62
143
  self.xsize = self.theshape[0]
63
144
  self.ysize = self.theshape[1]
@@ -69,22 +150,157 @@ class fMRIDataset:
69
150
  self.slicesize = self.xsize * self.ysize
70
151
  self.numvox = self.slicesize * self.numslices
71
152
 
72
- def setnumskip(self, numskip):
153
+ def setnumskip(self, numskip: int) -> None:
154
+ """
155
+ Set the number of timepoints to skip and update the timepoints accordingly.
156
+
157
+ This method updates the internal `numskip` attribute and recalculates the
158
+ `timepoints` by subtracting the number of skipped points from the real timepoints.
159
+
160
+ Parameters
161
+ ----------
162
+ numskip : int
163
+ The number of timepoints to skip. This value is stored in the `numskip`
164
+ attribute and used to compute the effective timepoints.
165
+
166
+ Returns
167
+ -------
168
+ None
169
+ This method modifies the object's attributes in-place and does not return
170
+ any value.
171
+
172
+ Notes
173
+ -----
174
+ The `timepoints` attribute is automatically updated to reflect the difference
175
+ between `realtimepoints` and `numskip`. This is typically used in time-series
176
+ analysis where certain initial timepoints are excluded from calculations.
177
+
178
+ Examples
179
+ --------
180
+ >>> obj.setnumskip(5)
181
+ >>> print(obj.numskip)
182
+ 5
183
+ >>> print(obj.timepoints)
184
+ # Will show the difference between realtimepoints and 5
185
+ """
73
186
  self.numskip = numskip
74
187
  self.timepoints = self.realtimepoints - self.numskip
75
188
 
76
- def setvalid(self, validvoxels):
189
+ def setvalid(self, validvoxels: NDArray) -> None:
190
+ """
191
+ Set the valid voxels for the object.
192
+
193
+ Parameters
194
+ ----------
195
+ validvoxels : NDArray
196
+ Array containing the valid voxel indices or flags indicating
197
+ which voxels are considered valid in the dataset.
198
+
199
+ Returns
200
+ -------
201
+ None
202
+ This method does not return any value.
203
+
204
+ Notes
205
+ -----
206
+ This method assigns the provided array to the internal `validvoxels` attribute
207
+ of the object, which is typically used to filter or validate voxel data
208
+ during processing operations.
209
+
210
+ Examples
211
+ --------
212
+ >>> obj = MyClass()
213
+ >>> valid_voxels = np.array([1, 2, 3, 5, 8])
214
+ >>> obj.setvalid(valid_voxels)
215
+ >>> print(obj.validvoxels)
216
+ [1 2 3 5 8]
217
+ """
77
218
  self.validvoxels = validvoxels
78
219
 
79
- def byslice(self):
220
+ def byslice(self) -> NDArray:
221
+ """
222
+ Return data sliced along the time dimension with specified skip.
223
+
224
+ This method extracts data from the internal `thedata` array, skipping
225
+ the first `numskip` time points and reshaping the result into a
226
+ standardized 3D array format.
227
+
228
+ Returns
229
+ -------
230
+ NDArray
231
+ 3D array with shape (slicesize, numslices, timepoints) containing
232
+ the sliced data with skipped time points removed.
233
+
234
+ Notes
235
+ -----
236
+ The returned array is reshaped from the original data structure to
237
+ facilitate further processing and analysis. The slicing operation
238
+ removes the first `numskip` time points from the original data.
239
+
240
+ Examples
241
+ --------
242
+ >>> result = obj.byslice()
243
+ >>> print(result.shape)
244
+ (100, 50, 200)
245
+ """
80
246
  return self.thedata[:, :, :, self.numskip :].reshape(
81
247
  (self.slicesize, self.numslices, self.timepoints)
82
248
  )
83
249
 
84
- def byvol(self):
250
+ def byvol(self) -> NDArray:
251
+ """
252
+ Reshape data to volume-time format.
253
+
254
+ This method extracts a subset of data along the fourth dimension and reshapes
255
+ it into a 2D array where rows represent voxels and columns represent timepoints.
256
+
257
+ Returns
258
+ -------
259
+ NDArray
260
+ 2D array of shape (numvox, timepoints) containing the reshaped data.
261
+ Each row corresponds to a voxel and each column to a timepoint.
262
+
263
+ Notes
264
+ -----
265
+ The method slices the data array starting from index `numskip` along the
266
+ fourth dimension and reshapes the remaining data into a 2D structure.
267
+
268
+ Examples
269
+ --------
270
+ >>> result = obj.byvol()
271
+ >>> print(result.shape)
272
+ (numvox, timepoints)
273
+ """
85
274
  return self.thedata[:, :, :, self.numskip :].reshape((self.numvox, self.timepoints))
86
275
 
87
- def byvox(self):
276
+ def byvox(self) -> NDArray:
277
+ """
278
+ Return voxel data with skip dimension sliced.
279
+
280
+ This method extracts a subset of the fourth dimension from the internal
281
+ data array, starting from the index specified by `numskip` to the end.
282
+
283
+ Returns
284
+ -------
285
+ NDArray
286
+ A numpy array containing the voxel data with the fourth dimension
287
+ sliced from `numskip` index to the end. The shape will be
288
+ (self.thedata.shape[0], self.thedata.shape[1], self.thedata.shape[2],
289
+ self.thedata.shape[3] - self.numskip)
290
+
291
+ Notes
292
+ -----
293
+ The function assumes that `self.thedata` is a 4-dimensional numpy array
294
+ and `self.numskip` is a non-negative integer less than the size of the
295
+ fourth dimension.
296
+
297
+ Examples
298
+ --------
299
+ >>> # Assuming self.thedata has shape (10, 10, 10, 20) and self.numskip = 5
300
+ >>> result = self.byvox()
301
+ >>> result.shape
302
+ (10, 10, 10, 15)
303
+ """
88
304
  return self.thedata[:, :, :, self.numskip :]
89
305
 
90
306
 
@@ -102,17 +318,58 @@ class ProbeRegressor:
102
318
 
103
319
  def __init__(
104
320
  self,
105
- inputvec,
106
- inputfreq,
107
- targetperiod,
108
- targetpoints,
109
- targetstartpoint,
110
- targetoversample=1,
111
- inputstart=0.0,
112
- inputoffset=0.0,
113
- targetstart=0.0,
114
- targetoffset=0.0,
115
- ):
321
+ inputvec: NDArray,
322
+ inputfreq: float,
323
+ targetperiod: float,
324
+ targetpoints: int,
325
+ targetstartpoint: int,
326
+ targetoversample: int = 1,
327
+ inputstart: float = 0.0,
328
+ inputoffset: float = 0.0,
329
+ targetstart: float = 0.0,
330
+ targetoffset: float = 0.0,
331
+ ) -> None:
332
+ """
333
+ Initialize the object with input and target parameters.
334
+
335
+ Parameters
336
+ ----------
337
+ inputvec : NDArray
338
+ Input vector data array
339
+ inputfreq : float
340
+ Input frequency in Hz
341
+ targetperiod : float
342
+ Target period in seconds
343
+ targetpoints : int
344
+ Number of target points
345
+ targetstartpoint : int
346
+ Starting point index for target
347
+ targetoversample : int, optional
348
+ Oversampling factor for target (default is 1)
349
+ inputstart : float, optional
350
+ Starting time for input (default is 0.0)
351
+ inputoffset : float, optional
352
+ Input offset value (default is 0.0)
353
+ targetstart : float, optional
354
+ Starting time for target (default is 0.0)
355
+ targetoffset : float, optional
356
+ Target offset value (default is 0.0)
357
+
358
+ Returns
359
+ -------
360
+ None
361
+ This method initializes the object attributes and does not return any value.
362
+
363
+ Notes
364
+ -----
365
+ This constructor sets up the input vector with specified frequency and start time,
366
+ and initializes target parameters for subsequent processing.
367
+
368
+ Examples
369
+ --------
370
+ >>> obj = MyClass(inputvec=np.array([1, 2, 3]), inputfreq=100.0,
371
+ ... targetperiod=0.1, targetpoints=100, targetstartpoint=0)
372
+ """
116
373
  self.inputoffset = inputoffset
117
374
  self.setinputvec(inputvec, inputfreq, inputstart=inputstart)
118
375
  self.targetperiod = targetperiod
@@ -121,17 +378,111 @@ class ProbeRegressor:
121
378
  self.targetpoints = targetpoints
122
379
  self.targetstartpoint = targetstartpoint
123
380
 
124
- def setinputvec(self, inputvec, inputfreq, inputstart=0.0):
381
+ def setinputvec(self, inputvec: NDArray, inputfreq: float, inputstart: float = 0.0) -> None:
382
+ """
383
+ Set the input vector and associated parameters for the object.
384
+
385
+ Parameters
386
+ ----------
387
+ inputvec : NDArray
388
+ The input vector to be set. This is typically a numpy array containing
389
+ the input signal or data values.
390
+ inputfreq : float
391
+ The input frequency value. This represents the sampling frequency or
392
+ frequency parameter associated with the input vector.
393
+ inputstart : float, optional
394
+ The starting time or phase value for the input. Default is 0.0.
395
+
396
+ Returns
397
+ -------
398
+ None
399
+ This method does not return any value.
400
+
401
+ Notes
402
+ -----
403
+ This method assigns the provided input vector and its associated parameters
404
+ to instance variables. The input vector is stored as ``self.inputvec``,
405
+ the frequency as ``self.inputfreq``, and the start value as ``self.inputstart``.
406
+
407
+ Examples
408
+ --------
409
+ >>> import numpy as np
410
+ >>> obj = MyClass()
411
+ >>> input_data = np.array([1, 2, 3, 4, 5])
412
+ >>> obj.setinputvec(input_data, inputfreq=10.0, inputstart=0.5)
413
+ >>> print(obj.inputvec)
414
+ [1 2 3 4 5]
415
+ >>> print(obj.inputfreq)
416
+ 10.0
417
+ >>> print(obj.inputstart)
418
+ 0.5
419
+ """
125
420
  self.inputvec = inputvec
126
421
  self.inputfreq = inputfreq
127
422
  self.inputstart = inputstart
128
423
 
129
- def makeinputtimeaxis(self):
424
+ def makeinputtimeaxis(self) -> None:
425
+ """
426
+ Create input time axis based on input vector properties.
427
+
428
+ This method generates a time axis for input data by linearly spacing
429
+ from 0 to the length of the input vector, normalized by the input frequency,
430
+ and adjusted by the input start time and offset.
431
+
432
+ Parameters
433
+ ----------
434
+ None
435
+
436
+ Returns
437
+ -------
438
+ None
439
+ This method modifies the instance in-place by setting the `inputtimeaxis` attribute.
440
+
441
+ Notes
442
+ -----
443
+ The time axis is calculated as:
444
+ ``inputtimeaxis = np.linspace(0.0, len(inputvec)) / inputfreq - (inputstarttime + inputoffset)``
445
+
446
+ Examples
447
+ --------
448
+ >>> obj.makeinputtimeaxis()
449
+ >>> print(obj.inputtimeaxis)
450
+ [ 0. 0.001 0.002 ... 0.998 0.999 ]
451
+ """
130
452
  self.inputtimeaxis = np.linspace(0.0, len(self.inputvec)) / self.inputfreq - (
131
453
  self.inputstarttime + self.inputoffset
132
454
  )
133
455
 
134
- def maketargettimeaxis(self):
456
+ def maketargettimeaxis(self) -> None:
457
+ """
458
+ Create a target time axis for signal processing.
459
+
460
+ This method generates a linearly spaced time axis based on the target period,
461
+ start point, and number of points specified in the object's attributes.
462
+
463
+ Parameters
464
+ ----------
465
+ None
466
+
467
+ Returns
468
+ -------
469
+ None
470
+ This method modifies the object's `targettimeaxis` attribute in-place.
471
+
472
+ Notes
473
+ -----
474
+ The time axis is generated using `numpy.linspace` with the following parameters:
475
+ - Start point: `targetperiod * targetstartpoint`
476
+ - End point: `targetperiod * targetstartpoint + targetperiod * targetpoints`
477
+ - Number of points: `targetpoints`
478
+ - Endpoint: True
479
+
480
+ Examples
481
+ --------
482
+ >>> obj.maketargettimeaxis()
483
+ >>> print(obj.targettimeaxis)
484
+ [0. 0.1 0.2 0.3 0.4]
485
+ """
135
486
  self.targettimeaxis = np.linspace(
136
487
  self.targetperiod * self.targetstartpoint,
137
488
  self.targetperiod * self.targetstartpoint + self.targetperiod * self.targetpoints,
@@ -155,15 +506,58 @@ class Coherer:
155
506
 
156
507
  def __init__(
157
508
  self,
158
- Fs=0.0,
159
- freqmin=None,
160
- freqmax=None,
161
- ncprefilter=None,
162
- reftc=None,
163
- detrendorder=1,
164
- windowfunc="hamming",
165
- debug=False,
166
- ):
509
+ Fs: float = 0.0,
510
+ freqmin: float | None = None,
511
+ freqmax: float | None = None,
512
+ ncprefilter: Any | None = None,
513
+ reftc: NDArray | None = None,
514
+ detrendorder: int = 1,
515
+ windowfunc: str = "hamming",
516
+ debug: bool = False,
517
+ ) -> None:
518
+ """
519
+ Initialize the Coherer object with configuration parameters.
520
+
521
+ Parameters
522
+ ----------
523
+ Fs : float, default=0.0
524
+ Sampling frequency in Hz.
525
+ freqmin : float, optional
526
+ Minimum frequency for filtering. If None, no minimum frequency filtering is applied.
527
+ freqmax : float, optional
528
+ Maximum frequency for filtering. If None, no maximum frequency filtering is applied.
529
+ ncprefilter : Any, optional
530
+ Pre-filtering configuration for non-coherent filtering.
531
+ reftc : numpy.ndarray, optional
532
+ Reference time course for coherence calculations.
533
+ detrendorder : int, default=1
534
+ Order of detrending to apply to the data. 0 for no detrending, 1 for linear detrending.
535
+ windowfunc : str, default="hamming"
536
+ Window function to apply during spectral analysis. Options include 'hamming', 'hanning', 'blackman', etc.
537
+ debug : bool, default=False
538
+ If True, print initialization debug information.
539
+
540
+ Returns
541
+ -------
542
+ None
543
+ This method initializes the object's attributes and performs setup operations.
544
+
545
+ Notes
546
+ -----
547
+ The initialization process sets up all internal parameters and performs optional
548
+ debug printing if requested. The freqmin and freqmax parameters are only stored
549
+ if they are not None. The reftc parameter, if provided, triggers the setreftc method.
550
+
551
+ Examples
552
+ --------
553
+ >>> coherer = Coherer(Fs=100.0, freqmin=1.0, freqmax=50.0, debug=True)
554
+ Coherer init:
555
+ Fs: 100.0
556
+ windowfunc: hamming
557
+ detrendorder: 1
558
+ freqmin: 1.0
559
+ freqmax: 50.0
560
+ """
167
561
  self.Fs = Fs
168
562
  self.ncprefilter = ncprefilter
169
563
  self.reftc = reftc
@@ -184,7 +578,37 @@ class Coherer:
184
578
  print("\tfreqmin:", self.freqmin)
185
579
  print("\tfreqmax:", self.freqmax)
186
580
 
187
- def preptc(self, thetc):
581
+ def preptc(self, thetc: NDArray) -> NDArray:
582
+ """
583
+ Prepare timecourse by filtering, normalizing, detrending, and applying a window function.
584
+
585
+ This function applies a series of preprocessing steps to a timecourse signal including
586
+ noise filtering, normalization, and detrending to prepare it for further analysis.
587
+
588
+ Parameters
589
+ ----------
590
+ thetc : ndarray
591
+ Input timecourse data to be prepared, typically a 1D array of signal values.
592
+
593
+ Returns
594
+ -------
595
+ ndarray
596
+ Preprocessed timecourse data after filtering, normalization, and detrending.
597
+
598
+ Notes
599
+ -----
600
+ The preprocessing pipeline includes:
601
+ 1. Noise filtering using the class's ncprefilter
602
+ 2. Correlation-based normalization
603
+ 3. Detrending with specified order
604
+
605
+ Examples
606
+ --------
607
+ >>> # Assuming 'obj' is an instance of the class containing this method
608
+ >>> processed_tc = obj.preptc(timecourse_data)
609
+ >>> print(processed_tc.shape)
610
+ (n_timepoints,)
611
+ """
188
612
  # prepare timecourse by filtering, normalizing, detrending, and applying a window function
189
613
  return tide_math.corrnormalize(
190
614
  self.ncprefilter.apply(self.Fs, thetc),
@@ -192,7 +616,37 @@ class Coherer:
192
616
  windowfunc="None",
193
617
  )
194
618
 
195
- def setlimits(self, freqmin, freqmax):
619
+ def setlimits(self, freqmin: float, freqmax: float) -> None:
620
+ """
621
+ Set frequency limits for the object and calculate corresponding indices.
622
+
623
+ This method sets the minimum and maximum frequency values and calculates the
624
+ corresponding indices in the frequency axis if the frequency axis is valid.
625
+
626
+ Parameters
627
+ ----------
628
+ freqmin : float
629
+ The minimum frequency value to set.
630
+ freqmax : float
631
+ The maximum frequency value to set.
632
+
633
+ Returns
634
+ -------
635
+ None
636
+ This method modifies the object's attributes in-place and does not return a value.
637
+
638
+ Notes
639
+ -----
640
+ If `self.freqaxisvalid` is True, the method calculates `freqmininpts` and `freqmaxinpts`
641
+ which represent the indices corresponding to the frequency limits in `self.freqaxis`.
642
+ The calculation ensures that indices stay within valid bounds (0 to len(freqaxis)-1).
643
+
644
+ Examples
645
+ --------
646
+ >>> obj.setlimits(0.1, 1.0)
647
+ >>> print(obj.freqmin, obj.freqmax)
648
+ 0.1 1.0
649
+ """
196
650
  self.freqmin = freqmin
197
651
  self.freqmax = freqmax
198
652
  if self.freqaxisvalid:
@@ -208,7 +662,32 @@ class Coherer:
208
662
  print("\tfreqmin,freqmax:", self.freqmin, self.freqmax)
209
663
  print("\tfreqmininpts,freqmaxinpts:", self.freqmininpts, self.freqmaxinpts)
210
664
 
211
- def getaxisinfo(self):
665
+ def getaxisinfo(self) -> tuple[float, float, float, int]:
666
+ """
667
+ Get frequency axis information for the object.
668
+
669
+ Returns
670
+ -------
671
+ tuple[float, float, float, int]
672
+ A tuple containing:
673
+ - Minimum frequency value (float)
674
+ - Maximum frequency value (float)
675
+ - Frequency step size (float)
676
+ - Number of frequency points (int)
677
+
678
+ Notes
679
+ -----
680
+ This method extracts key frequency axis parameters from the object's frequency array.
681
+ The frequency axis is assumed to be linearly spaced, and the returned values represent
682
+ the range and spacing of the frequency data.
683
+
684
+ Examples
685
+ --------
686
+ >>> info = obj.getaxisinfo()
687
+ >>> print(f"Frequency range: {info[0]} to {info[1]} Hz")
688
+ >>> print(f"Frequency step: {info[2]} Hz")
689
+ >>> print(f"Number of points: {info[3]}")
690
+ """
212
691
  return (
213
692
  self.freqaxis[self.freqmininpts],
214
693
  self.freqaxis[self.freqmaxinpts],
@@ -216,7 +695,43 @@ class Coherer:
216
695
  self.freqmaxinpts - self.freqmininpts,
217
696
  )
218
697
 
219
- def setreftc(self, reftc):
698
+ def setreftc(self, reftc: NDArray) -> None:
699
+ """
700
+ Set reference time series and compute coherence statistics.
701
+
702
+ This method assigns the reference time series, processes it through the preprocessing
703
+ pipeline, and computes coherence statistics between the reference signal and itself.
704
+ The method also sets up frequency axis parameters and validates the data.
705
+
706
+ Parameters
707
+ ----------
708
+ reftc : numpy.ndarray
709
+ Reference time series data to be processed. The array will be copied and converted
710
+ to float type to ensure proper numerical operations.
711
+
712
+ Returns
713
+ -------
714
+ None
715
+ This method modifies the instance attributes in-place and does not return any value.
716
+
717
+ Notes
718
+ -----
719
+ The method performs the following operations:
720
+ 1. Assigns the input array to `self.reftc` with explicit float conversion
721
+ 2. Preprocesses the reference time series using `self.preptc()` method
722
+ 3. Computes coherence between the preprocessed reference signal and itself
723
+ 4. Sets up frequency axis and coherence data attributes
724
+ 5. Validates frequency limits and converts them to array indices
725
+ 6. Updates data validity flags
726
+
727
+ Examples
728
+ --------
729
+ >>> # Assuming 'obj' is an instance of the class containing this method
730
+ >>> reference_data = np.array([1.0, 2.0, 3.0, 4.0])
731
+ >>> obj.setreftc(reference_data)
732
+ >>> print(obj.freqaxis)
733
+ >>> print(obj.thecoherence)
734
+ """
220
735
  self.reftc = reftc + 0.0
221
736
  self.prepreftc = self.preptc(self.reftc)
222
737
 
@@ -238,10 +753,36 @@ class Coherer:
238
753
  self.freqaxis, self.freqmax, discretization="ceiling", debug=self.debug
239
754
  )
240
755
 
241
- def trim(self, vector):
756
+ def trim(self, vector: NDArray) -> NDArray:
242
757
  return vector[self.freqmininpts : self.freqmaxinpts]
243
758
 
244
- def run(self, thetc, trim=True, alt=False):
759
+ def run(
760
+ self, thetc: NDArray, trim: bool = True, alt: bool = False
761
+ ) -> tuple[NDArray, NDArray, int] | tuple[NDArray, NDArray, int, NDArray, NDArray, NDArray]:
762
+ """
763
+ Trim vector to specified frequency range indices.
764
+
765
+ Parameters
766
+ ----------
767
+ vector : NDArray
768
+ Input vector to be trimmed.
769
+
770
+ Returns
771
+ -------
772
+ NDArray
773
+ Trimmed vector containing elements from `self.freqmininpts` to `self.freqmaxinpts`.
774
+
775
+ Notes
776
+ -----
777
+ This function uses array slicing to extract a portion of the input vector based on
778
+ the frequency range boundaries defined by `self.freqmininpts` and `self.freqmaxinpts`.
779
+
780
+ Examples
781
+ --------
782
+ >>> trimmed_data = obj.trim(data_vector)
783
+ >>> print(trimmed_data.shape)
784
+ (freqmaxinpts - freqmininpts,)
785
+ """
245
786
  if len(thetc) != len(self.reftc):
246
787
  print(
247
788
  "Coherer: timecourses are of different sizes:",