Skip to content

Commit

Permalink
spectrum analyzer: waterfall plot optimizations
Browse files Browse the repository at this point in the history
- plot and sink optimizations
- on/off button for showing waterfall
- fixed inverted plot bug

Signed-off-by: Andrei Popa <[email protected]>
  • Loading branch information
andrei47w authored and adisuciu committed Feb 15, 2024
1 parent 55be10a commit fc7959a
Show file tree
Hide file tree
Showing 21 changed files with 965 additions and 804 deletions.
38 changes: 36 additions & 2 deletions src/DisplayPlot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -612,9 +612,10 @@ DisplayPlot::DisplayPlot(int nplots, QWidget* parent, bool isdBgraph,

d_bottomHandlesArea->setMinimumHeight(50);
d_rightHandlesArea->setMinimumWidth(50);
d_bottomHandlesArea->setLargestChildWidth(60);
d_rightHandlesArea->setLargestChildHeight(60);
// d_bottomHandlesArea->setLargestChildWidth(60);
// d_rightHandlesArea->setLargestChildHeight(60);
d_rightHandlesArea->setMinimumHeight(this->minimumHeight());
d_rightHandlesArea->setBottomPadding(50);

d_formatter = static_cast<PrefixFormatter *>(new MetricPrefixFormatter);

Expand Down Expand Up @@ -1808,6 +1809,39 @@ void DisplayPlot::setActiveVertAxis(unsigned int axisIdx, bool selected)
}
}

// remove empty space above plot
// assumes that axis labels are left and bottom, cursor handles are right and bottom
void DisplayPlot::adjustHandleAreasSize(bool cursors)
{
int top_height = cursors ? d_vCursorHandle1->height() / 2 : 2;
topHandlesArea()->setMinimumHeight(top_height);
topHandlesArea()->setMaximumHeight(top_height);

d_leftHandlesArea->setTopPadding(top_height);
d_rightHandlesArea->setTopPadding(top_height);

int bottom_height = cursors ? d_hCursorHandle1->height() : axisWidget(QwtAxis::XBottom)->height();
bottomHandlesArea()->setMinimumHeight(bottom_height);
bottomHandlesArea()->setMaximumHeight(bottom_height);

d_leftHandlesArea->setBottomPadding(bottom_height);
d_rightHandlesArea->setBottomPadding(bottom_height);

int right_width = cursors ? d_vCursorHandle1->width() : 2;
rightHandlesArea()->setMinimumWidth(right_width);
rightHandlesArea()->setMaximumWidth(right_width);

d_topHandlesArea->setRightPadding(right_width);
d_bottomHandlesArea->setRightPadding(right_width);

int left_width = axisWidget(QwtAxis::YLeft)->width();
leftHandlesArea()->setMinimumWidth(left_width);
leftHandlesArea()->setMaximumWidth(left_width);

d_topHandlesArea->setLeftPadding(left_width);
d_bottomHandlesArea->setLeftPadding(left_width);
}

int DisplayPlot::activeVertAxis()
{
return d_activeVertAxis;
Expand Down
1 change: 1 addition & 0 deletions src/DisplayPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ class DisplayPlot:public PrintablePlot
virtual QString formatXValue(double value, int precision) const;
virtual QString formatYValue(double value, int precision) const;

void adjustHandleAreasSize(bool cursors = false);
void setCursorAxes(QwtAxisId fixed_axis, QwtAxisId mobile_axis);
public Q_SLOTS:
virtual void disableLegend();
Expand Down
37 changes: 12 additions & 25 deletions src/FftDisplayPlot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,6 @@ void FftDisplayPlot::updateHandleAreaPadding()
{
d_leftHandlesArea->update();
d_bottomHandlesArea->setLeftPadding(d_leftHandlesArea->width());
d_bottomHandlesArea->setRightPadding(50);

d_rightHandlesArea->setTopPadding(50);
d_rightHandlesArea->setBottomPadding(50);

//update handle position to avoid cursors getting out of the plot bounds when changing the padding;
d_hCursorHandle1->updatePosition();
Expand Down Expand Up @@ -870,11 +866,6 @@ void FftDisplayPlot::_resetXAxisPoints()
}
}

void FftDisplayPlot::resetZoomerStack()
{
getZoomer()->setZoomStack(getZoomer()->zoomStack(), 0);
}

int64_t FftDisplayPlot::posAtFrequency(double freq, int chIdx) const
{
int64_t pos = 0;
Expand Down Expand Up @@ -903,29 +894,25 @@ void FftDisplayPlot::setAmplitude(double top, double bottom)
m_bottom = bottom;
}

void FftDisplayPlot::updateZoomerBase()
{
QRectF rect = QRectF(m_sweepStart, m_bottom, m_sweepStop - m_sweepStart, m_top - m_bottom);
getZoomer()->zoom(rect);

getZoomer()->blockSignals(true);
getZoomer()->setZoomBase(rect);
getZoomer()->QwtPlotZoomer::zoom(rect);
getZoomer()->blockSignals(false);

}

void FftDisplayPlot::customEvent(QEvent *e)
{
if (e->type() == TimeUpdateEvent::Type()) {
TimeUpdateEvent *ev = static_cast<TimeUpdateEvent *>(e);

this->plotData(ev->getTimeDomainPoints(),
ev->getNumTimeDomainDataPoints());

// reset zoomer base if plot horizontal axis changed
if (getZoomer()->zoomBase().left() != m_sweepStart || getZoomer()->zoomBase().width() != m_sweepStop - m_sweepStart) {
getZoomer()->blockSignals(true);

auto rect = QRectF(m_sweepStart, m_top, m_sweepStop - m_sweepStart, m_bottom - m_top);
getZoomer()->zoom(rect);
getZoomer()->setZoomBase(rect);
getZoomer()->zoom(0);

auto stack = QStack<QRectF>();
stack.push(getZoomer()->zoomStack().first());
getZoomer()->setZoomStack(stack, 0);

getZoomer()->blockSignals(false);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/FftDisplayPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ namespace adiscope {
void enableYaxisLabels();
QString formatXValue(double value, int precision) const;
QString formatYValue(double value, int precision) const;
void resetZoomerStack();
void setAmplitude(double top, double bottom);
void updateZoomerBase();
Q_SIGNALS:
void channelAdded(int);
void newFFTData();
Expand Down
119 changes: 57 additions & 62 deletions src/WaterfallDisplayPlot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@

using QwtAxis::XBottom;

namespace pt = boost::posix_time;
using namespace adiscope;
#include <QDebug>

Expand Down Expand Up @@ -218,7 +217,7 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(int nplots, QWidget* parent)

replot();

connect(this, SIGNAL(resetWaterfallData), SLOT(resetAvgAcquisitionTime));
connect(this, SIGNAL(resetWaterfallData()), this, SLOT(resetAvgAcquisitionTime()));

setupReadouts();
installEventFilter(this);
Expand Down Expand Up @@ -378,10 +377,6 @@ void WaterfallDisplayPlot::updateHandleAreaPadding()
{
d_leftHandlesArea->update();
d_bottomHandlesArea->setLeftPadding(d_leftHandlesArea->width());
d_bottomHandlesArea->setRightPadding(50);

d_rightHandlesArea->setTopPadding(50);
d_rightHandlesArea->setBottomPadding(50);

//update handle position to avoid cursors getting out of the plot bounds when changing the padding;
d_hCursorHandle1->updatePosition();
Expand Down Expand Up @@ -465,7 +460,7 @@ QString WaterfallDisplayPlot::formatYValue(double value, int precision) const
}

void WaterfallDisplayPlot::autoScale()
{
{
qDebug() << d_min_val << d_max_val;

setIntensityRange(d_min_val, d_max_val);
Expand Down Expand Up @@ -549,14 +544,17 @@ double WaterfallDisplayPlot::getResolutionBW() const { return d_resolution_bw; }

double WaterfallDisplayPlot::getStopFrequency() const { return d_stop_frequency; }

void WaterfallDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
void WaterfallDisplayPlot::plotNewData(const std::vector<double*> &dataPoints,
const int64_t numDataPoints,
gr::high_res_timer_type acquisitionTime,
const int droppedFrames)
gr::high_res_timer_type acquisitionTime)
{
// Display first half of the plot if d_half_freq is true
int64_t _npoints_in = d_half_freq ? (getStopFrequency() - getStartFrequency()) / getResolutionBW() : numDataPoints;
int64_t _in_index = d_half_freq ? getStartFrequency() / getResolutionBW() : 0;

// there was a fft resize meanwhile event was being sent
if (_npoints_in > numDataPoints - _in_index) return;

double current_time = gr::high_res_timer_now();

// convert to seconds
Expand Down Expand Up @@ -584,26 +582,21 @@ void WaterfallDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
updateCursorsData();

if (!d_stop && _npoints_in > 0) {
if (_npoints_in != d_numPoints) {
d_numPoints = _npoints_in;
resetAxis();

for (unsigned int i = 0; i < d_nplots; ++i) {
d_spectrogram[i]->invalidateCache();
d_spectrogram[i]->itemChanged();
}

if (isVisible()) {
replot();
}
}
d_leftHandlesArea->update();
d_bottomHandlesArea->update();

d_leftHandlesArea->update();
d_bottomHandlesArea->update();
((WaterfallZoomer*)d_zoomer[0])->setSecondsPerLine(time_per_line);
((WaterfallZoomer*)d_zoomer[0])->setCenterTime(centerTime);

((WaterfallZoomer*)d_zoomer[0])->setSecondsPerLine(time_per_line);
((WaterfallZoomer*)d_zoomer[0])->setCenterTime(centerTime);
if (_npoints_in != d_numPoints) {
d_numPoints = _npoints_in;
resetAxis();

for (unsigned int i = 0; i < d_nplots; ++i) {
d_spectrogram[i]->invalidateCache();
d_spectrogram[i]->itemChanged();
}
} else {
for (int i = 0; i<d_nplots; i++) {
if (enabledChannelID != i) {
setAlpha(i, 0);
Expand All @@ -612,19 +605,39 @@ void WaterfallDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
setAlpha(i, 255);
}

d_data[i]->addFFTData(&(dataPoints[i][_in_index]), _npoints_in, droppedFrames);
d_data[i]->addFFTData(&dataPoints[i][_in_index], _npoints_in);
d_data[i]->incrementNumLinesToUpdate();
d_spectrogram[i]->invalidateCache();
d_spectrogram[i]->itemChanged();
}
}

replot();
d_visible_line_count = std::min(d_visible_line_count + 1, d_nrows);
replot();
d_visible_line_count = std::min(d_visible_line_count + 1, d_nrows);
}

Q_EMIT newWaterfallData();
}

void WaterfallDisplayPlot::useLogFreq(bool use_log_freq)
{
if (use_log_freq && d_half_freq) {
setPlotLogaritmic(true);
setAxisScaleEngine(QwtAxis::XBottom, new QwtLogScaleEngine);
replot();
auto div = axisScaleDiv(QwtAxis::XBottom);
setXaxisMajorTicksPos(div.ticks(2));
} else {
setPlotLogaritmic(false);
OscScaleEngine *scaleEngine = new OscScaleEngine();
this->setAxisScaleEngine(QwtAxis::XBottom, (QwtScaleEngine *)scaleEngine);
replot();
auto div = axisScaleDiv(QwtAxis::XBottom);
setXaxisNumDiv((div.ticks(2)).size() - 1);
}
replot();
}

void WaterfallDisplayPlot::setIntensityRange(double minIntensity,
double maxIntensity)
{
Expand Down Expand Up @@ -700,7 +713,7 @@ void WaterfallDisplayPlot::replot()
((WaterfallZoomer*)d_zoomer[0])->updateTrackerText();
}

QwtPlot::replot();
BasicPlot::replot();
}

void WaterfallDisplayPlot::clearData()
Expand Down Expand Up @@ -965,6 +978,18 @@ void WaterfallDisplayPlot::setUpdateTime(double t)
d_time_per_fft = t;
}

void WaterfallDisplayPlot::updateZoomerBase()
{
QRectF rect = QRectF(d_start_frequency, 0, d_stop_frequency - d_start_frequency, d_visible_samples);
getZoomer()->zoom(rect);

getZoomer()->blockSignals(true);
getZoomer()->setZoomBase(rect);
getZoomer()->QwtPlotZoomer::zoom(rect);
getZoomer()->blockSignals(false);

}

void WaterfallDisplayPlot::customEvent(QEvent *e)
{
if (e->type() == WaterfallUpdateEvent::Type()) {
Expand All @@ -973,37 +998,7 @@ void WaterfallDisplayPlot::customEvent(QEvent *e)
const uint64_t numDataPoints = event->getNumDataPoints();
const gr::high_res_timer_type dataTimestamp = event->getDataTimestamp();

for (unsigned int i = 0; i < d_nplots; ++i) {
const double* min_val =
std::min_element(&dataPoints[i][0], &dataPoints[i][numDataPoints - 1]);
const double* max_val =
std::max_element(&dataPoints[i][0], &dataPoints[i][numDataPoints - 1]);
if (*min_val < d_min_val || i == 0)
d_min_val = *min_val;
if (*max_val > d_max_val || i == 0)
d_max_val = *max_val;
}
// autoScale();
// qDebug() << d_min_val << d_max_val;

plotNewData(dataPoints, numDataPoints, dataTimestamp, 0);

// reset zoomer base if plot axis changed
if (getZoomer()->zoomBase().left() != d_start_frequency || getZoomer()->zoomBase().width() != d_stop_frequency - d_start_frequency) {
getZoomer()->blockSignals(true);

auto vert_interval = axisInterval(QwtAxis::YLeft);
auto rect = QRectF(d_start_frequency, vert_interval.minValue(), d_stop_frequency - d_start_frequency, vert_interval.maxValue() - vert_interval.minValue());
getZoomer()->zoom(rect);
getZoomer()->setZoomBase(rect);
getZoomer()->zoom(0);

auto stack = QStack<QRectF>();
stack.push(getZoomer()->zoomStack().first());
getZoomer()->setZoomStack(stack, 0);

getZoomer()->blockSignals(false);
}
plotNewData(dataPoints, numDataPoints, dataTimestamp);
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/WaterfallDisplayPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,9 @@ class WaterfallDisplayPlot : public DisplayPlot
double getStartFrequency() const;
double getStopFrequency() const;

void plotNewData(const std::vector<double*> dataPoints,
void plotNewData(const std::vector<double*> &dataPoints,
const int64_t numDataPoints,
gr::high_res_timer_type acquisitionTime,
const int droppedFrames);
gr::high_res_timer_type acquisitionTime);

void setIntensityRange(double minIntensity, double maxIntensity);
double getMinIntensity(unsigned int which) const;
Expand Down Expand Up @@ -148,6 +147,9 @@ class WaterfallDisplayPlot : public DisplayPlot
void setupReadouts();
void updateCursorsData();

void useLogFreq(bool use_log_freq);
void updateZoomerBase();

public Q_SLOTS:
void
setIntensityColorMapType(const unsigned int, const int, const QColor, const QColor);
Expand All @@ -174,6 +176,7 @@ private Q_SLOTS:
void updatedLowerIntensityLevel(const double);
void updatedUpperIntensityLevel(const double);
void newWaterfallData();
void resetWaterfallData();

private:
void _updateIntensityRangeDisplay();
Expand Down
4 changes: 2 additions & 2 deletions src/spectrumUpdateEvents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ ConstUpdateEvent::getNumDataPoints() const
/***************************************************************************/


WaterfallUpdateEvent::WaterfallUpdateEvent(const std::vector<volk::vector<double>> dataPoints,
WaterfallUpdateEvent::WaterfallUpdateEvent(const std::vector<double*> &dataPoints,
const uint64_t numDataPoints,
const gr::high_res_timer_type dataTimestamp)
: QEvent(QEvent::Type(SpectrumUpdateEventType))
Expand All @@ -415,7 +415,7 @@ if (numDataPoints < 1) {
for (size_t i = 0; i < _nplots; i++) {
_dataPoints.push_back(new double[_numDataPoints]);
if (numDataPoints > 0) {
memcpy(_dataPoints[i], dataPoints[i].data(), _numDataPoints * sizeof(double));
memcpy(_dataPoints[i], dataPoints[i], _numDataPoints * sizeof(double));
}
}

Expand Down
Loading

0 comments on commit fc7959a

Please sign in to comment.