Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

NetworkMonitor.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   SpikeStream Application                                               *
00003  *   Copyright (C) 2007 by David Gamez                                     *
00004  *   david@davidgamez.eu                                                   *
00005  *   Version 0.1                                                           *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 
00023 //SpikeStream includes
00024 #include "NetworkMonitor.h"
00025 #include "PVMMessages.h"
00026 #include "Debug.h"
00027 #include "Utilities.h"
00028 #include "GlobalVariables.h"
00029 #include "SpikeStreamMainWindow.h"
00030 
00031 //Qt includes
00032 #include <qmessagebox.h>
00033 
00034 //Other includes
00035 #include "mysql++.h"
00036 #include "pvm3.h"
00037 using namespace mysqlpp;
00038 
00039 
00040 /* Declare and initialise static variables. */
00041 GLfloat NetworkMonitor::marginL = 5.0f;
00042 GLfloat NetworkMonitor::marginW = 5.0f;
00043 
00044 
00045 /*! Constructor for live simulation monitoring. */
00046 NetworkMonitor::NetworkMonitor(NeuronGroup neuronGrp, DBInterface *netDBInter, QWidget *parent) : QGLWidget(parent, "Network Monitor"){
00047         //Store database reference
00048         networkDBInterface = netDBInter;
00049 
00050         //Set up a short version of this reference
00051         spikeStrApp = SpikeStreamMainWindow::spikeStreamApplication;
00052 
00053         //Record that we are live monitoring
00054         liveMonitoring = true;
00055 
00056         //Store parameters of the neuron group that is being monitored
00057         neuronGrpID = neuronGrp.neuronGrpID;
00058         neuronGrpWidth = neuronGrp.width;
00059         neuronGrpLength = neuronGrp.length;
00060 
00061         //Set message time step to zero.
00062         messageTimeStep = 0;
00063         
00064         //Initialise numberOfSpikes to zero
00065         numberOfSpikes = 0;
00066 
00067         //Initialize array for receiving spikes
00068         unpackArray = new unsigned int[MAX_NUMBER_OF_SPIKES];
00069         
00070         /* Extract information about neuron group from database. 
00071                 Need the number of neurons in the group and the lowest neuronID in the group
00072                 By assuming that the neuron group is a continuous number of neuronIDs starting at 
00073                 neuronGrpStart it becomes easy to achieve random access to any neuron using the 
00074                 neuronID */
00075         int startXPos, startYPos;
00076         try{
00077                 Query query = networkDBInterface->getQuery();
00078                 query.reset();
00079                 query<<"SELECT COUNT(NeuronID), MIN(NeuronID), MAX(NeuronID) FROM Neurons WHERE NeuronGrpID = "<<neuronGrpID;
00080                 Result countResults = query.store();
00081                 Row neurGrpPropRow(*countResults.begin());//Should only be one row
00082                 numberOfNeurons = Utilities::getUInt((std::string)neurGrpPropRow["COUNT(NeuronID)"]);
00083                 startNeuronID = Utilities::getUInt((std::string)neurGrpPropRow["MIN(NeuronID)"]);
00084         
00085                 /* Get the edge position and spacing of the neuron group */
00086                 query.reset();
00087                 query<<"SELECT X, Y FROM NeuronGroups WHERE NeuronGrpID = "<<neuronGrpID;
00088                 Result startGrpPosRes = query.store();
00089                 Row startGrpPosRow(*startGrpPosRes.begin());//Should only be one row
00090                 startXPos = Utilities::getInt((std::string)startGrpPosRow["X"]);
00091                 startYPos = Utilities::getInt((std::string)startGrpPosRow["Y"]);
00092         }
00093         catch (const BadQuery& er) {// Handle any query errors
00094                 cerr<<"NetworkMonitor: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00095                 QString errorString = "Bad query extracting neuron information: \"";
00096                 errorString += er.what();
00097                 errorString += "\"";
00098                 QMessageBox::critical( 0, "NeuralNetwork Database Error", errorString);
00099                 return;
00100         }
00101         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00102                 cerr<<"NetworkMonitor: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00103                 QString errorString = "Exception thrown extracting neuron information: \"";
00104                 errorString += er.what();
00105                 errorString += "\"";
00106                 QMessageBox::critical( 0, "NeuralNetwork Database Error", errorString);
00107                 return;
00108         }
00109         catch(std::exception& er){// Catch-all for std exceptions
00110                 cerr<<"NetworkMonitor: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00111                 QString errorString = "Exception thrown extracting neuron information: \"";
00112                 errorString += er.what();
00113                 errorString += "\"";
00114                 QMessageBox::critical( 0, "NeuralNetwork Database Error", errorString);
00115                 return;
00116         }
00117 
00118         
00119         /* Extract the X and Y position of the neurons normalised so that coordinates start
00120                 from the edge of the neuron group and not from the origin. */
00121         try{
00122                 Connection* fastTmpConnection = networkDBInterface->getNewConnection();
00123                 Query fastQuery = fastTmpConnection->query();
00124                 fastQuery.reset();
00125                 fastQuery<<"SELECT NeuronID, X, Y FROM Neurons WHERE NeuronGrpID = "<<neuronGrpID;
00126                 ResUse neuronPosRes = fastQuery.use();
00127                 Row neuronPosRow;
00128                 if(neuronPosRes){
00129                         while (neuronPosRow = neuronPosRes.fetch_row()) {
00130                                 unsigned int neuronID = Utilities::getUInt((std::string)neuronPosRow["NeuronID"]);
00131                                 int xPos = Utilities::getInt((std::string)neuronPosRow["X"]);
00132                                 int yPos = Utilities::getInt((std::string)neuronPosRow["Y"]);
00133                                 
00134                                 //Subtract start position so that xPos and yPos are relative to startPos
00135                                 xPos -= startXPos;
00136                                 yPos -= startYPos;
00137         
00138                                 //Add to position maps
00139                                 neuronXPosMap[neuronID] = (GLfloat)xPos;
00140                                 neuronYPosMap[neuronID] = (GLfloat)yPos;
00141                         }
00142                 }
00143                 else{
00144                         cerr<<"NetworkMonitor: CANNOT RETRIEVE NEURON DETAILS: "<<fastQuery.error()<<endl;
00145                 }
00146 
00147                 //Close temporary connection
00148                 fastTmpConnection->close();
00149         }
00150         catch (const EndOfResults& er) {//EndOfResults exception thrown when fetch row no longer returns anything
00151                 //No need to do anything here - this is normal behaviour
00152         }
00153         catch (const BadQuery& er) {// Handle any query errors
00154                 cerr<<"NetworkMonitor: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00155                 QString errorString = "Bad query adding layer to table: \"";
00156                 errorString += er.what();
00157                 errorString += "\"";
00158                 QMessageBox::critical( 0, "Add Layer Error", errorString);
00159         }
00160         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00161                 cerr<<"NetworkMonitor: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00162                 QString errorString = "Exception thrown adding layer to table: \"";
00163                 errorString += er.what();
00164                 errorString += "\"";
00165                 QMessageBox::critical( 0, "Add Layer Error", errorString);
00166         }
00167         catch(std::exception& er){// Catch-all for std exceptions
00168                 cerr<<"NetworkMonitor: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00169                 QString errorString = "Exception thrown adding layer to table: \"";
00170                 errorString += er.what();
00171                 errorString += "\"";
00172                 QMessageBox::critical( 0, "Add Layer Error", errorString);
00173         }
00174 
00175         
00176         //Store frame width and height
00177         frameWidth = frameSize().width();
00178         frameHeight = frameSize().height();
00179 
00180         /* Set the scaling factors taking account of the space at the top for the time step
00181                  and the margin around the drawing area. */
00182         scaleFactorWidth = ((GLfloat)frameWidth - 2.0f * marginW)/(GLfloat)neuronGrpWidth;
00183         if(scaleFactorWidth < 0.0f)
00184                 scaleFactorWidth = 0.0f;
00185 
00186         scaleFactorLength = ((GLfloat)frameHeight - 2.0f * marginL - 20.0f )/(GLfloat)neuronGrpLength;
00187         if(scaleFactorLength < 0.0f)
00188                 scaleFactorLength = 0.0f;
00189 
00190         //Calculate the size to draw vertices
00191         setPointSize();
00192 
00193         //Set up the font
00194         arialFont = new QFont( "Arial", 10);
00195 
00196         //Initialise any other variables
00197         map1Active = true;
00198         drawingMapPointer = &firingNeuronMap1;
00199         bufferMapPointer = &firingNeuronMap2;
00200 }
00201 
00202 
00203 /*! Constructor for archive monitoring. */
00204 NetworkMonitor::NetworkMonitor(NeuronGroup neuronGrp, QWidget *parent) : QGLWidget(parent, "Network Monitor"){
00205         //Set up a short version of this reference
00206         spikeStrApp = SpikeStreamMainWindow::spikeStreamApplication;
00207 
00208         //Record that we are monitoring an archive
00209         liveMonitoring = false;
00210 
00211         //Store parameters of the neuron group that is being monitored
00212         neuronGrpID = neuronGrp.neuronGrpID;
00213         neuronGrpWidth = neuronGrp.width;
00214         neuronGrpLength = neuronGrp.length;
00215 
00216         //Initialise variables
00217         messageTimeStep = 0;
00218 
00219         /* Set up maps linking neuronIDs to positions. This works in the same way as
00220                 the method that is used to create the neuron groups. Any changes there will
00221                 need to be reflected here as well. */
00222         unsigned int neuronIDCounter = neuronGrp.startNeuronID;
00223         for(unsigned int yPos = 0; yPos < neuronGrpLength; ++yPos){
00224                 for(unsigned int xPos = 0; xPos < neuronGrpWidth; ++xPos){
00225                         neuronXPosMap[neuronIDCounter] = (GLfloat)xPos;
00226                         neuronYPosMap[neuronIDCounter] = (GLfloat)yPos;
00227                         ++neuronIDCounter;
00228                 }
00229         }
00230 
00231         //Store frame width and height
00232         frameWidth = frameSize().width();
00233         frameHeight = frameSize().height();
00234 
00235         /* Set the scaling factors taking account of the space at the top for the time step
00236                  and the margin around the drawing area. */
00237         scaleFactorWidth = ((GLfloat)frameWidth - 2.0f * marginW)/(GLfloat)neuronGrpWidth;
00238         if(scaleFactorWidth < 0.0f)
00239                 scaleFactorWidth = 0.0f;
00240 
00241         scaleFactorLength = ((GLfloat)frameHeight - 2.0f * marginL - 20.0f )/(GLfloat)neuronGrpLength;
00242         if(scaleFactorLength < 0.0f)
00243                 scaleFactorLength = 0.0f;
00244 
00245         //Calculate the size of the vertices
00246         setPointSize();
00247 
00248         //Set up font
00249         arialFont = new QFont( "Arial", 10);
00250 
00251         //Initialise any other variables
00252         map1Active = true;
00253         drawingMapPointer = &firingNeuronMap1;
00254         bufferMapPointer = &firingNeuronMap2;
00255 }
00256 
00257 
00258 /*! Destructor. */
00259 NetworkMonitor::~ NetworkMonitor(){
00260         #ifdef MEMORY_DEBUG
00261                 cout<<"DESTROYING NETWORK MONITOR"<<endl;
00262         #endif//MEMORY_DEBUG
00263 
00264         delete arialFont;
00265 
00266         //Delete unpack array
00267         if(liveMonitoring)
00268                 delete [] unpackArray;
00269 
00270 }
00271 
00272 
00273 //----------------------------------------------------------------------------
00274 //---------------              PUBLIC METHODS                -----------------
00275 //----------------------------------------------------------------------------
00276 
00277 /*! Resets the network monitor, possibly at the end of a simulation or archive display. */
00278 void NetworkMonitor::reset(){
00279         numberOfSpikes = 0;
00280         messageTimeStep = 0;
00281         firingNeuronMap1.clear();
00282         firingNeuronMap2.clear();
00283         update();
00284 }
00285 
00286 
00287 //----------------------------------------------------------------------------
00288 //--------------- PROTECTED METHODS INHERITED FROM QGL -----------------------
00289 //----------------------------------------------------------------------------
00290 
00291 /*! Called to initialise OpenGL. */
00292 void NetworkMonitor::initializeGL(){
00293         /* Lock the main mutex so that NetworkViewer's OpenGL commands do not  
00294                 clash with this classes' OpenGL commands. This only works for events
00295                 generated whilst this class is drawing. */
00296         spikeStrApp->lock();
00297 
00298     /* Set a subtly different background depending on whether we are
00299                 live monitoring or playing back an archive. */
00300         if(liveMonitoring)
00301                 glClearColor(1.0f, 0.93f, 0.93f, 0.0f);//Very pale red
00302         else
00303                 glClearColor(0.93f, 1.0f, 0.93f, 0.0f);//Very pale green
00304 
00305         //Dark red drawing colour
00306         glColor3f(0.2f, 0.0f, 0.0f);
00307 
00308         /*Unlock the main mutex so that NetworkViewer can process events and send OpenGL 
00309                 commands. */
00310         spikeStrApp->unlock();
00311 }
00312 
00313 
00314 /*! Called to paint OpenGL. */
00315 void NetworkMonitor::paintGL(){
00316         /*Lock the main mutex so that NetworkViewer's OpenGL commands do not  
00317                 clash with this classes' OpenGL commands. When this is in the 
00318                 middle of rendering, NetworkViewer cannot start rendering initiated
00319                 by events.*/
00320         spikeStrApp->lock();
00321 
00322         // Clear the window with current clearing color
00323         glClear(GL_COLOR_BUFFER_BIT);
00324 
00325         //Print simulation step at the top of the screen
00326         renderText(2, 12, "Time step: " + QString::number(messageTimeStep), *arialFont);
00327 
00328         //Set point size
00329         glPointSize(pointSize);
00330 
00331         //Store orginal state of the matrix
00332         glPushMatrix();
00333 
00334         //Move a bit in so that vertices are not off the edge
00335         glTranslated(marginW, marginL, 0.0);
00336         
00337         //Draw the neurons in the active map
00338         glBegin(GL_POINTS);
00339                 for(map<unsigned int, bool>::iterator iter = drawingMapPointer->begin(); iter != drawingMapPointer->end(); ++iter){
00340                         glVertex2f(neuronXPosMap[iter->first] * scaleFactorWidth, neuronYPosMap[iter->first] * scaleFactorLength);
00341                 }
00342         glEnd();
00343 
00344         //Restore orginal state of the matrix
00345         glPopMatrix();
00346 
00347         //Check for errors
00348         checkOpenGLErrors();
00349 
00350         /*Unlock the main mutex so that NetworkViewer can process events and send OpenGL 
00351                 commands. */
00352         spikeStrApp->unlock();
00353 }
00354 
00355 
00356 /*! Called when frame is resized. */
00357 void NetworkMonitor::resizeGL(int frameW, int frameH){
00358         /*Lock the main mutex so when this is in the
00359                 middle of sending OpenGL commands, NetworkViewer cannot start
00360                 sending OpenGL commands initiated through events. */
00361         spikeStrApp->lock();
00362 
00363         //Store the width and height for paint method
00364         frameWidth = frameW;
00365         frameHeight = frameH;
00366 
00367         /* Set the scaling factors taking account of the space at the top for the time step
00368                  and the margin around the drawing area. */
00369         scaleFactorWidth = ((GLfloat)frameWidth - 2.0f * marginW)/(GLfloat)neuronGrpWidth;
00370         if(scaleFactorWidth < 0.0f)
00371                 scaleFactorWidth = 0.0f;
00372 
00373         scaleFactorLength = ((GLfloat)frameHeight - 2.0f * marginL - 20.0f )/(GLfloat)neuronGrpLength;
00374         if(scaleFactorLength < 0.0f)
00375                 scaleFactorLength = 0.0f;
00376 
00377         //Set the vertex size
00378         setPointSize();
00379         
00380     // Prevent a divide by zero, when window is too short
00381     // (you cant make a window of zero width).
00382     if(frameHeight == 0)
00383         frameHeight = 1;
00384 
00385     glViewport(0, 0, frameWidth, frameHeight);
00386 
00387     // Reset the coordinate system before modifying
00388     glMatrixMode(GL_PROJECTION);
00389     glLoadIdentity();
00390 
00391         // Psuedo window coordinates
00392         gluOrtho2D(0.0, (GLfloat) frameWidth, 0.0f, (GLfloat) frameHeight);
00393 
00394     glMatrixMode(GL_MODELVIEW);
00395     glLoadIdentity();
00396 
00397         //Check for OpenGL errors
00398         checkOpenGLErrors();
00399 
00400         /*Unlock the main mutex so that NetworkViewer can process events and send OpenGL 
00401                 commands. */
00402         spikeStrApp->unlock();
00403 }
00404 
00405 
00406 //------------------------------------------------------------------------
00407 //------------------------- PRIVATE METHODS ------------------------------
00408 //------------------------------------------------------------------------
00409 
00410 /*! Checks for errors in OpenGL. */ 
00411 void NetworkMonitor::checkOpenGLErrors(){
00412         GLenum err = glGetError();
00413         while(err != GL_NO_ERROR){
00414                 cerr<<"NetworkMonitor OpenGL ERROR: "<<gluErrorString(err)<<endl;
00415                 cerr.flush();
00416                 err = glGetError();
00417         }
00418 }
00419 
00420 
00421 /*! Debug method that prints out the mapping between neuron id and position. */
00422 void NetworkMonitor::printPositionMaps(){
00423         cout<<"X Position map: "<<endl;
00424         for(map<unsigned int, GLfloat>::iterator iter = neuronXPosMap.begin(); iter != neuronXPosMap.end(); ++iter){
00425                 cout<<"\tNeuronID: "<<iter->first<<"; XPos: "<<iter->second<<endl;
00426         }
00427         cout<<"Y Position map: "<<endl;
00428         for(map<unsigned int, GLfloat>::iterator iter = neuronYPosMap.begin(); iter != neuronYPosMap.end(); ++iter){
00429                 cout<<"\tNeuronID: "<<iter->first<<"; YPos: "<<iter->second<<endl;
00430         }
00431 }
00432 
00433 
00434 /*! Processes a list of firing neurons from the task simulating a neuron group. */
00435 void NetworkMonitor::processFiringNeuronList(){
00436         //Get the time step of the message
00437         int info = pvm_upkuint(&messageTimeStep, 1, 1);
00438         #ifdef PVM_DEBUG
00439                 if(info < 0){
00440                         cerr<<"NetworkMonitor: ERROR EXTRACTING MESSAGE TIME STEP; TASK ID = "<<pvm_mytid()<<"; messageTimeStep: "<<messageTimeStep<<endl;
00441                         return;
00442                 }
00443         #endif//PVM_DEBUG
00444 
00445         // Extract the number of neurons in the message
00446         info = pvm_upkuint(&numberOfSpikes, 1, 1);
00447         #ifdef PVM_DEBUG
00448                 if(info < 0){
00449                         cerr<<"NetworkMonitor: ERROR NUMBER OF FIRING NEURONS FROM MESSAGE; TASK ID = "<<pvm_mytid()<<"; numberOfSpikes: "<<numberOfSpikes<<endl;
00450                         return;
00451                 }
00452         #endif//PVM_DEBUG
00453 
00454         //Unpack the list of firing neurons 
00455         info = pvm_upkuint(unpackArray, numberOfSpikes, 1);//Unpack neuron ids as integers
00456         #ifdef PVM_DEBUG
00457                 if(info < 0){
00458                         cerr<<"NetworkMonitor: ERROR UNPACKING UNSIGNED INT FROM MESSAGE. NUMBER OF SPIKES = "<<numberOfSpikes<<endl;
00459                         return;
00460                 }
00461         #endif//PVM_DEBUG
00462         
00463         //Add the neuron ids to the firing neuron map
00464         for(unsigned int i=0; i<numberOfSpikes; ++i){
00465                 //Add it to the buffer map
00466                 (*bufferMapPointer)[ unpackArray[i] ] = true;
00467         }
00468 
00469         #ifdef SPIKE_DEBUG
00470                 cout<<"NetworkMonitor: NeuronGrpID = "<<neuronGrpID<<". Number of neurons processed: "<<numberOfSpikes<<" at timeStep: "<<messageTimeStep<<endl;
00471         #endif//SPIKE_DEBUG
00472 
00473         //Swap maps and repaint widget.
00474         swapMaps();
00475 }
00476 
00477 
00478 /*! Processes a list of spikes from the task simulating the neuron group that is being monitored. */
00479 void NetworkMonitor::processSpikeList(){
00480         //Get the time step of the message
00481         int info = pvm_upkuint(&messageTimeStep, 1, 1);
00482         #ifdef PVM_DEBUG
00483                 if(info < 0){
00484                         cerr<<"NetworkMonitor: ERROR EXTRACTING MESSAGE TIME STEP; TASK ID = "<<pvm_mytid()<<"; messageTimeStep: "<<messageTimeStep<<endl;
00485                         return;
00486                 }
00487         #endif//PVM_DEBUG
00488 
00489         // Extract the number of spikes in the message
00490         info = pvm_upkuint(&numberOfSpikes, 1, 1);
00491         #ifdef PVM_DEBUG
00492                 if(info < 0){
00493                         cerr<<"NetworkMonitor: ERROR NUMBER OF FIRING NEURONS FROM MESSAGE; TASK ID = "<<pvm_mytid()<<"; numberOfSpikes: "<<numberOfSpikes<<endl;
00494                         return;
00495                 }
00496         #endif//PVM_DEBUG
00497 
00498         //Unpack the list of spikes 
00499         info = pvm_upkuint(unpackArray, numberOfSpikes, 1);//Unpack from and to neuron ids as two shorts compressed into an integer
00500         #ifdef PVM_DEBUG
00501                 if(info < 0){
00502                         cerr<<"NetworkMonitor: ERROR UNPACKING UNSIGNED INT FROM MESSAGE. NUMBER OF SPIKES = "<<numberOfSpikes<<endl;
00503                         return;
00504                 }
00505         #endif//PVM_DEBUG
00506         
00507         //Process the spikes to get the from ids
00508         for(unsigned int i=0; i<numberOfSpikes; ++i){
00509                 /* Add the from neuron ID to the from key.
00510                         Only need the from neuron id because we are monitoring spikes from a layer*/
00511                 unpkFromNeurID = (unsigned short) unpackArray[i];
00512                 unpkFromNeurID += startNeuronID;
00513 
00514                 //Add it to the buffer map
00515                 (*bufferMapPointer)[ unpkFromNeurID ] = true;
00516         }
00517 
00518         #ifdef SPIKE_DEBUG
00519                 cout<<"NetworkMonitor: NeuronGrpID = "<<neuronGrpID<<". Number of spikes processed: "<<numberOfSpikes<<" at timeStep: "<<messageTimeStep<<endl;
00520         #endif//SPIKE_DEBUG
00521 
00522         //Swap the active maps and updates the display
00523         swapMaps();
00524 }
00525 
00526 
00527 /*! Use scaleFactorWidth to set point size appropriately. 
00528                 Since neuron groups could be rectangular, but vertexes are always square it is 
00529                 probably too much effort trying to make this perfect. */
00530 void NetworkMonitor::setPointSize(){
00531         pointSize = scaleFactorWidth * 0.9;
00532         if(pointSize < 0.1)
00533                 pointSize = 0.1;
00534         else if(pointSize > 5.0)
00535                 pointSize = 5.0;
00536 }
00537 
00538 
00539 /*! Sets the current timestep. */
00540 void NetworkMonitor::setTimeStep(unsigned int timeStep){
00541         messageTimeStep = timeStep;
00542 }
00543 
00544 
00545 /*! Locks the application to prevent processing of events that triggers the draw method
00546         then swaps the reference so that it points to a different active map. */
00547 void NetworkMonitor::swapMaps(){
00548         /*Lock the mutex so main application can't post events to this thread 
00549                 whilst maps are being swapped. */
00550         spikeStrApp->lock();
00551 
00552         //Change the active map
00553         map1Active = !map1Active;
00554 
00555         //Clear the map that is not being used and point the map pointer to the active map
00556         if(map1Active){
00557                 drawingMapPointer = &firingNeuronMap1;
00558                 bufferMapPointer = &firingNeuronMap2;
00559                 firingNeuronMap2.clear();
00560         }
00561         else{
00562                 drawingMapPointer = &firingNeuronMap2;
00563                 bufferMapPointer = &firingNeuronMap1;
00564                 firingNeuronMap1.clear();
00565         }
00566 
00567         //Update the display
00568         //FIXME Qt instructions say to use updateGL() here, but this crashes it.
00569         update();
00570 
00571         //Unlock the mutex
00572         spikeStrApp->unlock();
00573 }
00574 
00575 
00576 
00577 
00578 

Generated on Mon Sep 3 22:29:04 2007 for SpikeStream Application by  doxygen 1.4.4