SignalForge 0.0.2__tar.gz → 1.0.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.
- signalforge-1.0.0/PKG-INFO +157 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/README.md +8 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge/__init__.py +1 -1
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge/nonstationary_nongaussian.py +80 -17
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge/single_chan_signal.py +214 -100
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge/stationary_gaussian.py +26 -0
- signalforge-1.0.0/SignalForge/stationary_nongaussian.py +1438 -0
- signalforge-1.0.0/SignalForge/utils.py +1165 -0
- signalforge-1.0.0/SignalForge.egg-info/PKG-INFO +157 -0
- signalforge-1.0.0/pyproject.toml +39 -0
- signalforge-0.0.2/PKG-INFO +0 -23
- signalforge-0.0.2/SignalForge/stationary_nongaussian.py +0 -934
- signalforge-0.0.2/SignalForge/utils.py +0 -526
- signalforge-0.0.2/SignalForge.egg-info/PKG-INFO +0 -23
- signalforge-0.0.2/pyproject.toml +0 -3
- {signalforge-0.0.2 → signalforge-1.0.0}/LICENSE +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/MANIFEST.in +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge.egg-info/SOURCES.txt +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge.egg-info/dependency_links.txt +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge.egg-info/requires.txt +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/SignalForge.egg-info/top_level.txt +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/requirements.txt +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/setup.cfg +0 -0
- {signalforge-0.0.2 → signalforge-1.0.0}/setup.py +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: SignalForge
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A comprehensive Python package for generating and analyzing non-Gaussian and non-stationary signals.
|
|
5
|
+
Home-page: https://github.com/GiulioCurti/SignalForge
|
|
6
|
+
Author: Giulio Curti
|
|
7
|
+
Author-email: Giulio Curti <giulio.curti@dottorandi.unipg.it>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/GiulioCurti/SignalForge
|
|
10
|
+
Project-URL: Documentation, https://signalforge.readthedocs.io/
|
|
11
|
+
Project-URL: Repository, https://github.com/GiulioCurti/SignalForge.git
|
|
12
|
+
Project-URL: Bug-Tracker, https://github.com/GiulioCurti/SignalForge/issues
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
18
|
+
Requires-Python: >=3.8
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: numpy>=2.0
|
|
22
|
+
Requires-Dist: scipy
|
|
23
|
+
Requires-Dist: matplotlib>=3.10
|
|
24
|
+
Requires-Dist: tqdm
|
|
25
|
+
Requires-Dist: PyWavelets
|
|
26
|
+
Requires-Dist: pyNNST
|
|
27
|
+
Requires-Dist: statsmodels
|
|
28
|
+
Dynamic: author
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
[](https://github.com/GiulioCurti/SignalForge/actions/workflows/python-app.yml)
|
|
33
|
+
[](https://signalforge.readthedocs.io/en/latest/)
|
|
34
|
+
|
|
35
|
+
SignalForge
|
|
36
|
+
-----------
|
|
37
|
+
|
|
38
|
+
SignalForge is an open-source Python package that provides a comprehensive set of tools for analyzing and generating non-Gaussian, non-stationary signals in engineering applications. While traditional signal processing methods often rely on assumptions of Gaussianity and stationarity, real-world signals—especially those found in mechanical systems—frequently deviate from these idealized models. SignalForge bridges this gap by offering advanced, yet user-friendly tools to simulate, inspect, and manipulate signals with complex statistical properties. Whether you're designing loads for testing, exploring time-varying behavior, or developing new algorithms, SignalForge enables you to work with signals that better reflect real operating conditions. Built with extensibility and clarity in mind, the package is suitable for researchers, practitioners, and students working across mechanical engineering, signal processing, and beyond.
|
|
39
|
+
|
|
40
|
+
See the [documentation](<https://signalforge.readthedocs.io/en/latest/>) for a complete overview of the implemented methods for analisys and signal generation.
|
|
41
|
+
|
|
42
|
+
Installing SignalForge
|
|
43
|
+
------------------------------------------------------------
|
|
44
|
+
The package is published in PiPy. To install it:
|
|
45
|
+
```bash
|
|
46
|
+
pip install signalforge
|
|
47
|
+
```
|
|
48
|
+
or you can clone it from GitHub
|
|
49
|
+
```bash
|
|
50
|
+
git clone https://github.com/GiulioCurti/SignalForge.git
|
|
51
|
+
```
|
|
52
|
+
and locally install it from inside the folder SignalForge
|
|
53
|
+
```bash
|
|
54
|
+
pip install -e .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Example code on how to generate a Stationary Gaussian Signal
|
|
58
|
+
------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
Stationary Gaussian signals can be easily generated via the specific class StationaryGaussian. Its usage is briefly shown in the following example code:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from SignalForge import StationaryGaussian
|
|
64
|
+
|
|
65
|
+
fpsd = [10,20] # Frequency vector [Hz]
|
|
66
|
+
psd = [1,1] # Power density vecrtor [(m/s^2)^2/Hz]
|
|
67
|
+
fs = 200 # Sampling frequency [Hz]
|
|
68
|
+
T = 200 # Time duration [s]
|
|
69
|
+
gauss_signal = StationaryGaussian(
|
|
70
|
+
fpsd=fpsd,
|
|
71
|
+
psd=psd,
|
|
72
|
+
fs=fs,
|
|
73
|
+
T = T,
|
|
74
|
+
name = 'Stationary Gaussian',
|
|
75
|
+
unit='$m/s^2$'
|
|
76
|
+
) # StationaryGaussian class initialization
|
|
77
|
+
print(gauss_signal)
|
|
78
|
+
gauss_signal.plot() # Plotting Timehistory
|
|
79
|
+
gauss_signal.plot_psd() # Plotting Power spectral density
|
|
80
|
+
```
|
|
81
|
+
Implemented non-linear transformartion methods to add non-gaussianity are the following:
|
|
82
|
+
|
|
83
|
+
- Hermite-Winterstein ('winter')
|
|
84
|
+
- Cubic polynomial ('cubic')
|
|
85
|
+
- Hyperbolic transform – Zheng (‘zheng’)
|
|
86
|
+
- Sarkani ('sarkani')
|
|
87
|
+
- Improved nonlinear transform ('zmnl')
|
|
88
|
+
- Steinwolf ('steinwolf')
|
|
89
|
+
- Smallwoood Poisson shots ('smallwood')
|
|
90
|
+
- Van Baren ('vanbaren')
|
|
91
|
+
|
|
92
|
+
Example code on how to generate a Stationary Non Gaussian Signal
|
|
93
|
+
------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
Stationary non Gaussian signals can be easily generated via the specific class StationaryNonGaussian. Its usage is briefly shown in the following example code:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from SignalForge import StationaryNonGaussian
|
|
99
|
+
|
|
100
|
+
fpsd = [10,20] # Frequency vector [Hz]
|
|
101
|
+
psd = [1,1] # Power density vecrtor [(m/s^2)^2/Hz]
|
|
102
|
+
fs = 200 # Sampling frequency [Hz]
|
|
103
|
+
T = 200 # Time duration [s]
|
|
104
|
+
input_kurtosis = 6
|
|
105
|
+
nongauss_signal = StationaryNonGaussian(
|
|
106
|
+
fpsd = fpsd,
|
|
107
|
+
psd = psd,
|
|
108
|
+
T = T,
|
|
109
|
+
kurtosis=input_kurtosis,
|
|
110
|
+
fs = fs,
|
|
111
|
+
method='zmnl',
|
|
112
|
+
name = 'Stationary NonGaussian',
|
|
113
|
+
unit='$m/s^2$'
|
|
114
|
+
) # StationaryNonGaussian class initalization
|
|
115
|
+
print(nongauss_signal)
|
|
116
|
+
nongauss_signal.plot() # Plotting Timehistory
|
|
117
|
+
nongauss_signal.plot_psd() # Plotting Power spectral density
|
|
118
|
+
nongauss_signal.plot_fft() # Plotting Fourier Transform
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Example code on how to generate a Non Stationary Non Gaussian Signal
|
|
122
|
+
------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
Non stationary non Gaussian signals can be easily generated via the specific class NonStationaryGaussian. Its usage is briefly shown in the following example code:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from SignalForge import NonStationaryNonGaussian
|
|
128
|
+
|
|
129
|
+
fpsd = [10,20] # Frequency vector [Hz]
|
|
130
|
+
psd = [1,1] # Power density vecrtor [(m/s^2)^2/Hz]
|
|
131
|
+
fs = 200 # Sampling frequency [Hz]
|
|
132
|
+
T = 200 # Time duration [s]
|
|
133
|
+
params = {'input_kurtosis': 10}
|
|
134
|
+
nonstat_signal = NonStationaryNonGaussian(
|
|
135
|
+
fpsd = fpsd,
|
|
136
|
+
psd = psd,
|
|
137
|
+
T = T,
|
|
138
|
+
params = params,
|
|
139
|
+
fs = fs,
|
|
140
|
+
method='trapp_am',
|
|
141
|
+
name = 'NonStationary NonGaussian',
|
|
142
|
+
unit='$m/s^2$'
|
|
143
|
+
) # NonStationaryNonGaussian class initalization
|
|
144
|
+
print(nonstat_signal)
|
|
145
|
+
nonstat_signal.plot() # Plotting Timehistory
|
|
146
|
+
nonstat_signal.plot_psd() # Plotting Timehistory
|
|
147
|
+
nonstat_signal.plot_sftf() # Plotting Short Time Fourier Transform
|
|
148
|
+
```
|
|
149
|
+
Implemented transformartion methods to build non-gaussianity signals are the following:
|
|
150
|
+
|
|
151
|
+
- Beta amplitude modulation ('beta_am')
|
|
152
|
+
- Gaussian amplitude modulation ('trapp_am')
|
|
153
|
+
- Rayleigh amplitude modulation ('ray_am')
|
|
154
|
+
- Frequency modulation via STFT ('fm')
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
@@ -14,6 +14,14 @@ The package is published in PiPy. To install it:
|
|
|
14
14
|
```bash
|
|
15
15
|
pip install signalforge
|
|
16
16
|
```
|
|
17
|
+
or you can clone it from GitHub
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/GiulioCurti/SignalForge.git
|
|
20
|
+
```
|
|
21
|
+
and locally install it from inside the folder SignalForge
|
|
22
|
+
```bash
|
|
23
|
+
pip install -e .
|
|
24
|
+
```
|
|
17
25
|
|
|
18
26
|
Example code on how to generate a Stationary Gaussian Signal
|
|
19
27
|
------------------------------------------------------------
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import scipy as sp
|
|
3
1
|
import matplotlib.pyplot as plt
|
|
4
|
-
from tqdm import tqdm
|
|
5
2
|
|
|
6
3
|
from .utils import *
|
|
7
4
|
from .single_chan_signal import SingleChanSignal
|
|
@@ -267,12 +264,48 @@ def get_trapp_amplitude_modulation(
|
|
|
267
264
|
A. Trapp, M. J. Makua, e P. Wolfsteiner, «Fatigue assessment of amplitude-modulated non-stationary random vibration loading», Procedia Struct. Integr., vol. 17, pp. 379–386, 2019, doi: 10.1016/j.prostr.2019.08.050.
|
|
268
265
|
"""
|
|
269
266
|
def get_trapp_carrier(p, delta_m, gaussian_carier):
|
|
270
|
-
"""
|
|
267
|
+
"""
|
|
268
|
+
Generate amplitude modulation carrier based on power-law transformation.
|
|
269
|
+
|
|
270
|
+
Parameters
|
|
271
|
+
----------
|
|
272
|
+
p : float
|
|
273
|
+
Exponent for the power-law transformation.
|
|
274
|
+
delta_m : float
|
|
275
|
+
Offset for the amplitude modulation.
|
|
276
|
+
gaussian_carier : np.ndarray
|
|
277
|
+
The Gaussian carrier signal.
|
|
278
|
+
|
|
279
|
+
Returns
|
|
280
|
+
-------
|
|
281
|
+
np.ndarray
|
|
282
|
+
The transformed Rayleigh carrier signal.
|
|
283
|
+
"""
|
|
271
284
|
ray_carrier = np.abs(gaussian_carier)**p+delta_m
|
|
272
285
|
return ray_carrier
|
|
273
286
|
|
|
274
287
|
def trapp_am_opt_fun(params, gauss_carrier, input_kurtosis):
|
|
275
|
-
"""
|
|
288
|
+
"""
|
|
289
|
+
Optimization objective function for Trapp amplitude modulation.
|
|
290
|
+
|
|
291
|
+
This function calculates the absolute difference between the transformed
|
|
292
|
+
signal's kurtosis and skewness and the target values.
|
|
293
|
+
|
|
294
|
+
Parameters
|
|
295
|
+
----------
|
|
296
|
+
params : list
|
|
297
|
+
Parameters for the `get_trapp_carrier` function.
|
|
298
|
+
gauss_carrier : np.ndarray
|
|
299
|
+
The Gaussian carrier signal.
|
|
300
|
+
input_kurtosis : float
|
|
301
|
+
The target kurtosis.
|
|
302
|
+
|
|
303
|
+
Returns
|
|
304
|
+
-------
|
|
305
|
+
float
|
|
306
|
+
The absolute difference between the transformed signal's kurtosis and skewness
|
|
307
|
+
and the target values.
|
|
308
|
+
"""
|
|
276
309
|
carrier = get_trapp_carrier(*params, gaussian_carier=gauss_carrier)
|
|
277
310
|
nonstat_sign = _add_am_carrier(gauss_signal, carrier)
|
|
278
311
|
transformed_kurtosis = sp.stats.kurtosis(nonstat_sign) + 3
|
|
@@ -386,19 +419,49 @@ class NonStationaryNonGaussian(SingleChanSignal):
|
|
|
386
419
|
PSD interpolation method: 'lin' or 'log'. Default is 'lin'.
|
|
387
420
|
"""
|
|
388
421
|
def __init__(
|
|
389
|
-
self,
|
|
390
|
-
fpsd:np.ndarray,
|
|
391
|
-
psd:np.ndarray,
|
|
392
|
-
T:float,
|
|
422
|
+
self,
|
|
423
|
+
fpsd:np.ndarray,
|
|
424
|
+
psd:np.ndarray,
|
|
425
|
+
T:float,
|
|
393
426
|
fs:float = None,
|
|
394
|
-
dfpsd:float = 0.5,
|
|
395
|
-
method:str = 'beta_am',
|
|
396
|
-
params = None,
|
|
397
|
-
name:str="",
|
|
398
|
-
var:str='x',
|
|
399
|
-
unit:str="$m/s^2$",
|
|
400
|
-
seed:int=None,
|
|
401
|
-
interp:str ='lin'):
|
|
427
|
+
dfpsd:float = 0.5,
|
|
428
|
+
method:str = 'beta_am',
|
|
429
|
+
params = None,
|
|
430
|
+
name:str="",
|
|
431
|
+
var:str='x',
|
|
432
|
+
unit:str="$m/s^2$",
|
|
433
|
+
seed:int=None,
|
|
434
|
+
interp:str ='lin'):
|
|
435
|
+
"""
|
|
436
|
+
Initializes a NonStationaryNonGaussian signal generator.
|
|
437
|
+
|
|
438
|
+
Parameters
|
|
439
|
+
----------
|
|
440
|
+
fpsd : np.ndarray
|
|
441
|
+
Frequency vector for the input PSD.
|
|
442
|
+
psd : np.ndarray
|
|
443
|
+
Power spectral density values.
|
|
444
|
+
T : float
|
|
445
|
+
Total duration of the signal [s].
|
|
446
|
+
fs : float, optional
|
|
447
|
+
Wanted sampling frequency. If None -> 2*fpsd[-1].
|
|
448
|
+
dfpsd : float, optional
|
|
449
|
+
Frequency resolution [Hz]. Default is 0.5.
|
|
450
|
+
method : str, optional
|
|
451
|
+
Modulation method: 'beta_am', 'ray_am', 'trapp_am', or 'fm'. Default is 'beta_am'.
|
|
452
|
+
params : dict, optional
|
|
453
|
+
Dictionary of parameters for the modulation method.
|
|
454
|
+
name : str, optional
|
|
455
|
+
Name of the signal.
|
|
456
|
+
var : str, optional
|
|
457
|
+
Variable symbol, e.g., 'x'.
|
|
458
|
+
unit : str, optional
|
|
459
|
+
Signal unit. Default is '$m/s^2$'.
|
|
460
|
+
seed : int, optional
|
|
461
|
+
Random seed for reproducibility.
|
|
462
|
+
interp : str, optional
|
|
463
|
+
PSD interpolation method: 'lin' or 'log'. Default is 'lin'.
|
|
464
|
+
"""
|
|
402
465
|
|
|
403
466
|
method = method.lower()
|
|
404
467
|
interp = interp.lower()
|