Skip to content

Commit a68d15c

Browse files
committed
Add spike raster mode
1 parent 7fc0a97 commit a68d15c

2 files changed

Lines changed: 175 additions & 27 deletions

File tree

Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp

Lines changed: 144 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ void LfpDisplayCanvas::updateScreenBuffer()
386386
float invAlpha = 1.0f - alpha;
387387

388388
screenBuffer->clear(channel, sbi, 1);
389+
screenBufferMean->clear(channel, sbi, 1);
389390
screenBufferMin->clear(channel, sbi, 1);
390391
screenBufferMax->clear(channel, sbi, 1);
391392

@@ -412,6 +413,7 @@ void LfpDisplayCanvas::updateScreenBuffer()
412413
// same thing again, but this time add the min,mean, and max of all samples in current pixel
413414
float sample_min = 10000000;
414415
float sample_max = -10000000;
416+
float sample_mean = 0;
415417

416418
int nextpix = (dbi +(int)ratio +1) % (displayBufferSize+1); // position to next pixels index
417419

@@ -423,8 +425,8 @@ void LfpDisplayCanvas::updateScreenBuffer()
423425
for (int j = dbi; j < nextpix; j++)
424426
{
425427

426-
float sample_current = displayBuffer->getSample(channel, j);
427-
//sample_mean = sample_mean + sample_current;
428+
float sample_current = displayBuffer->getSample(channel, j);
429+
sample_mean = sample_mean + sample_current;
428430

429431
if (sample_min>sample_current)
430432
{
@@ -461,8 +463,8 @@ void LfpDisplayCanvas::updateScreenBuffer()
461463
}else{
462464
sampleCountPerPixel[sbi]=0;
463465
}
464-
//sample_mean = sample_mean/c;
465-
//screenBufferMean->addSample(channel, sbi, sample_mean*gain);
466+
sample_mean = sample_mean/c;
467+
screenBufferMean->addSample(channel, sbi, sample_mean*gain);
466468

467469
screenBufferMin->addSample(channel, sbi, sample_min*gain);
468470
screenBufferMax->addSample(channel, sbi, sample_max*gain);
@@ -579,6 +581,11 @@ bool LfpDisplayCanvas::getInputInvertedState()
579581
return options->getInputInvertedState(); //invertInputButton->getToggleState();
580582
}
581583

584+
bool LfpDisplayCanvas::getDisplaySpikeRasterizerState()
585+
{
586+
return options->getDisplaySpikeRasterizerState();
587+
}
588+
582589
bool LfpDisplayCanvas::getDrawMethodState()
583590
{
584591

@@ -876,23 +883,22 @@ LfpDisplayOptions::LfpDisplayOptions(LfpDisplayCanvas* canvas_, LfpTimescale* ti
876883

877884

878885

879-
// init stream rate displaying options
880-
// streamRateDisplayedOptions.add("High");
881-
// streamRateDisplayedOptions.add("Low");
882-
// selectedStreamRateDisplayed = 1;
883-
// selectedChannelDisplaySkipValue = streamRateDisplayedOptions[selectedStreamRateDisplayed - 1];
884-
//
885-
// streamRateDisplayedSelection = new ComboBox("Displayed Stream Rate");
886-
// streamRateDisplayedSelection->addItemList(streamRateDisplayedOptions, 1);
887-
// streamRateDisplayedSelection->setSelectedId(selectedStreamRateDisplayed, sendNotification);
888-
// streamRateDisplayedSelection->setEditableText(false);
889-
// streamRateDisplayedSelection->addListener(this);
890-
// addAndMakeVisible(streamRateDisplayedSelection);
891-
//
892-
// streamRateDisplayedLabel = new Label("Displayed Stream Rate Label", "Display Stream Rate");
893-
// streamRateDisplayedLabel->setFont(labelFont);
894-
// streamRateDisplayedLabel->setColour(Label::textColourId, labelColour);
895-
// addAndMakeVisible(streamRateDisplayedLabel);
886+
// init spike raster options
887+
spikeRasterSelectionOptions = {"Off", "-50", "-100", "-150", "-200", "-300", "-400", "-500"};
888+
selectedSpikeRasterThreshold = 1;
889+
selectedSpikeRasterThresholdValue = spikeRasterSelectionOptions[selectedSpikeRasterThreshold - 1];
890+
891+
spikeRasterSelection = new ComboBox("spikeRasterSelection");
892+
spikeRasterSelection->addItemList(spikeRasterSelectionOptions, 1);
893+
spikeRasterSelection->setSelectedId(selectedSpikeRasterThreshold, dontSendNotification);
894+
spikeRasterSelection->setEditableText(true);
895+
spikeRasterSelection->addListener(this);
896+
addAndMakeVisible(spikeRasterSelection);
897+
898+
spikeRasterLabel = new Label("spikeRasterLabel", "Spike Raster Thresh.");
899+
spikeRasterLabel->setFont(labelFont);
900+
spikeRasterLabel->setColour(Label::textColourId, labelColour);
901+
addAndMakeVisible(spikeRasterLabel);
896902

897903

898904

@@ -1154,7 +1160,7 @@ void LfpDisplayOptions::resized()
11541160

11551161
pauseButton->setBounds(450,getHeight()-50,50,44);
11561162

1157-
// Channel Zoom Slider
1163+
11581164
// Reverse Channels Display
11591165
reverseChannelsDisplayButton->setBounds(pauseButton->getRight() + 5,
11601166
getHeight() - 50,
@@ -1186,6 +1192,17 @@ void LfpDisplayOptions::resized()
11861192
22);
11871193

11881194

1195+
// Spike raster plotting button
1196+
spikeRasterSelection->setBounds(medianOffsetPlottingButton->getX(),
1197+
medianOffsetPlottingButton->getBottom(),
1198+
60,
1199+
25);
1200+
spikeRasterLabel->setBounds(spikeRasterSelection->getRight(),
1201+
spikeRasterSelection->getY(),
1202+
120,
1203+
22);
1204+
1205+
11891206
// Saturation Warning Selection
11901207
saturationWarningSelection->setBounds(250, getHeight()-90, 60, 25);
11911208

@@ -1285,6 +1302,19 @@ bool LfpDisplayOptions::getInputInvertedState()
12851302
return invertInputButton->getToggleState();
12861303
}
12871304

1305+
bool LfpDisplayOptions::getDisplaySpikeRasterizerState()
1306+
{
1307+
// return spikeRasterButton->getToggleState();
1308+
return false;
1309+
}
1310+
1311+
void LfpDisplayOptions::setDisplaySpikeRasterizerState(bool isEnabled)
1312+
{
1313+
// spikeRasterButton->setToggleState(isEnabled, dontSendNotification);
1314+
1315+
// if (isEnabled) medianOffsetPlottingButton->setToggleState(true, sendNotification);
1316+
}
1317+
12881318
void LfpDisplayOptions::setRangeSelection(float range, bool canvasMustUpdate)
12891319
{
12901320
if (canvasMustUpdate)
@@ -1344,7 +1374,14 @@ void LfpDisplayOptions::buttonClicked(Button* b)
13441374
}
13451375
if (b == medianOffsetPlottingButton)
13461376
{
1347-
lfpDisplay->setMedianOffsetPlotting(b->getToggleState());
1377+
if (lfpDisplay->getSpikeRasterPlotting())
1378+
{
1379+
medianOffsetPlottingButton->setToggleState(true, dontSendNotification);
1380+
}
1381+
else
1382+
{
1383+
lfpDisplay->setMedianOffsetPlotting(b->getToggleState());
1384+
}
13481385
return;
13491386
}
13501387
if (b == drawMethodButton)
@@ -1439,6 +1476,48 @@ void LfpDisplayOptions::comboBoxChanged(ComboBox* cb)
14391476
const int skipAmt = pow(2, cb->getSelectedId() - 1);
14401477
lfpDisplay->setChannelDisplaySkipAmount(skipAmt);
14411478
}
1479+
else if (cb == spikeRasterSelection)
1480+
{
1481+
// if custom value
1482+
if (cb->getSelectedId() == 0)
1483+
{
1484+
auto val = fabsf(cb->getText().getFloatValue());
1485+
1486+
if (val == 0) // if value is zero, just disable plotting and set text to "Off"
1487+
{
1488+
cb->setSelectedItemIndex(0, dontSendNotification);
1489+
lfpDisplay->setSpikeRasterPlotting(false);
1490+
return;
1491+
}
1492+
1493+
if (val > 500)
1494+
{
1495+
val = 500;
1496+
}
1497+
1498+
val *= -1;
1499+
1500+
spikeRasterSelection->setText(String(val), dontSendNotification);
1501+
lfpDisplay->setSpikeRasterThreshold(val);
1502+
medianOffsetPlottingButton->setToggleState(true, dontSendNotification);
1503+
lfpDisplay->setMedianOffsetPlotting(true);
1504+
lfpDisplay->setSpikeRasterPlotting(true);
1505+
}
1506+
else if (cb->getSelectedItemIndex() == 0) // if "Off"
1507+
{
1508+
lfpDisplay->setSpikeRasterPlotting(false);
1509+
return;
1510+
}
1511+
else
1512+
{
1513+
auto val = cb->getText().getFloatValue();
1514+
1515+
lfpDisplay->setSpikeRasterThreshold(val);
1516+
medianOffsetPlottingButton->setToggleState(true, dontSendNotification);
1517+
lfpDisplay->setMedianOffsetPlotting(true);
1518+
lfpDisplay->setSpikeRasterPlotting(true);
1519+
}
1520+
}
14421521
else if (cb == colourSchemeOptionSelection)
14431522
{
14441523
// hide the old colour scheme config options if they are displayed
@@ -2585,6 +2664,26 @@ void LfpDisplay::setMedianOffsetPlotting(bool isEnabled)
25852664
m_MedianOffsetPlottingFlag = isEnabled;
25862665
}
25872666

2667+
bool LfpDisplay::getSpikeRasterPlotting()
2668+
{
2669+
return m_SpikeRasterPlottingFlag;
2670+
}
2671+
2672+
void LfpDisplay::setSpikeRasterPlotting(bool isEnabled)
2673+
{
2674+
m_SpikeRasterPlottingFlag = isEnabled;
2675+
}
2676+
2677+
float LfpDisplay::getSpikeRasterThreshold()
2678+
{
2679+
return m_SpikeRasterThreshold;
2680+
}
2681+
2682+
void LfpDisplay::setSpikeRasterThreshold(float thresh)
2683+
{
2684+
m_SpikeRasterThreshold = thresh;
2685+
}
2686+
25882687
void LfpDisplay::mouseWheelMove(const MouseEvent& e, const MouseWheelDetails& wheel)
25892688
{
25902689

@@ -3179,6 +3278,10 @@ void LfpChannelDisplay::pxPaint()
31793278
if (from_raw < -options->selectedSaturationValueFloat) { saturateWarningLo=true;};
31803279
if (to_raw < -options->selectedSaturationValueFloat) { saturateWarningLo=true;};
31813280

3281+
bool spikeFlag = display->getSpikeRasterPlotting()
3282+
&& !(saturateWarningHi || saturateWarningLo)
3283+
&& (from_raw - canvas->getYCoordMean(chan, i) < display->getSpikeRasterThreshold()
3284+
|| to_raw - canvas->getYCoordMean(chan, i) < display->getSpikeRasterThreshold());
31823285

31833286
from = from + getHeight()/2; // so the plot is centered in the channeldisplay
31843287
to = to + getHeight()/2;
@@ -3202,7 +3305,7 @@ void LfpChannelDisplay::pxPaint()
32023305
plotterInfo.samplerange = samplerange;
32033306

32043307
// TODO: (kelly) complete transition toward plotter class encapsulation
3205-
display->getPlotterPtr()->plot(bdLfpChannelBitmap, plotterInfo);
3308+
// display->getPlotterPtr()->plot(bdLfpChannelBitmap, plotterInfo);
32063309

32073310
}
32083311
else //drawmethod
@@ -3216,10 +3319,17 @@ void LfpChannelDisplay::pxPaint()
32163319
plotterInfo.lineColour = lineColour;
32173320

32183321
// TODO: (kelly) complete transition toward plotter class encapsulation
3219-
display->getPlotterPtr()->plot(bdLfpChannelBitmap, plotterInfo); // plotterInfo is prepared above
3322+
// display->getPlotterPtr()->plot(bdLfpChannelBitmap, plotterInfo); // plotterInfo is prepared above
32203323

32213324
}
32223325

3326+
// Do the actual plotting for the selected plotting method
3327+
if (!display->getSpikeRasterPlotting())
3328+
display->getPlotterPtr()->plot(bdLfpChannelBitmap, plotterInfo);
3329+
3330+
3331+
3332+
32233333
// now draw warnings, if needed
32243334
if (canvas->drawClipWarning) // draw simple warning if display cuts off data
32253335
{
@@ -3250,6 +3360,15 @@ void LfpChannelDisplay::pxPaint()
32503360
clipWarningLo=false;
32513361
}
32523362

3363+
if (spikeFlag) // draw spikes
3364+
{
3365+
for (int k=jfrom_wholechannel; k<=jto_wholechannel; k++){ // draw line
3366+
if(k>0 & k<display->lfpChannelBitmap.getHeight()){
3367+
bdLfpChannelBitmap.setPixelColour(i,k,lineColour);
3368+
}
3369+
};
3370+
}
3371+
32533372

32543373
if (canvas->drawSaturationWarning) // draw bigger warning if actual data gets cuts off
32553374
{

Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ class LfpDisplayCanvas : public Visualizer,
105105
/** Returns the number of channels NOT hidden for display */
106106
int getNumChannelsVisible();
107107
bool getInputInvertedState();
108+
109+
/** Returns a bool describing whether the spike raster functionality is enabled */
110+
bool getDisplaySpikeRasterizerState();
111+
108112
bool getDrawMethodState();
109113

110114
int getChannelSampleRate(int channel);
@@ -270,6 +274,12 @@ class LfpDisplayOptions : public Component,
270274
int getChannelHeight();
271275
bool getDrawMethodState();
272276
bool getInputInvertedState();
277+
278+
/** Return a bool describing whether the spike raster functionality is enabled */
279+
bool getDisplaySpikeRasterizerState();
280+
281+
/** Sets the state of the spike raster functionality on/off */
282+
void setDisplaySpikeRasterizerState(bool isEnabled);
273283

274284
//void setRangeSelection(float range, bool canvasMustUpdate);
275285
void setSpreadSelection();
@@ -298,8 +308,8 @@ class LfpDisplayOptions : public Component,
298308
int selectedChannelDisplaySkip;
299309
String selectedChannelDisplaySkipValue;
300310

301-
int selectedStreamRateDisplayed;
302-
String selectedStreamRateDisplayedValue;
311+
int selectedSpikeRasterThreshold;
312+
String selectedSpikeRasterThresholdValue;
303313

304314
// this enum is a candidate option for refactoring, not used yet
305315
enum ChannelDisplaySkipValue {
@@ -342,6 +352,11 @@ class LfpDisplayOptions : public Component,
342352
ScopedPointer<UtilityButton> pauseButton;
343353
OwnedArray<UtilityButton> typeButtons;
344354

355+
// label and button for spike raster functionality
356+
ScopedPointer<Label> spikeRasterLabel;
357+
ScopedPointer<ComboBox> spikeRasterSelection;
358+
StringArray spikeRasterSelectionOptions;
359+
345360
// label and button for reversing the order of displayed channels
346361
ScopedPointer<Label> reverseChannelsDisplayLabel;
347362
ScopedPointer<UtilityButton> reverseChannelsDisplayButton;
@@ -543,6 +558,18 @@ class LfpDisplay : public Component
543558

544559
/** Sets the state for the median offset plotting function */
545560
void setMedianOffsetPlotting(bool isEnabled);
561+
562+
/** Returns true if spike raster is enabled for plotting, else false */
563+
bool getSpikeRasterPlotting();
564+
565+
/** Sets the state for the spike raster plotting function */
566+
void setSpikeRasterPlotting(bool isEnabled);
567+
568+
/** Returns the value at which the spike raster will detect and draw spikes */
569+
float getSpikeRasterThreshold();
570+
571+
/** Set the threshold value for the spike raster plotting function */
572+
void setSpikeRasterThreshold(float thresh);
546573

547574
/** Returns true if a single channel is focused in viewport */
548575
bool getSingleChannelState();
@@ -626,6 +653,8 @@ class LfpDisplay : public Component
626653

627654
bool channelsReversed;
628655
bool m_MedianOffsetPlottingFlag;
656+
bool m_SpikeRasterPlottingFlag;
657+
float m_SpikeRasterThreshold;
629658

630659
LfpDisplayCanvas* canvas;
631660
Viewport* viewport;

0 commit comments

Comments
 (0)