PowerSpectra¶
- class acoular.spectra.PowerSpectra¶
Bases:
BaseSpectra
Provides the cross-spectral matrix of multichannel time-domain data and its eigen-decomposition.
This class is designed to compute the cross-spectral matrix (CSM) efficiently using the Welch method [19] with support for windowing and overlapping data segments. It also calculates the eigenvalues and eigenvectors of the CSM, allowing for spectral analysis and advanced signal processing tasks.
- Key features:
Efficient Calculation: Computes the CSM using FFT-based methods.
Caching: Results can be cached in HDF5 files to avoid redundant calculations for identical inputs and parameters.
Lazy Evaluation: Calculations are triggered only when attributes like
csm
,eva
, oreve
are accessed.Dynamic Input Handling: Automatically recomputes results when the input data or parameters change.
- source = Instance(SamplesGenerator)¶
The data source for the time-domain samples. It must be an instance of
SamplesGenerator
or a derived class.
- ind_low = Property(_ind_low, desc='index of lowest frequency line')¶
Index of lowest frequency line to compute. Default is
1
. Only used by objects that fetch the CSM. PowerSpectra computes every frequency line.
- ind_high = Property(_ind_high, desc='index of lowest frequency line')¶
Index of highest frequency line to compute. Default is
-1
(last possible line for defaultblock_size
).
- cached = Bool(True, desc='cached flag')¶
A flag indicating whether the result should be cached in HDF5 files. Default is
True
.
- num_blocks = Property(desc='overall number of FFT blocks')¶
The number of FFT blocks used for averaging. This is derived from the
block_size
andoverlap
parameters. (read-only)
- freq_range = Property(desc='frequency range')¶
2-element array with the lowest and highest frequency. If the higher frequency is larger than the max frequency, the max frequency will be the upper bound.
- indices = Property(desc='index range')¶
The sequence of frequency indices between
ind_low
andind_high
. (read-only)
- basename = Property(depends_on=['source.digest'], desc='basename for cache file')¶
The name of the cache file (without the file extension) used for storing results. (read-only)
- csm = Property(desc='cross spectral matrix')¶
The cross-spectral matrix, represented as an array of shape
(n, m, m)
of complex values forn
frequencies andm
channels as innum_channels
. (read-only)
- eva = Property(desc='eigenvalues of cross spectral matrix')¶
The eigenvalues of the CSM, stored as an array of shape
(n,)
of floats forn
frequencies. (read-only)
- eve = Property(desc='eigenvectors of cross spectral matrix')¶
The eigenvectors of the cross spectral matrix, stored as an array of shape
(n, m, m)
of floats forn
frequencies andm
channels as innum_channels
. (read-only)
- digest = Property( …¶
A unique identifier for the spectra, based on its properties. (read-only)
- h5f = Instance(H5CacheFileBase, transient=True)¶
The HDF5 cache file used for storing the results if
cached
is set toTrue
.
- calc_csm()¶
Calculate the CSM for the given source data.
This method computes the CSM by performing a block-wise Fast Fourier Transform (FFT) on the source data, applying a window function, and averaging the results. Only the upper triangular part of the matrix is computed for efficiency, and the lower triangular part is constructed via transposition and complex conjugation.
- Returns:
numpy.ndarray
The computed cross spectral matrix as an array of shape
(n, m, m)
of complex values forn
frequencies andm
channels as innum_channels
.
Examples
>>> import numpy as np >>> from acoular import TimeSamples >>> from acoular.spectra import PowerSpectra >>> >>> data = np.random.rand(1000, 4) >>> ts = TimeSamples(data=data, sample_freq=51200) >>> print(ts.num_channels, ts.num_samples, ts.sample_freq) 4 1000 51200.0 >>> ps = PowerSpectra(source=ts, block_size=128, window='Blackman') >>> ps.csm.shape (65, 4, 4)
- calc_ev()¶
Calculate eigenvalues and eigenvectors of the CSM for each frequency.
The eigenvalues represent the spectral power, and the eigenvectors correspond to the principal components of the matrix. This calculation is performed for all frequency slices of the CSM.
- Returns:
tuple
ofnumpy.ndarray
- A tuple containing:
eva
(numpy.ndarray
): Eigenvalues as a 2D array of shape(n, m)
, wheren
is the number of frequencies andm
is the number of channels. The datatype depends on the precision.eve
(numpy.ndarray
): Eigenvectors as a 3D array of shape(n, m, m)
. The datatype is consistent with the precision of the input data.
Notes
The precision of the eigenvalues is determined by
precision
('float64'
forcomplex128
precision and'float32'
forcomplex64
precision).This method assumes the CSM is already computed and accessible via
csm
.
Examples
>>> import numpy as np >>> from acoular import TimeSamples >>> from acoular.spectra import PowerSpectra >>> >>> data = np.random.rand(1000, 4) >>> ts = TimeSamples(data=data, sample_freq=51200) >>> ps = PowerSpectra(source=ts, block_size=128, window='Hanning') >>> eva, eve = ps.calc_ev() >>> print(eva.shape, eve.shape) (65, 4) (65, 4, 4)
- calc_eva()¶
Calculate eigenvalues of the CSM.
This method computes and returns the eigenvalues of the CSM for all frequency slices.
- Returns:
numpy.ndarray
A 2D array of shape
(n, m)
containing the eigenvalues forn
frequencies andm
channels. The datatype depends onprecision
('float64'
forcomplex128
precision and'float32'
forcomplex64
precision).
Notes
This method internally calls
calc_ev()
and extracts only the eigenvalues.
- calc_eve()¶
Calculate eigenvectors of the Cross Spectral Matrix (CSM).
This method computes and returns the eigenvectors of the CSM for all frequency slices.
- Returns:
numpy.ndarray
A 3D array of shape
(n, m, m)
containing the eigenvectors forn
frequencies andm
channels. Each sliceeve[f]
represents an(m, m)
matrix of eigenvectors for frequencyf
. The datatype matches theprecision
of the CSM (complex128
orcomplex64
).
Notes
This method internally calls
calc_ev()
and extracts only the eigenvectors.
- synthetic_ev(freq, num=0)¶
Retrieve synthetic eigenvalues for a specified frequency or frequency range.
This method calculates the eigenvalues of the CSM for a single frequency or a synthetic frequency range. If
num
is set to0
, it retrieves the eigenvalues at the exact frequency. Otherwise, it averages eigenvalues across a range determined byfreq
andnum
.- Parameters:
- freq
float
The target frequency for which the eigenvalues are calculated. This is the center frequency for synthetic averaging.
- num
int
, optional The number of subdivisions in the logarithmic frequency space around the center frequency
freq
.0
(default): Only the eigenvalues for the exact frequency line are returned.Non-zero:
num
frequency band width
0
single frequency line
1
octave band
3
third-octave band
n
1/n-octave band
- freq
- Returns:
numpy.ndarray
An array of eigenvalues. If
num == 0
, the eigenvalues for the single frequency are returned. Fornum > 0
, a summed array of eigenvalues across the synthetic frequency range is returned.
Examples
>>> import numpy as np >>> from acoular import TimeSamples >>> from acoular.spectra import PowerSpectra >>> np.random.seed(0) >>> >>> data = np.random.rand(1000, 4) >>> ts = TimeSamples(data=data, sample_freq=51200) >>> ps = PowerSpectra(source=ts, block_size=128, window='Hamming') >>> ps.synthetic_ev(freq=5000, num=5) array([0.00048803, 0.0010141 , 0.00234248, 0.00457097]) >>> ps.synthetic_ev(freq=5000) array([0.00022468, 0.0004589 , 0.00088059, 0.00245989])