Skip to content
Snippets Groups Projects
Commit c6faf745 authored by Stuart Layton's avatar Stuart Layton
Browse files

initial commit of SpikePlot.cpp and SpikePlot.h which define a general spike...

initial commit of SpikePlot.cpp and SpikePlot.h which define a general spike plotting object that can completely replace ElectrodePlot, TetrodePlot, StereotrodePlot. SpikePlot objects can be added to the canvas and render fine, however, eventually the Tetrode variant of the SpikePlot causes a segfault, probably due to the way that spikes are copied around in the SpikeDisplayCanvas.
parent d0abe5ec
No related branches found
No related tags found
No related merge requests found
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
0BBDB7C2B8CE82F1B0844B70 /* Documentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8214D83845C25F39EEC13CD /* Documentation.cpp */; }; 0BBDB7C2B8CE82F1B0844B70 /* Documentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8214D83845C25F39EEC13CD /* Documentation.cpp */; };
0DDC562EC2B04A26AE6CBB2B /* TetrodePlot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBB9A423728922E96F55074F /* TetrodePlot.cpp */; }; 0DDC562EC2B04A26AE6CBB2B /* TetrodePlot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBB9A423728922E96F55074F /* TetrodePlot.cpp */; };
116BB2F62451986C75586F9D /* ControlPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5AB4A3A63B9FDEAB09EEC9C8 /* ControlPanel.cpp */; }; 116BB2F62451986C75586F9D /* ControlPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5AB4A3A63B9FDEAB09EEC9C8 /* ControlPanel.cpp */; };
1180A1E3160BF28E0075D163 /* SpikePlot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1180A1E1160BF28E0075D163 /* SpikePlot.cpp */; };
11885833D32D03BA7E17138A /* DiscRecording.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AFA895DFA2087804F47ECF9 /* DiscRecording.framework */; }; 11885833D32D03BA7E17138A /* DiscRecording.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AFA895DFA2087804F47ECF9 /* DiscRecording.framework */; };
13457B3248E7646270A4FF88 /* CustomLookAndFeel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A32D8455B95FD230EBFD7891 /* CustomLookAndFeel.cpp */; }; 13457B3248E7646270A4FF88 /* CustomLookAndFeel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A32D8455B95FD230EBFD7891 /* CustomLookAndFeel.cpp */; };
14BE1E76E7BB3593A5F66DCC /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF41F256D0C244C2C02AE6E1 /* QuickTime.framework */; }; 14BE1E76E7BB3593A5F66DCC /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF41F256D0C244C2C02AE6E1 /* QuickTime.framework */; };
...@@ -123,6 +124,8 @@ ...@@ -123,6 +124,8 @@
0D20C3399D0492771F7A808A /* State.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = State.cpp; path = ../../Source/Dsp/State.cpp; sourceTree = SOURCE_ROOT; }; 0D20C3399D0492771F7A808A /* State.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = State.cpp; path = ../../Source/Dsp/State.cpp; sourceTree = SOURCE_ROOT; };
0D2903C450AE862C2C0060AA /* FileReaderThread.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FileReaderThread.cpp; path = ../../Source/Processors/DataThreads/FileReaderThread.cpp; sourceTree = SOURCE_ROOT; }; 0D2903C450AE862C2C0060AA /* FileReaderThread.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FileReaderThread.cpp; path = ../../Source/Processors/DataThreads/FileReaderThread.cpp; sourceTree = SOURCE_ROOT; };
10F82563E4A633BC234B2800 /* SignalGeneratorEditor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SignalGeneratorEditor.h; path = ../../Source/Processors/Editors/SignalGeneratorEditor.h; sourceTree = SOURCE_ROOT; }; 10F82563E4A633BC234B2800 /* SignalGeneratorEditor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SignalGeneratorEditor.h; path = ../../Source/Processors/Editors/SignalGeneratorEditor.h; sourceTree = SOURCE_ROOT; };
1180A1E1160BF28E0075D163 /* SpikePlot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SpikePlot.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/SpikePlot.cpp; sourceTree = "<group>"; };
1180A1E2160BF28E0075D163 /* SpikePlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpikePlot.h; path = ../../Source/Processors/Visualization/SpikePlotting/SpikePlot.h; sourceTree = "<group>"; };
126B0DE9B8D4E42DA7D57AAB /* sine_wave.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = sine_wave.png; path = ../../Resources/Images/Icons/sine_wave.png; sourceTree = SOURCE_ROOT; }; 126B0DE9B8D4E42DA7D57AAB /* sine_wave.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = sine_wave.png; path = ../../Resources/Images/Icons/sine_wave.png; sourceTree = SOURCE_ROOT; };
12866D44BE115E8837468F48 /* AudioNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioNode.h; path = ../../Source/Processors/AudioNode.h; sourceTree = SOURCE_ROOT; }; 12866D44BE115E8837468F48 /* AudioNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioNode.h; path = ../../Source/Processors/AudioNode.h; sourceTree = SOURCE_ROOT; };
137CF1AB4144076D79D50975 /* PoleFilter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PoleFilter.cpp; path = ../../Source/Dsp/PoleFilter.cpp; sourceTree = SOURCE_ROOT; }; 137CF1AB4144076D79D50975 /* PoleFilter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PoleFilter.cpp; path = ../../Source/Dsp/PoleFilter.cpp; sourceTree = SOURCE_ROOT; };
...@@ -398,6 +401,8 @@ ...@@ -398,6 +401,8 @@
1255E9B28ADAA1A1CADC4A6E /* SpikePlotting */ = { 1255E9B28ADAA1A1CADC4A6E /* SpikePlotting */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1180A1E1160BF28E0075D163 /* SpikePlot.cpp */,
1180A1E2160BF28E0075D163 /* SpikePlot.h */,
C92B3F413B0F24752ADE6730 /* StereotrodePlot.cpp */, C92B3F413B0F24752ADE6730 /* StereotrodePlot.cpp */,
FDD549F527C378CF36BDB8C7 /* StereotrodePlot.h */, FDD549F527C378CF36BDB8C7 /* StereotrodePlot.h */,
3BB44F767E701E3642435FA0 /* ElectrodePlot.cpp */, 3BB44F767E701E3642435FA0 /* ElectrodePlot.cpp */,
...@@ -964,6 +969,7 @@ ...@@ -964,6 +969,7 @@
FD157D98C4C31AE782659718 /* JuceLibraryCode2.mm in Sources */, FD157D98C4C31AE782659718 /* JuceLibraryCode2.mm in Sources */,
09AC8D29A08EE1FFBC4ADB23 /* JuceLibraryCode3.mm in Sources */, 09AC8D29A08EE1FFBC4ADB23 /* JuceLibraryCode3.mm in Sources */,
05339DCA8C59B707E61F1F2E /* JuceLibraryCode4.mm in Sources */, 05339DCA8C59B707E61F1F2E /* JuceLibraryCode4.mm in Sources */,
1180A1E3160BF28E0075D163 /* SpikePlot.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
......
...@@ -52,12 +52,25 @@ SpikeDisplayCanvas::~SpikeDisplayCanvas() ...@@ -52,12 +52,25 @@ SpikeDisplayCanvas::~SpikeDisplayCanvas()
void SpikeDisplayCanvas::initializeSpikePlots(){ void SpikeDisplayCanvas::initializeSpikePlots(){
std::cout<<"Initializing Plots"<<std::endl; std::cout<<"Initializing Plots"<<std::endl;
// This layout system really only works if plot types are aggregated together.
// It might be worthwhile to investigate the merits of using a grid system
// The canvas is defined as N grid widths wide. Each SpikePlot defines its
// dimensions in grid widths.
//
// Plots are added from left to right, top to bottom. A plot is put into place
// if it can fit into the next grid location w/o its top going above the current
// row and w/o its bottom going below the current row
//
// This would lead to dead space but it would allow the plots to all scale accoring
// to how much space they need. The current system of deciding plot sizes, isn't going
// to scale well.... this needs more thought
if (plots.size() != nPlots) if (plots.size() != nPlots)
{ {
int totalWidth = getWidth(); int totalWidth = getWidth();
int plotWidth = (totalWidth - yBuffer * ( nCols+1)) / nCols + .99; int plotWidth = (totalWidth - yBuffer * ( nCols+1)) / nCols + .99;
int plotHeight = plotWidth / 2 + .5; int plotHeight = plotWidth / 2 + .5;
int rowCount = 0; int rowCount = 0;
...@@ -66,77 +79,44 @@ void SpikeDisplayCanvas::initializeSpikePlots(){ ...@@ -66,77 +79,44 @@ void SpikeDisplayCanvas::initializeSpikePlots(){
for (int i = 0; i < nPlots; i++) for (int i = 0; i < nPlots; i++)
{ {
int pType;
switch (processor->getNumberOfChannelsForElectrode(i)) switch (processor->getNumberOfChannelsForElectrode(i)){
{
case 1: case 1:
{ pType = SINGLE_PLOT;
break;
std::cout << "Creating single electrode plot." << std::endl;
ElectrodePlot* p1 = new ElectrodePlot(
xBuffer + i%nCols * (plotWidth + xBuffer) ,
yBuffer + rowCount * (plotHeight + yBuffer),
plotWidth,
plotHeight);
plots.add(p1);
break;
}
case 2: case 2:
{ pType = STEREO_PLOT;
break;
std::cout << "Creating stereotrode plot." << std::endl;
StereotrodePlot* p2 = new StereotrodePlot(
xBuffer + i%nCols * (plotWidth + xBuffer) ,
yBuffer + rowCount * (plotHeight + yBuffer),
plotWidth,
plotHeight);
plots.add(p2);
break;
}
case 4: case 4:
{ pType = TETRODE_PLOT;
std::cout << "Creating tetrode plot." << std::endl; break;
default:
TetrodePlot* p3 = new TetrodePlot( pType = SINGLE_PLOT;
xBuffer + i%nCols * (plotWidth + xBuffer) , break;
yBuffer + rowCount * (plotHeight + yBuffer), }
plotWidth,
plotHeight); // bool use_generic_plots_flag = true;
plots.add(p3);
break; // BaseUIElement *sp;
}
default: // if (use_generic_plots_flag)
{ SpikePlot *sp = new SpikePlot(xBuffer + i%nCols * (plotWidth + xBuffer) ,
yBuffer + rowCount * (plotHeight + yBuffer),
std::cout << "Not sure what to do, creating single electrode plot." << std::endl; plotWidth, plotHeight, pType);
ElectrodePlot* p4 = new ElectrodePlot( // else
xBuffer + i%nCols * (plotWidth + xBuffer) , // sp = new StereotrodePlot(xBuffer + i%nCols * (plotWidth + xBuffer) ,
yBuffer + rowCount * (plotHeight + yBuffer), // yBuffer + rowCount * (plotHeight + yBuffer),
plotWidth, // plotWidth, plotHeight);
plotHeight); plots.add(sp);
plots.add(p4);
}
}
// SpikeObject tmpSpike;
// generateEmptySpike(&tmpSpike, 4);
// p.processSpikeObject(tmpSpike);
// plots.push_back(p);
if (i%nCols == nCols-1) if (i%nCols == nCols-1)
rowCount++; rowCount++;
} }
//totalHeight = rowCount * (plotHeight + yBuffer) + yBuffer * 2; //totalHeight = rowCount * (plotHeight + yBuffer) + yBuffer * 2;
// Set the total height of the Canvas to the top of the top most plot // Set the total height of the Canvas to the top of the top most plot
plotsInitialized = true;
plotsInitialized = true;
repositionSpikePlots(); repositionSpikePlots();
} }
} }
...@@ -319,7 +299,7 @@ void SpikeDisplayCanvas::processSpikeEvents() ...@@ -319,7 +299,7 @@ void SpikeDisplayCanvas::processSpikeEvents()
generateSimulatedSpike(&simSpike, 0, 0); generateSimulatedSpike(&simSpike, 0, 0);
for (int i = 0; i < 80; i++) for (int i = 0; i < newSpike.nChannels * newSpike.nSamples; i++)
{ {
simSpike.data[i] = newSpike.data[i] + 5000;// * 3 - 10000; simSpike.data[i] = newSpike.data[i] + 5000;// * 3 - 10000;
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "SpikePlotting/ElectrodePlot.h" #include "SpikePlotting/ElectrodePlot.h"
#include "SpikePlotting/StereotrodePlot.h" #include "SpikePlotting/StereotrodePlot.h"
#include "SpikePlotting/TetrodePlot.h" #include "SpikePlotting/TetrodePlot.h"
#include "SpikePlotting/SpikePlot.h"
#include "SpikeObject.h" #include "SpikeObject.h"
#include "Visualizer.h" #include "Visualizer.h"
......
#include "SpikePlot.h"
#include "../SpikeObject.h"
#include "PlotUtils.h"
SpikePlot::SpikePlot():
BaseUIElement(), limitsChanged(true), nChannels(0), plotType(0), nWaveAx(1), nProjAx(0)
{
}
SpikePlot::SpikePlot(int x, int y, int w, int h, int p):
BaseUIElement(x,y,w,h,0), limitsChanged(true), plotType(p)
{
switch(p){
case SINGLE_PLOT:
std::cout<<"SpikePlot as SINGLE_PLOT"<<std::endl;
nWaveAx = 1;
nProjAx = 0;
nChannels = 1;
break;
case STEREO_PLOT:
std::cout<<"SpikePlot as STEREO_PLOT"<<std::endl;
nWaveAx = 2;
nProjAx = 1;
nChannels = 2;
break;
case TETRODE_PLOT:
std::cout<<"SpikePlot as TETRODE_PLOT"<<std::endl;
nWaveAx = 4;
nProjAx = 6;
nChannels = 4;
break;
// case HIST_PLOT:
// nWaveAx = 1;
// nProjAx = 0;
// nHistAx = 1;
// break;
default: // unsupported number of axes provided
std::cout<<"SpikePlot as UNKNOWN, defaulting to SINGLE_PLOT"<<std::endl;
nWaveAx = 1;
nProjAx = 0;
plotType = SINGLE_PLOT;
nChannels = 1;
}
initAxes();
}
SpikePlot::~SpikePlot(){
}
// Each plot needs to update its children axes when its redraw gets called.
// it also needs to call the parent plot when children axes get added it
// should place them in the correct location because it KNOWS where WAVE1 and PROJ1x3
// should go by default. This isn't as general as it should be but its a good push in
// the right direction
void SpikePlot::redraw(){
//std::cout<<"SpikePlot() starting drawing"<<std::endl;\
//BaseUIElement::clearNextDraw = true;
//BaseUIElement::redraw();
for (int i=0; i<nWaveAx; i++)
wAxes[i].redraw();
// wAxes[1].redraw();
for (int i=0; i<nProjAx; i++)
pAxes[i].redraw();
}
// This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes
void SpikePlot::processSpikeObject(SpikeObject s){
//std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl;
for (int i=0; i<nWaveAx; i++)
wAxes[i].updateSpikeData(s);
// wAxes[1].updateSpikeData(s);
for (int i=0; i<nProjAx; i++)
pAxes[i].updateSpikeData(s);
}
void SpikePlot::setEnabled(bool e){
BaseUIElement::enabled = e;
for (int i=0; i<nWaveAx; i++)
wAxes[i].setEnabled(e);
// wAxes[1].setEnabled(e);
for (int i=0; i<nProjAx; i++)
pAxes[i].setEnabled(e);
}
bool SpikePlot::getEnabled(){
return BaseUIElement::enabled;
}
void SpikePlot::initAxes(){
initLimits();
for (int i=0; i<nWaveAx; i++){
wAxes[i] = WaveAxes(0, 0, 1, 1, WAVE1 + i); // add i to increment the wave channel
wAxes[i].setWaveformColor(1.0, 1.0, 1.0);
}
// wAxes[1] = WaveAxes(0, 0, 1, 1, WAVE2);
// wAxes[0].setWaveformColor(1.0, 1.0, 1.0);
// wAxes[1].setWaveformColor(1.0, 1.0, 1.0);
for (int i=0; i<nProjAx; i++){
pAxes[i] = ProjectionAxes(0, 0, 1, 1, PROJ1x2 + i);
pAxes[i].setPointColor(1.0, 1.0, 1.0);
}
updateAxesPositions();
setLimitsOnAxes();
}
void SpikePlot::updateAxesPositions(){
int minX = BaseUIElement::xpos;
int minY = BaseUIElement::ypos;
/*
* This code is BUGGY it doesn't scale with the number of plot dimensions!
* Need to split it into a switch case
*/
double axesWidth;// = BaseUIElement::width/2;
double axesHeight;// = BaseUIElement::height;
int nProjCols, nWaveCols;
switch (plotType){
case SINGLE_PLOT:
nProjCols = 0;
nWaveCols = 1;
axesWidth = width;
axesHeight = height;
break;
case STEREO_PLOT:
nProjCols = 1;
nWaveCols = 2;
axesWidth = width/2;
axesHeight = height;
break;
case TETRODE_PLOT:
nProjCols = 3;
nWaveCols = 2;
axesWidth = width/4;
axesHeight = height/2;
break;
}
for (int i=0; i<nWaveAx; i++)
wAxes[i].setPosition(minX + (i % nWaveCols) * axesWidth, minY + (i/nWaveCols) * axesHeight, axesWidth, axesHeight);
for (int i=0; i<nProjAx; i++)
pAxes[i].setPosition(minX + (1 + i%nProjCols) * axesWidth, minY + (i/nProjCols) * axesHeight, axesWidth, axesHeight);
}
void SpikePlot::setLimitsOnAxes(){
std::cout<<"SpikePlot::setLimitsOnAxes()"<<std::endl;
for (int i=0; i<nWaveAx; i++)
wAxes[i].setYLims(limits[0][0], limits[0][1]);
for (int i=0; i<nProjAx; i++){
pAxes[i].setYLims(limits[0][0], limits[0][1]);
pAxes[i].setXLims(limits[1][0], limits[1][1]);
}
}
void SpikePlot::setPosition(int x, int y, double w, double h){
// std::cout<<"SpikePlot::setPosition()"<<std::endl;
BaseUIElement::setPosition(x,y,w,h);
updateAxesPositions();
}
void SpikePlot::initLimits(){
for (int i=0; i<nChannels; i++)
{
limits[i][0] = 3045;//-1*pow(2,11);
limits[i][1] = 9503;//pow(2,14)*1.6;
}
}
void SpikePlot::getPreferredDimensions(double *w, double *h){
*w = 150;
*h = 75;
}
void SpikePlot::clear(){
std::cout<<"SpikePlot::clear()"<<std::endl;
for (int i=0; i<nWaveAx; i++)
wAxes[i].clear();
for (int i=0; i<nProjAx; i++)
pAxes[i].clear();
}
bool SpikePlot::processKeyEvent(SimpleKeyEvent k){
return true;
}
void SpikePlot::pan(int dim, bool up){
std::cout<<"SpikePlot::pan() dim:"<<dim<<std::endl;
if (dim>1 || dim<0)
return;
int mean = (limits[dim][0] + limits[dim][1])/2;
int dLim = limits[dim][1] - mean;
if (up)
mean = mean + dLim/20;
else
mean = mean - dLim/20;
limits[dim][0] = mean-dLim;
limits[dim][1] = mean+dLim;
setLimitsOnAxes();
}
void SpikePlot::zoom(int dim, bool in){
std::cout<<"SpikePlot::zoom()"<<std::endl;
if (dim>1 || dim<0)
return;
int mean = (limits[dim][0] + limits[dim][1])/2;
int dLim = limits[dim][1] - mean;
if (in)
dLim = dLim * .90;
else
dLim = dLim / .90;
limits[dim][0] = mean-dLim;
limits[dim][1] = mean+dLim;
setLimitsOnAxes();
}
#ifndef SPIKE_PLOT_H_
#define SPIKE_PLOT_H_
#if defined(__linux__)
#include <GL/glut.h>
#else
#include <GLUT/glut.h>
#endif
#include <list>
#include <math.h>
#include "WaveAxes.h"
#include "ProjectionAxes.h"
#include "BaseUIElement.h"
#include "PlotUtils.h"
#include "SimpleKeyEvent.h"
#define TETRODE_PLOT 1004
#define STEREO_PLOT 1002
#define SINGLE_PLOT 1001
//#define HIST_PLOT 1000 // perhaps we'll use hist plots at a later date but not for now
class SpikePlot : public BaseUIElement{
bool enabled;
bool limitsChanged;
static const int MAX_N_CHAN = 4;
static const int MAX_N_PROJ = 6;
int nChannels;
int plotType;
int nWaveAx;
int nProjAx;
double limits[MAX_N_CHAN][2];
WaveAxes wAxes[MAX_N_CHAN];
ProjectionAxes pAxes[MAX_N_PROJ];
// void zoomAxes(int n, bool xdim, int zoomval);
// void zoomProjection (int n, bool xdim, int zoomval);
// void zoomWaveform (int n, bool xdim, int zoomval);
// void panAxes(int n, bool xdim, int panval);
// void panProjection (int n, bool xdim, int panval);
// void panWaveform(int n, bool xdim, int panval);
void initLimits();
void setLimitsOnAxes();
void updateAxesPositions();
public:
SpikePlot();
SpikePlot(int x, int y,int w,int h, int pType);
virtual ~SpikePlot();
void initAxes();
void redraw();
void setEnabled(bool enabled);
bool getEnabled();
void setPosition(int,int,double,double);
void getPreferredDimensions(double*, double*);
void mouseDown(int x, int y);
void mouseDragX(int dx, bool shift, bool ctr);
void mouseDragY(int dy, bool shift, bool ctr);
bool processKeyEvent(SimpleKeyEvent k);
void processSpikeObject(SpikeObject s);
void clear();
void zoom(int, bool);
void pan(int, bool);
};
#endif
...@@ -29,25 +29,31 @@ void StereotrodePlot::redraw(){ ...@@ -29,25 +29,31 @@ void StereotrodePlot::redraw(){
//BaseUIElement::clearNextDraw = true; //BaseUIElement::clearNextDraw = true;
//BaseUIElement::redraw(); //BaseUIElement::redraw();
wAxes[0].redraw(); for (int i=0; i<nWaveAx; i++)
wAxes[1].redraw(); wAxes[i].redraw();
pAxes[0].redraw(); // wAxes[1].redraw();
for (int i=0; i<nProjAx; i++)
pAxes[i].redraw();
} }
// This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes // This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes
void StereotrodePlot::processSpikeObject(SpikeObject s){ void StereotrodePlot::processSpikeObject(SpikeObject s){
//std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl; //std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl;
wAxes[0].updateSpikeData(s); for (int i=0; i<nWaveAx; i++)
wAxes[1].updateSpikeData(s); wAxes[i].updateSpikeData(s);
pAxes[0].updateSpikeData(s); // wAxes[1].updateSpikeData(s);
for (int i=0; i<nProjAx; i++)
pAxes[i].updateSpikeData(s);
} }
void StereotrodePlot::setEnabled(bool e){ void StereotrodePlot::setEnabled(bool e){
BaseUIElement::enabled = e; BaseUIElement::enabled = e;
wAxes[0].setEnabled(e); for (int i=0; i<nWaveAx; i++)
wAxes[1].setEnabled(e); wAxes[i].setEnabled(e);
pAxes[0].setEnabled(e); // wAxes[1].setEnabled(e);
for (int i=0; i<nProjAx; i++)
pAxes[i].setEnabled(e);
} }
bool StereotrodePlot::getEnabled(){ bool StereotrodePlot::getEnabled(){
...@@ -57,32 +63,47 @@ bool StereotrodePlot::getEnabled(){ ...@@ -57,32 +63,47 @@ bool StereotrodePlot::getEnabled(){
void StereotrodePlot::initAxes(){ void StereotrodePlot::initAxes(){
initLimits(); initLimits();
for (int i=0; i<nWaveAx; i++){
wAxes[i] = WaveAxes(0, 0, 1, 1, WAVE1 + i); // add i to increment the wave channel
wAxes[i].setWaveformColor(1.0, 1.0, 1.0);
}
// wAxes[1] = WaveAxes(0, 0, 1, 1, WAVE2);
// wAxes[0].setWaveformColor(1.0, 1.0, 1.0);
// wAxes[1].setWaveformColor(1.0, 1.0, 1.0);
for (int i=0; i<nProjAx; i++){
pAxes[i] = ProjectionAxes(0, 0, 1, 1, PROJ1x2 + i);
pAxes[i].setPointColor(1.0, 1.0, 1.0);
}
updateAxesPositions();
setLimitsOnAxes();
}
void StereotrodePlot::updateAxesPositions(){
int minX = BaseUIElement::xpos; int minX = BaseUIElement::xpos;
int minY = BaseUIElement::ypos; int minY = BaseUIElement::ypos;
double axesWidth = BaseUIElement::width/2; double axesWidth = BaseUIElement::width/2;
double axesHeight = BaseUIElement::height; double axesHeight = BaseUIElement::height;
for (int i=0; i<nWaveAx; i++)
wAxes[0] = WaveAxes(minX, minY, axesWidth/2, axesHeight, WAVE1); wAxes[i].setPosition(minX + (i%2) * axesWidth/2, minY + (i/2) * axesHeight, axesWidth/2, axesHeight);
wAxes[1] = WaveAxes(minX + axesWidth/2, minY, axesWidth/2, axesHeight, WAVE2); // wAxes[1].setPosition(minX + axesWidth/2, minY, axesWidth/2, axesHeight);
wAxes[0].setWaveformColor(1.0, 1.0, 1.0); for (int i=0; i<nProjAx; i++)
wAxes[1].setWaveformColor(1.0, 1.0, 1.0); pAxes[0].setPosition(minX + (1 + i%2) * axesWidth, minY + (i/2) * axesHeight, axesWidth, axesHeight);
pAxes[0] = ProjectionAxes(minX + axesWidth, minY, axesWidth, axesHeight, PROJ1x2);
pAxes[0].setPointColor(1.0, 1.0, 1.0);
setLimitsOnAxes();
} }
void StereotrodePlot::setLimitsOnAxes(){ void StereotrodePlot::setLimitsOnAxes(){
std::cout<<"StereotrodePlot::setLimitsOnAxes()"<<std::endl; std::cout<<"StereotrodePlot::setLimitsOnAxes()"<<std::endl;
wAxes[0].setYLims(limits[0][0], limits[0][1]); for (int i=0; i<nWaveAx; i++)
wAxes[1].setYLims(limits[1][0], limits[1][1]); wAxes[i].setYLims(limits[0][0], limits[0][1]);
pAxes[0].setYLims(limits[0][0], limits[0][1]); // wAxes[1].setYLims(limits[1][0], limits[1][1]);
pAxes[0].setXLims(limits[1][0], limits[1][1]); for (int i=0; i<nProjAx; i++){
pAxes[i].setYLims(limits[0][0], limits[0][1]);
pAxes[i].setXLims(limits[1][0], limits[1][1]);
}
} }
...@@ -90,15 +111,8 @@ void StereotrodePlot::setPosition(int x, int y, double w, double h){ ...@@ -90,15 +111,8 @@ void StereotrodePlot::setPosition(int x, int y, double w, double h){
// std::cout<<"StereotrodePlot::setPosition()"<<std::endl; // std::cout<<"StereotrodePlot::setPosition()"<<std::endl;
BaseUIElement::setPosition(x,y,w,h); BaseUIElement::setPosition(x,y,w,h);
int minX = BaseUIElement::xpos; updateAxesPositions();
int minY = BaseUIElement::ypos;
double axesWidth = BaseUIElement::width/2;
double axesHeight = BaseUIElement::height;
wAxes[0].setPosition(minX, minY, axesWidth/2, axesHeight);
wAxes[1].setPosition(minX + axesWidth/2, minY, axesWidth/2, axesHeight);
pAxes[0].setPosition(minX + axesWidth, minY, axesWidth, axesHeight);
} }
int StereotrodePlot::getNumberOfAxes(){ int StereotrodePlot::getNumberOfAxes(){
...@@ -106,16 +120,15 @@ int StereotrodePlot::getNumberOfAxes(){ ...@@ -106,16 +120,15 @@ int StereotrodePlot::getNumberOfAxes(){
} }
void StereotrodePlot::initLimits(){ void StereotrodePlot::initLimits(){
for (int i=0; i<2; i++) for (int i=0; i<nChannel; i++)
{ {
limits[i][0] = -1*pow(2,11); limits[i][0] = 3705;//-1*pow(2,11);
limits[i][1] = pow(2,14)*1.6; limits[i][1] = 6201;//pow(2,14)*1.6;
} }
} }
void StereotrodePlot::getPreferredDimensions(double *w, double *h){ void StereotrodePlot::getPreferredDimensions(double *w, double *h){
*w = 75; *w = 150;
*h = 75; *h = 75;
} }
...@@ -126,30 +139,7 @@ void StereotrodePlot::clear(){ ...@@ -126,30 +139,7 @@ void StereotrodePlot::clear(){
bool StereotrodePlot::processKeyEvent(SimpleKeyEvent k){ bool StereotrodePlot::processKeyEvent(SimpleKeyEvent k){
// std::cout<<"Key:"<<(char)k.key<<std::endl;
// switch(k.key)
// {
// case '=':
// for (int i=0; i<=WAVE4; i++)
// zoomWaveform(i, false, 3);
// break;
// case '+':
// for (int i=0; i<=WAVE4; i++)
// panWaveform(i, false, 3);
// break;
// case '-':
// for (int i=0; i<=WAVE4; i++)
// zoomWaveform(i, false, -3);
// break;
// case '_':
// for (int i=0; i<=WAVE4; i++)
// panWaveform(i, false, -3);
// break;
// case 'C':
// clearOnNextDraw(true);
// break;
// }
return true; return true;
} }
......
...@@ -21,10 +21,15 @@ class StereotrodePlot : public BaseUIElement{ ...@@ -21,10 +21,15 @@ class StereotrodePlot : public BaseUIElement{
bool enabled; bool enabled;
bool limitsChanged; bool limitsChanged;
double limits[2][2];
static const int MAX_N_CHAN = 4;
WaveAxes wAxes[2]; static const int nChannel = 2;
ProjectionAxes pAxes[1]; static const int nWaveAx = 2;
static const int nProjAx = 1;
double limits[MAX_N_CHAN][2];
WaveAxes wAxes[nWaveAx];
ProjectionAxes pAxes[nProjAx];
...@@ -52,7 +57,7 @@ public: ...@@ -52,7 +57,7 @@ public:
void setEnabled(bool enabled); void setEnabled(bool enabled);
bool getEnabled(); bool getEnabled();
void setPosition(int,int,double,double); void setPosition(int,int,double,double);
void getPreferredDimensions(double*, double*); void getPreferredDimensions(double*, double*);
int getNumberOfAxes(); int getNumberOfAxes();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment