SignalProcessingTools 1.2.0__tar.gz
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.
- signalprocessingtools-1.2.0/PKG-INFO +157 -0
- signalprocessingtools-1.2.0/ReadMe.md +139 -0
- signalprocessingtools-1.2.0/SignalProcessingTools/__init__.py +1 -0
- signalprocessingtools-1.2.0/SignalProcessingTools/__version__.py +3 -0
- signalprocessingtools-1.2.0/SignalProcessingTools/space_signal.py +189 -0
- signalprocessingtools-1.2.0/SignalProcessingTools/time_signal.py +572 -0
- signalprocessingtools-1.2.0/SignalProcessingTools.egg-info/PKG-INFO +157 -0
- signalprocessingtools-1.2.0/SignalProcessingTools.egg-info/SOURCES.txt +14 -0
- signalprocessingtools-1.2.0/SignalProcessingTools.egg-info/dependency_links.txt +1 -0
- signalprocessingtools-1.2.0/SignalProcessingTools.egg-info/requires.txt +7 -0
- signalprocessingtools-1.2.0/SignalProcessingTools.egg-info/top_level.txt +1 -0
- signalprocessingtools-1.2.0/pyproject.toml +6 -0
- signalprocessingtools-1.2.0/setup.cfg +31 -0
- signalprocessingtools-1.2.0/tests/test_space_signal.py +66 -0
- signalprocessingtools-1.2.0/tests/test_time_signal.py +366 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: SignalProcessingTools
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Signal processing tools
|
|
5
|
+
Author: attr: SignalProcessingTools.__author__
|
|
6
|
+
Author-email: bruno.zuadacoelho@deltares.nl, aron.noordam@deltares.nl
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: matplotlib>=3.10
|
|
13
|
+
Requires-Dist: numpy>=2.2
|
|
14
|
+
Requires-Dist: scipy>=1.15
|
|
15
|
+
Provides-Extra: testing
|
|
16
|
+
Requires-Dist: pytest>=8.3; extra == "testing"
|
|
17
|
+
Requires-Dist: tox>=4.24; extra == "testing"
|
|
18
|
+
|
|
19
|
+
# SignalProcessingTools
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
A comprehensive Python package for time and space domain signal processing operations with a focus on vibration analysis and frequency-domain transformations.
|
|
24
|
+
The space domain operations focus on railway applications, while the time domain operations are more general.
|
|
25
|
+
|
|
26
|
+
## Overview
|
|
27
|
+
|
|
28
|
+
SignalProcessingTools provides a suite of tools for analyzing, transforming, and processing data.
|
|
29
|
+
|
|
30
|
+
### Time domain operations:
|
|
31
|
+
* Fast Fourier Transforms (FFT) and inverse FFT
|
|
32
|
+
* Signal filtering
|
|
33
|
+
* Integration
|
|
34
|
+
* Power Spectral Density (PSD) using Welch's method
|
|
35
|
+
* Spectrogram generation
|
|
36
|
+
* Effective velocity calculations using SBR method
|
|
37
|
+
* 1/3 octave band analysis
|
|
38
|
+
* Windowing functions (Hann, Hamming, Blackman, etc.)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Space domain operations:
|
|
42
|
+
* D0, D1, D2, and D3 track longitudinal levels, following EN 13848-1:2006.
|
|
43
|
+
* Hmax and Hrms according to Zandberg et al. (2022).
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
### Install from PyPI
|
|
48
|
+
You can install the package directly from PyPI using pip:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install SignalProcessingTools
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Install from Source
|
|
55
|
+
To install the package from the source, clone the repository and run the following commands:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/PlatypusBytes/SignalProcessing.git
|
|
59
|
+
cd SignalProcessing
|
|
60
|
+
pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
### Basic Example of Time Domain Operations
|
|
66
|
+
|
|
67
|
+
#### FFT and signal integration
|
|
68
|
+
```python
|
|
69
|
+
import numpy as np
|
|
70
|
+
from SignalProcessingTools.time_signal import SignalProcessing, Windows
|
|
71
|
+
|
|
72
|
+
# Create a test signal
|
|
73
|
+
t = np.linspace(0, 10, 5001)
|
|
74
|
+
y = 1.75 * np.sin(2 * np.pi * 6 * t)
|
|
75
|
+
|
|
76
|
+
# Initialize the signal processor
|
|
77
|
+
sig = SignalProcessing(t, y)
|
|
78
|
+
|
|
79
|
+
# Perform FFT
|
|
80
|
+
sig.fft()
|
|
81
|
+
|
|
82
|
+
# Integrate the signal
|
|
83
|
+
sig.integrate(baseline=True, hp=True, fpass=1, n=6)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Windowed Processing and PSD and spectrogram
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
# Create a signal processor with Hamming window
|
|
90
|
+
sig = SignalProcessing(t, y, window=Windows.HAMMING, window_size=4096)
|
|
91
|
+
|
|
92
|
+
# Calculate Power Spectral Density
|
|
93
|
+
sig.psd()
|
|
94
|
+
|
|
95
|
+
# Generate a spectrogram
|
|
96
|
+
sig.spectrogram()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Signal Filtering
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
# Apply a low-pass filter to remove high frequency noise
|
|
103
|
+
sig.filter(10, 4, type_filter="lowpass")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Effective Velocity Calculation (SBR-B Method)
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
# Calculate effective velocity using SBR method
|
|
110
|
+
sig.v_eff_SBR()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Basic Example of Spatial Domain Operations
|
|
114
|
+
|
|
115
|
+
#### D0, D1, D2, and D3 Calculation
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
import numpy as np
|
|
119
|
+
from SignalProcessingTools.space_signal import SpatialSignal
|
|
120
|
+
from SignalProcessingTools.space_signal import EN13848
|
|
121
|
+
|
|
122
|
+
# Create test data
|
|
123
|
+
x = np.linspace(0, 100, 50001)
|
|
124
|
+
omega = 2 * np.pi * 6
|
|
125
|
+
y = 1.75 * np.sin(omega * x)
|
|
126
|
+
y_noise = y + 0.01 * np.sin(120 * x)
|
|
127
|
+
|
|
128
|
+
sig = SpaceSignalProcessing(x, y_noise)
|
|
129
|
+
# Compute track longitudinal levels
|
|
130
|
+
sig.compute_track_longitudinal_levels()
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### Hmax and Hrms Calculation
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
x_track = np.linspace(0, 500, 25001)
|
|
137
|
+
track_irregularity = (
|
|
138
|
+
0.002 * np.sin(2 * np.pi * 0.1 * x_track) +
|
|
139
|
+
0.001 * np.sin(2 * np.pi * 0.2 * x_track) +
|
|
140
|
+
0.0005 * np.sin(2 * np.pi * 0.4 * x_track) +
|
|
141
|
+
0.0002 * np.random.randn(len(x_track))
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
sig_hmax = SpaceSignalProcessing(x_track, track_irregularity)
|
|
145
|
+
# Compute Hmax parameters
|
|
146
|
+
sig_hmax.compute_Hmax(convert_m2mm=True)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Example Files
|
|
150
|
+
|
|
151
|
+
A comprehensive example demonstrating all features is provided for the [time signal](./example_time_signal.py) and [space signal](./example_space_signal.py).
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
This project is licensed under the MIT License - see the License file for details.
|
|
157
|
+
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# SignalProcessingTools
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
A comprehensive Python package for time and space domain signal processing operations with a focus on vibration analysis and frequency-domain transformations.
|
|
6
|
+
The space domain operations focus on railway applications, while the time domain operations are more general.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
SignalProcessingTools provides a suite of tools for analyzing, transforming, and processing data.
|
|
11
|
+
|
|
12
|
+
### Time domain operations:
|
|
13
|
+
* Fast Fourier Transforms (FFT) and inverse FFT
|
|
14
|
+
* Signal filtering
|
|
15
|
+
* Integration
|
|
16
|
+
* Power Spectral Density (PSD) using Welch's method
|
|
17
|
+
* Spectrogram generation
|
|
18
|
+
* Effective velocity calculations using SBR method
|
|
19
|
+
* 1/3 octave band analysis
|
|
20
|
+
* Windowing functions (Hann, Hamming, Blackman, etc.)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Space domain operations:
|
|
24
|
+
* D0, D1, D2, and D3 track longitudinal levels, following EN 13848-1:2006.
|
|
25
|
+
* Hmax and Hrms according to Zandberg et al. (2022).
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
### Install from PyPI
|
|
30
|
+
You can install the package directly from PyPI using pip:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install SignalProcessingTools
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Install from Source
|
|
37
|
+
To install the package from the source, clone the repository and run the following commands:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git clone https://github.com/PlatypusBytes/SignalProcessing.git
|
|
41
|
+
cd SignalProcessing
|
|
42
|
+
pip install -e .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
### Basic Example of Time Domain Operations
|
|
48
|
+
|
|
49
|
+
#### FFT and signal integration
|
|
50
|
+
```python
|
|
51
|
+
import numpy as np
|
|
52
|
+
from SignalProcessingTools.time_signal import SignalProcessing, Windows
|
|
53
|
+
|
|
54
|
+
# Create a test signal
|
|
55
|
+
t = np.linspace(0, 10, 5001)
|
|
56
|
+
y = 1.75 * np.sin(2 * np.pi * 6 * t)
|
|
57
|
+
|
|
58
|
+
# Initialize the signal processor
|
|
59
|
+
sig = SignalProcessing(t, y)
|
|
60
|
+
|
|
61
|
+
# Perform FFT
|
|
62
|
+
sig.fft()
|
|
63
|
+
|
|
64
|
+
# Integrate the signal
|
|
65
|
+
sig.integrate(baseline=True, hp=True, fpass=1, n=6)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Windowed Processing and PSD and spectrogram
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
# Create a signal processor with Hamming window
|
|
72
|
+
sig = SignalProcessing(t, y, window=Windows.HAMMING, window_size=4096)
|
|
73
|
+
|
|
74
|
+
# Calculate Power Spectral Density
|
|
75
|
+
sig.psd()
|
|
76
|
+
|
|
77
|
+
# Generate a spectrogram
|
|
78
|
+
sig.spectrogram()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Signal Filtering
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# Apply a low-pass filter to remove high frequency noise
|
|
85
|
+
sig.filter(10, 4, type_filter="lowpass")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Effective Velocity Calculation (SBR-B Method)
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
# Calculate effective velocity using SBR method
|
|
92
|
+
sig.v_eff_SBR()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Basic Example of Spatial Domain Operations
|
|
96
|
+
|
|
97
|
+
#### D0, D1, D2, and D3 Calculation
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
import numpy as np
|
|
101
|
+
from SignalProcessingTools.space_signal import SpatialSignal
|
|
102
|
+
from SignalProcessingTools.space_signal import EN13848
|
|
103
|
+
|
|
104
|
+
# Create test data
|
|
105
|
+
x = np.linspace(0, 100, 50001)
|
|
106
|
+
omega = 2 * np.pi * 6
|
|
107
|
+
y = 1.75 * np.sin(omega * x)
|
|
108
|
+
y_noise = y + 0.01 * np.sin(120 * x)
|
|
109
|
+
|
|
110
|
+
sig = SpaceSignalProcessing(x, y_noise)
|
|
111
|
+
# Compute track longitudinal levels
|
|
112
|
+
sig.compute_track_longitudinal_levels()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Hmax and Hrms Calculation
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
x_track = np.linspace(0, 500, 25001)
|
|
119
|
+
track_irregularity = (
|
|
120
|
+
0.002 * np.sin(2 * np.pi * 0.1 * x_track) +
|
|
121
|
+
0.001 * np.sin(2 * np.pi * 0.2 * x_track) +
|
|
122
|
+
0.0005 * np.sin(2 * np.pi * 0.4 * x_track) +
|
|
123
|
+
0.0002 * np.random.randn(len(x_track))
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
sig_hmax = SpaceSignalProcessing(x_track, track_irregularity)
|
|
127
|
+
# Compute Hmax parameters
|
|
128
|
+
sig_hmax.compute_Hmax(convert_m2mm=True)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Example Files
|
|
132
|
+
|
|
133
|
+
A comprehensive example demonstrating all features is provided for the [time signal](./example_time_signal.py) and [space signal](./example_space_signal.py).
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
This project is licensed under the MIT License - see the License file for details.
|
|
139
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .__version__ import __version__
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from typing import Optional, List, Tuple
|
|
2
|
+
import numpy as np
|
|
3
|
+
import numpy.typing as npt
|
|
4
|
+
from .time_signal import TimeSignalProcessing, FilterDesign, Windows
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SpaceSignalProcessing:
|
|
8
|
+
"""
|
|
9
|
+
SignalProcessing class for processing signals in space.
|
|
10
|
+
"""
|
|
11
|
+
def __init__(self, x: npt.NDArray[np.float64], values: npt.NDArray[np.float64], Fs: Optional[float] = None):
|
|
12
|
+
"""
|
|
13
|
+
Initializes the ProcessSignal object.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
:param x (npt.NDArray[np.float64]): coordinates of the signal
|
|
18
|
+
:param values (npt.NDArray[np.float64]): signal values
|
|
19
|
+
:param Fs (Optional[float]): sampling frequency of the signal (optional: default None)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
self.coordinates = x
|
|
23
|
+
self.signal_raw = values
|
|
24
|
+
self.n_points = values.shape[0]
|
|
25
|
+
|
|
26
|
+
# acquisition frequency
|
|
27
|
+
if Fs is None:
|
|
28
|
+
self.fs = int(np.ceil(1 / np.mean(np.diff(x))))
|
|
29
|
+
|
|
30
|
+
else:
|
|
31
|
+
self.fs = Fs
|
|
32
|
+
|
|
33
|
+
# track quality indexes
|
|
34
|
+
self.d0 = None
|
|
35
|
+
self.d1 = None
|
|
36
|
+
self.d2 = None
|
|
37
|
+
self.d3 = None
|
|
38
|
+
# track descriptors
|
|
39
|
+
self.rms_bands = None
|
|
40
|
+
self.max_fast = None
|
|
41
|
+
self.max_fast_Dx = None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def compute_track_longitudinal_levels(self):
|
|
45
|
+
"""
|
|
46
|
+
Computes the track longitudinal levels, following EN 13848-1:2006.
|
|
47
|
+
|
|
48
|
+
The method computes the D0, D1, D2, and D3 components of the signal.
|
|
49
|
+
It uses the following frequency bands:
|
|
50
|
+
- D0: 1m < lambda <= 5m (1/5 Hz < f <= 1 Hz)
|
|
51
|
+
- D1: 3m < lambda <= 25m (1/25 Hz < f <= 1/3 Hz)
|
|
52
|
+
- D2: 25m < lambda <= 70m (1/70 Hz < f <= 1/25 Hz)
|
|
53
|
+
- D3: 70m < lambda <= 150m (1/150 Hz < f <= 1/70 Hz)
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
sig = TimeSignalProcessing(self.coordinates, self.signal_raw, Fs=self.fs)
|
|
57
|
+
sig.filter([1/5., 1.], 4, type_filter="bandpass", filter_design=FilterDesign.BUTTERWORTH)
|
|
58
|
+
self.d0 = sig.signal
|
|
59
|
+
|
|
60
|
+
sig.reset()
|
|
61
|
+
sig.filter([1/25., 1/3.], 4, type_filter="bandpass", filter_design=FilterDesign.BUTTERWORTH)
|
|
62
|
+
self.d1 = sig.signal
|
|
63
|
+
sig.reset()
|
|
64
|
+
|
|
65
|
+
sig.filter([1/70., 1/25.], 4, type_filter="bandpass", filter_design=FilterDesign.BUTTERWORTH)
|
|
66
|
+
self.d2 = sig.signal
|
|
67
|
+
sig.reset()
|
|
68
|
+
|
|
69
|
+
sig.filter([1/150., 1/70.], 4, type_filter="bandpass", filter_design=FilterDesign.BUTTERWORTH)
|
|
70
|
+
self.d3 = sig.signal
|
|
71
|
+
sig.reset()
|
|
72
|
+
|
|
73
|
+
def compute_Hmax(self, convert_m2mm: bool = True):
|
|
74
|
+
"""
|
|
75
|
+
Computes the descriptor Hmax and Hrms according to Zandberg et al. (2022)
|
|
76
|
+
'Deriving parameters for the characterisation of the railway track quality in
|
|
77
|
+
relation to environmental vibration'
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
:param convert_m2mm (optional, default = True): if True, converts the results from m to mm
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
# octave bands used for the processing
|
|
85
|
+
one_third_octave_bands = [[.08, .10],
|
|
86
|
+
[.10, .126],
|
|
87
|
+
[.126, .16],
|
|
88
|
+
[.16, .20],
|
|
89
|
+
[.20, .253],
|
|
90
|
+
[.253, .32],
|
|
91
|
+
[.32, .40],
|
|
92
|
+
[.40, .50],
|
|
93
|
+
[.50, .63],
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# setting for the processing
|
|
98
|
+
self.DXmaxFast = 1
|
|
99
|
+
nb_fft_min = 256 # minimum number of samples for the power spectral density
|
|
100
|
+
derivative = [0, 0, 0, 2, 2, 2, 2, 2, 2] # number of times that each frequency band is derived
|
|
101
|
+
|
|
102
|
+
# RMS of the square root of the power spectral density
|
|
103
|
+
self.rms_bands = np.zeros(len(one_third_octave_bands))
|
|
104
|
+
# maximum effective value over the entire signal
|
|
105
|
+
self.max_fast = np.zeros(len(one_third_octave_bands))
|
|
106
|
+
# maximum effective value over the length Dx
|
|
107
|
+
self.max_fast_Dx = np.zeros(len(one_third_octave_bands))
|
|
108
|
+
|
|
109
|
+
# convert the signal from m to mm
|
|
110
|
+
if convert_m2mm:
|
|
111
|
+
self.signal = self.signal_raw * 1000
|
|
112
|
+
|
|
113
|
+
# compute the power spectral density
|
|
114
|
+
n_fft = int(np.max([2 ** (np.ceil(np.log2(len(self.signal)))), nb_fft_min]))
|
|
115
|
+
# if signal is odd length, add a zero to make it even
|
|
116
|
+
if len(self.signal) % 2 != 0:
|
|
117
|
+
signal = np.append(self.signal, 0)
|
|
118
|
+
coordinates = np.append(self.coordinates, self.coordinates[-1] + (self.coordinates[1] - self.coordinates[0]))
|
|
119
|
+
else:
|
|
120
|
+
signal = self.signal
|
|
121
|
+
coordinates = self.coordinates
|
|
122
|
+
sig = TimeSignalProcessing(coordinates, signal, Fs=self.fs, window=Windows.HAMMING,
|
|
123
|
+
window_size=len(signal))
|
|
124
|
+
sig.psd(nb_points=n_fft, detrend=False)
|
|
125
|
+
|
|
126
|
+
# compute the rsm psd
|
|
127
|
+
self.__rms_effective(sig.frequency_Pxx, sig.Pxx, one_third_octave_bands, derivative)
|
|
128
|
+
# compute the effective values
|
|
129
|
+
self.__effective_values(one_third_octave_bands, derivative)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def __rms_effective(self, frequency: npt.NDArray[np.float64], Pxx: npt.NDArray[np.float64],
|
|
133
|
+
one_third_octave_bands: List[Tuple[float, float]], derivative: List[int]):
|
|
134
|
+
"""
|
|
135
|
+
Computes RMS square root of power spectral density
|
|
136
|
+
|
|
137
|
+
Parameters
|
|
138
|
+
----------
|
|
139
|
+
:param frequency (npt.NDArray[np.float64]): frequency vector
|
|
140
|
+
:param Pxx (npt.NDArray[np.float64]): power spectral density
|
|
141
|
+
:param one_third_octave_bands (List[Tuple[float, float]]): frequency bands
|
|
142
|
+
:param derivative (List[int]): derivative order
|
|
143
|
+
"""
|
|
144
|
+
# frequency step
|
|
145
|
+
delta_f = frequency[1] - frequency[0]
|
|
146
|
+
|
|
147
|
+
# compute the rms value at each frequency band
|
|
148
|
+
for i, band in enumerate(one_third_octave_bands):
|
|
149
|
+
# find indexes where the bands exist
|
|
150
|
+
idx = np.where((frequency >= band[0]) & (frequency < band[1]))[0]
|
|
151
|
+
Pxx[idx] = (2 * np.pi * frequency[idx]) ** (2 * derivative[i]) * Pxx[idx]
|
|
152
|
+
self.rms_bands[i] = np.sqrt(np.sum(Pxx[idx] * delta_f))
|
|
153
|
+
|
|
154
|
+
def __effective_values(self, one_third_octave_bands: List[Tuple[float, float]], derivative: List[int]):
|
|
155
|
+
"""
|
|
156
|
+
Computes the effective values of the signal
|
|
157
|
+
|
|
158
|
+
Parameters
|
|
159
|
+
----------
|
|
160
|
+
:param one_third_octave_bands (List[Tuple[float, float]]): frequency bands
|
|
161
|
+
:param derivative (List[int]): derivative order
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
n = 4 # number of time constants
|
|
165
|
+
tau = 2 # time constant
|
|
166
|
+
|
|
167
|
+
fout = 1 / (1 - np.exp(-n))
|
|
168
|
+
|
|
169
|
+
dx = self.coordinates[1] - self.coordinates[0]
|
|
170
|
+
|
|
171
|
+
for i, band in enumerate(one_third_octave_bands):
|
|
172
|
+
derivative_value = derivative[i]
|
|
173
|
+
sig = TimeSignalProcessing(self.coordinates, self.signal, Fs=self.fs)
|
|
174
|
+
sig.filter(np.array(band), N=3, type_filter="bandpass", filter_design=FilterDesign.BUTTERWORTH)
|
|
175
|
+
new_signal = sig.signal
|
|
176
|
+
|
|
177
|
+
while derivative_value != 0:
|
|
178
|
+
new_signal = np.diff(new_signal) / dx
|
|
179
|
+
derivative_value -= 1
|
|
180
|
+
|
|
181
|
+
ksi = np.linspace(0, n * tau, int(n * tau / dx + 1))
|
|
182
|
+
g = fout * np.exp(-ksi / tau)
|
|
183
|
+
|
|
184
|
+
convoluted_signal = np.sqrt(np.convolve(new_signal**2, g) * dx / tau)
|
|
185
|
+
self.max_fast[i] = np.max(convoluted_signal)
|
|
186
|
+
idx = np.floor((len(self.signal) - np.floor(self.DXmaxFast / dx)) / 2) + \
|
|
187
|
+
np.linspace(0, np.floor(self.DXmaxFast / dx)-1, int(np.floor(self.DXmaxFast / dx)))
|
|
188
|
+
|
|
189
|
+
self.max_fast_Dx[i] = np.max(convoluted_signal[idx.astype(int)])
|