2020-11-25 23:47:29 +08:00
|
|
|
#include "tracemath.h"
|
|
|
|
|
2020-11-29 02:32:18 +08:00
|
|
|
#include "medianfilter.h"
|
2020-12-02 05:28:32 +08:00
|
|
|
#include "tdr.h"
|
2020-12-12 03:28:40 +08:00
|
|
|
#include "dft.h"
|
2020-12-03 05:15:34 +08:00
|
|
|
#include "Traces/trace.h"
|
2020-11-29 02:32:18 +08:00
|
|
|
|
2020-11-25 23:47:29 +08:00
|
|
|
TraceMath::TraceMath()
|
|
|
|
{
|
|
|
|
input = nullptr;
|
|
|
|
dataType = DataType::Invalid;
|
2020-11-28 20:57:22 +08:00
|
|
|
error("Invalid input");
|
2020-11-25 23:47:29 +08:00
|
|
|
}
|
|
|
|
|
2020-11-29 02:32:18 +08:00
|
|
|
TraceMath *TraceMath::createMath(TraceMath::Type type)
|
|
|
|
{
|
|
|
|
switch(type) {
|
|
|
|
case Type::MedianFilter:
|
|
|
|
return new Math::MedianFilter();
|
2020-12-02 05:28:32 +08:00
|
|
|
case Type::TDR:
|
|
|
|
return new Math::TDR();
|
2020-12-12 03:28:40 +08:00
|
|
|
case Type::DFT:
|
|
|
|
return new Math::DFT();
|
2020-11-29 02:32:18 +08:00
|
|
|
default:
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TraceMath::TypeInfo TraceMath::getInfo(TraceMath::Type type)
|
|
|
|
{
|
|
|
|
TypeInfo ret = {};
|
|
|
|
switch(type) {
|
|
|
|
case Type::MedianFilter:
|
|
|
|
ret.name = "Median filter";
|
|
|
|
ret.explanationWidget = Math::MedianFilter::createExplanationWidget();
|
|
|
|
break;
|
2020-12-02 05:28:32 +08:00
|
|
|
case Type::TDR:
|
|
|
|
ret.name = "TDR";
|
|
|
|
ret.explanationWidget = Math::TDR::createExplanationWidget();
|
2020-11-29 02:32:18 +08:00
|
|
|
break;
|
2020-12-12 03:28:40 +08:00
|
|
|
case Type::DFT:
|
|
|
|
ret.name = "DFT";
|
|
|
|
ret.explanationWidget = Math::DFT::createExplanationWidget();
|
|
|
|
break;
|
2020-11-29 02:32:18 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-11-25 23:47:29 +08:00
|
|
|
TraceMath::Data TraceMath::getSample(unsigned int index)
|
|
|
|
{
|
|
|
|
return data.at(index);
|
|
|
|
}
|
|
|
|
|
2020-11-29 05:34:40 +08:00
|
|
|
double TraceMath::getStepResponse(unsigned int index)
|
|
|
|
{
|
|
|
|
if(stepResponse.size() > index) {
|
|
|
|
return stepResponse[index];
|
|
|
|
} else {
|
|
|
|
return std::numeric_limits<double>::quiet_NaN();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-29 02:32:18 +08:00
|
|
|
TraceMath::Data TraceMath::getInterpolatedSample(double x)
|
|
|
|
{
|
|
|
|
Data ret;
|
|
|
|
|
|
|
|
if(data.size() == 0 || x < data.front().x || x > data.back().x) {
|
|
|
|
ret.y = std::numeric_limits<std::complex<double>>::quiet_NaN();
|
|
|
|
ret.x = std::numeric_limits<double>::quiet_NaN();
|
|
|
|
} else {
|
|
|
|
auto it = lower_bound(data.begin(), data.end(), x, [](const Data &lhs, const double x) -> bool {
|
|
|
|
return lhs.x < x;
|
|
|
|
});
|
|
|
|
if(it->x == x) {
|
|
|
|
ret = *it;
|
|
|
|
} else {
|
|
|
|
// no exact match, needs to interpolate
|
|
|
|
auto high = *it;
|
|
|
|
it--;
|
|
|
|
auto low = *it;
|
|
|
|
double alpha = (x - low.x) / (high.x - low.x);
|
|
|
|
ret.y = low.y * (1 - alpha) + high.y * alpha;
|
|
|
|
ret.x = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-11-25 23:47:29 +08:00
|
|
|
unsigned int TraceMath::numSamples()
|
|
|
|
{
|
|
|
|
return data.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TraceMath::removeInput()
|
|
|
|
{
|
|
|
|
if(input) {
|
|
|
|
// disconnect everything from the input
|
|
|
|
disconnect(input, nullptr, this, nullptr);
|
|
|
|
input = nullptr;
|
|
|
|
data.clear();
|
|
|
|
dataType = DataType::Invalid;
|
|
|
|
emit outputTypeChanged(dataType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TraceMath::assignInput(TraceMath *input)
|
|
|
|
{
|
|
|
|
Q_ASSERT(input != nullptr);
|
|
|
|
if(input != this->input) {
|
|
|
|
removeInput();
|
|
|
|
this->input = input;
|
|
|
|
connect(input, &TraceMath::outputTypeChanged, this, &TraceMath::inputTypeChanged);
|
2020-12-02 05:28:32 +08:00
|
|
|
inputTypeChanged(input->dataType);
|
2020-11-25 23:47:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TraceMath::inputTypeChanged(TraceMath::DataType type)
|
|
|
|
{
|
|
|
|
auto newType = outputType(type);
|
2020-12-02 05:28:32 +08:00
|
|
|
dataType = newType;
|
|
|
|
data.clear();
|
|
|
|
if(dataType == DataType::Invalid) {
|
|
|
|
error("Invalid input data");
|
|
|
|
disconnect(input, &TraceMath::outputSamplesChanged, this, &TraceMath::inputSamplesChanged);
|
|
|
|
updateStepResponse(false);
|
|
|
|
} else {
|
|
|
|
connect(input, &TraceMath::outputSamplesChanged, this, &TraceMath::inputSamplesChanged);
|
2020-11-27 23:31:05 +08:00
|
|
|
inputSamplesChanged(0, input->data.size());
|
2020-11-25 23:47:29 +08:00
|
|
|
}
|
2020-12-02 05:28:32 +08:00
|
|
|
emit outputTypeChanged(dataType);
|
2020-11-25 23:47:29 +08:00
|
|
|
}
|
|
|
|
|
2020-11-28 20:57:22 +08:00
|
|
|
void TraceMath::warning(QString warn)
|
|
|
|
{
|
|
|
|
statusString = warn;
|
|
|
|
status = Status::Warning;
|
|
|
|
emit statusChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TraceMath::error(QString err)
|
|
|
|
{
|
|
|
|
statusString = err;
|
|
|
|
status = Status::Error;
|
|
|
|
emit statusChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TraceMath::success()
|
|
|
|
{
|
|
|
|
if(status != Status::Ok) {
|
|
|
|
status = Status::Ok;
|
|
|
|
emit statusChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-29 05:34:40 +08:00
|
|
|
void TraceMath::updateStepResponse(bool valid)
|
|
|
|
{
|
|
|
|
if(valid) {
|
|
|
|
stepResponse.resize(data.size());
|
|
|
|
double accumulate = 0.0;
|
|
|
|
for(unsigned int i=0;i<data.size();i++) {
|
|
|
|
accumulate += data[i].y.real();
|
|
|
|
stepResponse[i] = accumulate;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
stepResponse.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-12 03:28:40 +08:00
|
|
|
TraceMath *TraceMath::getInput() const
|
|
|
|
{
|
|
|
|
return input;
|
|
|
|
}
|
|
|
|
|
2020-11-28 20:57:22 +08:00
|
|
|
QString TraceMath::getStatusDescription() const
|
|
|
|
{
|
|
|
|
return statusString;
|
|
|
|
}
|
|
|
|
|
2020-12-03 05:15:34 +08:00
|
|
|
Trace *TraceMath::root()
|
|
|
|
{
|
|
|
|
auto root = this;
|
|
|
|
while(root->input) {
|
|
|
|
root = root->input;
|
|
|
|
}
|
|
|
|
return static_cast<Trace*>(root);
|
|
|
|
}
|
|
|
|
|
2020-11-28 20:57:22 +08:00
|
|
|
TraceMath::Status TraceMath::getStatus() const
|
|
|
|
{
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2020-11-25 23:47:29 +08:00
|
|
|
TraceMath::DataType TraceMath::getDataType() const
|
|
|
|
{
|
|
|
|
return dataType;
|
|
|
|
}
|