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

ConnectionPropertiesDialog.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 "ConnectionPropertiesDialog.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 
00028 //Qt includes
00029 #include <qlayout.h>
00030 #include <qaccel.h>
00031 #include <qpushbutton.h>
00032 #include <qradiobutton.h>
00033 #include <qbuttongroup.h>
00034 #include <qmessagebox.h>
00035 
00036 //Other includes
00037 #include <mysql++.h>
00038 #include <map>
00039 #include <string>
00040 #include <sstream>
00041 #include <iostream>
00042 using namespace std;
00043 using namespace mysqlpp;
00044 
00045 
00046 /*! Constructor used for standard connections that allows user to select the connection type */
00047 ConnectionPropertiesDialog::ConnectionPropertiesDialog(QWidget *parent, const char *name, DBInterface *dbInter) : QDialog(parent, name){
00048         //Store reference to dbInterface
00049         dbInterface = dbInter;
00050 
00051         //Initialise variables
00052         editMode = false;
00053         connectionType = -1;
00054         fromNeurGrpID = -1;
00055         toNeurGrpID = -1;
00056         parameterError = false;
00057 
00058         //Call method to assemble dialog
00059         loadError = false;
00060         try{
00061                 constructDialog();
00062         }
00063         catch (const BadQuery& er) {// Handle any query errors
00064                 cerr<<"ConnectionPropertiesDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00065                 QString errorString = "Bad query when constructing dialog: \"";
00066                 errorString += er.what();
00067                 errorString += "\"";
00068                 QMessageBox::critical( 0, "Connection Properties Error", errorString);
00069                 loadError = true;
00070         }
00071         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00072                 cerr<<"ConnectionPropertiesDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00073                 QString errorString = "Exception thrown constructing dialog: \"";
00074                 errorString += er.what();
00075                 errorString += "\"";
00076                 QMessageBox::critical( 0, "Connection Properties Error", errorString);
00077                 loadError = true;
00078         }
00079         catch(std::exception& er){// Catch-all for any other exceptions
00080                 cerr<<"ConnectionPropertiesDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00081                 QString errorString = "Exception thrown constructing dialog: \"";
00082                 errorString += er.what();
00083                 errorString += "\"";
00084                 QMessageBox::critical( 0, "Connection Properties Error", errorString);
00085                 loadError = true;
00086         }
00087 }
00088 
00089 
00090 /*! Constructor used when creating SIMNOS component connections. In this case the
00091         from and to neuron group id are known along with the connection type. In this
00092         case this dialog is used to gather remaining information about the connection */
00093 ConnectionPropertiesDialog::ConnectionPropertiesDialog(QWidget *parent, const char *name, DBInterface *dbInter, unsigned int fNeurGrpID, unsigned int tNeurGrpID, unsigned short connType) : QDialog(parent, name){
00094         //Store reference to dbInterface
00095         dbInterface = dbInter;
00096 
00097         //Initialise variables
00098         editMode = true;
00099         connectionType = connType;
00100         fromNeurGrpID = fNeurGrpID;
00101         toNeurGrpID = tNeurGrpID;
00102 
00103         //Call method to assemble dialog
00104         try{
00105                 constructDialog();
00106         }
00107         catch (const BadQuery& er) {// Handle any query errors
00108                 cerr<<"ConnectionPropertiesDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00109                 QString errorString = "Bad query when constructing dialog: \"";
00110                 errorString += er.what();
00111                 errorString += "\"";
00112                 QMessageBox::critical( 0, "Connection Properties Error", errorString);
00113                 loadError = true;
00114         }
00115         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00116                 cerr<<"ConnectionPropertiesDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00117                 QString errorString = "Exception thrown constructing dialog: \"";
00118                 errorString += er.what();
00119                 errorString += "\"";
00120                 QMessageBox::critical( 0, "Connection Properties Error", errorString);
00121                 loadError = true;
00122         }
00123         catch(std::exception& er){// Catch-all for any other exceptions
00124                 cerr<<"ConnectionPropertiesDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00125                 QString errorString = "Exception thrown constructing dialog: \"";
00126                 errorString += er.what();
00127                 errorString += "\"";
00128                 QMessageBox::critical( 0, "Connection Properties Error", errorString);
00129                 loadError = true;
00130         }
00131 }
00132 
00133 
00134 /*! Creates the dialog, either using the supplied neuron group ids or allowing
00135         the user to select the neuron group ids and connection type */
00136 void ConnectionPropertiesDialog::constructDialog(){
00137 
00138         /* Validators that are used to check for the correct input
00139                 Parameter validator assumes that the parameters will be between -100,000 and 100,000
00140                 Delay validator assumes that delay will be between 0 and 250 ms. */
00141         paramValidator = new QDoubleValidator(-100000.0, 100000.0, 4, this);
00142         delayValidator = new QIntValidator(DEFAULT_MIN_DELAY, DEFAULT_MAX_DELAY, this);
00143         
00144         //Create vertical box to arrane dialog widget
00145         QVBoxLayout *vBox = new QVBoxLayout(this, 5, 10, "Main vertical Box");
00146         
00147         //Set up radio buttons to choose between inter and intra layer connections
00148         if(!editMode){
00149                 QButtonGroup *buttonGroup = new QButtonGroup();
00150                 intraRadioButt = new QRadioButton("Connections within a single layer", this, "intraRadio");
00151                 intraRadioButt->setChecked(true);
00152                 interRadioButt = new QRadioButton("Connections between layers", this, "interRadio");
00153                 interRadioButt->setChecked(false);
00154                 buttonGroup->insert(intraRadioButt);
00155                 buttonGroup->insert(interRadioButt);
00156         
00157                 //Set up labels for combo boxes
00158                 intraLayerLabel = new QLabel("Layer:", this, "Intra layer choice");
00159                 fromLayerLabel = new QLabel("From Layer:", this, "Inter layer from");
00160                 fromLayerLabel->setEnabled(false);
00161                 toLayerLabel = new QLabel("To Layer:", this, "Inter layer to");
00162                 toLayerLabel->setEnabled(false);
00163         }
00164         
00165         //Initialise parameter table before intitializing combo boxes. Otherwise get segmentation fault
00166         connParamTable = new ConnectionParameterTable(3, 2, this);
00167         
00168         if(editMode){//Fill table with the parameters for the connection type 
00169                 loadParameterTable(connectionType);
00170         }
00171         else{//Set up combo boxes
00172                 intraLayerCombo = new QComboBox(this, "Intra layer combo");
00173                 fromLayerCombo = new QComboBox(this, "from layer combo");
00174                 fromLayerCombo->setEnabled(false);
00175                 toLayerCombo = new QComboBox(this, "to layer combo");
00176                 toLayerCombo->setEnabled(false);
00177                 loadLayerNames();
00178         
00179                 //Arrange all the components in the connection widget
00180                 //First the intra layer components
00181                 vBox->addWidget(intraRadioButt);
00182                 QHBoxLayout *intraBox = new QHBoxLayout();
00183                 intraBox->addSpacing(20);
00184                 intraBox->addWidget(intraLayerLabel);
00185                 intraBox->addWidget(intraLayerCombo);
00186                 intraBox->addStretch(5);
00187                 vBox->addLayout(intraBox);
00188         
00189                 //Add inter layer components
00190                 vBox->addWidget(interRadioButt);
00191         
00192                 QHBoxLayout *interBox = new QHBoxLayout();
00193                 interBox->addSpacing(20);
00194                 interBox->addWidget(fromLayerLabel);
00195                 interBox->addWidget(fromLayerCombo);
00196                 interBox->addWidget(toLayerLabel);
00197                 interBox->addWidget(toLayerCombo);
00198                 interBox->addStretch(5);
00199                 vBox->addLayout(interBox);
00200                 
00201                 vBox->addSpacing(15);
00202                 
00203                 //Add combo box for connection type. Initially set to values for intra layer connection
00204                 QHBoxLayout *connTypeBox = new QHBoxLayout();
00205                 connectionTypeCombo = new QComboBox(this, "Connection Type");
00206                 connectionTypeCombo->setMinimumSize(250,30);
00207                 
00208                 //Initially fill eith intra layer connection types
00209                 fillConnectionTypeCombo_INTRA();
00210                 connTypeBox->addWidget(new QLabel("Connection Type", this, "Connection type"));
00211                 connTypeBox->addWidget(connectionTypeCombo);
00212                 connTypeBox->addStretch(3);
00213                 vBox->addLayout(connTypeBox);
00214         }
00215 
00216         //Finish table to show connection parameters
00217         vBox->addWidget(new QLabel("Connection Parameters", this, "Connection params"));
00218         connParamTable->setSorting(false);
00219         connParamTable->verticalHeader()->hide();
00220         connParamTable->setLeftMargin(0);
00221         connParamTable->horizontalHeader()->hide();
00222         connParamTable->setTopMargin(0);
00223         connParamTable->setColumnWidth( 0, 300);
00224         connParamTable->setColumnWidth( 1, 100);
00225         vBox->addWidget(connParamTable);
00226         
00227         vBox->addSpacing(5);
00228 
00229         //Add combo box for synapse type
00230         QHBoxLayout *synapseTypeBox = new QHBoxLayout();
00231         synapseTypeCombo = new QComboBox(this, "SynapseType");
00232         synapseTypeCombo->setMinimumSize(250, 30);
00233 
00234         //Load up the synapse types from the database
00235         Query query = dbInterface->getQuery();
00236         query.reset();
00237         query<<"SELECT TypeID, Description FROM SynapseTypes";
00238         Result typeResult = query.store();
00239         int counter = 0;
00240         for(Result::iterator iter = typeResult.begin(); iter != typeResult.end(); ++iter){
00241                 Row synTypeRow(*iter);
00242                 unsigned short synapseTypeID = Utilities::getUShort((std::string) synTypeRow["TypeID"]);
00243 
00244                 //Store link between neuron type and combo index
00245                 synapseTypePositionMap[counter] = synapseTypeID;
00246 
00247                 QString typeDescription = (std::string) synTypeRow["Description"];
00248                 typeDescription += " [" + (std::string) synTypeRow["TypeID"] + "]";
00249                 synapseTypeCombo->insertItem(typeDescription);
00250                 counter++;
00251         }
00252 
00253         //Add combo to dialog
00254         synapseTypeBox->addWidget(new QLabel("Synapse type", this, "Synapse type"));
00255         synapseTypeBox->addWidget(synapseTypeCombo);
00256         synapseTypeBox->addStretch(5);
00257         vBox->addLayout(synapseTypeBox);
00258         
00259         vBox->addSpacing(5);
00260         
00261         //Set up labels and fields for delay 
00262         QHBoxLayout *delayBox = new QHBoxLayout();
00263         delayBox->addWidget(new QLabel("Delay Range:", this, "delay range"));
00264         delayBox->addSpacing(10);
00265         delayBox->addWidget(new QLabel("Min", this, "min delay"));
00266         minDelayText = new QLineEdit(QString::number(DEFAULT_MIN_DELAY), this);
00267         minDelayText->setValidator( delayValidator );
00268         minDelayText->setMaximumSize(50,20);
00269         delayBox->addWidget(minDelayText);
00270         delayBox->addSpacing(5);
00271         delayBox->addWidget(new QLabel("Max", this, "max delay"));
00272         maxDelayText = new QLineEdit(QString::number(DEFAULT_MAX_DELAY), this);
00273         maxDelayText->setValidator(delayValidator);
00274         maxDelayText->setMaximumSize(50, 20);
00275         delayBox->addWidget(maxDelayText);
00276         delayBox->addStretch(5);
00277         vBox->addLayout(delayBox);
00278         
00279         vBox->addSpacing(15);
00280         
00281         //Set up ok and cancel buttons
00282         QHBoxLayout *buttonBox = new QHBoxLayout();
00283         QPushButton *okPushButton = new QPushButton("Ok", this, "okButton");
00284         QPushButton *cancelPushButton = new QPushButton("Cancel", this, "cancelButton");        
00285         buttonBox->addWidget(okPushButton);
00286         buttonBox->addWidget(cancelPushButton);
00287         vBox->addLayout(buttonBox);
00288         
00289         //Connect signals to slots for event handling
00290         if(!editMode){
00291                 connect (intraRadioButt, SIGNAL(clicked()), this, SLOT(layerRadioStateChanged()));
00292                 connect (interRadioButt, SIGNAL(clicked()), this, SLOT(layerRadioStateChanged()));
00293                 connect (connectionTypeCombo, SIGNAL(activated(int)), this, SLOT(paramSelectionChanged()));
00294         }
00295 
00296         connect (okPushButton, SIGNAL(clicked()), this, SLOT(okButtonPressed()));
00297         connect (cancelPushButton, SIGNAL(clicked()), this, SLOT(reject()));
00298         connect (connParamTable, SIGNAL(valueChanged(int, int)), this, SLOT(paramValueChanged(int, int)));      
00299         
00300         //Set up accelerator for return button
00301         QAccel *returnAccel = new QAccel( this );
00302     returnAccel->connectItem( returnAccel->insertItem( Key_Enter ), this, SLOT(okButtonPressed()));
00303 }
00304 
00305 
00306 /*! Destructor
00307         Qt widgets created with this as a reference should be deleted automatically. */
00308 ConnectionPropertiesDialog::~ConnectionPropertiesDialog(){
00309         #ifdef MEMORY_DEBUG
00310                 cout<<"DELETING CONNECTION PROPERTIES DIALOG"<<endl;
00311         #endif//MEMORY_DEBUG
00312 }
00313 
00314 
00315 //--------------------------------------------------------------------------------
00316 //----------------------------- PUBLIC METHODS -----------------------------------
00317 //--------------------------------------------------------------------------------
00318 
00319 /*! Returns a connection holder containing all the critical information about a connection group. */
00320 ConnectionHolder ConnectionPropertiesDialog::getConnectionHolder(){
00321         ConnectionHolder connHolder;
00322 
00323         //Set to and from layer id
00324         if(editMode){
00325                 connHolder.fromLayerID = fromNeurGrpID;
00326                 connHolder.toLayerID = toNeurGrpID;
00327                 connHolder.connectionType = connectionType;
00328         }
00329         else{
00330                 //Need to adjust response depending on whether the intra or inter layer button is selected
00331                 if(intraRadioButt->isOn()){//Connections within a single layer
00332                         connHolder.fromLayerID = Utilities::getNeuronGrpID(intraLayerCombo->currentText());
00333                         connHolder.toLayerID =  Utilities::getNeuronGrpID(intraLayerCombo->currentText());
00334                 }
00335                 else {//Inter radio button should be on in this case
00336                         connHolder.fromLayerID = Utilities::getNeuronGrpID(fromLayerCombo->currentText());
00337                         connHolder.toLayerID = Utilities::getNeuronGrpID(toLayerCombo->currentText());
00338                 }
00339 
00340                 //Fill connection holder with connection type
00341                 string connectionText = connectionTypeCombo->currentText().ascii();
00342                 connHolder.connectionType = ConnectionType::getType(connectionText);
00343         }
00344         
00345         //Next set the delay values in the connection holder
00346         connHolder.minDelay = (unsigned short)minDelayText->text().toInt();
00347         connHolder.maxDelay = (unsigned short)maxDelayText->text().toInt();
00348 
00349         //Set the synapse type
00350         //Need to convert from combo box selection to the unsigned short representing the neuron type
00351         int comboIndex = synapseTypeCombo->currentItem();
00352         connHolder.synapseType =  synapseTypePositionMap[comboIndex];
00353 
00354         //Get the connection parameters
00355         connHolder.paramMap = getConnectionParameters();
00356         
00357         return connHolder;
00358 }
00359 
00360 
00361 /*! Returns a map containing all the connection parameters. */
00362 map<string, double> ConnectionPropertiesDialog::getConnectionParameters(){
00363         map<string, double> connParamMap;
00364         map<string, string> connParamNames;
00365         unsigned short connType;
00366         if(editMode){
00367                 connType = connectionType;
00368         }
00369         else{
00370                 connType = ConnectionType::getType(connectionTypeCombo->currentText());
00371         }
00372         ConnectionType::getParameters(connParamNames, connType);//This returns a map filled with default values, so will ignore these and replace them with the values from the parameter table
00373         for(map<string, string>::iterator iter = connParamNames.begin(); iter != connParamNames.end(); iter++){
00374                 string tempParamName = (*iter).first;
00375                 connParamMap[tempParamName] = getParameterValue(tempParamName);
00376         }
00377         return connParamMap;
00378 }
00379 
00380 
00381 //-------------------------------------------------------------------------
00382 //----------------------- SLOTS -------------------------------------------
00383 //-------------------------------------------------------------------------
00384 
00385 /*! Sets up dialog depending on whether it is for intra or inter layer connections. */
00386 void ConnectionPropertiesDialog::layerRadioStateChanged(){
00387         if(intraRadioButt->isChecked()){
00388                 intraLayerLabel->setEnabled(true);
00389                 intraLayerCombo->setEnabled(true);
00390                 fromLayerLabel->setEnabled(false);
00391                 fromLayerCombo->setEnabled(false);
00392                 toLayerLabel->setEnabled(false);
00393                 toLayerCombo->setEnabled(false);
00394                 fillConnectionTypeCombo_INTRA();
00395         }
00396         else if(interRadioButt->isChecked()){
00397                 intraLayerLabel->setEnabled(false);
00398                 intraLayerCombo->setEnabled(false);
00399                 fromLayerLabel->setEnabled(true);
00400                 fromLayerCombo->setEnabled(true);
00401                 toLayerLabel->setEnabled(true);
00402                 toLayerCombo->setEnabled(true);
00403                 fillConnectionTypeCombo_INTER();        
00404         }
00405 }
00406 
00407 
00408 /*! Runs checks on parameters and delay, informing the user about any errors and changes. */
00409 void ConnectionPropertiesDialog::okButtonPressed(){
00410         if(loadError){
00411                 QMessageBox::critical( 0, "Connection Properties Error", "Error encountered loading dialog.\nConnection properties may be corrupted.\nPress cancel instead.");
00412                 return;
00413         }
00414 
00415         //Set parameter error to false
00416         parameterError = false;
00417 
00418         //End editing on any cells that are being changed
00419         connParamTable->endAllEditing();
00420 
00421         //If the ending of editing has created a parameter error want to return
00422         if(parameterError)
00423                 return;
00424 
00425         //In edit mode just do checks on the connection parameters and return
00426         if(editMode){
00427                 if(!checkConnection_INTER(fromNeurGrpID, toNeurGrpID, connectionType))
00428                         return;
00429         }
00430         else{//Run full checks
00431                 //If interRadioButt is selected, check that from layer and to layer are different - otherwise it is not an inter layer connection
00432                 if(interRadioButt->isOn()){
00433                         if(fromLayerCombo->currentText() == toLayerCombo->currentText()){
00434                                 QMessageBox::warning(this, "Inter Layer Connection Error", "For an *inter* layer connection, 'from' and 'to' layers must be different");
00435                                 return;
00436                         }
00437                 }
00438                 //Check connection parameters
00439                 if(intraRadioButt->isOn()){//Connection within a single layer
00440                         unsigned short connType = ConnectionType::getType(connectionTypeCombo->currentText());
00441                         if(!checkConnection_INTRA(connType))
00442                                 return;
00443                 }
00444                 else{//Connections between layers
00445                         unsigned int fromLayerID = Utilities::getNeuronGrpID(fromLayerCombo->currentText());
00446                         unsigned int toLayerID = Utilities::getNeuronGrpID(toLayerCombo->currentText());
00447                         unsigned short connType = ConnectionType::getType(connectionTypeCombo->currentText());
00448                         if(!checkConnection_INTER(fromLayerID, toLayerID, connType))
00449                                 return;
00450                 }
00451         }
00452         
00453         //Run checks on min delay
00454         QString errorString = "";
00455         int minDelay = 0;
00456         if(minDelayText->text() == ""){
00457                 errorString += "No minimum delay specified.\n";
00458                 minDelay = -1;
00459         }
00460         else{
00461                 minDelay = minDelayText->text().toInt();
00462                 if(minDelay < 0)
00463                         errorString += "Minimum delay cannot be less than 0.\n";
00464                 if(minDelay > 250)
00465                         errorString += "Minimum delay cannot be greater than 250 ms.\n";
00466         } 
00467         int maxDelay = 0;
00468         if(maxDelayText->text() == ""){
00469                 errorString += "No maximum delay specified.\n";
00470                 maxDelay = -1;
00471         }
00472         else{
00473                 maxDelay = maxDelayText->text().toInt();
00474                 if(maxDelay < 0)
00475                         errorString += "Maximum delay cannot be less than 0.\n";
00476                 if(maxDelay > 250)
00477                         errorString += "Maximum delay cannot be greater than 250 ms.\n";
00478         }
00479         //Check that min delay is less than max delay
00480         if(minDelay != -1 && maxDelay != -1)//Only run this check if they have both been set.
00481                 if(minDelay > maxDelay)
00482                         errorString += "Minimum delay cannot be greater than maximum delay.\n";
00483         if(errorString != ""){
00484                 QMessageBox::warning( this, "Information Errors", errorString);
00485                 return;
00486         }
00487         
00488         //If method has got this far everything should be ok
00489         accept();
00490 }
00491 
00492 
00493 /*! Changes the parameters displayed in the parameter table depending on the connection 
00494         type selected. */
00495 void ConnectionPropertiesDialog::paramSelectionChanged(){
00496         unsigned short connType = ConnectionType::getType(connectionTypeCombo->currentText());
00497         loadParameterTable(connType);
00498 }
00499 
00500 
00501 /*! When the user edits a parameter in the parameter table this method is called, which
00502         checks the new value for errors. */
00503 void ConnectionPropertiesDialog::paramValueChanged(int row, int col){
00504         int pos = 0;
00505         QString paramText = connParamTable->text(row, col);
00506         if(paramValidator->validate(paramText, pos) != QValidator::Acceptable){
00507                 QString errorText = "Parameter: " + connParamTable->text(row, 0) + "\nPlease enter a number between -100000 and 100000";
00508                 QMessageBox::warning(this, "Incorrect Parameter Value!", errorText);
00509                 loadParameterTable(ConnectionType::getType(connectionTypeCombo->currentText()));
00510         }
00511 
00512         parameterError = true;
00513 }
00514 
00515 
00516 //-----------------------------------------------------------------------------------
00517 //------------------------------ PRIVATE METHODS ------------------------------------
00518 //-----------------------------------------------------------------------------------
00519 
00520 /*! Checks the parameters of the connection for inter layer connection types
00521         Only need to check this for certain connection topologies. */
00522 //FIXME MUST HANDLE ROTATION PARAMETER BEING SET BY USER
00523 bool ConnectionPropertiesDialog::checkConnection_INTER(unsigned int fromLayerID, unsigned int toLayerID, unsigned short connectionType){
00524         //OnCentreOffSurround and OffCentreOnSurround
00525         //These two types will produce a connection field of the same size so can check them together
00526         if((connectionType == ConnectionType::OnCentreOffSurround) || (connectionType == ConnectionType::OffCentreOnSurround)){
00527                 //Get the width and length of the to layer in neurons
00528                 Query query = dbInterface->getQuery();
00529                 query.reset();
00530                 query<<"SELECT Width, Length FROM NeuronGroups WHERE NeuronGrpID = "<<toLayerID;
00531                 Result toLayerRes= query.store();
00532                 Row toRow(*toLayerRes.begin());
00533                 int toWidth_Neur = Utilities::getInt((std::string)toRow["Width"]);
00534                 int toLength_Neur = Utilities::getInt((std::string)toRow["Length"]);
00535                 
00536                 //Next get the size of the from layer in absolute values
00537                 query.reset();
00538                 query<<"SELECT Width, Length, Spacing FROM NeuronGroups WHERE NeuronGrpID = "<<fromLayerID;
00539                 Result fromLayerRes= query.store();
00540                 Row fromRow(*fromLayerRes.begin());
00541                 int fromWidth_Neur = Utilities::getInt((std::string)fromRow["Width"]);
00542                 int fromLength_Neur = Utilities::getInt((std::string)fromRow["Length"]);
00543                 int fromSpacing_Pts = Utilities::getInt((std::string)fromRow["Spacing"]);
00544                 double fromWidth_Pts = (double)((fromWidth_Neur - 1) * fromSpacing_Pts);
00545                 double fromLength_Pts= (double)((fromLength_Neur -1) * fromSpacing_Pts);
00546         
00547                 //Extract values for relevant parameters from parameter table
00548                 double outerWidth = getParameterValue("Outer width");
00549                 double outerLength = getParameterValue("Outer length");
00550                 double innerWidth = getParameterValue("Inner width");
00551                 double innerLength = getParameterValue("Inner length");
00552                 int rotate = (int)getParameterValue("Rotate?");
00553                 double overlap = getParameterValue("Overlap");
00554                 double excitatoryWeight = getParameterValue("Excitation weight");
00555                 double inhibitoryWeight = getParameterValue("Inhibition weight");
00556                 int normalDistribution = (int)getParameterValue("Normal weight distribution?");
00557                 double weightRange = getParameterValue("Weight range");
00558                 
00559                 //Do some basic sanity checks
00560                 QString errorString = "";
00561                 if(overlap >= outerWidth)//Overlap has to be less than OuterWidth. For the moment allow it to be negative, although this may be a bad idea.
00562                         errorString += "Overlap has to be less than OuterWidth.\n";
00563                         
00564                 if(outerWidth < 1)//Outer width has to be greater than one
00565                         errorString += "Outer width must be greater than 1. Otherwise it will not cover more than one neuron.\n";
00566 
00567                 if(innerWidth >= outerWidth || innerLength >= outerLength)
00568                         errorString += "Inner width and length have to be smaller than Outer width and length.";
00569 
00570                 if(!(rotate == 1 || rotate == 0))
00571                         errorString += "Rotate should be 0 (false) or 1 (true).\n";
00572                 
00573                 if(!(normalDistribution == 1 || normalDistribution ==0))
00574                         errorString += "Normal distribution should be 0 (false) or 1 (true).\n";
00575                 
00576                 if(excitatoryWeight < 0.0 || excitatoryWeight > 1.0)
00577                         errorString += "Excitation weight should be between 0.0 and 1.0.\n";
00578                 
00579                 if(inhibitoryWeight > 0.0 || inhibitoryWeight < -1.0)
00580                         errorString += "Inhibition weight should be between -1.0 and 0.0.\n";
00581                 
00582                 if(weightRange > 2.0)
00583                         errorString += "Cannot set weight range greater than range of possible weights.\n";
00584                         
00585                 //Display error messages
00586                 if(errorString != ""){
00587                         QMessageBox::warning(this, "Parameter Error(s)", errorString);
00588                         return false;
00589                 }
00590                 
00591                 //Determine the best fit orientation between the two layers. This will reduce the amount of adjustment needed
00592                 bool rotateLayer, toWidthLongest = false, toLengthLongest = false, fromWidthLongest = false, fromLengthLongest = false;
00593                 if(toWidth_Neur > toLength_Neur)
00594                         toWidthLongest = true;
00595                 if(toLength_Neur > toWidth_Neur)//Need to do this in case they are equal
00596                         toLengthLongest = true;
00597                 if(fromWidth_Neur > fromLength_Neur)
00598                         fromWidthLongest = true;
00599                 if(fromLength_Neur > fromWidth_Neur)
00600                         fromLengthLongest = true;
00601                 if((toWidthLongest && fromLengthLongest) || (toLengthLongest && fromWidthLongest)){
00602                         rotateLayer = true;
00603                         setParameterValue("Rotate?", 1);
00604                 }
00605                 else{
00606                         rotateLayer = false;
00607                         setParameterValue("Rotate?", 0);
00608                 }
00609                 
00610                 //Now calculate the area required in the from layer if it is to be connected to the to layer with this type of connection
00611                 double requiredConnAreaWidth, requiredConnAreaLength;
00612                 if(rotateLayer){
00613                         requiredConnAreaWidth = ((double)toLength_Neur * outerWidth) - (((double)toLength_Neur - 1.0) * overlap);
00614                         requiredConnAreaLength = ((double)toWidth_Neur * outerLength) - (((double)toWidth_Neur - 1.0) * overlap);
00615                 }
00616                 else{
00617                         requiredConnAreaWidth = ((double)toWidth_Neur * outerWidth) - (((double)toWidth_Neur - 1.0) * overlap);
00618                         requiredConnAreaLength = ((double)toLength_Neur * outerLength) - (((double)toLength_Neur - 1.0) * overlap);
00619                 }
00620                 Utilities::roundTwoDecimalPlaces(requiredConnAreaWidth);//To reduce the precision of the comparison and hopefully avoid trivial errors 
00621                 Utilities::roundTwoDecimalPlaces(requiredConnAreaLength);//To reduce the precision of the comparison and hopefully avoid trivial errors
00622                 
00623                 //Compare the two areas
00624                 if(!((requiredConnAreaWidth == fromWidth_Pts) && (requiredConnAreaLength == fromLength_Pts))){//The two layers do not match
00625                         //Adjust the outer width and length automatically, keeping the overlap constant
00626                         double newOuterWidth, newOuterLength;
00627                         if(rotateLayer){
00628                                 newOuterWidth = (fromWidth_Pts + ((double)toLength_Neur - 1.0)*overlap)/(double)toLength_Neur;
00629                                 newOuterLength = (fromLength_Pts + ((double)toWidth_Neur - 1.0)*overlap)/(double)toWidth_Neur;
00630                         }
00631                         else{
00632                                 newOuterWidth = (fromWidth_Pts + ((double)toWidth_Neur - 1.0)*overlap)/(double)toWidth_Neur;
00633                                 newOuterLength = (fromLength_Pts + ((double)toLength_Neur - 1.0)*overlap)/(double)toLength_Neur;
00634                         }
00635                         
00636                         //If outerWidth or length are less than 1, a simple adjustment is not going to sort the connection out 
00637                         //Probably the to layer is bigger than the from layer, which makes this type of connection senseless
00638                         if(newOuterWidth <= 1.0 || newOuterLength <= 1.0){
00639                                 QMessageBox::warning(this, "Layer Size Mismatch!", "To make these two layers connect the adjusted outer width and length become less than 1.\nThis means that the connections will only cover one neuron.\nChoose different layers or a different type of connection.");
00640                                 return false;
00641                         }
00642                         
00643                         //If this point is reached, new values should be ok.
00644                         setParameterValue("Outer width", newOuterWidth);
00645                         setParameterValue("Outer length", newOuterLength);
00646                         setParameterValue("Inner width", innerWidth * (newOuterWidth/outerWidth));//Need to change this otherwise it could be larger than outerWidth
00647                         setParameterValue("Inner length",  innerLength * (newOuterLength/outerLength));
00648                         
00649                         //Inform user that values have been changed.
00650                         if(rotateLayer)
00651                                 QMessageBox::warning(this, "Layer Size Mismatch!", "There was a mismatch between the two layers you are trying to connect.\n Outer and Inner width and length have been adjusted.\n Layers will be rotated.\n Overlap has been left constant.");
00652                         else
00653                                 QMessageBox::warning(this, "Layer Size Mismatch!", "There was a mismatch between the two layers you are trying to connect.\n Outer and Inner width and length have been adjusted.\n Overlap has been left constant.");
00654                         return false;
00655                 }
00656                 else //The layers match so connection should be ok
00657                         return true;
00658         }
00659 
00660         //Handle errors in the unstructured type
00661         else if (connectionType == ConnectionType::Unstructured){
00662                 double averageWeight = getParameterValue("Average weight");
00663                 double weightRange = getParameterValue("Weight range");
00664                 double connectionDensity = getParameterValue("Connection density");
00665 
00666                 //Do some basic sanity checks
00667                 QString errorString = "";
00668                 if(averageWeight < -1.0 || averageWeight > 1.0)
00669                         errorString += "Weight should be between -1.0 and 1.0.\n";
00670                 
00671                 if(weightRange > 2.0)
00672                         errorString += "Cannot set weight range greater than range of possible weights.\n";
00673 
00674                 if(connectionDensity > 1.0 || connectionDensity < 0.0001)
00675                         errorString += "Connection density must be between 1.0 and 0.0001.\n";
00676                         
00677                 //Display error messages
00678                 if(errorString != ""){
00679                         QMessageBox::warning(this, "Parameter Error(s)", errorString);
00680                         return false;
00681                 }
00682                 return true;
00683         }
00684 
00685         //Check parameters for Unstructured excitatory inhibitory
00686         else if(connectionType == ConnectionType::UnstructuredExInhibInter){
00687                 double excitatoryPercentage = getParameterValue("Excitatory percentage");
00688                 double excitationWeight = getParameterValue("Excitation weight");
00689                 double excitationWeightRange = getParameterValue("Excitation weight range");
00690                 double inhibitionWeight = getParameterValue("Inhibition weight");
00691                 double inhibitionWeightRange = getParameterValue("Inhibition weight range");
00692                 double excitationConnProb = getParameterValue("Excitation connection prob");
00693                 double inhibitionConnProb = getParameterValue("Inhibition connection prob");
00694 
00695                 //Do some basic sanity checks
00696                 QString errorString = "";
00697                 if(excitatoryPercentage < 0.0 || excitatoryPercentage > 100.0)
00698                         errorString += "Excitatory percentage must be between 0 and 100.\n";
00699                 
00700                 if(excitationWeight < 0.0 || excitationWeight > 1.0)
00701                         errorString += "Excitation weight must be between 0.0 and 1.0.\n";
00702                 
00703                 if(excitationWeightRange < 0.0 || excitationWeightRange > 1.0)
00704                         errorString += "Excitation weight range must be between 0 and 1.\n";
00705                                 
00706                 if(inhibitionWeight < -1.0 || inhibitionWeight > 0.0)
00707                         errorString += "Inhibition weight must be between -1.0 and 0.0.\n";
00708                 
00709                 if(inhibitionWeightRange < 0.0 || inhibitionWeightRange > 1.0)
00710                         errorString += "Inhibition weight range must be between 0 and 1.\n";
00711 
00712                 if(excitationConnProb < 0.0 || excitationConnProb > 1.0)
00713                         errorString += "Excitation connection probability must be between 0 and 1.\n";
00714                 
00715                 if(inhibitionConnProb < 0.0 || inhibitionConnProb > 1.0)
00716                         errorString += "Inhibition connection probability must be between 0 and 1.\n";
00717                         
00718                 //Display error messages
00719                 if(errorString != ""){
00720                         QMessageBox::warning(this, "Parameter Error(s)", errorString);
00721                         return false;
00722                 }
00723                 return true;
00724         }
00725 
00726         //Handle errors in the topographic type
00727         else if (connectionType == ConnectionType::Topographic){
00728                 double averageWeight = getParameterValue("Average weight");
00729                 double weightRange = getParameterValue("Weight range");
00730                 double overlap = getParameterValue("Overlap");
00731 
00732                 //Do some basic sanity checks
00733                 QString errorString = "";
00734                 if(averageWeight < -1.0 || averageWeight > 1.0)
00735                         errorString += "Weight should be between -1.0 and 1.0.\n";
00736                 
00737                 if(weightRange > 2.0)
00738                         errorString += "Cannot set weight range greater than range of possible weights.\n";
00739                 
00740                 if(overlap < 0.0)
00741                         errorString += "The overlap must be zero or more.\n";
00742 
00743                 //Display error messages
00744                 if(errorString != ""){
00745                         QMessageBox::warning(this, "Parameter Error(s)", errorString);
00746                         return false;
00747                 }
00748                 return true;
00749         }
00750 
00751         //Handle errors for the Virtual type of connection
00752         else if(connectionType == ConnectionType::Virtual){
00753                 /*Need to check whether there is a non-virtual connection between the layers. 
00754                         No point in creating a virtual connection when there is a non-virtual connection */
00755                 unsigned int fromNeurGrpID = Utilities::getNeuronGrpID(fromLayerCombo->currentText());
00756                 unsigned int toNeurGrpID = Utilities::getNeuronGrpID(toLayerCombo->currentText());
00757                 try{
00758                         Query query = dbInterface->getQuery();
00759                         query.reset();
00760                         query<<"SELECT COUNT(*) FROM ConnectionGroups WHERE FromNeuronGrpID = "<<fromNeurGrpID<<" AND ToNeuronGrpID = "<<toNeurGrpID;
00761                         Result countRes= query.store();
00762                         Row countRow(*countRes.begin());
00763                         if(Utilities::getUInt((std::string) countRow["COUNT(*)"]) > 0 ){//Already a connection between these neuron groups
00764                                 QMessageBox::warning(this, "Connection Error", "Virtual connections are unnecessary when there are real connections between neuron groups");
00765                                 return false;
00766                         }
00767                 }
00768                 catch(Exception &exception){
00769                         cerr<<"ConnectionPropertiesDialog: Exception: "<<exception.what();
00770                         return false;
00771                 }
00772                 return true;
00773         }
00774 
00775         //Handle errors for the SIMNOS component connection type
00776         else if (connectionType == ConnectionType::SIMNOSComponent){
00777                 double averageWeight = getParameterValue("Average weight");
00778                 double weightRange = getParameterValue("Weight range");
00779 
00780                 //Do some basic sanity checks
00781                 QString errorString = "";
00782                 if(averageWeight < -1.0 || averageWeight > 1.0)
00783                         errorString += "Weight should be between -1.0 and 1.0.\n";
00784                 
00785                 if(weightRange > 2.0)
00786                         errorString += "Cannot set weight range greater than range of possible weights.\n";
00787                 
00788                 //Check that layers are the same width
00789                 //Get the dimensions of the from group
00790                 Query query = dbInterface->getQuery();
00791                 query<<"SELECT Width FROM NeuronGroups WHERE NeuronGrpID = "<<fromLayerID;
00792                 Result fromLayerRes= query.store();
00793                 Row fromRow(*fromLayerRes.begin());
00794                 int fromWidth = Utilities::getInt((std::string)fromRow["Width"]);
00795                 
00796                 //Get the dimensions of the to group
00797                 query.reset();
00798                 query<<"SELECT Width FROM NeuronGroups WHERE NeuronGrpID = "<<toLayerID;
00799                 Result toLayerRes= query.store();
00800                 Row toRow(*toLayerRes.begin());
00801                 int toWidth = Utilities::getInt((std::string)toRow["Width"]);
00802 
00803                 //Check lengths are the same
00804                 if(fromWidth != toWidth)
00805                         errorString += "From and to neuron groups must be the same width for SIMNOS Component connections.\n";
00806 
00807                 //Display error messages
00808                 if(errorString != ""){
00809                         QMessageBox::warning(this, "Parameter Error(s)", errorString);
00810                         return false;
00811                 }
00812                 return true;
00813         }
00814 
00815         //Inter layer connection type has not been found
00816         else{
00817                 cerr<<"ConnectionPropertiesDialog: Connection type has not been found in parameter error checking method: "<<connectionType<<endl;
00818                 QMessageBox::critical( 0, "Connection Type Error", "Connection type has not been found.");
00819                 return false;
00820         }
00821 }
00822 
00823 
00824 /*! Checks the parametes for intra layer connections. */
00825 bool ConnectionPropertiesDialog::checkConnection_INTRA(unsigned short connectionType){
00826 
00827         //Check parameters for simple cortex connections
00828         if(connectionType == ConnectionType::SimpleCortex){
00829                 double inhibitionRadius = getParameterValue("Inhibition radius");
00830                 double excitationRadius = getParameterValue("Excitation radius");
00831                 double overlap = getParameterValue("Overlap");
00832                 double excitationConnDensity = getParameterValue("Excitation connection density");
00833                 double inhibitionConnDensity = getParameterValue("Inhibition connection density");
00834                 double normalDistribution = getParameterValue("Normal weight distribution?");
00835                 double weightRange = getParameterValue("Weight range");
00836                 double excitatoryWeight = getParameterValue("Excitation weight");
00837                 double inhibitoryWeight = getParameterValue("Inhibition weight");
00838                 
00839                 //Do some basic sanity checks
00840                 QString errorString = "";
00841                 if(inhibitionRadius <= excitationRadius)
00842                         errorString += "For this type of connection inhibition radius should be greater than the excitation radius.\n";
00843                 
00844                 if(overlap >= excitationRadius)
00845                         errorString += "Overlap cannot be greater than excitation radius.\n";
00846                 
00847                 if(overlap >= inhibitionRadius)
00848                         errorString += "Overlap cannot be greater than inhibition radius.\n";
00849                 
00850                 if(overlap < 0)
00851                         errorString += "Overlap cannot be a negative number.\n";
00852                 
00853                 if(excitationConnDensity < 0.0 )
00854                         errorString += "Connection density must be greater than 0.\n";
00855 
00856                 if(inhibitionConnDensity < 0.0 )
00857                         errorString += "Inhibition density must be greater than 0.\n";
00858                 
00859                 if(!(normalDistribution == 1 || normalDistribution ==0))
00860                         errorString += "Normal distribution should be 0 (false) or 1 (true).\n";
00861                 
00862                 if(excitatoryWeight < 0.0 || excitatoryWeight > 1.0)
00863                         errorString += "Excitation weight should be between 0.0 and 1.0.\n";
00864                 
00865                 if(inhibitoryWeight > 0.0 || inhibitoryWeight < -1.0)
00866                         errorString += "Inhibition weight should be between -1.0 and 0.0.\n";
00867                 
00868                 if(weightRange > 2.0)
00869                         errorString += "Cannot set weight range greater than range of possible weights.\n";
00870                         
00871                 //Display error messages
00872                 if(errorString != ""){
00873                         QMessageBox::warning(this, "Parameter Error(s)", errorString);
00874                         return false;
00875                 }
00876                 return true;    
00877         }
00878 
00879         //Check parameters for Unstructured excitatory inhibitory
00880         else if(connectionType == ConnectionType::UnstructuredExInhibIntra){
00881                 double excitatoryPercentage = getParameterValue("Excitatory percentage");
00882                 double excitationWeight = getParameterValue("Excitation weight");
00883                 double excitationWeightRange = getParameterValue("Excitation weight range");
00884                 double inhibitionWeight = getParameterValue("Inhibition weight");
00885                 double inhibitionWeightRange = getParameterValue("Inhibition weight range");
00886                 double excitationConnProb = getParameterValue("Excitation connection prob");
00887                 double inhibitionConnProb = getParameterValue("Inhibition connection prob");
00888 
00889                 //Do some basic sanity checks
00890                 QString errorString = "";
00891                 if(excitatoryPercentage < 0.0 || excitatoryPercentage > 100.0)
00892                         errorString += "Excitatory percentage must be between 0 and 100.\n";
00893                 
00894                 if(excitationWeight < 0.0 || excitationWeight > 1.0)
00895                         errorString += "Excitation weight must be between 0.0 and 1.0.\n";
00896                 
00897                 if(excitationWeightRange < 0.0 || excitationWeightRange > 1.0)
00898                         errorString += "Excitation weight range must be between 0 and 1.\n";
00899                                 
00900                 if(inhibitionWeight < -1.0 || inhibitionWeight > 0.0)
00901                         errorString += "Inhibition weight must be between -1.0 and 0.0.\n";
00902                 
00903                 if(inhibitionWeightRange < 0.0 || inhibitionWeightRange > 1.0)
00904                         errorString += "Inhibition weight range must be between 0 and 1.\n";
00905 
00906                 if(excitationConnProb < 0.0 || excitationConnProb > 1.0)
00907                         errorString += "Excitation connection probability must be between 0 and 1.\n";
00908                 
00909                 if(inhibitionConnProb < 0.0 || inhibitionConnProb > 1.0)
00910                         errorString += "Inhibition connection probability must be between 0 and 1.\n";
00911                         
00912                 //Display error messages
00913                 if(errorString != ""){
00914                         QMessageBox::warning(this, "Parameter Error(s)", errorString);
00915                         return false;
00916                 }
00917                 return true;
00918         }
00919 
00920         //Have not found this intra layer connection type
00921         else{
00922                 cerr<<"ConnectionPropertiesDialog: Connection Type not recognized in parameter checking method: "<<connectionType<<endl;
00923                 QMessageBox::critical( 0, "Connection Type Error", "Connection type has not been found.");
00924                 return false;
00925         }
00926 }
00927 
00928 
00929 /*! Fills connection type combo with the connection types appropriate to inter layer 
00930         connections and sets up the parameter table appropriately. */
00931 void ConnectionPropertiesDialog::fillConnectionTypeCombo_INTER(){
00932         connectionTypeCombo->clear();
00933         unsigned short* interTypeArray = ConnectionType::getInterLayerTypes();
00934         for(int i=0; i<ConnectionType::NumberInterTypes; i++){
00935                 if(interTypeArray[i] != ConnectionType::TempVirtual && interTypeArray[i] != ConnectionType::SIMNOSComponent)//Filter out temporary virtual connections and SIMNOS connections
00936                         connectionTypeCombo->insertItem(ConnectionType::getDescription(interTypeArray[i]));
00937         }
00938         //If there is at least one inter connection type
00939         if(ConnectionType::NumberInterTypes > 0){
00940                 loadParameterTable(interTypeArray[0]);
00941         }
00942         //If there are no inter connection types defined, reset table to zero rows.
00943         else
00944                 connParamTable->setNumRows(0);
00945 
00946         //Clean up dynamically allocated array
00947         delete [] interTypeArray;
00948 }
00949 
00950 
00951 
00952 /*! Fills the connection type combo with the connection types appropriate 
00953         to intra layer connections. */
00954 void ConnectionPropertiesDialog::fillConnectionTypeCombo_INTRA(){
00955         connectionTypeCombo->clear();
00956         unsigned short* intraTypeArray = ConnectionType::getIntraLayerTypes();
00957         for(int i=0; i<ConnectionType::NumberIntraTypes; i++){
00958                 connectionTypeCombo->insertItem(ConnectionType::getDescription(intraTypeArray[i]));
00959         }
00960 
00961         //If there is at least one intra connection type
00962         if(ConnectionType::NumberIntraTypes > 0){
00963                 loadParameterTable(intraTypeArray[0]);
00964         }
00965         //If there are no intra connection types defined, reset table to zero rows.
00966         else
00967                 connParamTable->setNumRows(0);
00968         
00969         //Clean up dynamically allocated array
00970         delete [] intraTypeArray;
00971 }
00972 
00973 
00974 /*! Searches through the parameter table to get the latest value of a parameter. */
00975 double ConnectionPropertiesDialog::getParameterValue(QString paramName){
00976         for(int i=0; i<connParamTable->numRows(); i++){
00977                 if(connParamTable->text(i, 0) == paramName){//Found parameter, need to convert to double
00978                         bool ok = true;
00979                         double tempDouble = connParamTable->text(i, 1).toDouble(&ok);
00980                         if(ok)
00981                                 return tempDouble;
00982                         else{
00983                                 cerr<<"ConnectionPropertiesDialog: PARAMETER TO DOUBLE CONVERSION ERROR: "<<paramName<<endl;
00984                                 QMessageBox::critical( 0, "Conversion Error", "Parameter to double conversion error.");
00985                                 exit(1);
00986                         }
00987                 }
00988         }
00989         cerr<<"ConnectionPropertiesDialog: PARAMETER NOT FOUND: "<<paramName<<endl;
00990         QMessageBox::critical( 0, "Parameter Error", "Parameter not found.");
00991         exit(1);
00992 }
00993 
00994 
00995 /*! Loads up the layer names into the combo boxes. */
00996 void ConnectionPropertiesDialog::loadLayerNames(){
00997         Query query = dbInterface->getQuery();
00998         query.reset();
00999 
01000         if(editMode){
01001                 //Sort out from layer
01002                 query<<"SELECT Name FROM NeuronGroups WHERE NeuronGrpID = "<<fromNeurGrpID;
01003                 Result fromLayerResult= query.store();
01004                 Row fromLayerRow(*fromLayerResult.begin());//Neuron grp id is unique
01005                 QString fromLayerString((std::string)fromLayerRow["Name"] + " [" + QString::number(fromNeurGrpID) + "]");
01006                 fromLayerCombo->insertItem(fromLayerString);
01007 
01008                 //Sort out to layer
01009                 query.reset();
01010                 query<<"SELECT Name FROM NeuronGroups WHERE NeuronGrpID = "<<toNeurGrpID;
01011                 Result toLayerResult= query.store();
01012                 Row toLayerRow(*toLayerResult.begin());//Neuron grp id is unique
01013                 QString toLayerString((std::string)toLayerRow["Name"] + " [" + QString::number(toNeurGrpID) + "]");
01014                 toLayerCombo->insertItem(toLayerString);
01015         }
01016         else{//Add all neuron groups to combos
01017                 query<<"SELECT Name, NeuronGrpID FROM NeuronGroups";
01018                 Result layerResult= query.store();
01019                 for(Result::iterator resIter = layerResult.begin(); resIter < layerResult.end(); resIter++){
01020                         Row row(*resIter);
01021                         QString layerString((std::string)row.at(0) + " [" += (std::string)row[1] += "]");
01022                         intraLayerCombo->insertItem(layerString);
01023                         fromLayerCombo->insertItem(layerString);
01024                         toLayerCombo->insertItem(layerString);
01025                 }
01026         }
01027 }
01028 
01029 
01030 /*! Loads parameter table from parameters specified in ConnectionType
01031         These should all be doubles. */
01032 void ConnectionPropertiesDialog::loadParameterTable(unsigned short connType){
01033         //First create map and fill it with parameters
01034         map<string, string> tempParamMap;
01035         ConnectionType::getParameters(tempParamMap, connType);
01036         
01037         //Now fill parameter table with parameters
01038         int rowCount = 0;
01039         map<string, string>::iterator iter = tempParamMap.begin();
01040         connParamTable->setNumRows(0);
01041         while(iter != tempParamMap.end()){
01042                 connParamTable->insertRows(rowCount, 1);
01043                 connParamTable->setItem( rowCount, 0, new QTableItem( connParamTable, QTableItem::Never, iter->first));
01044                 connParamTable->setItem( rowCount, 1, new QTableItem(connParamTable, QTableItem::WhenCurrent, iter->second));
01045                 rowCount++;
01046                 iter++;
01047         }
01048 }
01049 
01050 
01051 /*! Sets the value of a parameter. */
01052 void ConnectionPropertiesDialog::setParameterValue(QString paramName, double value){
01053         for(int i=0; i<connParamTable->numRows(); i++){
01054                 if(connParamTable->text(i, 0) == paramName){//Found parameter
01055                         QString tempStr;
01056                         connParamTable->setText(i, 1, tempStr.setNum(value));
01057                         return;
01058                 }
01059         }
01060         cerr<<"ConnectionPropertiesDialog: PARAMETER NOT FOUND: "<<paramName<<endl;
01061         QMessageBox::critical( 0, "Parameter Error", "Parameter not found.");
01062         //This error is non critical because it only prevents program from changing parameter values
01063 }
01064 
01065 
01066 

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