#include "WaveAxes.h" WaveAxes::WaveAxes(): GenericAxes(), drawWaveformLine(true), drawWaveformPoints(false), drawGrid(true), overlay(false), convertLabelUnits(true) { GenericAxes::gotFirstSpike = false; ylims[0] = 0; ylims[1] = 1; setWaveformColor(1.0,1.0,0.6); setThresholdColor(1.0, 0.1, 0.1); setGridColor(0.4, 0.2, 0.2); } WaveAxes::WaveAxes(int x, int y, double w, double h, int t): GenericAxes(x,y,w,h,t), drawWaveformLine(true), drawWaveformPoints(false), drawGrid(true), overlay(false), convertLabelUnits(true) { GenericAxes::gotFirstSpike = false; setWaveformColor(1.0,1.0,0.6); setThresholdColor(1.0, 0.1, 0.1); setGridColor(0.2, 0.2, 0.2); } void WaveAxes::updateSpikeData(SpikeObject newSpike){ //std::cout<<"WaveAxes::updateSpikeData()"<<std::endl; GenericAxes::updateSpikeData(newSpike); } void WaveAxes::redraw(){ BaseUIElement::redraw(); plot(); BaseUIElement::drawElementEdges(); } void WaveAxes::plot(){ int chan = 0; // If no spikes have been received then don't plot anything if (!gotFirstSpike) { std::cout<<"\tWaiting for the first spike"<<std::endl; return; } // 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.nSamples-1, ylims[1]); // draw the grid lines for the waveforms? if(drawGrid) drawWaveformGrid(s.threshold[chan], s.gain[chan]); //compute the spatial width for each wawveform sample float dx = 1; float x = 0; // type corresponds to channel so we need to calculate the starting // 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; //Draw the individual waveform points connected with a line glColor3fv(waveColor); glLineWidth(2); glBegin( GL_LINE_STRIP ); int dSamples = 1; for (int i=0; i<s.nSamples; i++) { //std::cout<<"\t"<<s.data[sampIdx]; glVertex2f(x, s.data[sampIdx]); sampIdx += dSamples; x +=dx; } glEnd(); //Draw the threshold line and label glColor3fv(thresholdColor); glLineWidth(1); glLineStipple(4, 0xAAAA); // make a dashed line glEnable(GL_LINE_STIPPLE); glBegin( GL_LINE_STRIP ); glVertex2f(0, s.threshold[chan]); glVertex2f(s.nSamples, s.threshold[chan]); glEnd(); glDisable(GL_LINE_STIPPLE); char cstr[100] = {0}; makeLabel(s.threshold[chan], s.gain[chan], convertLabelUnits, cstr); String str = String(cstr); float yOffset = (ylims[1] - ylims[0])/BaseUIElement::height * 2; drawString(1 ,s.threshold[chan] + yOffset, 15, str, font); } void WaveAxes::drawWaveformGrid(int thold, int gain){ double voltRange = ylims[1] - ylims[0]; double pixelRange = BaseUIElement::height; //This is a totally arbitrary value that seemed to lok the best for me 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); double meanRange = voltRange/2; glColor3fv(gridColor); glLineWidth(1); char cstr[200] = {0}; String str; double tickVoltage = thold; // If the limits are bad we don't want to hang the program trying to draw too many ticks // so count the number of ticks drawn and kill the routine after 100 draws int tickCount=0; while(tickVoltage < ylims[1] - voltPerTick*1.5) // Draw the ticks above the thold line { tickVoltage = roundUp(tickVoltage + voltPerTick, 100); glBegin(GL_LINE_STRIP); glVertex2i(0, tickVoltage); glVertex2i(s.nSamples, tickVoltage); glEnd(); makeLabel(tickVoltage, gain, convertLabelUnits, cstr); str = String(cstr); drawString(1, tickVoltage+voltPerTick/10, 15, str, font); if (tickCount++>100) return; } tickVoltage = thold; tickCount = 0; 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.nSamples, tickVoltage); glEnd(); makeLabel(tickVoltage, gain, convertLabelUnits, cstr); str = String(cstr); drawString(1, tickVoltage+voltPerTick/10, 15, str, font); if (tickCount++>100) return; } } void WaveAxes::setWaveformColor(GLfloat r, GLfloat g, GLfloat b){ waveColor[0] = r; waveColor[1] = g; waveColor[2] = b; } void WaveAxes::setThresholdColor(GLfloat r, GLfloat g, GLfloat b){ thresholdColor[0] = r; thresholdColor[1] = g; thresholdColor[2] = b; } // void WaveAxes::setPointColor(GLfloat r, GLfloat g, GLfloat b){ // pointColor[0] = r; // pointColor[1] = g; // pointColor[2] = b; // } void WaveAxes::setGridColor(GLfloat r, GLfloat g, GLfloat b){ gridColor[0] = r; gridColor[1] = g; gridColor[2] = b; }