rapidtide 3.0.11__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 (139) 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 +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 +25 -3
  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 +2225 -108
  24. rapidtide/dlfiltertorch.py +4843 -0
  25. rapidtide/externaltools.py +327 -12
  26. rapidtide/fMRIData_class.py +79 -40
  27. rapidtide/filter.py +1899 -810
  28. rapidtide/fit.py +2004 -574
  29. rapidtide/genericmultiproc.py +93 -18
  30. rapidtide/happy_supportfuncs.py +2044 -171
  31. rapidtide/helper_classes.py +584 -43
  32. rapidtide/io.py +2363 -370
  33. rapidtide/linfitfiltpass.py +341 -75
  34. rapidtide/makelaggedtcs.py +211 -20
  35. rapidtide/maskutil.py +423 -53
  36. rapidtide/miscmath.py +827 -121
  37. rapidtide/multiproc.py +210 -22
  38. rapidtide/patchmatch.py +234 -33
  39. rapidtide/peakeval.py +32 -30
  40. rapidtide/ppgproc.py +2203 -0
  41. rapidtide/qualitycheck.py +352 -39
  42. rapidtide/refinedelay.py +422 -57
  43. rapidtide/refineregressor.py +498 -184
  44. rapidtide/resample.py +671 -185
  45. rapidtide/scripts/applyppgproc.py +28 -0
  46. rapidtide/simFuncClasses.py +1052 -77
  47. rapidtide/simfuncfit.py +260 -46
  48. rapidtide/stats.py +540 -238
  49. rapidtide/tests/happycomp +9 -0
  50. rapidtide/tests/test_dlfiltertorch.py +627 -0
  51. rapidtide/tests/test_findmaxlag.py +24 -8
  52. rapidtide/tests/test_fullrunhappy_v1.py +0 -2
  53. rapidtide/tests/test_fullrunhappy_v2.py +0 -2
  54. rapidtide/tests/test_fullrunhappy_v3.py +1 -0
  55. rapidtide/tests/test_fullrunhappy_v4.py +2 -2
  56. rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
  57. rapidtide/tests/test_simroundtrip.py +8 -8
  58. rapidtide/tests/utils.py +9 -8
  59. rapidtide/tidepoolTemplate.py +142 -38
  60. rapidtide/tidepoolTemplate_alt.py +165 -44
  61. rapidtide/tidepoolTemplate_big.py +189 -52
  62. rapidtide/util.py +1217 -118
  63. rapidtide/voxelData.py +684 -37
  64. rapidtide/wiener.py +19 -12
  65. rapidtide/wiener2.py +113 -7
  66. rapidtide/wiener_doc.py +255 -0
  67. rapidtide/workflows/adjustoffset.py +105 -3
  68. rapidtide/workflows/aligntcs.py +85 -2
  69. rapidtide/workflows/applydlfilter.py +87 -10
  70. rapidtide/workflows/applyppgproc.py +522 -0
  71. rapidtide/workflows/atlasaverage.py +210 -47
  72. rapidtide/workflows/atlastool.py +100 -3
  73. rapidtide/workflows/calcSimFuncMap.py +294 -64
  74. rapidtide/workflows/calctexticc.py +201 -9
  75. rapidtide/workflows/ccorrica.py +97 -4
  76. rapidtide/workflows/cleanregressor.py +168 -29
  77. rapidtide/workflows/delayvar.py +163 -10
  78. rapidtide/workflows/diffrois.py +81 -3
  79. rapidtide/workflows/endtidalproc.py +144 -4
  80. rapidtide/workflows/fdica.py +195 -15
  81. rapidtide/workflows/filtnifti.py +70 -3
  82. rapidtide/workflows/filttc.py +74 -3
  83. rapidtide/workflows/fitSimFuncMap.py +206 -48
  84. rapidtide/workflows/fixtr.py +73 -3
  85. rapidtide/workflows/gmscalc.py +113 -3
  86. rapidtide/workflows/happy.py +801 -199
  87. rapidtide/workflows/happy2std.py +144 -12
  88. rapidtide/workflows/happy_parser.py +138 -9
  89. rapidtide/workflows/histnifti.py +118 -2
  90. rapidtide/workflows/histtc.py +84 -3
  91. rapidtide/workflows/linfitfilt.py +117 -4
  92. rapidtide/workflows/localflow.py +328 -28
  93. rapidtide/workflows/mergequality.py +79 -3
  94. rapidtide/workflows/niftidecomp.py +322 -18
  95. rapidtide/workflows/niftistats.py +174 -4
  96. rapidtide/workflows/pairproc.py +88 -2
  97. rapidtide/workflows/pairwisemergenifti.py +85 -2
  98. rapidtide/workflows/parser_funcs.py +1421 -40
  99. rapidtide/workflows/physiofreq.py +137 -11
  100. rapidtide/workflows/pixelcomp.py +208 -5
  101. rapidtide/workflows/plethquality.py +103 -21
  102. rapidtide/workflows/polyfitim.py +151 -11
  103. rapidtide/workflows/proj2flow.py +75 -2
  104. rapidtide/workflows/rankimage.py +111 -4
  105. rapidtide/workflows/rapidtide.py +272 -15
  106. rapidtide/workflows/rapidtide2std.py +98 -2
  107. rapidtide/workflows/rapidtide_parser.py +109 -9
  108. rapidtide/workflows/refineDelayMap.py +143 -33
  109. rapidtide/workflows/refineRegressor.py +682 -93
  110. rapidtide/workflows/regressfrommaps.py +152 -31
  111. rapidtide/workflows/resamplenifti.py +85 -3
  112. rapidtide/workflows/resampletc.py +91 -3
  113. rapidtide/workflows/retrolagtcs.py +98 -6
  114. rapidtide/workflows/retroregress.py +165 -9
  115. rapidtide/workflows/roisummarize.py +173 -5
  116. rapidtide/workflows/runqualitycheck.py +71 -3
  117. rapidtide/workflows/showarbcorr.py +147 -4
  118. rapidtide/workflows/showhist.py +86 -2
  119. rapidtide/workflows/showstxcorr.py +160 -3
  120. rapidtide/workflows/showtc.py +159 -3
  121. rapidtide/workflows/showxcorrx.py +184 -4
  122. rapidtide/workflows/showxy.py +185 -15
  123. rapidtide/workflows/simdata.py +262 -36
  124. rapidtide/workflows/spatialfit.py +77 -2
  125. rapidtide/workflows/spatialmi.py +251 -27
  126. rapidtide/workflows/spectrogram.py +305 -32
  127. rapidtide/workflows/synthASL.py +154 -3
  128. rapidtide/workflows/tcfrom2col.py +76 -2
  129. rapidtide/workflows/tcfrom3col.py +74 -2
  130. rapidtide/workflows/tidepool.py +2969 -130
  131. rapidtide/workflows/utils.py +19 -14
  132. rapidtide/workflows/utils_doc.py +293 -0
  133. rapidtide/workflows/variabilityizer.py +116 -3
  134. {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/METADATA +3 -2
  135. {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/RECORD +139 -122
  136. {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/entry_points.txt +1 -0
  137. {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/WHEEL +0 -0
  138. {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/licenses/LICENSE +0 -0
  139. {rapidtide-3.0.11.dist-info → rapidtide-3.1.dist-info}/top_level.txt +0 -0
@@ -18,11 +18,13 @@
18
18
  #
19
19
  import sys
20
20
  import warnings
21
+ from typing import Any
21
22
 
22
23
  import matplotlib.pyplot as plt
23
24
  import numpy as np
24
25
  import scipy as sp
25
26
  from numpy.polynomial import Polynomial
27
+ from numpy.typing import NDArray
26
28
  from scipy.optimize import curve_fit
27
29
  from statsmodels.robust import mad
28
30
 
@@ -58,6 +60,50 @@ class SimilarityFunctionator:
58
60
  filterinputdata=True,
59
61
  debug=False,
60
62
  ):
63
+ """
64
+ Initialize the similarity function analysis object.
65
+
66
+ Parameters
67
+ ----------
68
+ Fs : float, optional
69
+ Sampling frequency in Hz. Default is 0.0.
70
+ similarityfuncorigin : int, optional
71
+ Origin point for similarity function calculation. Default is 0.
72
+ lagmininpts : int, optional
73
+ Minimum lag in samples. Default is 0.
74
+ lagmaxinpts : int, optional
75
+ Maximum lag in samples. Default is 0.
76
+ ncprefilter : array-like, optional
77
+ Pre-filter for cross-correlation calculation. Default is None.
78
+ negativegradient : bool, optional
79
+ Flag to indicate if negative gradient should be used. Default is False.
80
+ reftc : array-like, optional
81
+ Reference time course for cross-correlation. Default is None.
82
+ reftcstart : float, optional
83
+ Start time for reference time course. Default is 0.0.
84
+ detrendorder : int, optional
85
+ Order of detrending to apply to data. Default is 1.
86
+ filterinputdata : bool, optional
87
+ Flag to indicate if input data should be filtered. Default is True.
88
+ debug : bool, optional
89
+ Flag to enable debug mode. Default is False.
90
+
91
+ Returns
92
+ -------
93
+ None
94
+ This method initializes the object attributes but does not return any value.
95
+
96
+ Notes
97
+ -----
98
+ The initialization sets up all necessary parameters for cross-correlation analysis.
99
+ If a reference time course is provided, it is set using the setreftc method.
100
+ All lag parameters are converted to integers by adding 0 to ensure proper type handling.
101
+
102
+ Examples
103
+ --------
104
+ >>> obj = CrossCorrelationAnalyzer(Fs=100.0, lagmininpts=-10, lagmaxinpts=10)
105
+ >>> obj = CrossCorrelationAnalyzer(reftc=reference_data, reftcstart=5.0)
106
+ """
61
107
  self.setFs(Fs)
62
108
  self.similarityfuncorigin = similarityfuncorigin
63
109
  self.lagmininpts = lagmininpts + 0
@@ -72,10 +118,78 @@ class SimilarityFunctionator:
72
118
  self.setreftc(self.reftc)
73
119
  self.reftcstart = reftcstart + 0.0
74
120
 
75
- def setFs(self, Fs):
121
+ def setFs(self, Fs: float) -> None:
122
+ """Set the sampling frequency for the system.
123
+
124
+ Parameters
125
+ ----------
126
+ Fs : float
127
+ Sampling frequency in Hz. This parameter determines the rate at which
128
+ samples are taken from the continuous signal.
129
+
130
+ Returns
131
+ -------
132
+ None
133
+ This method does not return any value.
134
+
135
+ Notes
136
+ -----
137
+ The sampling frequency is a critical parameter that affects the
138
+ resolution and accuracy of digital signal processing operations.
139
+ It should be set appropriately based on the Nyquist criterion to
140
+ avoid aliasing.
141
+
142
+ Examples
143
+ --------
144
+ >>> obj = MyClass()
145
+ >>> obj.setFs(44100.0)
146
+ >>> print(obj.Fs)
147
+ 44100.0
148
+ """
76
149
  self.Fs = Fs
77
150
 
78
- def preptc(self, thetc, isreftc=False):
151
+ def preptc(self, thetc: NDArray, isreftc: bool = False) -> NDArray:
152
+ """
153
+ Prepare timecourse by filtering, normalizing, detrending, and applying a window function.
154
+
155
+ This function applies a series of preprocessing steps to the input timecourse, including
156
+ optional filtering, normalization, detrending, and window function application. The specific
157
+ processing steps depend on the input parameters and class configuration.
158
+
159
+ Parameters
160
+ ----------
161
+ thetc : numpy.ndarray
162
+ Input timecourse data to be prepared
163
+ isreftc : bool, optional
164
+ Flag indicating whether the input is a reference timecourse. If True, the timecourse
165
+ is filtered using the class's prefilter and then normalized. Default is False.
166
+
167
+ Returns
168
+ -------
169
+ numpy.ndarray
170
+ Prepared and normalized timecourse data after filtering, normalization, detrending,
171
+ and window function application
172
+
173
+ Notes
174
+ -----
175
+ The preprocessing pipeline applies the following steps in order:
176
+ 1. Filtering (if applicable based on isreftc and filterinputdata flags)
177
+ 2. Gradient calculation (when negativegradient is True)
178
+ 3. Normalization with detrending and window function application
179
+
180
+ When isreftc is True, the input is filtered using self.ncprefilter.apply() before
181
+ normalization. When isreftc is False and negativegradient is True, the negative gradient
182
+ of the filtered timecourse is used. Otherwise, the filtering behavior depends on the
183
+ filterinputdata flag.
184
+
185
+ Examples
186
+ --------
187
+ >>> # Prepare a timecourse with default settings
188
+ >>> prepared_tc = processor.preptc(input_tc)
189
+ >>>
190
+ >>> # Prepare a reference timecourse
191
+ >>> ref_tc = processor.preptc(input_tc, isreftc=True)
192
+ """
79
193
  # prepare timecourse by filtering, normalizing, detrending, and applying a window function
80
194
  if isreftc:
81
195
  thenormtc = tide_math.corrnormalize(
@@ -106,14 +220,79 @@ class SimilarityFunctionator:
106
220
 
107
221
  return thenormtc
108
222
 
109
- def trim(self, vector):
223
+ def trim(self, vector: NDArray) -> NDArray:
224
+ """
225
+ Trim vector based on similarity function origin and lag constraints.
226
+
227
+ Parameters
228
+ ----------
229
+ vector : NDArray
230
+ Input vector to be trimmed.
231
+
232
+ Returns
233
+ -------
234
+ NDArray
235
+ Trimmed vector containing elements from
236
+ `self.similarityfuncorigin - self.lagmininpts` to
237
+ `self.similarityfuncorigin + self.lagmaxinpts`.
238
+
239
+ Notes
240
+ -----
241
+ This function extracts a subset of the input vector based on the origin point
242
+ of the similarity function and the minimum/maximum lag constraints. The trimming
243
+ ensures that only relevant portions of the vector are considered for similarity
244
+ calculations.
245
+
246
+ Examples
247
+ --------
248
+ >>> # Assuming self.similarityfuncorigin = 10, self.lagmininpts = 2, self.lagmaxinpts = 3
249
+ >>> trimmed_vector = trim(vector)
250
+ >>> # Returns vector[8:13] where 8 = 10 - 2 and 13 = 10 + 3
251
+ """
110
252
  return vector[
111
253
  self.similarityfuncorigin
112
254
  - self.lagmininpts : self.similarityfuncorigin
113
255
  + self.lagmaxinpts
114
256
  ]
115
257
 
116
- def getfunction(self, trim=True):
258
+ def getfunction(self, trim: bool = True) -> tuple[NDArray | None, NDArray | None, int | None]:
259
+ """
260
+ Retrieve simulation function data with optional trimming.
261
+
262
+ This method returns the simulation function data and time axis, with optional
263
+ trimming based on the trim parameter. The method handles different validation
264
+ states of the data and returns appropriate tuples of (function, time_axis, max_value)
265
+ or None values depending on the data validity.
266
+
267
+ Parameters
268
+ ----------
269
+ trim : bool, optional
270
+ If True, trims the simulation function and time axis using the internal
271
+ trim method. If False, returns the raw data without trimming. Default is True.
272
+
273
+ Returns
274
+ -------
275
+ tuple
276
+ A tuple containing:
277
+ - NDArray or None: Trimmed or untrimmed simulation function data
278
+ - NDArray or None: Trimmed or untrimmed time axis data
279
+ - int or None: Global maximum value, or None if not available
280
+
281
+ Notes
282
+ -----
283
+ The method checks the validity of data through `self.datavalid` and `self.timeaxisvalid` attributes.
284
+ If `self.datavalid` is True, returns both function and time axis data.
285
+ If `self.datavalid` is False but `self.timeaxisvalid` is True, returns only time axis data.
286
+ If neither is valid, prints an error message and returns (None, None, None).
287
+
288
+ Examples
289
+ --------
290
+ >>> result = obj.getfunction(trim=True)
291
+ >>> func_data, time_data, max_val = result
292
+ >>>
293
+ >>> result = obj.getfunction(trim=False)
294
+ >>> func_data, time_data, max_val = result
295
+ """
117
296
  if self.datavalid:
118
297
  if trim:
119
298
  return (
@@ -137,15 +316,53 @@ class SimilarityFunctionator:
137
316
  class MutualInformationator(SimilarityFunctionator):
138
317
  def __init__(
139
318
  self,
140
- windowfunc="hamming",
141
- norm=True,
142
- madnorm=False,
143
- smoothingtime=-1.0,
144
- bins=20,
145
- sigma=0.25,
146
- *args,
147
- **kwargs,
148
- ):
319
+ windowfunc: str = "hamming",
320
+ norm: bool = True,
321
+ madnorm: bool = False,
322
+ smoothingtime: float = -1.0,
323
+ bins: int = 20,
324
+ sigma: float = 0.25,
325
+ *args: Any,
326
+ **kwargs: Any,
327
+ ) -> None:
328
+ """
329
+ Initialize the MutualInformationator object with specified parameters.
330
+
331
+ Parameters
332
+ ----------
333
+ windowfunc : str, optional
334
+ Window function to use for spectral analysis. Default is "hamming".
335
+ norm : bool, optional
336
+ Whether to normalize the data. Default is True.
337
+ madnorm : bool, optional
338
+ Whether to use median absolute deviation normalization. Default is False.
339
+ smoothingtime : float, optional
340
+ Time scale for smoothing filter. If > 0, a noncausal filter is set up.
341
+ Default is -1.0 (no smoothing).
342
+ bins : int, optional
343
+ Number of bins for histogram-based calculations. Default is 20.
344
+ sigma : float, optional
345
+ Standard deviation for Gaussian smoothing. Default is 0.25.
346
+ *args : Any
347
+ Additional positional arguments passed to parent class.
348
+ **kwargs : Any
349
+ Additional keyword arguments passed to parent class.
350
+
351
+ Returns
352
+ -------
353
+ None
354
+ This method initializes the object in-place and does not return anything.
355
+
356
+ Notes
357
+ -----
358
+ When `smoothingtime` is positive, a noncausal filter is initialized with
359
+ frequency settings based on the specified smoothing time scale.
360
+
361
+ Examples
362
+ --------
363
+ >>> mi = MutualInformationator(windowfunc="hanning", bins=30, smoothingtime=2.0)
364
+ >>> mi = MutualInformationator(norm=False, madnorm=True, sigma=0.5)
365
+ """
149
366
  self.windowfunc = windowfunc
150
367
  self.norm = norm
151
368
  self.madnorm = madnorm
@@ -160,7 +377,37 @@ class MutualInformationator(SimilarityFunctionator):
160
377
  )
161
378
  super(MutualInformationator, self).__init__(*args, **kwargs)
162
379
 
163
- def setlimits(self, lagmininpts, lagmaxinpts):
380
+ def setlimits(self, lagmininpts: int, lagmaxinpts: int) -> None:
381
+ """
382
+ Set the minimum and maximum lag limits for the analysis.
383
+
384
+ This function configures the lag limits based on the provided parameters and
385
+ adjusts the smoothing filter padding time if necessary to ensure proper
386
+ signal processing behavior.
387
+
388
+ Parameters
389
+ ----------
390
+ lagmininpts : int
391
+ The minimum lag value in terms of number of points.
392
+ lagmaxinpts : int
393
+ The maximum lag value in terms of number of points.
394
+
395
+ Returns
396
+ -------
397
+ None
398
+ This function does not return any value.
399
+
400
+ Notes
401
+ -----
402
+ The function automatically adjusts the smoothing filter padding time to be
403
+ no larger than the total time span of the data. If the adjustment is made,
404
+ a message is printed to indicate the new padding time value.
405
+
406
+ Examples
407
+ --------
408
+ >>> setlimits(10, 100)
409
+ >>> # Sets minimum lag to 10 points and maximum lag to 100 points
410
+ """
164
411
  self.lagmininpts = lagmininpts
165
412
  self.lagmaxinpts = lagmaxinpts
166
413
  origpadtime = self.smoothingfilter.getpadtime()
@@ -170,10 +417,70 @@ class MutualInformationator(SimilarityFunctionator):
170
417
  print("lowering smoothing filter pad time to", newpadtime)
171
418
  self.smoothingfilter.setpadtime(newpadtime)
172
419
 
173
- def setbins(self, bins):
420
+ def setbins(self, bins: int) -> None:
421
+ """
422
+ Set the number of bins for histogram calculation.
423
+
424
+ Parameters
425
+ ----------
426
+ bins : int
427
+ The number of bins to use for histogram calculation.
428
+
429
+ Returns
430
+ -------
431
+ None
432
+ This method does not return any value.
433
+
434
+ Notes
435
+ -----
436
+ This method assigns the specified number of bins to the instance variable
437
+ `self.bins`. The bins parameter determines the granularity of the histogram
438
+ distribution.
439
+
440
+ Examples
441
+ --------
442
+ >>> obj = MyClass()
443
+ >>> obj.setbins(10)
444
+ >>> print(obj.bins)
445
+ 10
446
+ """
174
447
  self.bins = bins
175
448
 
176
- def setreftc(self, reftc, offset=0.0):
449
+ def setreftc(self, reftc: NDArray, offset: float = 0.0) -> None:
450
+ """
451
+ Set reference time course and compute cross-mutual information.
452
+
453
+ This method initializes the reference time course and computes the cross-mutual
454
+ information between the reference time course and itself to determine the
455
+ optimal time alignment and similarity function.
456
+
457
+ Parameters
458
+ ----------
459
+ reftc : NDArray
460
+ Reference time course array to be set and processed.
461
+ offset : float, optional
462
+ Time offset to be applied to the time axis (default is 0.0).
463
+
464
+ Returns
465
+ -------
466
+ None
467
+ This method modifies the object's attributes in-place and does not return anything.
468
+
469
+ Notes
470
+ -----
471
+ The method performs the following operations:
472
+ 1. Stores a copy of the reference time course
473
+ 2. Pre-processes the reference time course using preptc method
474
+ 3. Computes cross-mutual information using tide_corr.cross_mutual_info
475
+ 4. Adjusts the time axis by the specified offset
476
+ 5. Sets various internal attributes including similarity function normalization
477
+
478
+ Examples
479
+ --------
480
+ >>> obj.setreftc(reference_data, offset=0.5)
481
+ >>> print(obj.timeaxis)
482
+ >>> print(obj.similarityfunclen)
483
+ """
177
484
  self.reftc = reftc + 0.0
178
485
  self.prepreftc = self.preptc(self.reftc, isreftc=True)
179
486
 
@@ -197,10 +504,91 @@ class MutualInformationator(SimilarityFunctionator):
197
504
  print(f"MutualInformationator setreftc: {self.timeaxis}")
198
505
  print(f"MutualInformationator setreftc: {self.mi_norm=}")
199
506
 
200
- def getnormfac(self):
507
+ def getnormfac(self) -> float:
508
+ """
509
+ Return the normalization factor stored in the instance.
510
+
511
+ This method provides access to the normalization factor that has been
512
+ previously computed and stored in the instance variable `mi_norm`.
513
+
514
+ Returns
515
+ -------
516
+ float
517
+ The normalization factor value stored in `self.mi_norm`.
518
+
519
+ Notes
520
+ -----
521
+ The normalization factor is typically used to scale or normalize
522
+ data within the class. This value should be set before calling this
523
+ method to ensure meaningful results.
524
+
525
+ Examples
526
+ --------
527
+ >>> instance = MyClass()
528
+ >>> instance.mi_norm = 2.5
529
+ >>> norm_factor = instance.getnormfac()
530
+ >>> print(norm_factor)
531
+ 2.5
532
+ """
201
533
  return self.mi_norm
202
534
 
203
- def run(self, thetc, locs=None, trim=True, gettimeaxis=True):
535
+ def run(
536
+ self,
537
+ thetc: NDArray,
538
+ locs: NDArray | None = None,
539
+ trim: bool = True,
540
+ gettimeaxis: bool = True,
541
+ ) -> tuple[NDArray, NDArray, int] | NDArray:
542
+ """
543
+ Compute cross-mutual information between test and reference timecourses.
544
+
545
+ This function calculates the cross-mutual information between a test timecourse
546
+ and a reference timecourse, optionally applying preprocessing, trimming, and
547
+ smoothing. It supports both trimmed and untrimmed outputs, and can return
548
+ time axis information depending on the input parameters.
549
+
550
+ Parameters
551
+ ----------
552
+ thetc : NDArray
553
+ Test timecourse array of shape (n_times,).
554
+ locs : NDArray | None, optional
555
+ Locations to compute mutual information at; if provided, the function
556
+ will return only the similarity function values at these locations.
557
+ Default is None.
558
+ trim : bool, optional
559
+ If True, trim the output similarity function and time axis to the
560
+ valid range defined by `lagmininpts` and `lagmaxinpts`. If False,
561
+ the full similarity function is returned. Default is True.
562
+ gettimeaxis : bool, optional
563
+ If True, return the time axis along with the similarity function.
564
+ If False, only the similarity function is returned. Default is True.
565
+
566
+ Returns
567
+ -------
568
+ tuple[NDArray, NDArray, int] | NDArray
569
+ If `locs` is not None, returns the similarity function values at the
570
+ specified locations.
571
+ If `trim` is True and `gettimeaxis` is True, returns a tuple of:
572
+ - trimmed similarity function (NDArray)
573
+ - trimmed time axis (NDArray)
574
+ - index of the global maximum (int)
575
+ If `trim` is False and `gettimeaxis` is True, returns a tuple of:
576
+ - full similarity function (NDArray)
577
+ - full time axis (NDArray)
578
+ - index of the global maximum (int)
579
+ If `gettimeaxis` is False, returns only the similarity function (NDArray).
580
+
581
+ Notes
582
+ -----
583
+ This function uses `tide_corr.cross_mutual_info` for computing cross-mutual
584
+ information, and applies normalization and optional smoothing based on
585
+ instance attributes.
586
+
587
+ Examples
588
+ --------
589
+ >>> result = obj.run(test_tc, locs=None, trim=True, gettimeaxis=True)
590
+ >>> sim_func, time_axis, max_idx = result
591
+ """
204
592
  if len(thetc) != len(self.reftc):
205
593
  print(
206
594
  "MutualInformationator: timecourses are of different sizes:",
@@ -293,24 +681,124 @@ class MutualInformationator(SimilarityFunctionator):
293
681
  class Correlator(SimilarityFunctionator):
294
682
  def __init__(
295
683
  self,
296
- windowfunc="hamming",
297
- corrweighting="None",
298
- corrpadding=0,
299
- baselinefilter=None,
300
- *args,
301
- **kwargs,
302
- ):
684
+ windowfunc: str = "hamming",
685
+ corrweighting: str = "None",
686
+ corrpadding: int = 0,
687
+ baselinefilter: Any | None = None,
688
+ *args: Any,
689
+ **kwargs: Any,
690
+ ) -> None:
691
+ """
692
+ Initialize the Correlator with specified parameters.
693
+
694
+ Parameters
695
+ ----------
696
+ windowfunc : str, default="hamming"
697
+ Window function to apply during correlation. Common options include
698
+ 'hamming', 'hanning', 'blackman', etc.
699
+ corrweighting : str, default="None"
700
+ Correlation weighting method. Can be 'None' or other weighting schemes
701
+ depending on implementation.
702
+ corrpadding : int, default=0
703
+ Padding size to apply during correlation operations.
704
+ baselinefilter : Any | None, default=None
705
+ Baseline filtering method or object to apply. Can be None to skip filtering.
706
+ *args : Any
707
+ Additional positional arguments passed to parent class.
708
+ **kwargs : Any
709
+ Additional keyword arguments passed to parent class.
710
+
711
+ Returns
712
+ -------
713
+ None
714
+ This method initializes the instance and does not return any value.
715
+
716
+ Notes
717
+ -----
718
+ The Correlator class inherits from a parent class, and this initialization
719
+ method sets up the correlation parameters before calling the parent's
720
+ initialization method.
721
+
722
+ Examples
723
+ --------
724
+ >>> correlator = Correlator(windowfunc="hanning", corrpadding=10)
725
+ >>> correlator = Correlator(baselinefilter=my_filter_object)
726
+ """
303
727
  self.windowfunc = windowfunc
304
728
  self.corrweighting = corrweighting
305
729
  self.corrpadding = corrpadding
306
730
  self.baselinefilter = baselinefilter
307
731
  super(Correlator, self).__init__(*args, **kwargs)
308
732
 
309
- def setlimits(self, lagmininpts, lagmaxinpts):
733
+ def setlimits(self, lagmininpts: int, lagmaxinpts: int) -> None:
734
+ """
735
+ Set the minimum and maximum lag limits for the analysis.
736
+
737
+ Parameters
738
+ ----------
739
+ lagmininpts : int
740
+ The minimum lag value in points for the analysis.
741
+ lagmaxinpts : int
742
+ The maximum lag value in points for the analysis.
743
+
744
+ Returns
745
+ -------
746
+ None
747
+ This method does not return any value.
748
+
749
+ Notes
750
+ -----
751
+ This method assigns the provided lag limits to instance variables
752
+ `self.lagmininpts` and `self.lagmaxinpts`. The lag limits define the
753
+ range of lags to be considered in the subsequent analysis operations.
754
+
755
+ Examples
756
+ --------
757
+ >>> obj = MyClass()
758
+ >>> obj.setlimits(5, 20)
759
+ >>> print(obj.lagmininpts)
760
+ 5
761
+ >>> print(obj.lagmaxinpts)
762
+ 20
763
+ """
310
764
  self.lagmininpts = lagmininpts
311
765
  self.lagmaxinpts = lagmaxinpts
312
766
 
313
- def setreftc(self, reftc, offset=0.0):
767
+ def setreftc(self, reftc: NDArray, offset: float = 0.0) -> None:
768
+ """
769
+ Set reference time course and initialize related attributes.
770
+
771
+ This function sets the reference time course, computes related parameters,
772
+ and initializes the time axis for similarity function calculations.
773
+
774
+ Parameters
775
+ ----------
776
+ reftc : NDArray
777
+ Reference time course array used for similarity calculations.
778
+ offset : float, optional
779
+ Time offset to apply to the reference time axis (default is 0.0).
780
+
781
+ Returns
782
+ -------
783
+ None
784
+ This function modifies instance attributes in-place and does not return anything.
785
+
786
+ Notes
787
+ -----
788
+ This function performs the following operations:
789
+ 1. Creates a copy of the reference time course
790
+ 2. Computes preprocessed reference time course using preptc method
791
+ 3. Calculates similarity function length and origin
792
+ 4. Constructs time axis based on sampling frequency and offset
793
+
794
+ The time axis is centered around zero with the specified offset applied.
795
+
796
+ Examples
797
+ --------
798
+ >>> setreftc(reftc_array, offset=0.5)
799
+ >>> print(self.timeaxis)
800
+ >>> print(self.similarityfunclen)
801
+ """
314
802
  self.reftc = reftc + 0.0
315
803
  self.prepreftc = self.preptc(self.reftc, isreftc=True)
316
804
  self.similarityfunclen = len(self.reftc) * 2 - 1
@@ -324,7 +812,40 @@ class Correlator(SimilarityFunctionator):
324
812
  self.timeaxisvalid = True
325
813
  self.datavalid = False
326
814
 
327
- def run(self, thetc, trim=True):
815
+ def run(self, thetc: NDArray, trim: bool = True) -> tuple[NDArray, NDArray, int]:
816
+ """
817
+ Compute the correlation between test and reference timecourses.
818
+
819
+ This function performs correlation analysis between a test timecourse and a reference
820
+ timecourse, applying preprocessing and optional filtering. It returns the similarity
821
+ function, time axis, and the index of the global maximum.
822
+
823
+ Parameters
824
+ ----------
825
+ thetc : ndarray
826
+ Test timecourse to be correlated with the reference timecourse.
827
+ trim : bool, optional
828
+ If True, trims the similarity function and time axis to remove zero-padding
829
+ effects. Default is True.
830
+
831
+ Returns
832
+ -------
833
+ tuple of (ndarray, ndarray, int)
834
+ A tuple containing:
835
+ - similarity function (ndarray)
836
+ - time axis (ndarray)
837
+ - index of the global maximum (int)
838
+
839
+ Notes
840
+ -----
841
+ The function exits with status code 1 if the lengths of `thetc` and `self.reftc`
842
+ do not match.
843
+
844
+ Examples
845
+ --------
846
+ >>> result = correlator.run(test_timecourse, trim=True)
847
+ >>> similarity_func, time_axis, max_index = result
848
+ """
328
849
  if len(thetc) != len(self.reftc):
329
850
  print(
330
851
  "Correlator: timecourses are of different sizes:",
@@ -428,43 +949,70 @@ class SimilarityFunctionFitter:
428
949
  functype="correlation",
429
950
  peakfittype="gauss",
430
951
  ):
431
- r"""
952
+ """
953
+ Initialize a correlation peak finder.
954
+
955
+ This constructor sets up the parameters for fitting and searching correlation
956
+ functions to find peak locations, amplitudes, and widths.
432
957
 
433
958
  Parameters
434
959
  ----------
435
- corrtimeaxis: 1D float array
436
- The time axis of the correlation function
437
- lagmin: float
438
- The minimum allowed lag time in seconds
439
- lagmax: float
440
- The maximum allowed lag time in seconds
441
- absmaxsigma: float
442
- The maximum allowed peak halfwidth in seconds
443
- hardlimit
444
- bipolar: boolean
445
- If true find the correlation peak with the maximum absolute value, regardless of sign
446
- lthreshval
447
- uthreshval
448
- debug
449
- zerooutbadfit
450
- maxguess
451
- useguess
452
- searchfrac
453
- lagmod
454
- enforcethresh
455
- displayplots
960
+ corrtimeaxis : 1D float array, optional
961
+ The time axis of the correlation function. Default is None.
962
+ lagmin : float, optional
963
+ The minimum allowed lag time in seconds. Default is -30.0.
964
+ lagmax : float, optional
965
+ The maximum allowed lag time in seconds. Default is 30.0.
966
+ absmaxsigma : float, optional
967
+ The maximum allowed peak halfwidth in seconds. Default is 1000.0.
968
+ absminsigma : float, optional
969
+ The minimum allowed peak halfwidth in seconds. Default is 0.25.
970
+ hardlimit : bool, optional
971
+ If True, enforce hard limits on peak fitting. Default is True.
972
+ bipolar : bool, optional
973
+ If True, find the correlation peak with the maximum absolute value,
974
+ regardless of sign. Default is False.
975
+ lthreshval : float, optional
976
+ Lower threshold value for correlation function. Default is 0.0.
977
+ uthreshval : float, optional
978
+ Upper threshold value for correlation function. Default is 1.0.
979
+ debug : bool, optional
980
+ If True, enable debug output. Default is False.
981
+ zerooutbadfit : bool, optional
982
+ If True, set bad fits to zero. Default is True.
983
+ maxguess : float, optional
984
+ Maximum guess for peak fitting. Default is 0.0.
985
+ useguess : bool, optional
986
+ If True, use initial guess for peak fitting. Default is False.
987
+ searchfrac : float, optional
988
+ Fraction of the search range to consider for peak fitting. Default is 0.5.
989
+ lagmod : float, optional
990
+ Modulus for lag values. Default is 1000.0.
991
+ enforcethresh : bool, optional
992
+ If True, enforce threshold constraints. Default is True.
993
+ allowhighfitamps : bool, optional
994
+ If True, allow high amplitude fits. Default is False.
995
+ displayplots : bool, optional
996
+ If True, display plots during fitting. Default is False.
997
+ functype : str, optional
998
+ Type of function to fit. Either "correlation" or "mutualinfo". Default is "correlation".
999
+ peakfittype : str, optional
1000
+ Type of peak fit to use. Default is "gauss".
456
1001
 
457
1002
  Returns
458
1003
  -------
459
-
460
-
461
- Methods
462
- -------
463
- fit(corrfunc):
464
- Fit the correlation function given in corrfunc and return the location of the peak in seconds, the maximum
465
- correlation value, the peak width
466
- setrange(lagmin, lagmax):
467
- Specify the search range for lag peaks, in seconds
1004
+ None
1005
+ This method initializes the object and does not return any value.
1006
+
1007
+ Notes
1008
+ -----
1009
+ The `corrtimeaxis` must be provided before calling `fit()` method.
1010
+ The `functype` parameter determines whether to fit a correlation or mutual information function.
1011
+
1012
+ Examples
1013
+ --------
1014
+ >>> peakfinder = PeakFinder(corrtimeaxis=time_axis, lagmin=-20, lagmax=20)
1015
+ >>> peak_location, peak_value, peak_width = peakfinder.fit(correlation_data)
468
1016
  """
469
1017
  self.setcorrtimeaxis(corrtimeaxis)
470
1018
  self.lagmin = lagmin + 0.0
@@ -491,16 +1039,40 @@ class SimilarityFunctionFitter:
491
1039
  self.allowhighfitamps = allowhighfitamps
492
1040
  self.displayplots = displayplots
493
1041
 
494
- def _maxindex_noedge(self, corrfunc):
1042
+ def _maxindex_noedge(self, corrfunc: NDArray) -> tuple[int, float]:
495
1043
  """
1044
+ Find the index of the maximum value in correlation function, avoiding edge effects.
1045
+
1046
+ This function searches for the maximum value in the correlation function while
1047
+ avoiding the edges of the data. It handles bipolar correlation functions by
1048
+ considering both positive and negative peaks, returning the one with the larger
1049
+ absolute value. The function also accounts for edge effects by adjusting the
1050
+ search boundaries when the maximum is found at the edge.
496
1051
 
497
1052
  Parameters
498
1053
  ----------
499
- corrfunc
1054
+ corrfunc : NDArray
1055
+ Correlation function array to search for maximum value
500
1056
 
501
1057
  Returns
502
1058
  -------
503
-
1059
+ tuple[int, float]
1060
+ Tuple containing:
1061
+ - maxindex: Index of the maximum value in the correlation function
1062
+ - flipfac: Flipping factor (-1.0 if minimum was selected, 1.0 otherwise)
1063
+
1064
+ Notes
1065
+ -----
1066
+ The function adjusts search boundaries to avoid edge effects:
1067
+ - If maximum is at index 0, lowerlim is incremented
1068
+ - If maximum is at upper limit, upperlim is decremented
1069
+ - For bipolar correlation functions, both positive and negative peaks are considered
1070
+ - The search continues until no edge effects are detected
1071
+
1072
+ Examples
1073
+ --------
1074
+ >>> max_index, flip_factor = obj._maxindex_noedge(corrfunc)
1075
+ >>> print(f"Maximum at index {max_index} with flip factor {flip_factor}")
504
1076
  """
505
1077
  lowerlim = 0
506
1078
  upperlim = len(self.corrtimeaxis) - 1
@@ -524,33 +1096,269 @@ class SimilarityFunctionFitter:
524
1096
  done = False
525
1097
  return maxindex, flipfac
526
1098
 
527
- def setfunctype(self, functype):
1099
+ def setfunctype(self, functype: str) -> None:
1100
+ """
1101
+ Set the function type for the object.
1102
+
1103
+ Parameters
1104
+ ----------
1105
+ functype : str
1106
+ The function type to be set. This should be a string identifier
1107
+ that defines the type of function this object represents.
1108
+
1109
+ Returns
1110
+ -------
1111
+ None
1112
+ This method does not return any value.
1113
+
1114
+ Notes
1115
+ -----
1116
+ This method directly assigns the provided function type to the
1117
+ internal `functype` attribute of the object.
1118
+
1119
+ Examples
1120
+ --------
1121
+ >>> obj = MyClass()
1122
+ >>> obj.setfunctype('linear')
1123
+ >>> obj.functype
1124
+ 'linear'
1125
+ """
528
1126
  self.functype = functype
529
1127
 
530
- def setpeakfittype(self, peakfittype):
1128
+ def setpeakfittype(self, peakfittype: str) -> None:
1129
+ """
1130
+ Set the peak fitting type for the analysis.
1131
+
1132
+ Parameters
1133
+ ----------
1134
+ peakfittype : str
1135
+ The type of peak fitting to be used. This parameter determines the
1136
+ mathematical model and fitting algorithm applied to the peak data.
1137
+
1138
+ Returns
1139
+ -------
1140
+ None
1141
+ This method does not return any value.
1142
+
1143
+ Notes
1144
+ -----
1145
+ This method directly assigns the provided peak fitting type to the
1146
+ instance variable `self.peakfittype`. The valid values for peakfittype
1147
+ depend on the specific implementation of the peak fitting algorithms
1148
+ available in the class.
1149
+
1150
+ Examples
1151
+ --------
1152
+ >>> analyzer = PeakAnalyzer()
1153
+ >>> analyzer.setpeakfittype('gaussian')
1154
+ >>> print(analyzer.peakfittype)
1155
+ 'gaussian'
1156
+ """
531
1157
  self.peakfittype = peakfittype
532
1158
 
533
- def setrange(self, lagmin, lagmax):
1159
+ def setrange(self, lagmin: float, lagmax: float) -> None:
1160
+ """
1161
+ Set the range of lags for the analysis.
1162
+
1163
+ Parameters
1164
+ ----------
1165
+ lagmin : float
1166
+ The minimum lag value for the analysis range.
1167
+ lagmax : float
1168
+ The maximum lag value for the analysis range.
1169
+
1170
+ Returns
1171
+ -------
1172
+ None
1173
+ This method does not return any value.
1174
+
1175
+ Notes
1176
+ -----
1177
+ This method updates the internal lag range parameters of the object.
1178
+ The lagmin value should be less than or equal to the lagmax value.
1179
+
1180
+ Examples
1181
+ --------
1182
+ >>> obj = MyClass()
1183
+ >>> obj.setrange(0.0, 10.0)
1184
+ >>> print(obj.lagmin)
1185
+ 0.0
1186
+ >>> print(obj.lagmax)
1187
+ 10.0
1188
+ """
534
1189
  self.lagmin = lagmin
535
1190
  self.lagmax = lagmax
536
1191
 
537
- def setcorrtimeaxis(self, corrtimeaxis):
1192
+ def setcorrtimeaxis(self, corrtimeaxis: NDArray | None) -> None:
1193
+ """
1194
+ Set the correlation time axis for the object.
1195
+
1196
+ This method assigns the provided correlation time axis to the object's
1197
+ `corrtimeaxis` attribute. If the input is not None, a copy of the array is
1198
+ created to avoid modifying the original data.
1199
+
1200
+ Parameters
1201
+ ----------
1202
+ corrtimeaxis : NDArray | None
1203
+ The correlation time axis array to be set. If None, the attribute will
1204
+ be set to None. If an array is provided, a copy will be created to
1205
+ prevent modification of the original array.
1206
+
1207
+ Returns
1208
+ -------
1209
+ None
1210
+ This method does not return any value.
1211
+
1212
+ Notes
1213
+ -----
1214
+ When a numpy array is passed, the method creates a copy using `+ 0.0`
1215
+ to ensure that modifications to the original array do not affect the
1216
+ object's internal state.
1217
+
1218
+ Examples
1219
+ --------
1220
+ >>> obj.setcorrtimeaxis(np.array([1, 2, 3, 4]))
1221
+ >>> obj.setcorrtimeaxis(None)
1222
+ """
538
1223
  if corrtimeaxis is not None:
539
1224
  self.corrtimeaxis = corrtimeaxis + 0.0
540
1225
  else:
541
1226
  self.corrtimeaxis = corrtimeaxis
542
1227
 
543
- def setguess(self, useguess, maxguess=0.0):
1228
+ def setguess(self, useguess: bool, maxguess: float = 0.0) -> None:
1229
+ """
1230
+ Set the guess parameters for the optimization process.
1231
+
1232
+ This method configures whether to use a guess value and sets the maximum
1233
+ guess value for optimization algorithms.
1234
+
1235
+ Parameters
1236
+ ----------
1237
+ useguess : bool
1238
+ Flag indicating whether to use a guess value in the optimization process.
1239
+ If True, the algorithm will attempt to use the provided guess value.
1240
+ If False, no guess value will be used.
1241
+ maxguess : float, optional
1242
+ Maximum guess value to be used in the optimization process. Default is 0.0.
1243
+ This parameter is only relevant when useguess is True.
1244
+
1245
+ Returns
1246
+ -------
1247
+ None
1248
+ This method does not return any value.
1249
+
1250
+ Notes
1251
+ -----
1252
+ The maxguess parameter is typically used to constrain the search space
1253
+ during optimization. When useguess is False, the maxguess parameter has
1254
+ no effect on the optimization process.
1255
+
1256
+ Examples
1257
+ --------
1258
+ >>> optimizer = Optimizer()
1259
+ >>> optimizer.setguess(True, 10.0)
1260
+ >>> optimizer.setguess(False)
1261
+ """
544
1262
  self.useguess = useguess
545
1263
  self.maxguess = maxguess
546
1264
 
547
- def setlthresh(self, lthreshval):
1265
+ def setlthresh(self, lthreshval: float) -> None:
1266
+ """
1267
+ Set the lower threshold value for the object.
1268
+
1269
+ Parameters
1270
+ ----------
1271
+ lthreshval : float
1272
+ The lower threshold value to be set. This value will be assigned to
1273
+ the instance attribute `lthreshval`.
1274
+
1275
+ Returns
1276
+ -------
1277
+ None
1278
+ This method does not return any value.
1279
+
1280
+ Notes
1281
+ -----
1282
+ This method assigns the provided threshold value to the instance attribute
1283
+ `lthreshval`. The threshold value is typically used for filtering or
1284
+ processing operations where values below this threshold are treated
1285
+ differently.
1286
+
1287
+ Examples
1288
+ --------
1289
+ >>> obj = MyClass()
1290
+ >>> obj.setlthresh(0.5)
1291
+ >>> print(obj.lthreshval)
1292
+ 0.5
1293
+ """
548
1294
  self.lthreshval = lthreshval
549
1295
 
550
- def setuthresh(self, uthreshval):
1296
+ def setuthresh(self, uthreshval: float) -> None:
1297
+ """
1298
+ Set the upper threshold value for the object.
1299
+
1300
+ Parameters
1301
+ ----------
1302
+ uthreshval : float
1303
+ The upper threshold value to be set. This value will be assigned to
1304
+ the object's internal `uthreshval` attribute.
1305
+
1306
+ Returns
1307
+ -------
1308
+ None
1309
+ This method does not return any value.
1310
+
1311
+ Notes
1312
+ -----
1313
+ This method directly assigns the provided threshold value to the object's
1314
+ internal attribute. No validation or processing is performed on the input value.
1315
+
1316
+ Examples
1317
+ --------
1318
+ >>> obj = MyClass()
1319
+ >>> obj.setuthresh(0.5)
1320
+ >>> print(obj.uthreshval)
1321
+ 0.5
1322
+ """
551
1323
  self.uthreshval = uthreshval
552
1324
 
553
- def diagnosefail(self, failreason):
1325
+ def diagnosefail(self, failreason: Any) -> str:
1326
+ """
1327
+ Diagnose the cause of a failure based on bitwise flags.
1328
+
1329
+ This function takes a failure reason encoded as a bitwise flag and returns
1330
+ a human-readable string describing the cause(s) of the failure. Each flag
1331
+ corresponds to a specific condition that may have led to the failure.
1332
+
1333
+ Parameters
1334
+ ----------
1335
+ failreason : Any
1336
+ A value representing the failure reason, typically an integer or array
1337
+ of integers. It is cast to `np.uint32` for bitwise operations.
1338
+
1339
+ Returns
1340
+ -------
1341
+ str
1342
+ A comma-separated string listing the reasons for the failure. If no
1343
+ reasons are found, returns "No error".
1344
+
1345
+ Notes
1346
+ -----
1347
+ The function checks the following flags:
1348
+ - ``FML_INITAMPLOW``, ``FML_INITAMPHIGH``, ``FML_INITWIDTHLOW``,
1349
+ ``FML_INITWIDTHHIGH``, ``FML_INITLAGLOW``, ``FML_INITLAGHIGH``:
1350
+ Initial parameter values are out of bounds.
1351
+ - ``FML_FITAMPLOW``, ``FML_FITAMPHIGH``, ``FML_FITWIDTHLOW``,
1352
+ ``FML_FITWIDTHHIGH``, ``FML_FITLAGLOW``, ``FML_FITLAGHIGH``:
1353
+ Fit parameter values are out of bounds.
1354
+ - ``FML_FITALGOFAIL``: Nonlinear fitting algorithm failed.
1355
+
1356
+ Examples
1357
+ --------
1358
+ >>> diagnosis = obj.diagnosefail(0x0001)
1359
+ >>> print(diagnosis)
1360
+ 'Initial amplitude too low'
1361
+ """
554
1362
  # define error values
555
1363
  reasons = []
556
1364
  if failreason.astype(np.uint32) & self.FML_INITAMPLOW:
@@ -586,7 +1394,52 @@ class SimilarityFunctionFitter:
586
1394
  else:
587
1395
  return "No error"
588
1396
 
589
- def fit(self, incorrfunc):
1397
+ def fit(self, incorrfunc: NDArray) -> tuple[int, float, float, float, int, Any, int, int]:
1398
+ """
1399
+ Fit a correlation function to determine peak parameters including lag, amplitude, and width.
1400
+
1401
+ This function performs a fit on the provided correlation function to extract key parameters
1402
+ such as the peak lag, amplitude, and width. It supports multiple fitting methods and handles
1403
+ various edge cases including invalid inputs, out-of-bounds values, and fitting failures.
1404
+
1405
+ Parameters
1406
+ ----------
1407
+ incorrfunc : ndarray
1408
+ The input correlation function to be fitted. Must match the length of `self.corrtimeaxis`.
1409
+
1410
+ Returns
1411
+ -------
1412
+ tuple[int, float, float, float, int, Any, int, int]
1413
+ A tuple containing:
1414
+
1415
+ - `maxindex` (int): Index of the maximum value in the correlation function.
1416
+ - `maxlag` (float): The lag corresponding to the peak, in seconds.
1417
+ - `maxval` (float): The amplitude of the peak, adjusted for flip factor.
1418
+ - `maxsigma` (float): The width of the peak, in seconds.
1419
+ - `maskval` (int): A flag indicating fit success (1) or failure (0).
1420
+ - `failreason` (Any): A bitmask indicating the reason for fit failure, if any.
1421
+ - `peakstart` (int): Start index of the peak region used in fitting.
1422
+ - `peakend` (int): End index of the peak region used in fitting.
1423
+
1424
+ Notes
1425
+ -----
1426
+ The function performs several checks:
1427
+
1428
+ - Ensures `self.corrtimeaxis` is defined and matches the input length.
1429
+ - Handles bipolar correlation functions and adjusts signs accordingly.
1430
+ - Applies initial parameter estimation based on the input data.
1431
+ - Supports multiple fitting algorithms including Gaussian, quadratic, and center-of-mass.
1432
+ - Applies bounds checking for lag, amplitude, and width to ensure physical validity.
1433
+ - Outputs debugging information if `self.debug` is set to True.
1434
+
1435
+ Examples
1436
+ --------
1437
+ >>> # Assuming `fit_instance` is an instance of the class containing this method
1438
+ >>> corr_func = np.array([0.1, 0.5, 1.0, 0.5, 0.1])
1439
+ >>> result = fit_instance.fit(corr_func)
1440
+ >>> print(result)
1441
+ (2, 1.0, 1.0, 0.5, 1, 0, 1, 3)
1442
+ """
590
1443
  # check to make sure xcorr_x and xcorr_y match
591
1444
  if self.corrtimeaxis is None:
592
1445
  print("Correlation time axis is not defined - exiting")
@@ -694,9 +1547,17 @@ class SimilarityFunctionFitter:
694
1547
  while peakpoints[peakstart - 1] == 1:
695
1548
  peakstart -= 1
696
1549
  else:
697
- while thegrad[peakend + 1] <= 0.0 and peakpoints[peakend + 1] == 1 and peakend < len(self.corrtimeaxis) - 2:
1550
+ while (
1551
+ thegrad[peakend + 1] <= 0.0
1552
+ and peakpoints[peakend + 1] == 1
1553
+ and peakend < len(self.corrtimeaxis) - 2
1554
+ ):
698
1555
  peakend += 1
699
- while thegrad[peakstart - 1] >= 0.0 and peakpoints[peakstart - 1] == 1 and peakstart >= 1:
1556
+ while (
1557
+ thegrad[peakstart - 1] >= 0.0
1558
+ and peakpoints[peakstart - 1] == 1
1559
+ and peakstart >= 1
1560
+ ):
700
1561
  peakstart -= 1
701
1562
  if self.debug:
702
1563
  print("final peakstart, peakend:", peakstart, peakend)
@@ -887,7 +1748,7 @@ class SimilarityFunctionFitter:
887
1748
  if self.debug:
888
1749
  print("poly coffs:", a, b, c)
889
1750
  print("maxlag, maxval, maxsigma:", maxlag, maxval, maxsigma)
890
- except np.lib.polynomial.RankWarning:
1751
+ except np.exceptions.RankWarning:
891
1752
  failreason |= self.FML_FITALGOFAIL
892
1753
  maxlag = 0.0
893
1754
  maxval = 0.0
@@ -1030,7 +1891,45 @@ class FrequencyTracker:
1030
1891
  freqs = None
1031
1892
  times = None
1032
1893
 
1033
- def __init__(self, lowerlim=0.1, upperlim=0.6, nperseg=32, Q=10.0, debug=False):
1894
+ def __init__(
1895
+ self,
1896
+ lowerlim: float = 0.1,
1897
+ upperlim: float = 0.6,
1898
+ nperseg: int = 32,
1899
+ Q: float = 10.0,
1900
+ debug: bool = False,
1901
+ ) -> None:
1902
+ """
1903
+ Initialize the object with spectral analysis parameters.
1904
+
1905
+ Parameters
1906
+ ----------
1907
+ lowerlim : float, optional
1908
+ Lower frequency limit for spectral analysis, default is 0.1
1909
+ upperlim : float, optional
1910
+ Upper frequency limit for spectral analysis, default is 0.6
1911
+ nperseg : int, optional
1912
+ Number of samples per segment for spectral analysis, default is 32
1913
+ Q : float, optional
1914
+ Quality factor for spectral analysis, default is 10.0
1915
+ debug : bool, optional
1916
+ Debug flag for verbose output, default is False
1917
+
1918
+ Returns
1919
+ -------
1920
+ None
1921
+ This method initializes the object attributes and does not return any value.
1922
+
1923
+ Notes
1924
+ -----
1925
+ The ``nfft`` attribute is set equal to ``nperseg`` during initialization.
1926
+
1927
+ Examples
1928
+ --------
1929
+ >>> obj = MyClass(lowerlim=0.2, upperlim=0.8, nperseg=64)
1930
+ >>> print(obj.lowerlim)
1931
+ 0.2
1932
+ """
1034
1933
  self.lowerlim = lowerlim
1035
1934
  self.upperlim = upperlim
1036
1935
  self.nperseg = nperseg
@@ -1038,7 +1937,46 @@ class FrequencyTracker:
1038
1937
  self.debug = debug
1039
1938
  self.nfft = self.nperseg
1040
1939
 
1041
- def track(self, x, fs):
1940
+ def track(self, x: NDArray, fs: float) -> tuple[NDArray, NDArray]:
1941
+ """
1942
+ Track peak frequencies in a signal using spectrogram analysis and peak fitting.
1943
+
1944
+ This function computes the spectrogram of the input signal, then tracks the
1945
+ dominant frequency component over time by fitting peaks in each time segment.
1946
+ The result is a tuple of time indices and corresponding peak frequencies.
1947
+
1948
+ Parameters
1949
+ ----------
1950
+ x : NDArray
1951
+ Input signal array to be analyzed.
1952
+ fs : float
1953
+ Sampling frequency of the input signal in Hz.
1954
+
1955
+ Returns
1956
+ -------
1957
+ tuple[NDArray, NDArray]
1958
+ A tuple containing:
1959
+ - times : NDArray
1960
+ Time indices corresponding to the tracked peaks (excluding the last time bin).
1961
+ - peakfreqs : NDArray
1962
+ Array of peak frequencies corresponding to each time segment.
1963
+ If no valid peak is found within the specified frequency range,
1964
+ the value is set to -1.0.
1965
+
1966
+ Notes
1967
+ -----
1968
+ - The input signal is padded with zeros at both ends to reduce edge effects.
1969
+ - The spectrogram is computed using a Hamming window and no overlap between segments.
1970
+ - Peak fitting is performed using a fast quadratic method.
1971
+ - Frequencies outside the range defined by `self.lowerlim` and `self.upperlim`
1972
+ are marked as invalid (set to -1.0).
1973
+
1974
+ Examples
1975
+ --------
1976
+ >>> times, peakfreqs = obj.track(signal, fs)
1977
+ >>> print(f"Peak frequencies: {peakfreqs}")
1978
+ >>> print(f"Time indices: {times}")
1979
+ """
1042
1980
  self.freqs, self.times, thespectrogram = sp.signal.spectrogram(
1043
1981
  np.concatenate(
1044
1982
  [np.zeros(int(self.nperseg // 2)), x, np.zeros(int(self.nperseg // 2))],
@@ -1088,7 +2026,44 @@ class FrequencyTracker:
1088
2026
 
1089
2027
  return self.times[:-1], peakfreqs
1090
2028
 
1091
- def clean(self, x, fs, times, peakfreqs, numharmonics=2):
2029
+ def clean(
2030
+ self, x: NDArray, fs: float, times: NDArray, peakfreqs: NDArray, numharmonics: int = 2
2031
+ ) -> NDArray:
2032
+ """
2033
+ Apply harmonic cleaning to a signal based on detected peak frequencies and their harmonics.
2034
+
2035
+ This function cleans a signal by applying bandpass filtering to specific time intervals
2036
+ centered at given peak frequencies. It supports filtering of harmonics up to a specified
2037
+ number and handles edge effects through padding.
2038
+
2039
+ Parameters
2040
+ ----------
2041
+ x : ndarray
2042
+ Input signal to be cleaned.
2043
+ fs : float
2044
+ Sampling frequency of the signal in Hz.
2045
+ times : ndarray
2046
+ Array of time indices (in seconds) where cleaning is applied.
2047
+ peakfreqs : ndarray
2048
+ Array of peak frequencies (in Hz) corresponding to each time index.
2049
+ numharmonics : int, optional
2050
+ Maximum number of harmonics to filter (default is 2).
2051
+
2052
+ Returns
2053
+ -------
2054
+ ndarray
2055
+ Cleaned signal with harmonics filtered out.
2056
+
2057
+ Notes
2058
+ -----
2059
+ - The function uses Chebyshev type II filter design for each harmonic.
2060
+ - Harmonics are filtered using `scipy.signal.filtfilt` for zero-phase filtering.
2061
+ - Edge effects are mitigated by padding the input signal with zeros.
2062
+
2063
+ Examples
2064
+ --------
2065
+ >>> cleaned_signal = obj.clean(x, fs=1000.0, times=[0.1, 0.5], peakfreqs=[50.0, 100.0])
2066
+ """
1092
2067
  nyquistfreq = 0.5 * fs
1093
2068
  y = x * 0.0
1094
2069
  halfwidth = int(self.nperseg // 2)