From 186c022b61376415efd643eccb17993431a6f2d8 Mon Sep 17 00:00:00 2001 From: Stuart Layton <slayton@mit.edu> Date: Mon, 19 Mar 2012 09:56:25 -0400 Subject: [PATCH] updated spike plotting to show points in the projection plots, points don't persists and I haven't been able to disable anti-aliasing on the mac so those things still need to be done --- .../SpikePlotting/ProjectionAxes.cpp | 418 ++++-------------- .../SpikePlotting/ProjectionAxes.h | 94 ++-- .../SpikePlotting/StereotrodePlot.cpp | 15 +- .../SpikePlotting/StereotrodePlot.h | 2 +- .../Visualization/SpikePlotting/WaveAxes.cpp | 2 +- 5 files changed, 124 insertions(+), 407 deletions(-) diff --git a/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp index a8ba41be0..f0fa53783 100644 --- a/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp +++ b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp @@ -1,369 +1,99 @@ -// #include "ProjectionAxes.h" +#include "ProjectionAxes.h" -// ProjectionAxes::ProjectionAxes(): -// BaseUIElement(), -// type(1), -// drawWaveformLine(true), -// drawWaveformPoints(false), -// drawGrid(true), -// gotFirstSpike(false), -// overlay(false), -// convertLabelUnits(true), -// resizedFlag(false) -// { -// ylims[0] = 0; -// ylims[1] = 1; -// setWaveformColor(1.0,1.0,0.6); -// setThresholdColor(1.0, 0.1, 0.1); -// setPointColor(1.0, 1.0, 1.0); -// setGridColor(0.4, 0.2, 0.2); - -// BaseUIElement::elementName = (char*) "ProjectionAxes"; -// } +ProjectionAxes::ProjectionAxes(): + GenericAxes(), + drawGrid(false), + overlay(false), + convertLabelUnits(true) +{ + GenericAxes::gotFirstSpike = false; + GenericAxes::resizedFlag = false; -// ProjectionAxes::ProjectionAxes(int x, int y, double w, double h, int t): -// BaseUIElement(x,y,w,h), -// drawWaveformLine(true), -// drawWaveformPoints(false), -// drawGrid(true), -// gotFirstSpike(false), -// overlay(false), -// convertLabelUnits(true), -// resizedFlag(false) -// { -// // if (t<WAVE1 || t>PROJ3x4) -// //("Invalid Axes type specified"); -// type = t; -// setWaveformColor(1.0,1.0,0.6); -// setThresholdColor(1.0, 0.1, 0.1); -// setPointColor(1.0, 1.0, 1.0); -// setGridColor(0.2, 0.2, 0.2); -// BaseUIElement::elementName = (char*) "ProjectionAxes"; + ylims[0] = 0; + ylims[1] = 1; + setPointColor(1.0,1.0,1.0); -// } -// void ProjectionAxes::updateSpikeData(SpikeObject newSpike){ -// if (!gotFirstSpike){ -// gotFirstSpike = true; -// printf("ProjectionAxes::updateSpikeData() got first spike\n"); -// } -// s = newSpike; -// } -// void ProjectionAxes::redraw(){ -// BaseUIElement::redraw(); -// if (BaseUIElement::enabled) -// plotData(); + BaseUIElement::elementName = (char*) "ProjectionAxes"; +} -// BaseUIElement::drawElementEdges(); -// } -// void ProjectionAxes::plotData(){ +ProjectionAxes::ProjectionAxes(int x, int y, double w, double h, int t): + GenericAxes(x,y,w,h,t), + drawGrid(true), + overlay(false), + convertLabelUnits(true) +{ + GenericAxes::gotFirstSpike = false; + GenericAxes::resizedFlag = false; -// if (!gotFirstSpike) -// { -// std::cout<<"\tWaiting for the first spike"<<std::endl; -// return; -// } -// switch(type){ -// case WAVE1: -// case WAVE2: -// case WAVE3: -// case WAVE4: -// plotWaveform(type); -// break; - -// case PROJ1x2: -// case PROJ1x3: -// case PROJ1x4: -// case PROJ2x3: -// case PROJ2x4: -// case PROJ3x4: -// plotProjection(type); -// break; -// default: -// std::cout<<"ProjectionAxes::plotData(), Invalid type specified, cannot plot"<<std::endl; -// exit(1); -// } -// } -// void ProjectionAxes::setYLims(double ymin, double ymax){ -// ylims[0] = ymin; -// ylims[1] = ymax; -// } -// void ProjectionAxes::getYLims(double *min, double *max){ -// *min = ylims[0]; -// *max = ylims[1]; -// } -// void ProjectionAxes::setXLims(double xmin, double xmax){ -// xlims[0] = xmin; -// xlims[1] = xmax; -// } -// void ProjectionAxes::getXLims(double *min, double *max){ -// *min = xlims[0]; -// *max = xlims[1]; -// } -// void ProjectionAxes::setType(int t){ -// if (t<WAVE1 || t>PROJ3x4){ -// std::cout<<"Invalid Axes type specified"; -// return; -// } + setPointColor(1.0,1.0,1.0); -// type = t; -// } -// int ProjectionAxes::getType(){ -// return type; -// } - + BaseUIElement::elementName = (char*) "ProjectionAxes"; -// void ProjectionAxes::plotWaveform(int chan){ +} -// if (chan>WAVE4 || chan<WAVE1) -// { -// std::cout<<"ProjectionAxes::plotWaveform() invalid channel, must be between 0 and 4"<<std::endl; -// return; -// } - -// if (s.n_samps_per_chan>1024) -// return; +void ProjectionAxes::updateSpikeData(SpikeObject newSpike){ + //std::cout<<"ProjectionAxes::updateSpikeData()"<<std::endl; + GenericAxes::updateSpikeData(newSpike); -// // Set the plotting range for the current axes -// // the xlims member is ignored as the -// // xdims are 0->number of samples per waveform minus one -// // so the line goes all the way to the edges -// // ydims are specified by the ylims vector - -// setViewportRange(0, ylims[0], s.n_samps_per_chan-1, ylims[1]); - -// if(!overlay){ -// glColor3f(0.0,0.0,0.0); -// glRectd(0, ylims[0], s.n_samps_per_chan, ylims[1]); -// } -// if(drawGrid) -// drawWaveformGrid(s.thresh[chan], s.gains[chan]); - -// //compute the spatial width for each wawveform sample -// float dx = 1; -// float x = 0; -// int sampIdx = chan; +} -// //Draw the individual waveform points connected with a line -// // if drawWaveformPoints is set to false then force the drawing of the line, _SOMETHING_ must be drawn -// glColor3fv(waveColor); +void ProjectionAxes::redraw(){ -// //if drawWaveformLine and drawWaveformPoints are both set -// if(drawWaveformLine){ -// glLineWidth(1); -// glBegin( GL_LINE_STRIP ); -// for (int i=0; i<s.n_samps_per_chan; i++) -// { -// glVertex2f(x, s.data[sampIdx]); -// sampIdx +=4; -// x +=dx; -// } -// glEnd(); -// } + BaseUIElement::redraw(); - -// //if drawWaveformLine and drawWaveformPoints are both set false then draw the points -// //this ensures that something is always drawn -// if(drawWaveformPoints || !drawWaveformLine){ -// x = 0; -// sampIdx = chan; -// glColor3fv(pointColor); -// glPointSize(1); -// glBegin( GL_POINTS ); -// for (int i=0; i<s.n_samps_per_chan; i++) -// { -// glVertex2f(x, s.data[sampIdx]); -// sampIdx +=4; -// x +=dx; -// } -// glEnd(); -// } -// // Draw the threshold line and label + plot(); -// glColor3fv(thresholdColor); -// glLineWidth(1); -// glLineStipple(4, 0xAAAA); // make a dashed line -// glEnable(GL_LINE_STIPPLE); - -// glBegin( GL_LINE_STRIP ); -// glVertex2f(0, s.thresh[chan]); -// glVertex2f(s.n_samps_per_chan, s.thresh[chan]); -// glEnd(); - -// glDisable(GL_LINE_STIPPLE); + BaseUIElement::drawElementEdges(); +} -// char str[500] = {0}; - -// /*if(convertLabelUnits) -// sprintf(str, "%duV", ad16ToUv(s.thresh[chan], s.gains[chan])); -// else -// sprintf(str, "%d", (int) s.thresh[chan]);*/ -// makeLabel(s.thresh[chan], s.gains[chan], convertLabelUnits, str); - -// // printf(str); - -// float yOffset = (ylims[1] - ylims[0])/BaseUIElement::height * 2; -// drawString(1 ,s.thresh[chan] + yOffset, GLUT_BITMAP_8_BY_13, str); -// } +void ProjectionAxes::plot(){ -// void ProjectionAxes::plotProjection(int proj){ -// // std::cout<<"ProjectionAxes::plotProjection():"<<proj<<" not yet implemented"<<std::endl; -// // if (proj<PROJ1x2 || proj>PROJ3x4) -// // error("ProjectionAxes:plotProjection() invalid projection specified"); - -// setViewportRange(xlims[0], ylims[0], xlims[1], ylims[1]); + setViewportRange(xlims[0], ylims[0], xlims[1], ylims[1]); -// int d1, d2; -// n2ProjIdx(proj, &d1, &d2); + int d1, d2; + n2ProjIdx(type, &d1, &d2); -// int idx1, idx2; -// calcWaveformPeakIdx(d1,d2,&idx1, &idx2); - -// if (drawGrid) -// drawProjectionGrid(s.gains[d1], s.gains[d2]); + int idx1, idx2; + calcWaveformPeakIdx(d1,d2,&idx1, &idx2); -// glColor3fv(pointColor); -// glPointSize(1); + //if (drawGrid) + // drawProjectionGrid(s.gain[d1], s.gain[d2]); -// glBegin(GL_POINTS); -// glVertex2f(s.data[idx1], s.data[idx2]); -// glEnd(); -// } + glColor3fv(pointColor); + glPointSize(1); -// void ProjectionAxes::calcWaveformPeakIdx(int d1, int d2, int *idx1, int *idx2){ + glBegin(GL_POINTS); + glVertex2f(s.data[idx1], s.data[idx2]); + glEnd(); +} -// int max1 = -1*pow(2,15); -// int max2 = max1; - -// for (int i=0; i<s.n_samps_per_chan ; i++){ -// if (s.data[i*s.n_chans + d1] > max1) -// { -// *idx1 = i*s.n_chans + d1; -// max1 = s.data[*idx1]; -// } -// if (s.data[i*s.n_chans + d2] > max2) -// { -// *idx2 = i*s.n_chans + d2; -// max2 = s.data[*idx2]; -// } -// } -// } -// void ProjectionAxes::drawWaveformGrid(int thold, int gain){ - -// double voltRange = ylims[1] - ylims[0]; -// double pixelRange = BaseUIElement::height; -// //This is a totally arbitrary value that i'll mess around with and set as a macro when I figure out a value I like -// int minPixelsPerTick = 25; -// int MAX_N_TICKS = 10; - -// int nTicks = pixelRange / minPixelsPerTick; -// while(nTicks>MAX_N_TICKS){ -// minPixelsPerTick += 5; -// nTicks = pixelRange / minPixelsPerTick; -// } -// int voltPerTick = (voltRange / nTicks); -// // Round to the nearest 200 + void ProjectionAxes::calcWaveformPeakIdx(int d1, int d2, int *idx1, int *idx2){ + int max1 = -1*pow(2,15); + int max2 = max1; -// double meanRange = voltRange/2; -// glColor3fv(gridColor); + for (int i=0; i<s.nSamples ; i++){ + if (s.data[d1*s.nSamples + i] > max1) + { + *idx1 = d1*s.nSamples+i; + max1 = s.data[*idx1]; + } + if (s.data[d2*s.nSamples+i] > max2) + { + *idx2 = d2*s.nSamples+i; + max2 = s.data[*idx2]; + } + } +} -// glLineWidth(1); -// char str[200] = {0}; - -// double tickVoltage = thold; -// while(tickVoltage < ylims[1] - voltPerTick/2) // Draw the ticks above the thold line -// { -// tickVoltage = roundUp(tickVoltage + voltPerTick, 100); - -// glBegin(GL_LINE_STRIP); -// glVertex2i(0, tickVoltage); -// glVertex2i(s.n_samps_per_chan, tickVoltage); -// glEnd(); - -// makeLabel(tickVoltage, gain, convertLabelUnits, str); -// drawString(1, tickVoltage+voltPerTick/10, GLUT_BITMAP_8_BY_13, str); -// } - -// tickVoltage = thold; -// while(tickVoltage > ylims[0] + voltPerTick) // draw the ticks below the thold line -// { -// tickVoltage = roundUp(tickVoltage - voltPerTick, 100); - -// glBegin(GL_LINE_STRIP); -// glVertex2i(0, tickVoltage); -// glVertex2i(s.n_samps_per_chan, tickVoltage); -// glEnd(); - -// makeLabel(tickVoltage, gain, convertLabelUnits, str); -// drawString(1, tickVoltage+voltPerTick/10, GLUT_BITMAP_8_BY_13, str); -// } - - -// } -// void ProjectionAxes::drawProjectionGrid(int gain1, int gain2){ -// return; // Disabled method, figure out how you want to implement this in the future - -// double voltRange = ylims[1] - ylims[0]; -// double threeQuarters = voltRange * 3.0f / 4.0f; - -// double pixelRange = BaseUIElement::height; -// //This is a totally arbitrary value that i'll mess around with and set as a macro when I figure out a value I like -// int minPixelsPerTick = 50; - -// int nTicks = pixelRange / minPixelsPerTick; -// int voltPerTick = (voltRange / nTicks); -// // Round to the nearest 200 - - -// double meanRange = voltRange/2; -// glColor3fv(gridColor); - -// glLineWidth(1); -// char str[100] = {0}; - -// makeLabel(threeQuarters, gain1, convertLabelUnits, str); -// drawString(threeQuarters, (ylims[1] - ylims[0]) / 100, GLUT_BITMAP_8_BY_13, str ); -// glBegin(GL_LINE_STRIP); -// glVertex2f(threeQuarters, ylims[0]); -// glVertex2f(threeQuarters, ylims[1]); -// glEnd(); -// glBegin(GL_LINE_STRIP); -// glVertex2f(ylims[0], threeQuarters); -// glVertex2f(ylims[1], threeQuarters); -// glEnd(); - - -// makeLabel(threeQuarters, gain2, convertLabelUnits, str); - -// drawString( ylims[0] + (ylims[1] - ylims[0])/25, threeQuarters, GLUT_BITMAP_8_BY_13, str ); - - -// } -// void ProjectionAxes::setWaveformColor(GLfloat r, GLfloat g, GLfloat b){ -// waveColor[0] = r; -// waveColor[1] = g; -// waveColor[2] = b; -// } -// void ProjectionAxes::setThresholdColor(GLfloat r, GLfloat g, GLfloat b){ -// thresholdColor[0] = r; -// thresholdColor[1] = g; -// thresholdColor[2] = b; -// } -// void ProjectionAxes::setPointColor(GLfloat r, GLfloat g, GLfloat b){ -// pointColor[0] = r; -// pointColor[1] = g; -// pointColor[2] = b; -// } -// void ProjectionAxes::setGridColor(GLfloat r, GLfloat g, GLfloat b){ -// gridColor[0] = r; -// gridColor[1] = g; -// gridColor[2] = b; -// } -// void ProjectionAxes::setPosition(int x, int y, double w, double h){ -// BaseUIElement::setPosition(x,y,w,h); -// resizedFlag = true; -// } -// void ProjectionAxes::clearOnNextDraw(bool b){ -// BaseUIElement::clearOnNextDraw(b); -// } \ No newline at end of file +void ProjectionAxes::setPointColor(GLfloat r, GLfloat g, GLfloat b){ + pointColor[0] = r; + pointColor[1] = g; + pointColor[2] = b; +} +void ProjectionAxes::setGridColor(GLfloat r, GLfloat g, GLfloat b){ + gridColor[0] = r; + gridColor[1] = g; + gridColor[2] = b; +} diff --git a/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h index 535e0f693..862075ca0 100644 --- a/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h +++ b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h @@ -1,68 +1,54 @@ -// #ifndef PROJECTION_AXES_H_ -// #define PROJECTION_AXES_H_ +#ifndef PROJECTION_AXES_H_ +#define PROJECTION_AXES_H_ -// #if defined(__linux__) -// #include <GL/glut.h> -// #else -// #include <GLUT/glut.h> -// #endif -// #include <stdlib.h> - -// #include "../SpikeObject.h" -// #include "BaseUIElement.h" -// #include "PlotUtils.h" +#if defined(__linux__) + #include <GL/glut.h> +#else + #include <GLUT/glut.h> +#endif +#include <stdlib.h> +#include "BaseUIElement.h" +#include "../SpikeObject.h" +#include "PlotUtils.h" +#include "GenericAxes.h" -// class ProjectionAxes: public BaseUIElement{ -// int type; -// void plotWaveform(int c); -// void plotProjection(int p); -// double xlims[2]; -// double ylims[2]; -// SpikeObject s; -// GLfloat waveColor[3]; -// GLfloat thresholdColor[3]; -// GLfloat pointColor[3]; -// GLfloat gridColor[3]; - -// void calcWaveformPeakIdx(int,int,int*,int*); +class ProjectionAxes: public GenericAxes{ -// bool gotFirstSpike; -// bool resizedFlag; + GLfloat pointColor[3]; + GLfloat gridColor[3]; + -// void drawWaveformGrid(int thold, int gain); -// void drawProjectionGrid(int gain1, int gain2); + void drawProjectionGrid(int thold, int gain); + void calcWaveformPeakIdx(int, int, int*, int*); + +protected: + void plot(); + -// public: -// ProjectionAxes(); -// ProjectionAxes(int x, int y, double w, double h, int t); -// void plotData(); -// void updateSpikeData(SpikeObject s); -// void setXLims(double xmin, double xmax); -// void getXLims(double *xmin, double *xmax); -// void setYLims(double ymin, double ymax); -// void getYLims(double *ymin, double *ymax); -// void setType(int type); -// int getType(); +public: + ProjectionAxes(); + ProjectionAxes(int x, int y, double w, double h, int t); -// void redraw(); + void updateSpikeData(SpikeObject s); + + void setPointColor(GLfloat r, GLfloat g, GLfloat b); + void setGridColor(GLfloat, GLfloat, GLfloat); + + void redraw(); -// void setWaveformColor(GLfloat r, GLfloat g, GLfloat b); -// void setThresholdColor(GLfloat r, GLfloat g, GLfloat b); -// void setPointColor(GLfloat r, GLfloat g, GLfloat b); -// void setGridColor(GLfloat, GLfloat, GLfloat); -// void setPosition(int,int,double,double); - -// bool drawWaveformLine; -// bool drawWaveformPoints; -// bool overlay; -// bool drawGrid; -// bool convertLabelUnits; + bool overlay; + bool drawGrid; + bool convertLabelUnits; -// void clearOnNextDraw(bool c); -// }; +}; + + + +#endif // PROJECTION_AXES_H_ + diff --git a/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp index c5fc78b0f..25ee2445a 100644 --- a/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp +++ b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp @@ -34,6 +34,7 @@ void StereotrodePlot::redraw(){ wAxes[0].redraw(); wAxes[1].redraw(); + pAxes.redraw(); } // This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes @@ -41,7 +42,7 @@ void StereotrodePlot::processSpikeObject(SpikeObject s){ //std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl; wAxes[0].updateSpikeData(s); wAxes[1].updateSpikeData(s); - //pAxesStereotrode.updateSpikeData(s); + pAxes.updateSpikeData(s); } void StereotrodePlot::setTitle(char *n){ plotTitle = n; @@ -52,7 +53,7 @@ void StereotrodePlot::setEnabled(bool e){ wAxes[0].setEnabled(e); wAxes[1].setEnabled(e); - //pAxesStereotrode.setEnabled(e); + pAxes.setEnabled(e); } bool StereotrodePlot::getEnabled(){ @@ -72,17 +73,17 @@ void StereotrodePlot::initAxes(){ wAxes[0] = WaveAxes(minX, minY, axesWidth/2, axesHeight, WAVE1); wAxes[1] = WaveAxes(minX + axesWidth/2, minY, axesWidth/2, axesHeight, WAVE2); - //pAxesStereotrode = ProjectionAxes(minX + axesWidth, minY, axesWidth, axesHeight, PROJ1x2) + pAxes = ProjectionAxes(minX + axesWidth, minY, axesWidth, axesHeight, PROJ1x2); //axes.setEnabled(false); wAxes[0].setYLims(-1*pow(2,11), pow(2,14)*1.6); wAxes[1].setYLims(-1*pow(2,11), pow(2,14)*1.6); - ////pAxesStereotrodeStereotrode.setYLims(-1*pow(2,11), pow(2,14)*1.6); - //pAxesStereotrode.setXLims(-1*pow(2,11), pow(2,14)*1.6); + pAxes.setYLims(-1*pow(2,11), pow(2,14)*1.6); + pAxes.setXLims(-1*pow(2,11), pow(2,14)*1.6); wAxes[0].setWaveformColor(1.0, 1.0, 1.0); wAxes[1].setWaveformColor(1.0, 1.0, 1.0); - //pAxesStereotrode.setWaveformColor(1.0, 1.0, 1.0); + pAxes.setPointColor(1.0, 1.0, 1.0); } @@ -96,7 +97,7 @@ void StereotrodePlot::setPosition(int x, int y, double w, double h){ wAxes[0] = WaveAxes(minX, minY, axesWidth/2, axesHeight, WAVE1); wAxes[1] = WaveAxes(minX + axesWidth/2, minY, axesWidth/2, axesHeight, WAVE2); - //pAxesStereotrode = ProjectionAxes(minX + axesWidth, minY, axesWidth, axesHeight, PROJ1x2) + pAxes = ProjectionAxes(minX + axesWidth, minY, axesWidth, axesHeight, PROJ1x2); titleBox.setPosition(x, y+h-titleHeight-3, w, titleHeight+3); } diff --git a/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h index 2b22bc7d6..dfbef0732 100644 --- a/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h +++ b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h @@ -34,7 +34,7 @@ class StereotrodePlot : public BaseUIElement{ double limits[1][2]; WaveAxes wAxes[2]; - //ProjectionAxes pAxes; + ProjectionAxes pAxes; diff --git a/Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp b/Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp index 90e50883b..1b1248df0 100644 --- a/Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp +++ b/Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp @@ -80,7 +80,7 @@ void WaveAxes::plot(){ // sample based upon which channel is getting plotted // type values are defined in PlotUtils.h int sampIdx = s.nSamples * type; // - std::cout<<"Starting with idx:"<<sampIdx<<std::endl; + //std::cout<<"Starting with idx:"<<sampIdx<<std::endl; //Draw the individual waveform points connected with a line glColor3fv(waveColor); -- GitLab