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

NetworkViewerProperties.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 "NetworkViewerProperties.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 #include "SimulationManager.h"
00028 #include "SpikeStreamMainWindow.h"
00029 
00030 //Qt includes
00031 #include <qlayout.h>
00032 #include <qbuttongroup.h>
00033 #include <qmessagebox.h>
00034 
00035 //Other includes
00036 #include <mysql++.h>
00037 using namespace std;
00038 using namespace mysqlpp;
00039 
00040 
00041 /*! Constructor. */
00042 NetworkViewerProperties::NetworkViewerProperties(QWidget *parent, NetworkViewer *nwViewer, DBInterface *dbInter) : QWidget(parent, "Network Viewer Properties"){
00043 
00044         //Store reference to the networkViewer and dbInterface
00045         networkViewer = nwViewer;
00046         dbInterface = dbInter;
00047         
00048         //Initialise data variables
00049         firstSingleNeuronNumber = 0;
00050         secondSingleNeuronNumber = 0;
00051         showFromConns = true;
00052         showToConns = true;
00053         betweenMode = false;
00054 
00055         //Create a dialog to control the highlighting
00056         highlightDialog = new HighlightDialog(this, networkViewer);
00057 
00058         //Create main vertical box for layout
00059         QVBoxLayout *vBox = new QVBoxLayout(this, 5, 10, "Main vertical Box");
00060         vBox->addSpacing(5);
00061 
00062         //Add button to control highlighting
00063         QHBoxLayout* highlightBox = new QHBoxLayout();
00064         highlightButton = new QPushButton("Highlight", this);
00065         highlightButton->setBaseSize(150, 20);
00066         highlightButton->setMinimumSize(150, 20);
00067         highlightButton->setMaximumSize(150, 20);
00068         connect(highlightButton, SIGNAL(clicked()), this, SLOT(highlightButtonPressed()));
00069         highlightBox->addWidget(highlightButton);
00070         highlightBox->addStretch(5);
00071         vBox->addLayout(highlightBox);
00072 
00073         //Set up check box to toggle full rendering of scene
00074         fullRenderCheckBox = new QCheckBox("Render high quality view", this);
00075         vBox->addWidget(fullRenderCheckBox);
00076         
00077         //Set up label and combo box to control the delay before full scene rendering takes place
00078         QHBoxLayout *renderDelayBox = new QHBoxLayout();
00079         renderDelayBox->addSpacing(20);
00080         renderDelayLabel = new QLabel("Render delay", this);
00081         renderDelayLabel->setEnabled(false);
00082         renderDelayBox->addWidget(renderDelayLabel);
00083         renderDelayCombo = new QComboBox(this);
00084         renderDelayCombo->insertItem(QString::number(0.5) + " seconds");
00085         renderDelayCombo->insertItem(QString::number(1) + " seconds");
00086         renderDelayCombo->insertItem(QString::number(2) + " seconds");
00087         renderDelayCombo->insertItem(QString::number(5) + " seconds");
00088         renderDelayCombo->insertItem(QString::number(10) + " seconds");
00089         renderDelayCombo->setEnabled(false);
00090         renderDelayCombo->setCurrentItem(1);
00091         renderDelayBox->addWidget(renderDelayCombo);
00092         renderDelayBox->addStretch(5);
00093         vBox->addLayout(renderDelayBox);
00094         
00095         //Set up progress bar to display render progress
00096         QHBoxLayout *renderProgressBox = new QHBoxLayout();
00097         renderProgressBox->addSpacing(20);
00098         renderProgressLabel = new QLabel("Render progress", this);
00099         renderProgressLabel->setEnabled(false);
00100         renderProgressBox->addWidget(renderProgressLabel);
00101         progressBar = new QProgressBar(10, this);
00102         progressBar->setEnabled(false);
00103         networkViewer->setRenderProgressBar(progressBar);//Set the progress bar in the network viewer to enable render updates
00104         renderProgressBox->addWidget(progressBar);
00105         renderCancelButton = new QPushButton("Cancel", this);
00106         renderCancelButton->setEnabled(false);
00107         renderProgressBox->addWidget(renderCancelButton);
00108         connect (renderCancelButton, SIGNAL(clicked()), this, SLOT(cancelRenderProgress()));
00109         renderProgressBox->addStretch(5);
00110         vBox->addLayout(renderProgressBox);
00111         
00112         vBox->addSpacing(20);
00113         
00114         //Add controls for connections
00115         connectionsCheckBox = new QCheckBox("Show connections", this);
00116         connectionsCheckBox->setChecked(true);//Start in connection mode
00117         vBox->addWidget(connectionsCheckBox);
00118         
00119         //Set up radio buttons to choose between connection displays
00120         QButtonGroup* connButtonGroup = new QButtonGroup();
00121         allConnRadioButt = new QRadioButton("All selected connections", this);
00122         allConnRadioButt->setChecked(true);
00123         allConnRadioButt->setEnabled(true);
00124         connButtonGroup->insert(allConnRadioButt);
00125         connsSingleNeurRadioButt = new QRadioButton("", this);
00126         connsSingleNeurRadioButt->setChecked(false);
00127         connsSingleNeurRadioButt->setEnabled(true);
00128         connButtonGroup->insert(connsSingleNeurRadioButt);
00129         
00130         //Add all connection radio button to viewer widget
00131         QHBoxLayout *allConnBox = new QHBoxLayout();
00132         allConnBox->addSpacing(20);
00133         allConnBox->addWidget(allConnRadioButt);
00134         vBox->addLayout(allConnBox);
00135         
00136         //Add neuron connection radio button
00137         QHBoxLayout *neuronConnsBox = new QHBoxLayout();
00138         neuronConnsBox->addSpacing(20);
00139         neuronConnsBox->addWidget(connsSingleNeurRadioButt);
00140         
00141         //Add filter to view positive or negative connections
00142         neurConnsFilterCombo = new QComboBox(this);
00143         neurConnsFilterCombo->insertItem("All connections");
00144         neurConnsFilterCombo->insertItem("Positive connections");
00145         neurConnsFilterCombo->insertItem("Negative connections");
00146         neurConnsFilterCombo->setEnabled(false);
00147         neuronConnsBox->addWidget(neurConnsFilterCombo);
00148         
00149         //Add filter to view from/to connections
00150         neurConnsFromToCombo = new QComboBox(this);
00151         neurConnsFromToCombo->insertItem("from/to");
00152         neurConnsFromToCombo->insertItem("from");
00153         neurConnsFromToCombo->insertItem("to");
00154         neurConnsFromToCombo->insertItem("between");
00155         neurConnsFromToCombo->setEnabled(false);
00156         neuronConnsBox->addWidget(neurConnsFromToCombo);
00157         
00158         //Add the rest of this line
00159         singleNeurNumLabel_1 = new QLabel(QString::number(firstSingleNeuronNumber), this);
00160         singleNeurNumLabel_1->setEnabled(false);
00161         neuronConnsBox->addWidget(singleNeurNumLabel_1);
00162         inLabel_1 = new QLabel("in", this);
00163         inLabel_1->setEnabled(false);
00164         neuronConnsBox->addWidget(inLabel_1);
00165         neurConnsNeurGrpCombo_1 = new QComboBox(this);
00166         neurConnsNeurGrpCombo_1->setEnabled(false);
00167         loadLayerNames(neurConnsNeurGrpCombo_1);
00168         neuronConnsBox->addWidget(neurConnsNeurGrpCombo_1);
00169         andLabel = new QLabel("and", this);
00170         andLabel->setEnabled(false);
00171         neuronConnsBox->addWidget(andLabel);
00172         singleNeurNumLabel_2 = new QLabel("0", this);
00173         singleNeurNumLabel_2->setEnabled(false);
00174         neuronConnsBox->addWidget(singleNeurNumLabel_2);
00175         inLabel_2 = new QLabel("in", this);
00176         inLabel_2->setEnabled(false);
00177         neuronConnsBox->addWidget(inLabel_2);
00178         neurConnsNeurGrpCombo_2 = new QComboBox(this);
00179         neurConnsNeurGrpCombo_2->setEnabled(false);
00180         loadLayerNames(neurConnsNeurGrpCombo_2);
00181         neuronConnsBox->addWidget(neurConnsNeurGrpCombo_2);
00182         neuronConnsBox->addStretch(5);
00183         vBox->addLayout(neuronConnsBox);
00184         
00185         //Add connection details check box
00186         QHBoxLayout *connDetailsCheckBoxBox = new QHBoxLayout();
00187         connDetailsCheckBoxBox->addSpacing(40);
00188         connectionDetailsCheckBox = new QCheckBox("Connection details", this);
00189         connectionDetailsCheckBox->setChecked(false);
00190         connectionDetailsCheckBox->setEnabled(false);
00191         connDetailsCheckBoxBox->addWidget(connectionDetailsCheckBox);
00192         vBox->addLayout(connDetailsCheckBoxBox);
00193         
00194         //Add widgets to display total number of connections
00195         QHBoxLayout *neurTotalConnsBox = new QHBoxLayout();
00196         neurTotalConnsBox->addSpacing(40);
00197         neurConnsLabel = new QLabel("Total number of connections: ", this);
00198         neurConnsLabel->setEnabled(false);
00199         neurTotalConnsBox->addWidget(neurConnsLabel);
00200         neurTotalConnsLabel = new QLabel("", this);
00201         neurTotalConnsLabel->setEnabled(false);
00202         neurTotalConnsBox->addWidget(neurTotalConnsLabel);
00203         neurTotalConnsBox->addStretch(5);
00204         vBox->addLayout(neurTotalConnsBox);
00205         
00206         //Add connection details table
00207         QHBoxLayout *connDetailsTableBox = new QHBoxLayout();
00208         connDetailsTableBox->addSpacing(40);
00209         connectionDetailsTable = new QTable(0, 6, this);
00210         connectionDetailsTable->setEnabled(false);
00211         connectionDetailsTable->setSelectionMode(QTable::NoSelection);
00212         connectionDetailsTable->verticalHeader()->hide();
00213         connectionDetailsTable->setLeftMargin(0);
00214         QHeader * connTableHeader = connectionDetailsTable->horizontalHeader();
00215         connTableHeader->setLabel(0, "ConnGrpID" );
00216         connectionDetailsTable->setColumnWidth(0, 75);
00217         connTableHeader->setLabel(1, "PreConnNeurID" );
00218         connectionDetailsTable->setColumnWidth(1, 110);
00219         connTableHeader->setLabel(2, "PostConnNeurID" );
00220         connectionDetailsTable->setColumnWidth(2, 110);
00221         connTableHeader->setLabel(3, "Saved Weight" );
00222         connectionDetailsTable->setColumnWidth(3, 90);
00223         connTableHeader->setLabel(4, "Temp Weight" );
00224         connectionDetailsTable->setColumnWidth(4, 90);
00225         connTableHeader->setLabel(5, "Delay" );
00226         connectionDetailsTable->setColumnWidth(5, 60);
00227         connectionDetailsTable->setMinimumSize(600,300);
00228         connDetailsTableBox->addWidget(connectionDetailsTable);
00229         connDetailsTableBox->addStretch(5);
00230         vBox->addLayout(connDetailsTableBox);
00231         
00232         vBox->addStretch(5);
00233 
00234         //Connect signals to slots
00235         connect (fullRenderCheckBox, SIGNAL(clicked()), this, SLOT(renderStateChanged()));
00236         connect (renderDelayCombo, SIGNAL(activated(int)), this, SLOT(renderDelayChanged(int)));
00237         connect (connectionsCheckBox, SIGNAL(clicked()), this, SLOT(connCheckBoxChanged()));
00238         connect (allConnRadioButt, SIGNAL(clicked()), this, SLOT(showConnectionsChanged()));
00239         connect (connsSingleNeurRadioButt, SIGNAL(clicked()), this, SLOT(showConnectionsChanged()));
00240         connect (neurConnsNeurGrpCombo_1, SIGNAL(activated(int)), this, SLOT(firstNeuronComboChanged(int)));
00241         connect (neurConnsNeurGrpCombo_2, SIGNAL(activated(int)), this, SLOT(secondNeuronComboChanged(int)));
00242         connect (neurConnsFilterCombo, SIGNAL(activated(int)), this, SLOT(filterCombosChanged(int)));
00243         connect (neurConnsFromToCombo, SIGNAL(activated(int)), this, SLOT(filterCombosChanged(int)));
00244         connect (connectionDetailsCheckBox, SIGNAL(clicked()), this, SLOT(showConnectionDetailsChanged()));
00245         connect (connTableHeader, SIGNAL(clicked(int)), this, SLOT(sortRows(int)));
00246 }
00247 
00248 
00249 /*! Destructor. */
00250 NetworkViewerProperties::~NetworkViewerProperties(){
00251         #ifdef MEMORY_DEBUG
00252                 cout<<"DELETING NETWORK VIEWER PROPERTIES"<<endl;
00253         #endif//MEMORY_DEBUG
00254 }
00255 
00256 
00257 //--------------------------------------------------------------------------------------
00258 //--------------------------------- PUBLIC METHODS -------------------------------------
00259 //--------------------------------------------------------------------------------------
00260 
00261 /*! Reloads details about the connections if they are visible. */
00262 void NetworkViewerProperties::reloadConnectionDetails(){
00263         if(connectionDetailsCheckBox->isChecked()){
00264                 loadConnectionDetails();
00265         }
00266 }
00267 
00268 
00269 /*! Updates the connection details table. */
00270 void NetworkViewerProperties::reloadConnections(){
00271         if(connectionDetailsCheckBox->isChecked()){
00272                 loadConnectionDetails();
00273         }
00274 }
00275 
00276 
00277 /*! Reloads the list of neuron group names and resets all information relevant to neuron groups. */
00278 void NetworkViewerProperties::reloadNeuronGroups(){
00279         try{
00280                 loadLayerNames(neurConnsNeurGrpCombo_1);
00281                 loadLayerNames(neurConnsNeurGrpCombo_2);
00282                 if(connsSingleNeurRadioButt->isOn() && (neurConnsNeurGrpCombo_1->count() > 0)){
00283                         unsigned int layer1ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_1->currentText());
00284                         if(betweenMode){
00285                                 unsigned int layer2ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_2->currentText());
00286                                 networkViewer->setNeuronConnectionMode(true, layer1ID, true, layer2ID);
00287                         }
00288                         else{
00289                                 networkViewer->setNeuronConnectionMode(true, layer1ID, false, 0);
00290                         }
00291                         if(connectionDetailsCheckBox->isChecked()){
00292                                 loadConnectionDetails();
00293                         }
00294                 }
00295         }
00296         catch (const BadQuery& er) {// Handle any query errors
00297                 cerr<<"NetworkViewerProperties: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00298                 QString errorString = "Bad query reloading neuron groups: \"";
00299                 errorString += er.what();
00300                 errorString += "\"";
00301                 QMessageBox::critical( 0, "Load Neuron Groups Error", errorString);
00302         }
00303         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00304                 cerr<<"NetworkViewerProperties: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00305                 QString errorString = "Exception thrown reloading neuron groups: \"";
00306                 errorString += er.what();
00307                 errorString += "\"";
00308                 QMessageBox::critical( 0, "Load Neuron Groups Error", errorString);
00309         }
00310         catch (std::exception& er) {// Catch-all for any other MySQL++ exceptions
00311                 cerr<<"NetworkViewerProperties: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00312                 QString errorString = "Exception thrown reloading neuron groups: \"";
00313                 errorString += er.what();
00314                 errorString += "\"";
00315                 QMessageBox::critical( 0, "Load Neuron Groups Error", errorString);
00316         }
00317 }
00318 
00319 
00320 /*! Controls which single neuron is displayed in the connection details table. */
00321 void NetworkViewerProperties::setFirstSingleNeuronNumber(unsigned int neuronNumber){
00322         firstSingleNeuronNumber = neuronNumber;
00323         singleNeurNumLabel_1->setText(QString::number(neuronNumber));
00324         if(connectionDetailsCheckBox->isChecked()){
00325                 loadConnectionDetails();
00326         }
00327         //Update the fire neuron text box to the selected neuron
00328         if(neurConnsNeurGrpCombo_1->count() > 0){
00329                 unsigned int neurGrpID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_1->currentText());
00330                 SpikeStreamMainWindow::spikeStrMainWin->setFromNeuronID(neurGrpID, neuronNumber);
00331         }       
00332 }
00333 
00334 
00335 /*! Sets the label displaying which connection or neuron group is being rendered. */
00336 void NetworkViewerProperties::setRenderProgressLabel(const QString labelText){
00337         renderProgressLabel->setText(labelText);
00338 }
00339 
00340 
00341 /*! Controls which single neuron is displayed in the connection details table. */
00342 void NetworkViewerProperties::setSecondSingleNeuronNumber(unsigned int neuronNumber){
00343         secondSingleNeuronNumber = neuronNumber;
00344         singleNeurNumLabel_2->setText(QString::number(neuronNumber));
00345         if(connectionDetailsCheckBox->isChecked()){
00346                 loadConnectionDetails();
00347         }
00348         //Update any classes that depend on this number
00349         SpikeStreamMainWindow::spikeStrMainWin->setToNeuronID(neuronNumber);
00350 }
00351 
00352 
00353 //-----------------------------------------------------------------------------------------
00354 //---------------------------------------- SLOTS ------------------------------------------
00355 //-----------------------------------------------------------------------------------------
00356 
00357 /*! Linked to the cancel render button and cancels the render. */
00358 void NetworkViewerProperties::cancelRenderProgress(){
00359         networkViewer->cancelRenderProgress();
00360 }
00361 
00362 
00363 /*! Called when the check box controlling whether connections are displayed is clicked
00364         Hides or shows the connections and their associated GUI components. */
00365 void NetworkViewerProperties::connCheckBoxChanged(){
00366         if(connectionsCheckBox->isChecked()){
00367                 allConnRadioButt->setEnabled(true);
00368                 connsSingleNeurRadioButt->setEnabled(true);
00369                 if(connsSingleNeurRadioButt->isChecked()){
00370                         neurConnsNeurGrpCombo_1->setEnabled(true);
00371                         neurConnsFilterCombo->setEnabled(true);
00372                         neurConnsFromToCombo->setEnabled(true);
00373                         connectionDetailsCheckBox->setEnabled(true);
00374                         inLabel_1->setEnabled(true);
00375                         singleNeurNumLabel_1->setEnabled(true);
00376                         if(connectionDetailsCheckBox->isChecked()){
00377                                 connectionDetailsTable->setEnabled(true);
00378                                 neurTotalConnsLabel->setEnabled(true);
00379                                 neurConnsLabel->setEnabled(true);
00380                         }
00381                         if(betweenMode){
00382                                 neurConnsNeurGrpCombo_2->setEnabled(true);
00383                                 andLabel->setEnabled(true);
00384                                 inLabel_2->setEnabled(true);
00385                                 singleNeurNumLabel_2->setEnabled(true);
00386                         }
00387                 }
00388                 networkViewer->showConnections(true);
00389         }
00390         else{
00391                 allConnRadioButt->setEnabled(false);
00392                 connsSingleNeurRadioButt->setEnabled(false);
00393                 neurConnsNeurGrpCombo_1->setEnabled(false);
00394                 neurConnsNeurGrpCombo_2->setEnabled(false);
00395                 neurConnsFilterCombo->setEnabled(false);
00396                 neurConnsFromToCombo->setEnabled(false);
00397                 neurConnsLabel->setEnabled(false);
00398                 connectionDetailsCheckBox->setEnabled(false);
00399                 connectionDetailsTable->setEnabled(false);
00400                 neurTotalConnsLabel->setEnabled(false);
00401                 singleNeurNumLabel_1->setEnabled(false);
00402                 andLabel->setEnabled(false);
00403                 inLabel_1->setEnabled(false);
00404                 inLabel_2->setEnabled(false);
00405                 singleNeurNumLabel_2->setEnabled(false);
00406                 networkViewer->showConnections(false);
00407         }
00408 }
00409 
00410 
00411 /*! Called when the filters controlling the connections to a single neuron are changed
00412         Sets the filters that are applied to the connections in singel neuron mode. */
00413 void NetworkViewerProperties::filterCombosChanged(int){
00414         //Extract the from/to settings
00415         switch(neurConnsFromToCombo->currentItem()){
00416                 case 0:
00417                         showFromConns = true;
00418                         showToConns = true;
00419                         betweenMode = false;
00420                         //Enable relevant components
00421                         neurConnsNeurGrpCombo_2->setEnabled(false);
00422                         singleNeurNumLabel_2->setEnabled(false);
00423                         andLabel->setEnabled(false);
00424                         inLabel_2->setEnabled(false);
00425                 break;
00426                 case 1:
00427                         showFromConns = true;
00428                         showToConns = false;
00429                         betweenMode = false;
00430                         //Enable relevant components
00431                         neurConnsNeurGrpCombo_2->setEnabled(false);
00432                         singleNeurNumLabel_2->setEnabled(false);
00433                         andLabel->setEnabled(false);
00434                         inLabel_2->setEnabled(false);
00435                 break;
00436                 case 2:
00437                         showFromConns = false;
00438                         showToConns = true;
00439                         betweenMode = false;
00440                         //Enable relevant components
00441                         neurConnsNeurGrpCombo_2->setEnabled(false);
00442                         singleNeurNumLabel_2->setEnabled(false);
00443                         andLabel->setEnabled(false);
00444                         inLabel_2->setEnabled(false);
00445                 break;
00446                 case 3:
00447                         showFromConns = true;
00448                         showToConns = true;
00449                         betweenMode = true;
00450                         //Enable relevant components
00451                         neurConnsNeurGrpCombo_2->setEnabled(true);
00452                         singleNeurNumLabel_2->setEnabled(true);
00453                         andLabel->setEnabled(true);
00454                         inLabel_2->setEnabled(true);
00455                 break;
00456                 default:
00457                         cerr<<"NetworkViewerProperties.cpp: CANNOT IDENTIFY FROM/TO COMBO INDEX - PROBABLY CHANGED AT SOME POINT WITHOUT UPDATING loadConnectionDetails()";
00458                         QMessageBox::critical( 0, "Connection Database Error", "Cannot identify from/to combo index");
00459                         return;
00460         }
00461 
00462         //Get the settings for the neuron filter in the network viewer properties
00463         short minWeight, maxWeight;
00464         switch(neurConnsFilterCombo->currentItem()){
00465                 case 0://Show all connections to neuron
00466                         minWeight = -128;
00467                         maxWeight = 127;
00468                 break;
00469                 case 1://Show positive connection weights to this neuron
00470                         minWeight = 0;
00471                         maxWeight = 127;
00472                 break;
00473                 case 2://Show negative connection weights to this neuron
00474                         minWeight = -128;
00475                         maxWeight = 0;
00476                 break;
00477                 default://Cannot find index. Must have been changed at some point without updating this method
00478                         cerr<<"NetworkViewerProperties: INDEX NOT FOUND"<<endl;
00479                         QMessageBox::critical( 0, "Filter Error", "Cannot identify neuron connections filter index.");
00480                         return;
00481         }
00482 
00483         //Set the filter mode in the network viewer
00484         //Check to see if filter mode is on or off. With filter mode off drawing is done more quickly
00485         if(neurConnsFromToCombo->currentItem() == 0 && neurConnsFilterCombo->currentItem() == 0)
00486                 networkViewer->setNeuronFilterMode(false, -1, -1, true, true, false);//Switch off filter mode
00487         else
00488                 networkViewer->setNeuronFilterMode(true, minWeight, maxWeight, showFromConns, showToConns, false);
00489         
00490         //Set the between mode in the network viewer
00491         if(betweenMode && neurConnsNeurGrpCombo_1->count() > 0){
00492                 unsigned int layer1ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_1->currentText());//Get the first neuron id
00493                 unsigned int layer2ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_2->currentText());//Get the second neuron id
00494                 networkViewer->setNeuronConnectionMode(true, layer1ID, true, layer2ID);
00495         }
00496         else if(neurConnsNeurGrpCombo_1->count() > 0){
00497                 unsigned int layer1ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_1->currentText());//Get the first neuron id
00498                 networkViewer->setNeuronConnectionMode(true, layer1ID, false, 0);
00499         }
00500         
00501         if(connectionDetailsCheckBox->isChecked())
00502                 loadConnectionDetails();
00503 }
00504 
00505 
00506 /*! Called when combo box controlling which layer is used for single neuron mode is activated. */
00507 void NetworkViewerProperties::firstNeuronComboChanged(int){
00508         if(connsSingleNeurRadioButt->isOn() && neurConnsNeurGrpCombo_1->count() > 0){
00509                 unsigned int layer1ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_1->currentText());
00510                 if(betweenMode){//In between mode
00511                         unsigned int layer2ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_2->currentText());//Get the second neuron id
00512                         networkViewer->setNeuronConnectionMode(true, layer1ID, true, layer2ID);
00513                 }
00514                 else{
00515                         networkViewer->setNeuronConnectionMode(true, layer1ID, false, 0);
00516                 }
00517         }
00518 }
00519 
00520 
00521 /*! Launches a dialog to add or remove the highlighting of neurons in the network.*/
00522 void NetworkViewerProperties::highlightButtonPressed(){
00523         highlightDialog->show();
00524 }
00525 
00526 
00527 /*! Controls the setting of the render delay. */
00528 void NetworkViewerProperties::renderDelayChanged(int){
00529         QString comboText = renderDelayCombo->currentText();
00530         QString delayText = comboText.section( ' ', 0, 0 );
00531         double tempDelay = 0.0;
00532         try{
00533                 tempDelay = Utilities::getDouble(delayText.ascii());
00534         }
00535         catch (std::exception& er) {// Catch-all for any other MySQL++ exceptions
00536                 cerr<<"NetworkViewerProperties: EXCEPTION \""<<er.what()<<"\""<<endl;
00537                 QString errorString = "Exception thrown converting string to double: \"";
00538                 errorString += er.what();
00539                 errorString += "\"";
00540                 QMessageBox::critical( 0, "Render Delay Error", errorString);
00541                 return;
00542         }
00543         networkViewer->setRenderDelay(tempDelay);
00544 }
00545 
00546 
00547 /*! Controls full render mode
00548         Enables the relevant GUI components and sets network viewer into full render mode. */
00549 void NetworkViewerProperties::renderStateChanged(){
00550         if(fullRenderCheckBox->isChecked()){
00551                 renderDelayLabel->setEnabled(true);
00552                 renderDelayCombo->setEnabled(true);
00553                 renderProgressLabel->setEnabled(true);
00554                 progressBar->setEnabled(true);
00555                 networkViewer->setFullRenderMode(true);
00556                 renderCancelButton->setEnabled(true);
00557         }
00558         else{
00559                 renderDelayLabel->setEnabled(false);
00560                 renderDelayCombo->setEnabled(false);
00561                 renderProgressLabel->setEnabled(false);
00562                 progressBar->setEnabled(false);
00563                 networkViewer->setFullRenderMode(false);
00564                 renderCancelButton->setEnabled(false);
00565         }
00566 }
00567 
00568 
00569 /*! Called when combo box controlling which layer is used for single neuron mode is activated.
00570         Identical to previous method, but keep separate for the moment. */
00571 void NetworkViewerProperties::secondNeuronComboChanged(int){
00572         if(connsSingleNeurRadioButt->isOn() && neurConnsNeurGrpCombo_1->count() > 0){
00573                 unsigned int layer1ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_1->currentText());
00574                 if(betweenMode){//In between mode
00575                         unsigned int layer2ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_2->currentText());//Get the second neuron id
00576                         networkViewer->setNeuronConnectionMode(true, layer1ID, true, layer2ID);
00577                 }
00578                 else{
00579                         networkViewer->setNeuronConnectionMode(true, layer1ID, false, 0);
00580                 }
00581         }
00582 }
00583 
00584 
00585 /*! Shows or hides the table displaying the list of connections for a single neuron
00586         Single neuron number should be meaningful by this point. */
00587 void NetworkViewerProperties::showConnectionDetailsChanged(){
00588         if(connectionDetailsCheckBox->isChecked()){
00589                 connectionDetailsTable->setEnabled(true);
00590                 neurConnsLabel->setEnabled(true);
00591                 neurTotalConnsLabel->setEnabled(true);
00592                 loadConnectionDetails();
00593         }
00594         else{
00595                 connectionDetailsTable->setEnabled(false);
00596                 neurConnsLabel->setEnabled(false);
00597                 neurTotalConnsLabel->setEnabled(false);
00598                 connectionDetailsTable->setNumRows(0);
00599         }
00600 }
00601 
00602 
00603 /*! Called in response to a change in the radio buttons controlling whether all connections
00604         are shown or just connections to a single neuron. */
00605 void NetworkViewerProperties::showConnectionsChanged(){
00606         if(allConnRadioButt->isOn()){
00607                 networkViewer->setNeuronConnectionMode(false, 0, false, 0);
00608                 connectionDetailsCheckBox->setEnabled(false);
00609                 connectionDetailsTable->setEnabled(false);
00610                 neurConnsLabel->setEnabled(false);
00611                 neurConnsNeurGrpCombo_1->setEnabled(false);
00612                 neurConnsNeurGrpCombo_2->setEnabled(false);
00613                 neurConnsFilterCombo->setEnabled(false);
00614                 neurConnsFromToCombo->setEnabled(false);
00615                 neurConnsLabel->setEnabled(false);
00616                 connectionDetailsCheckBox->setEnabled(false);
00617                 connectionDetailsTable->setEnabled(false);
00618                 neurTotalConnsLabel->setEnabled(false);
00619                 andLabel->setEnabled(false);
00620                 inLabel_1->setEnabled(false);
00621                 inLabel_2->setEnabled(false);
00622                 singleNeurNumLabel_1->setEnabled(false);
00623                 singleNeurNumLabel_2->setEnabled(false);
00624         }
00625         else if(connsSingleNeurRadioButt->isOn() && neurConnsNeurGrpCombo_1->count() > 0){
00626                 unsigned int layer1ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_1->currentText());
00627                 if(betweenMode){
00628                         unsigned int layer2ID = Utilities::getNeuronGrpID(neurConnsNeurGrpCombo_2->currentText());
00629                         networkViewer->setNeuronConnectionMode(true, layer1ID, true, layer2ID);
00630                         neurConnsNeurGrpCombo_2->setEnabled(true);
00631                         andLabel->setEnabled(true);
00632                         inLabel_2->setEnabled(true);
00633                         singleNeurNumLabel_2->setEnabled(true);
00634                 }
00635                 else{
00636                         networkViewer->setNeuronConnectionMode(true, layer1ID, false, 0);
00637                 }
00638                 connectionDetailsCheckBox->setEnabled(true);
00639                 if(connectionDetailsCheckBox->isChecked()){
00640                         neurConnsLabel->setEnabled(true);
00641                         neurTotalConnsLabel->setEnabled(true);
00642                         connectionDetailsTable->setEnabled(true);
00643                 }
00644                 neurConnsNeurGrpCombo_1->setEnabled(true);
00645                 neurConnsFilterCombo->setEnabled(true);
00646                 neurConnsFromToCombo->setEnabled(true);
00647                 singleNeurNumLabel_1->setEnabled(true);
00648                 inLabel_1->setEnabled(true);
00649         }
00650 }
00651 
00652 
00653 /*! Sorts rows in response to a click on one of the column headers. */
00654 void NetworkViewerProperties::sortRows(int col){
00655         connectionDetailsTable->sortColumn(col, false, true);
00656 }
00657 
00658 
00659 //-------------------------------------------------------------------------------
00660 //---------------------------- PRIVATE METHODS ----------------------------------
00661 //-------------------------------------------------------------------------------
00662 
00663 /*! Fills the table with details about a set of connecions to a neuron from the database. */
00664 void NetworkViewerProperties::loadConnectionDetails(){
00665         //First clear the table
00666         connectionDetailsTable->setNumRows(0);
00667         
00668         //Load all of the connection information from database
00669         try{
00670                 vector<unsigned int> *viewVector = networkViewer->getConnectionViewVector();
00671                 Query query = dbInterface->getQuery();
00672                 query.reset();
00673                 
00674                 if(!viewVector->empty()){//Only want to display connections within connection view vector
00675                         //Add neuron information to query
00676                         query<<"SELECT ConnGrpID, PreSynapticNeuronID, PostSynapticNeuronID, Weight, TempWeight, Delay FROM Connections WHERE ";
00677                         
00678                         //Control whether from or to connections are shown
00679                         if(betweenMode){
00680                                 query<<"((PreSynapticNeuronID = "<<firstSingleNeuronNumber<<" AND PostSynapticNeuronID = "<<secondSingleNeuronNumber<<") ";
00681                                 query<<"OR (PreSynapticNeuronID = "<<secondSingleNeuronNumber<<" AND PostSynapticNeuronID = "<<firstSingleNeuronNumber<<"))";
00682                         }
00683                         else{
00684                                 if(showFromConns && showToConns)
00685                                         query<<"(PreSynapticNeuronID = "<<firstSingleNeuronNumber<<" OR PostSynapticNeuronID = "<<firstSingleNeuronNumber<<")";
00686                         
00687                                 else if(showFromConns && !showToConns)
00688                                         query<<"PreSynapticNeuronID = "<<firstSingleNeuronNumber;
00689                                         
00690                                 else if (!showFromConns && showToConns)
00691                                         query<<"PostSynapticNeuronID = "<<firstSingleNeuronNumber;
00692                                 
00693                                 else{//Error, neither from nor to connections are showing
00694                                         cerr<<"NetworkViewerProperties: PROBLEM WITH FROM/TO FILTERING"<<endl;
00695                                         QMessageBox::critical( 0, "Connection Database Error", "Problem with from/to filtering");
00696                                         return;
00697                                 }
00698                         }
00699                         //Add list of displayed connection groups to query
00700                         query<<" AND (ConnGrpID = ";
00701                         for(unsigned int i=0; i< viewVector->size(); i++){
00702                                 query<<viewVector->at(i);
00703                                 if(i != viewVector->size() - 1)
00704                                         query<<" OR ConnGrpID = ";
00705                         
00706                         }
00707                         query<<")";
00708         
00709                 
00710                         //Add restrictions on weights to query
00711                         switch(neurConnsFilterCombo->currentItem()){
00712                                 case 0://No weight filtering, do nothing
00713                                         ;
00714                                 break;
00715                                 case 1://Only show positive weights
00716                                         query<<" AND Weight >= 0 AND Weight <= 127";
00717                                 break;
00718                                 case 2://Only show negative weights
00719                                         query<<" AND Weight < 0 AND Weight >= -128";
00720                                 break;
00721                                 default:
00722                                         cerr<<"NetworkViewerProperties: CANNOT IDENTIFY FILTER COMBO INDEX - PROBABLY CHANGED AT SOME POINT WITHOUT UPDATING loadConnectionDetails()";
00723                                         QMessageBox::critical( 0, "Connection Database Error", "Cannot find filter combo index");
00724                                         return;
00725                         }
00726                         Result result = query.store();
00727                         connectionDetailsTable->insertRows(0, result.size());//Add rows to table
00728                         int rowCount = 0;
00729                         for(Result::iterator iter = result.begin(); iter != result.end(); iter++){
00730                                 Row row(*iter);
00731                                 connectionDetailsTable->setItem(rowCount, 0, new QTableItem(connectionDetailsTable, QTableItem::Never, (string)row["ConnGrpID"]));
00732                                 connectionDetailsTable->setItem(rowCount, 1, new QTableItem(connectionDetailsTable, QTableItem::Never, (string)row["PreSynapticNeuronID"]));
00733                                 connectionDetailsTable->setItem(rowCount, 2, new QTableItem(connectionDetailsTable, QTableItem::Never, (string)row["PostSynapticNeuronID"]));
00734                                 connectionDetailsTable->setItem(rowCount, 3, new QTableItem(connectionDetailsTable, QTableItem::Never, (string)row["Weight"]));
00735                                 connectionDetailsTable->setItem(rowCount, 4, new QTableItem(connectionDetailsTable, QTableItem::Never, (string)row["TempWeight"]));
00736                                 connectionDetailsTable->setItem(rowCount, 5, new QTableItem(connectionDetailsTable, QTableItem::Never, (string)row["Delay"]));
00737                                 rowCount++;
00738                         }
00739                 }
00740         }
00741         catch (const BadQuery& er) {// Handle any query errors
00742                 cerr<<"NetworkViewerProperties: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00743                 QString errorString = "Bad query loading connection information: \"";
00744                 errorString += er.what();
00745                 errorString += "\"";
00746                 QMessageBox::critical( 0, "Connection Database Error", errorString);
00747         }
00748         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00749                 cerr<<"NetworkViewerProperties: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00750                 QString errorString = "Exception thrown loading connection information: \"";
00751                 errorString += er.what();
00752                 errorString += "\"";
00753                 QMessageBox::critical( 0, "Connection Database Error", errorString);
00754         }
00755         
00756         //Set Label indicating total number of connections
00757         neurTotalConnsLabel->setText(QString::number(connectionDetailsTable->numRows()));
00758 }
00759 
00760 
00761 /*! Loads a list of layer names and IDs into a combo box 
00762         Adapted from method in connection properties dialog. */
00763 void NetworkViewerProperties::loadLayerNames(QComboBox *comboBox){
00764         try{
00765                 comboBox->clear();
00766                 Query query = dbInterface->getQuery();
00767                 query.reset();
00768                 query<<"SELECT Name, NeuronGrpID FROM NeuronGroups";
00769                 Result layerResult= query.store();
00770                 for(Result::iterator resIter = layerResult.begin(); resIter < layerResult.end(); resIter++){
00771                         Row row(*resIter);
00772                         QString layerString((std::string)row["Name"] + " [" += (string)row["NeuronGrpID"] += "]");
00773                         comboBox->insertItem(layerString);
00774                 }
00775         }
00776         catch (const BadQuery& er) {// Handle any query errors
00777                 cerr<<"NetworkViewerProperties: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00778                 QString errorString = "Bad query loading layer names: \"";
00779                 errorString += er.what();
00780                 errorString += "\"";
00781                 QMessageBox::critical( 0, "Load Layer Names Error", errorString);
00782         }
00783         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00784                 cerr<<"NetworkViewerProperties: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00785                 QString errorString = "Exception thrown loading layer names: \"";
00786                 errorString += er.what();
00787                 errorString += "\"";
00788                 QMessageBox::critical( 0, "Load Layer Names Error", errorString);
00789         }
00790 }
00791 
00792 
00793 

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