00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00032 #include <qmessagebox.h>
00033
00034
00035 #include "mysql++.h"
00036 #include "pvm3.h"
00037 using namespace mysqlpp;
00038
00039
00040
00041 GLfloat NetworkMonitor::marginL = 5.0f;
00042 GLfloat NetworkMonitor::marginW = 5.0f;
00043
00044
00045
00046 NetworkMonitor::NetworkMonitor(NeuronGroup neuronGrp, DBInterface *netDBInter, QWidget *parent) : QGLWidget(parent, "Network Monitor"){
00047
00048 networkDBInterface = netDBInter;
00049
00050
00051 spikeStrApp = SpikeStreamMainWindow::spikeStreamApplication;
00052
00053
00054 liveMonitoring = true;
00055
00056
00057 neuronGrpID = neuronGrp.neuronGrpID;
00058 neuronGrpWidth = neuronGrp.width;
00059 neuronGrpLength = neuronGrp.length;
00060
00061
00062 messageTimeStep = 0;
00063
00064
00065 numberOfSpikes = 0;
00066
00067
00068 unpackArray = new unsigned int[MAX_NUMBER_OF_SPIKES];
00069
00070
00071
00072
00073
00074
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());
00082 numberOfNeurons = Utilities::getUInt((std::string)neurGrpPropRow["COUNT(NeuronID)"]);
00083 startNeuronID = Utilities::getUInt((std::string)neurGrpPropRow["MIN(NeuronID)"]);
00084
00085
00086 query.reset();
00087 query<<"SELECT X, Y FROM NeuronGroups WHERE NeuronGrpID = "<<neuronGrpID;
00088 Result startGrpPosRes = query.store();
00089 Row startGrpPosRow(*startGrpPosRes.begin());
00090 startXPos = Utilities::getInt((std::string)startGrpPosRow["X"]);
00091 startYPos = Utilities::getInt((std::string)startGrpPosRow["Y"]);
00092 }
00093 catch (const BadQuery& er) {
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) {
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){
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
00120
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
00135 xPos -= startXPos;
00136 yPos -= startYPos;
00137
00138
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
00148 fastTmpConnection->close();
00149 }
00150 catch (const EndOfResults& er) {
00151
00152 }
00153 catch (const BadQuery& er) {
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) {
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){
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
00177 frameWidth = frameSize().width();
00178 frameHeight = frameSize().height();
00179
00180
00181
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
00191 setPointSize();
00192
00193
00194 arialFont = new QFont( "Arial", 10);
00195
00196
00197 map1Active = true;
00198 drawingMapPointer = &firingNeuronMap1;
00199 bufferMapPointer = &firingNeuronMap2;
00200 }
00201
00202
00203
00204 NetworkMonitor::NetworkMonitor(NeuronGroup neuronGrp, QWidget *parent) : QGLWidget(parent, "Network Monitor"){
00205
00206 spikeStrApp = SpikeStreamMainWindow::spikeStreamApplication;
00207
00208
00209 liveMonitoring = false;
00210
00211
00212 neuronGrpID = neuronGrp.neuronGrpID;
00213 neuronGrpWidth = neuronGrp.width;
00214 neuronGrpLength = neuronGrp.length;
00215
00216
00217 messageTimeStep = 0;
00218
00219
00220
00221
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
00232 frameWidth = frameSize().width();
00233 frameHeight = frameSize().height();
00234
00235
00236
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
00246 setPointSize();
00247
00248
00249 arialFont = new QFont( "Arial", 10);
00250
00251
00252 map1Active = true;
00253 drawingMapPointer = &firingNeuronMap1;
00254 bufferMapPointer = &firingNeuronMap2;
00255 }
00256
00257
00258
00259 NetworkMonitor::~ NetworkMonitor(){
00260 #ifdef MEMORY_DEBUG
00261 cout<<"DESTROYING NETWORK MONITOR"<<endl;
00262 #endif//MEMORY_DEBUG
00263
00264 delete arialFont;
00265
00266
00267 if(liveMonitoring)
00268 delete [] unpackArray;
00269
00270 }
00271
00272
00273
00274
00275
00276
00277
00278 void NetworkMonitor::reset(){
00279 numberOfSpikes = 0;
00280 messageTimeStep = 0;
00281 firingNeuronMap1.clear();
00282 firingNeuronMap2.clear();
00283 update();
00284 }
00285
00286
00287
00288
00289
00290
00291
00292 void NetworkMonitor::initializeGL(){
00293
00294
00295
00296 spikeStrApp->lock();
00297
00298
00299
00300 if(liveMonitoring)
00301 glClearColor(1.0f, 0.93f, 0.93f, 0.0f);
00302 else
00303 glClearColor(0.93f, 1.0f, 0.93f, 0.0f);
00304
00305
00306 glColor3f(0.2f, 0.0f, 0.0f);
00307
00308
00309
00310 spikeStrApp->unlock();
00311 }
00312
00313
00314
00315 void NetworkMonitor::paintGL(){
00316
00317
00318
00319
00320 spikeStrApp->lock();
00321
00322
00323 glClear(GL_COLOR_BUFFER_BIT);
00324
00325
00326 renderText(2, 12, "Time step: " + QString::number(messageTimeStep), *arialFont);
00327
00328
00329 glPointSize(pointSize);
00330
00331
00332 glPushMatrix();
00333
00334
00335 glTranslated(marginW, marginL, 0.0);
00336
00337
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
00345 glPopMatrix();
00346
00347
00348 checkOpenGLErrors();
00349
00350
00351
00352 spikeStrApp->unlock();
00353 }
00354
00355
00356
00357 void NetworkMonitor::resizeGL(int frameW, int frameH){
00358
00359
00360
00361 spikeStrApp->lock();
00362
00363
00364 frameWidth = frameW;
00365 frameHeight = frameH;
00366
00367
00368
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
00378 setPointSize();
00379
00380
00381
00382 if(frameHeight == 0)
00383 frameHeight = 1;
00384
00385 glViewport(0, 0, frameWidth, frameHeight);
00386
00387
00388 glMatrixMode(GL_PROJECTION);
00389 glLoadIdentity();
00390
00391
00392 gluOrtho2D(0.0, (GLfloat) frameWidth, 0.0f, (GLfloat) frameHeight);
00393
00394 glMatrixMode(GL_MODELVIEW);
00395 glLoadIdentity();
00396
00397
00398 checkOpenGLErrors();
00399
00400
00401
00402 spikeStrApp->unlock();
00403 }
00404
00405
00406
00407
00408
00409
00410
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
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
00435 void NetworkMonitor::processFiringNeuronList(){
00436
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
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
00455 info = pvm_upkuint(unpackArray, numberOfSpikes, 1);
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
00464 for(unsigned int i=0; i<numberOfSpikes; ++i){
00465
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
00474 swapMaps();
00475 }
00476
00477
00478
00479 void NetworkMonitor::processSpikeList(){
00480
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
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
00499 info = pvm_upkuint(unpackArray, numberOfSpikes, 1);
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
00508 for(unsigned int i=0; i<numberOfSpikes; ++i){
00509
00510
00511 unpkFromNeurID = (unsigned short) unpackArray[i];
00512 unpkFromNeurID += startNeuronID;
00513
00514
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
00523 swapMaps();
00524 }
00525
00526
00527
00528
00529
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
00540 void NetworkMonitor::setTimeStep(unsigned int timeStep){
00541 messageTimeStep = timeStep;
00542 }
00543
00544
00545
00546
00547 void NetworkMonitor::swapMaps(){
00548
00549
00550 spikeStrApp->lock();
00551
00552
00553 map1Active = !map1Active;
00554
00555
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
00568
00569 update();
00570
00571
00572 spikeStrApp->unlock();
00573 }
00574
00575
00576
00577
00578