diff --git a/Software/PC_Application/LibreVNA-GUI/Tools/eyediagramdialog.cpp b/Software/PC_Application/LibreVNA-GUI/Tools/eyediagramdialog.cpp index 27a4a62..113b19e 100644 --- a/Software/PC_Application/LibreVNA-GUI/Tools/eyediagramdialog.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Tools/eyediagramdialog.cpp @@ -214,7 +214,7 @@ void EyeDiagramDialog::updateThread(unsigned int width, unsigned int height) updating = false; return; } - if(datarate <= trace->getSample(0).x) { + if(datarate <= 0) { emit calculationStatus("Data rate too low"); updating = false; return; @@ -347,16 +347,27 @@ void EyeDiagramDialog::updateThread(unsigned int width, unsigned int height) } } - auto scale = timestep / (length / (samples - 1)); unsigned long convolutedSize = length / timestep; if(convolutedSize > inVec.size()) { // impulse response is longer than what we display, truncate convolutedSize = inVec.size(); } impulseVec.resize(convolutedSize); + /* + * we can't use the impulse response directly because we most likely need samples inbetween + * the calculated values. Interpolation is available but if our sample spacing here is much + * wider than the impulse response data, we might miss peaks (or severely miscalculate their + * amplitude. + * Instead, the step response is interpolated and the impulse response determined by deriving + * it from the interpolated step response data. As the step response is the integrated imulse + * response data, we can't miss narrow peaks that way. + */ + double lastStepResponse = 0.0; for(unsigned long i=0;igetInterpolatedSample(x).y.real() * scale; + auto step = tdr->getInterpolatedStepResponse(x); + impulseVec[i] = step - lastStepResponse; + lastStepResponse = step; } eyeTimeShift += (risetime + falltime) * 1.25 / 4; diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.cpp index f1f258e..4760f40 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.cpp @@ -106,6 +106,37 @@ double TraceMath::getStepResponse(unsigned int index) } } +double TraceMath::getInterpolatedStepResponse(double x) +{ + if(stepResponse.size() != data.size()) { + // make sure all the step response data is available + return std::numeric_limits::quiet_NaN(); + } + + double ret = std::numeric_limits::quiet_NaN(); + + if(data.size() == 0 || x < data.front().x || x > data.back().x) { + ret = std::numeric_limits::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 = stepResponse[it - data.begin()]; + } else { + // no exact match, needs to interpolate + unsigned int highIndex = it - data.begin(); + unsigned int lowIndex = highIndex - 1; + auto high = *it; + it--; + auto low = *it; + double alpha = (x - low.x) / (high.x - low.x); + ret = stepResponse[lowIndex] * (1 - alpha) + stepResponse[highIndex] * alpha; + } + } + return ret; +} + TraceMath::Data TraceMath::getInterpolatedSample(double x) { Data ret; diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.h b/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.h index 4660057..6e572d8 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.h +++ b/Software/PC_Application/LibreVNA-GUI/Traces/Math/tracemath.h @@ -91,8 +91,9 @@ public: static TypeInfo getInfo(Type type); Data getSample(unsigned int index); - double getStepResponse(unsigned int index); Data getInterpolatedSample(double x); + double getStepResponse(unsigned int index); + double getInterpolatedStepResponse(double x); unsigned int numSamples(); static QString dataTypeToString(DataType type);