lasp/cpp_src/dsp/lasp_rtsignalviewer.cpp

105 lines
2.6 KiB
C++

/* #define DEBUGTRACE_ENABLED */
#include "debugtrace.hpp"
#include "lasp_daqdata.h"
#include "lasp_daq.h"
#include "lasp_rtsignalviewer.h"
#include <algorithm>
#include <mutex>
using std::cerr;
using std::endl;
using Lck = std::scoped_lock<std::mutex>;
using rte = std::runtime_error;
RtSignalViewer::RtSignalViewer(SmgrHandle mgr, const d approx_time_hist,
const us resolution, const us channel)
: ThreadedInDataHandler(mgr), _approx_time_hist(approx_time_hist),
_resolution(resolution), _channel(channel) {
DEBUGTRACE_ENTER;
if (approx_time_hist <= 0) {
throw rte("Invalid time history. Should be > 0");
}
if (resolution <= 1) {
throw rte("Invalid resolution. Should be > 1");
}
startThread();
}
void RtSignalViewer::inCallback(const DaqData &data) {
DEBUGTRACE_ENTER;
Lck lck(_sv_mtx);
/// Push new data in time buffer, scaled by sensitivity
_tb.push(data.toFloat(_channel) / _sens(_channel));
_dat.col(0) += _nsamples_per_point / _fs;
/// Required number of samples for a new 'point'
while (_tb.size() > _nsamples_per_point) {
// Roll forward time column
_dat.col(0) += _nsamples_per_point / _fs;
vd newvals = _tb.pop(_nsamples_per_point);
d newmax = newvals.max();
d newmin = newvals.min();
vd mincol = _dat.col(1);
vd maxcol = _dat.col(2);
_dat(arma::span(0, _resolution-2),1) = mincol(arma::span(1, _resolution-1));
_dat(arma::span(0, _resolution-2),2) = maxcol(arma::span(1, _resolution-1));
_dat(_resolution-1, 1) = newmin;
_dat(_resolution-1, 2) = newmax;
}
}
RtSignalViewer::~RtSignalViewer() {
stopThread();
}
void RtSignalViewer::reset(const Daq *daq) {
DEBUGTRACE_ENTER;
Lck lck(_sv_mtx);
// Reset time buffer
_tb.reset();
if (daq) {
_fs = daq->samplerate();
/// Update sensitivity values
_sens.resize(daq->neninchannels());
us i = 0;
for (const auto &ch : daq->enabledInChannels()) {
_sens[i] = ch.sensitivity;
i++;
}
/// The number of samples per point, based on which minmax are computed
_nsamples_per_point =
std::max<us>(static_cast<us>(_approx_time_hist / _resolution * _fs), 1);
const d dt_points = _nsamples_per_point / _fs;
const d tend = dt_points * _resolution;
// Initialize data array
_dat.resize(_resolution, 3);
_dat.col(0) = arma::linspace(0, tend, _resolution);
_dat.col(1).zeros();
_dat.col(2).zeros();
} else {
_sens.zeros();
_fs = 0;
_dat.reset();
}
}
dmat RtSignalViewer::getCurrentValue() const {
DEBUGTRACE_ENTER;
Lck lck(_sv_mtx);
return _dat;
}