Improved code for cubes. RtAps is not working. Don't know why. TimeBuffer code has better readability. Bugfix in output from Column to Numpy. GIL release for AvPowerSpectra::compute via Pybind.
This commit is contained in:
parent
6aa1262c73
commit
4764a52de8
@ -53,11 +53,11 @@ Daq::Daq(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
||||
if (!config.match(devinfo)) {
|
||||
throw rte("DaqConfiguration does not match device info");
|
||||
}
|
||||
if (neninchannels(false) > ninchannels) {
|
||||
if (neninchannels(false) > devinfo.ninchannels) {
|
||||
throw rte(
|
||||
"Number of enabled input channels is higher than device capability");
|
||||
}
|
||||
if (nenoutchannels() > noutchannels) {
|
||||
if (nenoutchannels() > devinfo.noutchannels) {
|
||||
throw rte(
|
||||
"Number of enabled output channels is higher than device capability");
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ DaqData::DaqData(const us nframes, const us nchannels,
|
||||
DEBUGTRACE_ENTER;
|
||||
DEBUGTRACE_PRINT(sw);
|
||||
|
||||
assert(sw > 0 && sw <= 8);
|
||||
_data = new (std::align_val_t{8}) byte_t[sw * nchannels * nframes];
|
||||
if (!_data) {
|
||||
throw rte("Could not allocate memory for DaqData!");
|
||||
@ -180,15 +181,18 @@ dmat DaqData::toFloat() const {
|
||||
return toFloat<int8_t>();
|
||||
break;
|
||||
case (DataType::dtype_int16):
|
||||
DEBUGTRACE_PRINT("Dtype = int16");
|
||||
return toFloat<int16_t>();
|
||||
break;
|
||||
case (DataType::dtype_int32):
|
||||
return toFloat<int32_t>();
|
||||
break;
|
||||
case (DataType::dtype_fl32):
|
||||
DEBUGTRACE_PRINT("Dtype = float32");
|
||||
return toFloat<float>();
|
||||
break;
|
||||
case (DataType::dtype_fl64):
|
||||
DEBUGTRACE_PRINT("Dtype = float64");
|
||||
return toFloat<double>();
|
||||
break;
|
||||
default:
|
||||
@ -206,5 +210,10 @@ void DaqData::print() const {
|
||||
cout << "First sample of first channel (as float)" << toFloat(0,0) << endl;
|
||||
cout << "Last sample of first channel (as float)" << toFloat(nframes-1,0) << endl;
|
||||
cout << "Last sample of last channel (as float)" << toFloat(nframes-1,nchannels-1) << endl;
|
||||
dmat data = toFloat();
|
||||
vrd max = arma::max(data, 0);
|
||||
vrd min = arma::min(data, 0);
|
||||
cout << "Maximum value in buf: " << max << endl;
|
||||
cout << "Minumum value in buf: " << min << endl;
|
||||
|
||||
}
|
||||
|
@ -260,9 +260,9 @@ public:
|
||||
us monitorOffset = monitorOutput ? 1 : 0;
|
||||
/* /// Put the output monitor in front */
|
||||
if (monitorOutput) {
|
||||
for (us sample = 0; sample < nFramesPerBlock; sample++) {
|
||||
data.value<double>(sample, 0) =
|
||||
buf[totalOffset + sample * nchannels + (nchannels - 1)];
|
||||
for (us frame = 0; frame < nFramesPerBlock; frame++) {
|
||||
data.value<double>(frame, 0) =
|
||||
buf[totalOffset + (frame * nchannels) + (nchannels - 1)];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ PowerSpectra::PowerSpectra(const vd &window)
|
||||
DEBUGTRACE_PRINT(win_pow);
|
||||
}
|
||||
|
||||
arma::Cube<c> PowerSpectra::compute(const dmat &input) {
|
||||
ccube PowerSpectra::compute(const dmat &input) {
|
||||
|
||||
/// Run very often. Silence this one.
|
||||
/* DEBUGTRACE_ENTER; */
|
||||
@ -36,7 +36,7 @@ arma::Cube<c> PowerSpectra::compute(const dmat &input) {
|
||||
|
||||
cmat rfft = _fft.fft(input_tmp);
|
||||
|
||||
arma::cx_cube output(rfft.n_rows, input.n_cols, input.n_cols);
|
||||
ccube output(rfft.n_rows, input.n_cols, input.n_cols);
|
||||
for (us i = 0; i < input.n_cols; i++) {
|
||||
/// This one can be run in parallel without any problem. Note that it is
|
||||
/// the inner loop that is run in parallel.
|
||||
@ -63,6 +63,7 @@ AvPowerSpectra::AvPowerSpectra(const us nfft, const Window::WindowType w,
|
||||
}
|
||||
|
||||
_overlap_keep = (nfft * overlap_percentage) / 100;
|
||||
DEBUGTRACE_PRINT(_overlap_keep);
|
||||
if (_overlap_keep >= nfft) {
|
||||
throw rte("Overlap is too high. Results in no jump. Please "
|
||||
"choose a smaller overlap percentage or a higher nfft");
|
||||
@ -77,39 +78,40 @@ AvPowerSpectra::AvPowerSpectra(const us nfft, const Window::WindowType w,
|
||||
DEBUGTRACE_PRINT(_alpha);
|
||||
}
|
||||
}
|
||||
void AvPowerSpectra::reset() {
|
||||
_timeBuf.reset();
|
||||
_est.reset();
|
||||
|
||||
std::optional<arma::cx_cube> AvPowerSpectra::compute(const dmat &timedata) {
|
||||
}
|
||||
|
||||
/* DEBUGTRACE_ENTER; */
|
||||
/* DEBUGTRACE_PRINT(timedata.n_rows); */
|
||||
/* DEBUGTRACE_PRINT(_ps.nfft); */
|
||||
std::optional<ccube> AvPowerSpectra::compute(const dmat &timedata) {
|
||||
|
||||
DEBUGTRACE_ENTER;
|
||||
DEBUGTRACE_PRINT(timedata.n_rows);
|
||||
DEBUGTRACE_PRINT(_ps.nfft);
|
||||
|
||||
_timeBuf.push(timedata);
|
||||
if (_est.n_cols == 0) {
|
||||
_est = arma::cx_cube(_ps.nfft / 2 + 1, timedata.n_cols, timedata.n_cols,
|
||||
arma::fill::zeros);
|
||||
}
|
||||
|
||||
std::optional<arma::cx_cube> res;
|
||||
|
||||
us i = 0;
|
||||
while (auto samples = _timeBuf.pop(_ps.nfft, _overlap_keep)) {
|
||||
/* DEBUGTRACE_PRINT((int)_mode); */
|
||||
DEBUGTRACE_PRINT((int)_mode);
|
||||
switch (_mode) {
|
||||
case (Mode::Spectrogram): {
|
||||
DEBUGTRACE_PRINT("Spectrogram mode");
|
||||
_est = _ps.compute(samples.value());
|
||||
} break;
|
||||
case (Mode::Averaging): {
|
||||
DEBUGTRACE_PRINT("Averaging mode");
|
||||
n_averages++;
|
||||
if (n_averages == 1) {
|
||||
_est = _ps.compute(samples.value());
|
||||
} else {
|
||||
_est = _est * (static_cast<d>(n_averages - 1) / n_averages) +
|
||||
_est = (static_cast<d>(n_averages - 1) / n_averages) * _est +
|
||||
_ps.compute(samples.value()) / n_averages;
|
||||
}
|
||||
} break;
|
||||
case (Mode::Leaking): {
|
||||
/* DEBUGTRACE_PRINT("Leaking mode"); */
|
||||
DEBUGTRACE_PRINT("Leaking mode");
|
||||
if (arma::size(_est) == arma::size(0, 0, 0)) {
|
||||
_est = _ps.compute(samples.value());
|
||||
} else {
|
||||
@ -124,7 +126,7 @@ std::optional<arma::cx_cube> AvPowerSpectra::compute(const dmat &timedata) {
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
std::optional<arma::cx_cube> AvPowerSpectra::get_est() {
|
||||
std::optional<ccube> AvPowerSpectra::get_est() const {
|
||||
if (_est.n_cols > 0)
|
||||
return _est;
|
||||
return std::nullopt;
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
* can be accessed by: C(f, i, j). Storage is such that frequency components
|
||||
* are contiguous.
|
||||
*/
|
||||
arma::Cube<c> compute(const dmat &input);
|
||||
ccube compute(const dmat &input);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -89,7 +89,7 @@ class AvPowerSpectra {
|
||||
/**
|
||||
* @brief Current estimate of cross-spectral density
|
||||
*/
|
||||
arma::cx_cube _est;
|
||||
ccube _est;
|
||||
|
||||
/**
|
||||
* @brief Buffer of storage of time data.
|
||||
@ -128,7 +128,11 @@ public:
|
||||
AvPowerSpectra(const AvPowerSpectra &) = delete;
|
||||
AvPowerSpectra &operator=(const AvPowerSpectra &) = delete;
|
||||
|
||||
void reset() { _est.reset(); }
|
||||
/**
|
||||
* @brief Reset to empty state. Clears the time buffer and sets estimator to
|
||||
* empty.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief Compute an update of the power spectra based on given time data.
|
||||
@ -143,7 +147,7 @@ public:
|
||||
* new estimate. It can be checked by operator bool().
|
||||
*
|
||||
*/
|
||||
std::optional<arma::cx_cube> compute(const dmat &timedata);
|
||||
std::optional<ccube> compute(const dmat &timedata);
|
||||
|
||||
/**
|
||||
* @brief Returns the latest estimate of cps (cross-power spectra.
|
||||
@ -151,7 +155,7 @@ public:
|
||||
* @return Pointer (reference, not owning!) to spectral estimate date, or
|
||||
* nullptr, in case nothing could yet be computed.
|
||||
*/
|
||||
std::optional<arma::cx_cube> get_est();
|
||||
std::optional<ccube> get_est() const;
|
||||
|
||||
/**
|
||||
* @brief The overlap is rounded to a certain amount of time samples. This
|
||||
|
@ -47,6 +47,7 @@ using vc = arma::Col<c>;
|
||||
using vrc = arma::Row<c>;
|
||||
using dmat = arma::Mat<d>;
|
||||
using cmat = arma::Mat<c>;
|
||||
using cube = arma::Cube<c>;
|
||||
using ccube = arma::Cube<c>;
|
||||
using dcube = arma::Cube<d>;
|
||||
|
||||
const d number_pi = arma::datum::pi;
|
||||
|
@ -6,42 +6,55 @@
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
RtAps::RtAps(StreamMgr &mgr, const Filter *freqWeightingFilter,
|
||||
const us nfft,
|
||||
const Window::WindowType w,
|
||||
const d overlap_percentage, const d time_constant)
|
||||
: ThreadedInDataHandler(mgr),
|
||||
_ps(nfft, w, overlap_percentage, time_constant) {
|
||||
|
||||
/* if (freqWeightingFilter != nullptr) { */
|
||||
/* _filterPrototype = freqWeightingFilter->clone(); */
|
||||
/* } */
|
||||
|
||||
start();
|
||||
}
|
||||
RtAps::~RtAps() {
|
||||
std::scoped_lock<std::mutex> lck(_mtx);
|
||||
stop();
|
||||
}
|
||||
bool RtAps::inCallback_threaded(const DaqData &data) {
|
||||
|
||||
/* DEBUGTRACE_ENTER; */
|
||||
DEBUGTRACE_ENTER;
|
||||
|
||||
std::scoped_lock<std::mutex> lck(_mtx);
|
||||
dmat fltdata = data.toFloat();
|
||||
const us nchannels = fltdata.n_cols;
|
||||
data.print();
|
||||
/* const us nchannels = fltdata.n_cols; */
|
||||
|
||||
if (_filterPrototype) {
|
||||
/* if (_filterPrototype) { */
|
||||
|
||||
// Adjust number of filters, if necessary
|
||||
if (nchannels > _freqWeightingFilter.size()) {
|
||||
while (nchannels > _freqWeightingFilter.size()) {
|
||||
_freqWeightingFilter.emplace_back(_filterPrototype->clone());
|
||||
}
|
||||
/* // Adjust number of filters, if necessary */
|
||||
/* if (nchannels > _freqWeightingFilter.size()) { */
|
||||
/* while (nchannels > _freqWeightingFilter.size()) { */
|
||||
/* _freqWeightingFilter.emplace_back(_filterPrototype->clone()); */
|
||||
/* } */
|
||||
|
||||
for (auto &filter : _freqWeightingFilter) {
|
||||
filter->reset();
|
||||
}
|
||||
}
|
||||
/* for (auto &filter : _freqWeightingFilter) { */
|
||||
/* filter->reset(); */
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
// Apply filtering
|
||||
#pragma omp parallel for
|
||||
for (us i = 0; i < nchannels; i++) {
|
||||
vd col = fltdata.col(i);
|
||||
_freqWeightingFilter.at(i)->filter(col);
|
||||
fltdata.col(i) = col;
|
||||
}
|
||||
} // End of if(_filterPrototype)
|
||||
/* // Apply filtering */
|
||||
/* #pragma omp parallel for */
|
||||
/* for (us i = 0; i < nchannels; i++) { */
|
||||
/* vd col = fltdata.col(i); */
|
||||
/* _freqWeightingFilter.at(i)->filter(col); */
|
||||
/* fltdata.col(i) = col; */
|
||||
/* } */
|
||||
/* } // End of if(_filterPrototype) */
|
||||
|
||||
std::optional<arma::cx_cube> res = _ps.compute(fltdata);
|
||||
|
||||
if (res.has_value()) {
|
||||
/* DEBUGTRACE_PRINT("Data ready!"); */
|
||||
_latest_est = std::make_unique<cube>(std::move(res.value()));
|
||||
}
|
||||
_ps.compute(fltdata);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -53,13 +66,18 @@ void RtAps::reset(const Daq *daq) { // Explicitly say
|
||||
DEBUGTRACE_ENTER;
|
||||
std::scoped_lock<std::mutex> lck(_mtx);
|
||||
_ps.reset();
|
||||
_latest_est.reset();
|
||||
}
|
||||
|
||||
std::unique_ptr<cube> RtAps::getCurrentValue() {
|
||||
std::unique_ptr<ccube> RtAps::getCurrentValue() {
|
||||
|
||||
/* DEBUGTRACE_ENTER; */
|
||||
std::scoped_lock<std::mutex> lck(_mtx);
|
||||
auto est = _ps.get_est();
|
||||
return std::make_unique<ccube>(est.value_or(ccube()));
|
||||
|
||||
return std::move(_latest_est);
|
||||
/* return std::move(_latest_est); */
|
||||
/* if (_latest_est) { */
|
||||
/* return std::make_unique<cube>(cube(*_latest_est)); */
|
||||
/* } else */
|
||||
/* return nullptr; */
|
||||
}
|
||||
|
@ -24,8 +24,6 @@ class RtAps : public ThreadedInDataHandler {
|
||||
std::mutex _mtx;
|
||||
std::unique_ptr<Filter> _filterPrototype;
|
||||
std::vector<std::unique_ptr<Filter>> _freqWeightingFilter;
|
||||
bool _data_ready = false;
|
||||
std::unique_ptr<cube> _latest_est;
|
||||
|
||||
AvPowerSpectra _ps;
|
||||
|
||||
@ -40,29 +38,15 @@ public:
|
||||
*/
|
||||
RtAps(StreamMgr &mgr, const Filter *freqWeightingFilter, const us nfft = 2048,
|
||||
const Window::WindowType w = Window::WindowType::Hann,
|
||||
const d overlap_percentage = 50., const d time_constant = -1)
|
||||
: ThreadedInDataHandler(mgr),
|
||||
_ps(nfft, w, overlap_percentage, time_constant) {
|
||||
|
||||
{
|
||||
std::scoped_lock<std::mutex> lck(_mtx);
|
||||
if (freqWeightingFilter != nullptr) {
|
||||
_filterPrototype = freqWeightingFilter->clone();
|
||||
}
|
||||
}
|
||||
start();
|
||||
}
|
||||
~RtAps() {
|
||||
std::scoped_lock<std::mutex> lck(_mtx);
|
||||
stop();
|
||||
}
|
||||
const d overlap_percentage = 50., const d time_constant = -1);
|
||||
~RtAps();
|
||||
|
||||
/**
|
||||
* @brief Get the latest estimate of the power spectra
|
||||
*
|
||||
* @return Optionally, if available, the latest values
|
||||
*/
|
||||
std::unique_ptr<cube> getCurrentValue();
|
||||
std::unique_ptr<ccube> getCurrentValue();
|
||||
|
||||
bool inCallback_threaded(const DaqData &) override final;
|
||||
void reset(const Daq *) override final;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* #define DEBUGTRACE_ENABLED */
|
||||
#include "debugtrace.hpp"
|
||||
#include "lasp_timebuffer.h"
|
||||
#include "debugtrace.hpp"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <deque>
|
||||
@ -23,9 +23,9 @@ public:
|
||||
}
|
||||
void push(const dmat &mat) {
|
||||
DEBUGTRACE_ENTER;
|
||||
#if LASP_DEBUG==1
|
||||
if(!_storage.empty()) {
|
||||
if(mat.n_cols != _storage.front().n_cols) {
|
||||
#if LASP_DEBUG == 1
|
||||
if (!_storage.empty()) {
|
||||
if (mat.n_cols != _storage.front().n_cols) {
|
||||
throw rte("Invalid number of channels in mat");
|
||||
}
|
||||
}
|
||||
@ -35,32 +35,36 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<dmat> pop(const us nsamples, us keep) {
|
||||
std::optional<dmat> pop(const us nframes, const us keep) {
|
||||
|
||||
DEBUGTRACE_ENTER;
|
||||
|
||||
if (keep > nsamples)
|
||||
throw rte("keep should be <= nsamples");
|
||||
if (keep >= nframes) {
|
||||
throw rte("keep should be < nframes");
|
||||
}
|
||||
|
||||
if (nsamples <= n_frames()) {
|
||||
if (nframes <= n_frames()) {
|
||||
|
||||
assert(!_storage.empty());
|
||||
|
||||
dmat res(nsamples, _storage.front().n_cols);
|
||||
dmat res(nframes, _storage.front().n_cols);
|
||||
|
||||
for (us i = 0; i < nsamples; i++) {
|
||||
us j = 0;
|
||||
for (us i = 0; i < nframes; i++) {
|
||||
|
||||
if (i + keep < nframes) {
|
||||
// Just pop elements and copy over
|
||||
res.row(i) = _storage.front();
|
||||
_storage.pop_front();
|
||||
|
||||
} else {
|
||||
|
||||
if (i + keep >= nsamples) {
|
||||
// Suppose keep == 0, then we never arrive here
|
||||
// Suppose keep == 1, then storage[0] is copyied over.
|
||||
// Suppose keep == 2, then storage[0[ and storage[1] is copyied over.
|
||||
// Etc.
|
||||
res.row(i) = _storage[i + keep - nsamples];
|
||||
} else {
|
||||
|
||||
// Just pop elements and copy over
|
||||
res.row(i) = _storage.front();
|
||||
_storage.pop_front();
|
||||
res.row(i) = _storage[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@ -79,11 +83,9 @@ public:
|
||||
};
|
||||
|
||||
TimeBuffer::TimeBuffer() : _imp(std::make_unique<TimeBufferImp>()) {}
|
||||
std::optional<dmat> TimeBuffer::pop(const us n_rows,const us keep) {
|
||||
std::optional<dmat> TimeBuffer::pop(const us n_rows, const us keep) {
|
||||
return _imp->pop(n_rows, keep);
|
||||
}
|
||||
TimeBuffer::~TimeBuffer(){}
|
||||
void TimeBuffer::reset() {
|
||||
_imp->reset();
|
||||
}
|
||||
TimeBuffer::~TimeBuffer() {}
|
||||
void TimeBuffer::reset() { _imp->reset(); }
|
||||
void TimeBuffer::push(const dmat &dat) { _imp->push(dat); }
|
||||
|
@ -9,6 +9,7 @@ namespace py = pybind11;
|
||||
template<typename T>
|
||||
using pyarray = py::array_t<T, py::array::f_style | py::array::forcecast>;
|
||||
using dpyarray = pyarray<d>;
|
||||
using cpyarray = pyarray<c>;
|
||||
|
||||
|
||||
/**
|
||||
@ -127,6 +128,6 @@ arma::Mat<T> NpyToCol(pyarray<T> data) {
|
||||
if (data.ndim() != 1) {
|
||||
throw std::runtime_error("Expects a 1D array");
|
||||
}
|
||||
return arma::Col<d>(data.mutable_data(0), data.size(), copy);
|
||||
return arma::Col<T>(data.mutable_data(0), data.size(), copy);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
namespace py = pybind11;
|
||||
using rte = std::runtime_error;
|
||||
|
||||
/**
|
||||
* \ingroup pybind
|
||||
@ -29,11 +30,25 @@ void init_dsp(py::module &m) {
|
||||
|
||||
py::class_<Fft> fft(m, "Fft");
|
||||
fft.def(py::init<us>());
|
||||
fft.def("fft", py::overload_cast<const vd &>(&Fft::fft));
|
||||
fft.def("fft", py::overload_cast<const dmat &>(&Fft::fft));
|
||||
fft.def("fft", [](Fft &f, dpyarray dat) {
|
||||
if (dat.ndim() == 1) {
|
||||
return ColToNpy<c>(f.fft(NpyToCol<d, false>(dat)));
|
||||
} else if (dat.ndim() == 2) {
|
||||
return MatToNpy<c>(f.fft(NpyToMat<d, false>(dat)));
|
||||
} else {
|
||||
throw rte("Invalid dimensions of array");
|
||||
}
|
||||
});
|
||||
fft.def("ifft", [](Fft &f, cpyarray dat) {
|
||||
if (dat.ndim() == 1) {
|
||||
return ColToNpy<d>(f.ifft(NpyToCol<c, false>(dat)));
|
||||
} else if (dat.ndim() == 2) {
|
||||
return MatToNpy<d>(f.ifft(NpyToMat<c, false>(dat)));
|
||||
} else {
|
||||
throw rte("Invalid dimensions of array");
|
||||
}
|
||||
});
|
||||
|
||||
fft.def("ifft", py::overload_cast<const vc &>(&Fft::ifft));
|
||||
fft.def("ifft", py::overload_cast<const cmat &>(&Fft::ifft));
|
||||
fft.def_static("load_fft_wisdom", &Fft::load_fft_wisdom);
|
||||
fft.def_static("store_fft_wisdom", &Fft::store_fft_wisdom);
|
||||
|
||||
@ -55,7 +70,7 @@ void init_dsp(py::module &m) {
|
||||
py::class_<SeriesBiquad, std::shared_ptr<SeriesBiquad>> sbq(m, "SeriesBiquad",
|
||||
filter);
|
||||
sbq.def(py::init([](dpyarray filter) {
|
||||
return std::make_shared<SeriesBiquad>(NpyToCol<d,false>(filter));
|
||||
return std::make_shared<SeriesBiquad>(NpyToCol<d, false>(filter));
|
||||
}));
|
||||
sbq.def("filter", [](SeriesBiquad &s, dpyarray input) {
|
||||
vd res = NpyToCol<d, true>(input);
|
||||
@ -89,10 +104,17 @@ void init_dsp(py::module &m) {
|
||||
py::arg("overlap_percentage") = 50.0, py::arg("time_constant") = -1);
|
||||
|
||||
aps.def("compute", [](AvPowerSpectra &aps, dpyarray timedata) {
|
||||
std::optional<arma::cx_cube> res =
|
||||
aps.compute(NpyToMat<d, false>(timedata));
|
||||
std::optional<ccube> res;
|
||||
{
|
||||
py::gil_scoped_release release;
|
||||
res = aps.compute(NpyToMat<d, false>(timedata));
|
||||
}
|
||||
|
||||
return CubeToNpy<c>(res.value_or(cube(0, 0, 0)));
|
||||
return CubeToNpy<c>(res.value_or(ccube(0, 0, 0)));
|
||||
});
|
||||
aps.def("get_est", [](const AvPowerSpectra &ps) {
|
||||
auto est = ps.get_est();
|
||||
return CubeToNpy<c>(est.value_or(ccube(0, 0, 0)));
|
||||
});
|
||||
|
||||
py::class_<SLM> slm(m, "cppSLM");
|
||||
|
@ -215,10 +215,10 @@ void init_datahandler(py::module &m) {
|
||||
);
|
||||
|
||||
rtaps.def("getCurrentValue", [](RtAps &rt) {
|
||||
std::unique_ptr<cube> val = rt.getCurrentValue();
|
||||
std::unique_ptr<ccube> val = rt.getCurrentValue();
|
||||
if (val) {
|
||||
return CubeToNpy<c> (*val);
|
||||
}
|
||||
return CubeToNpy<c>(cube(1,0,0));
|
||||
return CubeToNpy<c>(ccube(1,0,0));
|
||||
});
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ def test_aps1():
|
||||
|
||||
sig = np.random.randn(int(fs*tend))
|
||||
|
||||
cps = aps.compute(sig)
|
||||
cps = aps.compute(sig[:,None])
|
||||
|
||||
pow1 = np.sum(sig**2)/sig.size
|
||||
pow2 = np.sum((cps[:,0,0]).real)
|
||||
|
@ -27,7 +27,7 @@ out = bq.filter(in_)
|
||||
|
||||
from scipy.signal import welch
|
||||
nfft = 48000
|
||||
freq, H1 = welch(out[:,0],
|
||||
freq, H1 = welch(out,
|
||||
# scaling
|
||||
fs=fs,nfft=nfft)
|
||||
|
||||
|
@ -20,7 +20,7 @@ def test_forward_fft():
|
||||
sig = np.random.randn(nfft)
|
||||
fft_lasp = Fft(nfft)
|
||||
|
||||
res_lasp = fft_lasp.fft(sig)[:,0]
|
||||
res_lasp = fft_lasp.fft(sig)
|
||||
res_npy = np.fft.rfft(sig)
|
||||
assert(np.isclose(np.linalg.norm(res_lasp- res_npy), 0))
|
||||
|
||||
@ -38,11 +38,11 @@ def test_backward_fft():
|
||||
Sig = Sigr + 1j*Sigi
|
||||
|
||||
fft_lasp = Fft(nfft)
|
||||
sig_lasp = fft_lasp.ifft(Sig)[:,0]
|
||||
sig_lasp = fft_lasp.ifft(Sig)
|
||||
sig_py = np.fft.irfft(Sig)
|
||||
|
||||
assert(np.isclose(np.linalg.norm(sig_py- sig_lasp), 0))
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_forward_fft()
|
||||
# test_backward_fft()()
|
||||
test_backward_fft()
|
||||
|
@ -23,7 +23,7 @@ def test_ps():
|
||||
# sig = 8*np.cos(omg*t)
|
||||
|
||||
|
||||
cps = ps.compute(sig)
|
||||
cps = ps.compute(sig[:,None])
|
||||
|
||||
pow1 = np.sum(sig**2)/sig.size
|
||||
pow2 = np.sum((cps[:,0,0]).real)
|
||||
|
Loading…
Reference in New Issue
Block a user