LibreVNA/Software/PC_Application/averaging.cpp

167 lines
4.0 KiB
C++
Raw Normal View History

#include "averaging.h"
using namespace std;
Averaging::Averaging()
{
averages = 1;
2021-12-02 05:11:50 +08:00
mode = Mode::Mean;
}
void Averaging::reset(unsigned int points)
{
avg.clear();
for(unsigned int i = 0;i<points;i++) {
2022-08-05 02:12:15 +08:00
avg.push_back(deque<vector<complex<double>>>());
}
}
void Averaging::setAverages(unsigned int a)
{
averages = a;
reset(avg.size());
}
2022-08-05 02:12:15 +08:00
VirtualDevice::VNAMeasurement Averaging::process(VirtualDevice::VNAMeasurement d)
{
2022-08-05 02:12:15 +08:00
if(d.measurements.size() != numMeasurements) {
numMeasurements = d.measurements.size();
reset(avg.size());
}
2022-08-05 02:12:15 +08:00
vector<complex<double>> data;
for(auto m : d.measurements) {
data.push_back(m.second);
}
process(d.pointNum, data);
int i=0;
for(auto &m : d.measurements) {
m.second = data[i++];
}
2022-08-05 02:12:15 +08:00
return d;
}
2022-08-05 02:12:15 +08:00
VirtualDevice::SAMeasurement Averaging::process(VirtualDevice::SAMeasurement d)
{
if(d.measurements.size() != numMeasurements) {
numMeasurements = d.measurements.size();
reset(avg.size());
}
2022-08-05 02:12:15 +08:00
vector<complex<double>> data;
for(auto m : d.measurements) {
data.push_back(m.second);
}
process(d.pointNum, data);
int i=0;
for(auto &m : d.measurements) {
m.second = data[i++].real();
}
return d;
}
2021-12-02 05:11:50 +08:00
2022-08-05 02:12:15 +08:00
unsigned int Averaging::getLevel()
{
if(avg.size() > 0) {
return avg.back().size();
} else {
return 0;
}
}
2021-12-02 05:11:50 +08:00
2022-08-05 02:12:15 +08:00
unsigned int Averaging::currentSweep()
{
if(avg.size() > 0) {
return avg.front().size();
} else {
return 0;
}
2022-08-05 02:12:15 +08:00
}
2022-08-05 02:12:15 +08:00
Averaging::Mode Averaging::getMode() const
{
return mode;
}
2022-08-05 02:12:15 +08:00
void Averaging::setMode(const Mode &value)
{
mode = value;
}
2022-08-05 02:12:15 +08:00
void Averaging::process(int pointNum, std::vector<std::complex<double>> &data)
{
2022-08-05 02:12:15 +08:00
if(data.size() != numMeasurements) {
numMeasurements = data.size();
2022-08-04 23:31:24 +08:00
reset(avg.size());
}
2022-08-05 02:12:15 +08:00
if (pointNum == avg.size()) {
// add moving average entry
2022-08-04 23:31:24 +08:00
deque<vector<complex<double>>> deque;
avg.push_back(deque);
}
2022-08-05 02:12:15 +08:00
if (pointNum < avg.size()) {
// can compute average
// get correct queue
2022-08-05 02:12:15 +08:00
auto deque = &avg[pointNum];
// add newest sample to queue
2022-08-05 02:12:15 +08:00
deque->push_back(data);
// remove oldest sample if required number of averages reached
if(deque->size() > averages) {
deque->pop_front();
}
2022-08-05 02:12:15 +08:00
std::deque<complex<double>> averagedResults = {};
2022-08-04 23:31:24 +08:00
2021-12-02 05:11:50 +08:00
switch(mode) {
case Mode::Mean: {
// calculate average
2022-08-04 23:31:24 +08:00
complex<double> sum[numMeasurements];
2021-12-02 05:11:50 +08:00
for(auto s : *deque) {
2022-08-04 23:31:24 +08:00
for(int i=0;i<numMeasurements;i++) {
sum[i] += s[i];
}
}
for(auto s : sum) {
averagedResults.push_back(abs(s / (double) (deque->size())));
2021-12-02 05:11:50 +08:00
}
}
break;
case Mode::Median: {
auto size = deque->size();
2022-08-04 23:31:24 +08:00
// create sorted vectors
2022-08-05 02:12:15 +08:00
vector<vector<complex<double>>> vectors(numMeasurements);
auto comp = [=](const complex<double>&a, const complex<double>&b){
return abs(a) < abs(b);
};
2021-12-02 05:11:50 +08:00
for(auto d : *deque) {
2022-08-05 02:12:15 +08:00
int i=0;
2022-08-04 23:31:24 +08:00
for(auto &v : vectors) {
2022-08-05 02:12:15 +08:00
v.insert(upper_bound(v.begin(), v.end(), d[i], comp), d[i]);
i++;
2022-08-04 23:31:24 +08:00
}
2021-12-02 05:11:50 +08:00
}
if(size & 0x01) {
// odd number of samples
2022-08-04 23:31:24 +08:00
for(auto v : vectors) {
averagedResults.push_back(v[size / 2]);
}
2021-12-02 05:11:50 +08:00
} else {
// even number, use average of middle samples
2022-08-04 23:31:24 +08:00
for(auto v : vectors) {
2022-08-05 02:12:15 +08:00
averagedResults.push_back((v[size / 2 - 1] + v[size / 2]) / 2.0);
2022-08-04 23:31:24 +08:00
}
2021-12-02 05:11:50 +08:00
}
}
break;
}
2022-08-04 23:31:24 +08:00
2022-08-05 02:12:15 +08:00
for(auto &m : data) {
m = averagedResults.front();
averagedResults.pop_front();
2022-08-04 23:31:24 +08:00
}
}
2021-12-02 05:11:50 +08:00
}