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.
- rapidtide/Colortables.py +492 -27
- rapidtide/OrthoImageItem.py +1053 -47
- rapidtide/RapidtideDataset.py +1533 -86
- rapidtide/_version.py +3 -3
- rapidtide/calccoherence.py +196 -29
- rapidtide/calcnullsimfunc.py +191 -40
- rapidtide/calcsimfunc.py +245 -42
- rapidtide/correlate.py +1210 -393
- rapidtide/data/examples/src/testLD +56 -0
- rapidtide/data/examples/src/testalign +1 -1
- rapidtide/data/examples/src/testdelayvar +0 -1
- rapidtide/data/examples/src/testfmri +19 -1
- rapidtide/data/examples/src/testglmfilt +5 -5
- rapidtide/data/examples/src/testhappy +30 -1
- rapidtide/data/examples/src/testppgproc +17 -0
- rapidtide/data/examples/src/testrolloff +11 -0
- rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
- rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm.nii.gz +0 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm_mask.nii.gz +0 -0
- rapidtide/decorators.py +91 -0
- rapidtide/dlfilter.py +2225 -108
- rapidtide/dlfiltertorch.py +4843 -0
- rapidtide/externaltools.py +327 -12
- rapidtide/fMRIData_class.py +79 -40
- rapidtide/filter.py +1899 -810
- rapidtide/fit.py +2004 -574
- rapidtide/genericmultiproc.py +93 -18
- rapidtide/happy_supportfuncs.py +2044 -171
- rapidtide/helper_classes.py +584 -43
- rapidtide/io.py +2363 -370
- rapidtide/linfitfiltpass.py +341 -75
- rapidtide/makelaggedtcs.py +211 -20
- rapidtide/maskutil.py +423 -53
- rapidtide/miscmath.py +827 -121
- rapidtide/multiproc.py +210 -22
- rapidtide/patchmatch.py +234 -33
- rapidtide/peakeval.py +32 -30
- rapidtide/ppgproc.py +2203 -0
- rapidtide/qualitycheck.py +352 -39
- rapidtide/refinedelay.py +422 -57
- rapidtide/refineregressor.py +498 -184
- rapidtide/resample.py +671 -185
- rapidtide/scripts/applyppgproc.py +28 -0
- rapidtide/simFuncClasses.py +1052 -77
- rapidtide/simfuncfit.py +260 -46
- rapidtide/stats.py +540 -238
- rapidtide/tests/happycomp +9 -0
- rapidtide/tests/test_dlfiltertorch.py +627 -0
- rapidtide/tests/test_findmaxlag.py +24 -8
- rapidtide/tests/test_fullrunhappy_v1.py +0 -2
- rapidtide/tests/test_fullrunhappy_v2.py +0 -2
- rapidtide/tests/test_fullrunhappy_v3.py +1 -0
- rapidtide/tests/test_fullrunhappy_v4.py +2 -2
- rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
- rapidtide/tests/test_simroundtrip.py +8 -8
- rapidtide/tests/utils.py +9 -8
- rapidtide/tidepoolTemplate.py +142 -38
- rapidtide/tidepoolTemplate_alt.py +165 -44
- rapidtide/tidepoolTemplate_big.py +189 -52
- rapidtide/util.py +1217 -118
- rapidtide/voxelData.py +684 -37
- rapidtide/wiener.py +19 -12
- rapidtide/wiener2.py +113 -7
- rapidtide/wiener_doc.py +255 -0
- rapidtide/workflows/adjustoffset.py +105 -3
- rapidtide/workflows/aligntcs.py +85 -2
- rapidtide/workflows/applydlfilter.py +87 -10
- rapidtide/workflows/applyppgproc.py +522 -0
- rapidtide/workflows/atlasaverage.py +210 -47
- rapidtide/workflows/atlastool.py +100 -3
- rapidtide/workflows/calcSimFuncMap.py +294 -64
- rapidtide/workflows/calctexticc.py +201 -9
- rapidtide/workflows/ccorrica.py +97 -4
- rapidtide/workflows/cleanregressor.py +168 -29
- rapidtide/workflows/delayvar.py +163 -10
- rapidtide/workflows/diffrois.py +81 -3
- rapidtide/workflows/endtidalproc.py +144 -4
- rapidtide/workflows/fdica.py +195 -15
- rapidtide/workflows/filtnifti.py +70 -3
- rapidtide/workflows/filttc.py +74 -3
- rapidtide/workflows/fitSimFuncMap.py +206 -48
- rapidtide/workflows/fixtr.py +73 -3
- rapidtide/workflows/gmscalc.py +113 -3
- rapidtide/workflows/happy.py +813 -201
- rapidtide/workflows/happy2std.py +144 -12
- rapidtide/workflows/happy_parser.py +149 -8
- rapidtide/workflows/histnifti.py +118 -2
- rapidtide/workflows/histtc.py +84 -3
- rapidtide/workflows/linfitfilt.py +117 -4
- rapidtide/workflows/localflow.py +328 -28
- rapidtide/workflows/mergequality.py +79 -3
- rapidtide/workflows/niftidecomp.py +322 -18
- rapidtide/workflows/niftistats.py +174 -4
- rapidtide/workflows/pairproc.py +88 -2
- rapidtide/workflows/pairwisemergenifti.py +85 -2
- rapidtide/workflows/parser_funcs.py +1421 -40
- rapidtide/workflows/physiofreq.py +137 -11
- rapidtide/workflows/pixelcomp.py +208 -5
- rapidtide/workflows/plethquality.py +103 -21
- rapidtide/workflows/polyfitim.py +151 -11
- rapidtide/workflows/proj2flow.py +75 -2
- rapidtide/workflows/rankimage.py +111 -4
- rapidtide/workflows/rapidtide.py +272 -15
- rapidtide/workflows/rapidtide2std.py +98 -2
- rapidtide/workflows/rapidtide_parser.py +109 -9
- rapidtide/workflows/refineDelayMap.py +143 -33
- rapidtide/workflows/refineRegressor.py +682 -93
- rapidtide/workflows/regressfrommaps.py +152 -31
- rapidtide/workflows/resamplenifti.py +85 -3
- rapidtide/workflows/resampletc.py +91 -3
- rapidtide/workflows/retrolagtcs.py +98 -6
- rapidtide/workflows/retroregress.py +165 -9
- rapidtide/workflows/roisummarize.py +173 -5
- rapidtide/workflows/runqualitycheck.py +71 -3
- rapidtide/workflows/showarbcorr.py +147 -4
- rapidtide/workflows/showhist.py +86 -2
- rapidtide/workflows/showstxcorr.py +160 -3
- rapidtide/workflows/showtc.py +159 -3
- rapidtide/workflows/showxcorrx.py +184 -4
- rapidtide/workflows/showxy.py +185 -15
- rapidtide/workflows/simdata.py +262 -36
- rapidtide/workflows/spatialfit.py +77 -2
- rapidtide/workflows/spatialmi.py +251 -27
- rapidtide/workflows/spectrogram.py +305 -32
- rapidtide/workflows/synthASL.py +154 -3
- rapidtide/workflows/tcfrom2col.py +76 -2
- rapidtide/workflows/tcfrom3col.py +74 -2
- rapidtide/workflows/tidepool.py +2972 -133
- rapidtide/workflows/utils.py +19 -14
- rapidtide/workflows/utils_doc.py +293 -0
- rapidtide/workflows/variabilityizer.py +116 -3
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/METADATA +10 -9
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/RECORD +141 -122
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/entry_points.txt +1 -0
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/WHEEL +0 -0
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/top_level.txt +0 -0
rapidtide/simFuncClasses.py
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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
|
|
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
|
|
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.
|
|
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__(
|
|
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(
|
|
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)
|