Skip to content

Commit caf430d

Browse files
committed
Add LFP Viewer tests for handling low sampling rates on wide displays
1 parent 3c72049 commit caf430d

3 files changed

Lines changed: 130 additions & 0 deletions

File tree

Plugins/LfpViewer/LfpDisplayCanvas.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,29 @@ bool LfpDisplayCanvas::setChannelRange (int splitIndex, int range, ContinuousCha
633633

634634
return true;
635635
}
636+
637+
int LfpDisplayCanvas::getScreenBufferIndex (int splitIndex, int channel)
638+
{
639+
if (splitIndex < 0 || splitIndex >= displaySplits.size()
640+
|| channel < 0 || channel >= displaySplits[splitIndex]->screenBufferIndex.size())
641+
{
642+
return -1;
643+
}
644+
645+
return displaySplits[splitIndex]->screenBufferIndex[channel];
646+
}
647+
648+
float LfpDisplayCanvas::getScreenBufferMeanValue (int splitIndex, int channel, int sample)
649+
{
650+
if (splitIndex < 0 || splitIndex >= displaySplits.size()
651+
|| channel < 0 || channel >= displaySplits[splitIndex]->getNumChannels()
652+
|| sample < 0 || sample >= displaySplits[splitIndex]->screenBufferWidth)
653+
{
654+
return 0.0f;
655+
}
656+
657+
return displaySplits[splitIndex]->getYCoordMean (channel, sample);
658+
}
636659
#endif
637660

638661
void LfpDisplayCanvas::saveCustomParametersToXml (XmlElement* xml)

Plugins/LfpViewer/LfpDisplayCanvas.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ class TESTABLE LfpDisplayCanvas : public Visualizer,
129129
bool setChannelHeight (int splitIndex, int height);
130130

131131
bool setChannelRange (int splitIndex, int range, ContinuousChannel::Type type);
132+
133+
int getScreenBufferIndex (int splitIndex, int channel);
134+
135+
float getScreenBufferMeanValue (int splitIndex, int channel, int sample);
132136
#endif
133137

134138
bool isLoading;

Plugins/LfpViewer/Tests/LfpDisplayNodeTests.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,16 @@ class LfpDisplayNodeLowRateTests : public LfpDisplayNodeTests
391391
}
392392
};
393393

394+
class LfpDisplayNodeWideLowRatioTests : public LfpDisplayNodeTests
395+
{
396+
protected:
397+
void SetUp() override
398+
{
399+
sampleRate = 2500.0f;
400+
LfpDisplayNodeTests::SetUp();
401+
}
402+
};
403+
394404
// Checks if low sampling rate signals receive a sufficient buffer legnth
395405
TEST_F (LfpDisplayNodeLowRateTests, LowRateDisplayBufferHasMinimumSize)
396406
{
@@ -446,6 +456,99 @@ TEST_F (LfpDisplayNodeLowRateTests, LowRateSignalIsNotFlatLine)
446456
processor->stopAcquisition();
447457
}
448458

459+
TEST_F (LfpDisplayNodeLowRateTests, LowRateFirstSampleAdvancesScreenBuffer)
460+
{
461+
const int canvasX = 600;
462+
const int canvasY = 800;
463+
464+
std::unique_ptr<LfpViewer::LfpDisplayCanvas> canvas =
465+
std::make_unique<LfpViewer::LfpDisplayCanvas> (processor, LfpViewer::SplitLayouts::SINGLE, false);
466+
canvas->updateSettings();
467+
canvas->setSize (canvasX, canvasY);
468+
canvas->resized();
469+
canvas->setVisible (true);
470+
471+
processor->startAcquisition();
472+
canvas->beginAnimation();
473+
474+
auto inputBuffer = createBufferSinusoidal (1, numChannels, 1, 100);
475+
writeBlock (inputBuffer);
476+
canvas->refreshState();
477+
478+
EXPECT_GT (canvas->getScreenBufferIndex (0, 0), 0)
479+
<< "First low-rate sample was consumed without advancing the screen buffer";
480+
481+
processor->stopAcquisition();
482+
}
483+
484+
TEST_F (LfpDisplayNodeWideLowRatioTests, WideDisplayCarriesLowRatioInterpolationPhase)
485+
{
486+
const int canvasX = 6000;
487+
const int canvasY = 800;
488+
489+
std::unique_ptr<LfpViewer::LfpDisplayCanvas> canvas =
490+
std::make_unique<LfpViewer::LfpDisplayCanvas> (processor, LfpViewer::SplitLayouts::SINGLE, false);
491+
canvas->updateSettings();
492+
canvas->setSize (canvasX, canvasY);
493+
canvas->resized();
494+
canvas->setVisible (true);
495+
496+
processor->startAcquisition();
497+
canvas->beginAnimation();
498+
499+
auto firstSample = createBuffer (100.0f, 0.0f, numChannels, 1);
500+
writeBlock (firstSample);
501+
canvas->refreshState();
502+
503+
const int firstRefreshEnd = canvas->getScreenBufferIndex (0, 0);
504+
505+
auto secondSample = createBuffer (200.0f, 0.0f, numChannels, 1);
506+
writeBlock (secondSample);
507+
canvas->refreshState();
508+
509+
const float firstPixelAfterCarry = canvas->getScreenBufferMeanValue (0, 0, firstRefreshEnd);
510+
EXPECT_GT (firstPixelAfterCarry, 150.0f)
511+
<< "Low-ratio interpolation phase restarted instead of carrying across refreshes";
512+
513+
processor->stopAcquisition();
514+
}
515+
516+
TEST_F (LfpDisplayNodeWideLowRatioTests, WideDisplayDoesNotDropPixelsNearOneSamplePerPixel)
517+
{
518+
const int canvasX = 4242;
519+
const int canvasY = 800;
520+
const int blockSamples = 50;
521+
const int numBlocks = 10;
522+
const float timebase = 2.0f;
523+
524+
std::unique_ptr<LfpViewer::LfpDisplayCanvas> canvas =
525+
std::make_unique<LfpViewer::LfpDisplayCanvas> (processor, LfpViewer::SplitLayouts::SINGLE, false);
526+
canvas->updateSettings();
527+
canvas->setSize (canvasX, canvasY);
528+
canvas->resized();
529+
canvas->setVisible (true);
530+
531+
setExpectedImageParameters (canvas.get());
532+
533+
processor->startAcquisition();
534+
canvas->beginAnimation();
535+
536+
for (int block = 0; block < numBlocks; ++block)
537+
{
538+
auto inputBuffer = createBuffer (100.0f, 0.0f, numChannels, blockSamples);
539+
writeBlock (inputBuffer);
540+
canvas->refreshState();
541+
}
542+
543+
const float ratio = sampleRate * timebase / float (width);
544+
const int expectedPixels = int (float (blockSamples * numBlocks) / ratio);
545+
546+
EXPECT_GT (canvas->getScreenBufferIndex (0, 0), expectedPixels - 5)
547+
<< "Samples were consumed without advancing enough screen-buffer pixels";
548+
549+
processor->stopAcquisition();
550+
}
551+
449552
// A connected trace produces signal in almost every pixel column; isolated dots produce
450553
// signal in only ~numSamples columns. The midline band is excluded so a zero-buffer
451554
// flat line scores zero columns.

0 commit comments

Comments
 (0)