New smoothing implementation, that runs a bit faster
Building, testing and releasing LASP if it has a tag / Build-Test-Ubuntu (push) Failing after -1m19s Details
Building, testing and releasing LASP if it has a tag / Release-Ubuntu (push) Has been skipped Details

This commit is contained in:
Anne de Jong 2024-03-11 16:04:24 +01:00
parent 48d262fbf0
commit 3ec15ec645
3 changed files with 54 additions and 4 deletions

View File

@ -16,6 +16,7 @@ set(lasp_dsp_files
lasp_threadedindatahandler.cpp
lasp_ppm.cpp
lasp_clip.cpp
lasp_freqsmooth.cpp
)

View File

@ -1,13 +1,16 @@
#include <pybind11/pybind11.h>
#include <iostream>
#include "arma_npy.h"
#include "lasp_avpowerspectra.h"
#include "lasp_biquadbank.h"
#include "lasp_fft.h"
#include "lasp_filter.h"
#include "lasp_freqsmoothing.h"
#include "lasp_slm.h"
#include "lasp_streammgr.h"
#include "lasp_window.h"
#include <iostream>
#include <pybind11/pybind11.h>
using std::cerr;
using std::endl;
@ -27,7 +30,6 @@ using rte = std::runtime_error;
*/
void init_dsp(py::module &m) {
py::class_<Fft> fft(m, "Fft");
fft.def(py::init<us>());
fft.def("fft", [](Fft &f, dpyarray dat) {
@ -152,5 +154,12 @@ void init_dsp(py::module &m) {
slm.def("Lmax", [](const SLM &slm) { return ColToNpy<d>(slm.Lmax()); });
slm.def("Lpeak", [](const SLM &slm) { return ColToNpy<d>(slm.Lpeak()); });
slm.def_static("suggestedDownSamplingFac", &SLM::suggestedDownSamplingFac);
// Frequency smoother
m.def("freqSmooth", [](dpyarray freq, dpyarray X, unsigned w) {
vd freqa = NpyToCol<d, false>(freq);
vd Xa = NpyToCol<d, false>(X);
return ColToNpy(freqSmooth(freqa, Xa, w));
});
}
/** @} */

View File

@ -20,6 +20,7 @@ from enum import Enum, unique
import copy
import numpy as np
from numpy import log2, pi, sin
from ..lasp_cpp import freqSmooth
@unique
@ -152,7 +153,7 @@ def smoothCalcMatrix(freq, sw: SmoothingWidth):
return Q
def smoothSpectralData(freq, M, sw: SmoothingWidth,
def smoothSpectralData_old(freq, M, sw: SmoothingWidth,
st: SmoothingType = SmoothingType.levels):
"""
Apply fractional octave smoothing to data in the frequency domain.
@ -220,6 +221,45 @@ def smoothSpectralData(freq, M, sw: SmoothingWidth,
return Psm
def smoothSpectralData(freq, M, sw: SmoothingWidth,
st: SmoothingType = SmoothingType.levels):
"""
Apply fractional octave smoothing to data in the frequency domain.
Args:
freq: array of frequencies of data points [Hz] - equally spaced
M: array of data, either power or dB
the smoothing type `st`, the smoothing is applied.
sw: smoothing width
st: smoothing type = data type of input data
Returns:
freq : array frequencies of data points [Hz]
Msm : float smoothed magnitude of data points
"""
# Safety
if st == SmoothingType.ps:
assert np.min(M) >= 0, 'Power spectrum values cannot be negative'
if st == SmoothingType.levels and isinstance(M.dtype, complex):
raise RuntimeError('Decibel input should be real-valued')
# Convert to power
if st == SmoothingType.levels:
P = 10**(M/10)
elif st == SmoothingType.ps:
P = M
else:
raise RuntimeError(f"Incorrect SmoothingType: {st}")
Psm = freqSmooth(freq, P, sw.value[0])
# Convert to original format
if st == SmoothingType.levels:
Psm = 10*np.log10(Psm)
return Psm
# %% Test
if __name__ == "__main__":