00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "ConnectionPropertiesDialog.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027
00028
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
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
00047 ConnectionPropertiesDialog::ConnectionPropertiesDialog(QWidget *parent, const char *name, DBInterface *dbInter) : QDialog(parent, name){
00048
00049 dbInterface = dbInter;
00050
00051
00052 editMode = false;
00053 connectionType = -1;
00054 fromNeurGrpID = -1;
00055 toNeurGrpID = -1;
00056 parameterError = false;
00057
00058
00059 loadError = false;
00060 try{
00061 constructDialog();
00062 }
00063 catch (const BadQuery& er) {
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) {
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){
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
00091
00092
00093 ConnectionPropertiesDialog::ConnectionPropertiesDialog(QWidget *parent, const char *name, DBInterface *dbInter, unsigned int fNeurGrpID, unsigned int tNeurGrpID, unsigned short connType) : QDialog(parent, name){
00094
00095 dbInterface = dbInter;
00096
00097
00098 editMode = true;
00099 connectionType = connType;
00100 fromNeurGrpID = fNeurGrpID;
00101 toNeurGrpID = tNeurGrpID;
00102
00103
00104 try{
00105 constructDialog();
00106 }
00107 catch (const BadQuery& er) {
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) {
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){
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
00135
00136 void ConnectionPropertiesDialog::constructDialog(){
00137
00138
00139
00140
00141 paramValidator = new QDoubleValidator(-100000.0, 100000.0, 4, this);
00142 delayValidator = new QIntValidator(DEFAULT_MIN_DELAY, DEFAULT_MAX_DELAY, this);
00143
00144
00145 QVBoxLayout *vBox = new QVBoxLayout(this, 5, 10, "Main vertical Box");
00146
00147
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
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
00166 connParamTable = new ConnectionParameterTable(3, 2, this);
00167
00168 if(editMode){
00169 loadParameterTable(connectionType);
00170 }
00171 else{
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
00180
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
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
00204 QHBoxLayout *connTypeBox = new QHBoxLayout();
00205 connectionTypeCombo = new QComboBox(this, "Connection Type");
00206 connectionTypeCombo->setMinimumSize(250,30);
00207
00208
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
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
00230 QHBoxLayout *synapseTypeBox = new QHBoxLayout();
00231 synapseTypeCombo = new QComboBox(this, "SynapseType");
00232 synapseTypeCombo->setMinimumSize(250, 30);
00233
00234
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
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
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
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
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
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
00301 QAccel *returnAccel = new QAccel( this );
00302 returnAccel->connectItem( returnAccel->insertItem( Key_Enter ), this, SLOT(okButtonPressed()));
00303 }
00304
00305
00306
00307
00308 ConnectionPropertiesDialog::~ConnectionPropertiesDialog(){
00309 #ifdef MEMORY_DEBUG
00310 cout<<"DELETING CONNECTION PROPERTIES DIALOG"<<endl;
00311 #endif//MEMORY_DEBUG
00312 }
00313
00314
00315
00316
00317
00318
00319
00320 ConnectionHolder ConnectionPropertiesDialog::getConnectionHolder(){
00321 ConnectionHolder connHolder;
00322
00323
00324 if(editMode){
00325 connHolder.fromLayerID = fromNeurGrpID;
00326 connHolder.toLayerID = toNeurGrpID;
00327 connHolder.connectionType = connectionType;
00328 }
00329 else{
00330
00331 if(intraRadioButt->isOn()){
00332 connHolder.fromLayerID = Utilities::getNeuronGrpID(intraLayerCombo->currentText());
00333 connHolder.toLayerID = Utilities::getNeuronGrpID(intraLayerCombo->currentText());
00334 }
00335 else {
00336 connHolder.fromLayerID = Utilities::getNeuronGrpID(fromLayerCombo->currentText());
00337 connHolder.toLayerID = Utilities::getNeuronGrpID(toLayerCombo->currentText());
00338 }
00339
00340
00341 string connectionText = connectionTypeCombo->currentText().ascii();
00342 connHolder.connectionType = ConnectionType::getType(connectionText);
00343 }
00344
00345
00346 connHolder.minDelay = (unsigned short)minDelayText->text().toInt();
00347 connHolder.maxDelay = (unsigned short)maxDelayText->text().toInt();
00348
00349
00350
00351 int comboIndex = synapseTypeCombo->currentItem();
00352 connHolder.synapseType = synapseTypePositionMap[comboIndex];
00353
00354
00355 connHolder.paramMap = getConnectionParameters();
00356
00357 return connHolder;
00358 }
00359
00360
00361
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);
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
00383
00384
00385
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
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
00416 parameterError = false;
00417
00418
00419 connParamTable->endAllEditing();
00420
00421
00422 if(parameterError)
00423 return;
00424
00425
00426 if(editMode){
00427 if(!checkConnection_INTER(fromNeurGrpID, toNeurGrpID, connectionType))
00428 return;
00429 }
00430 else{
00431
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
00439 if(intraRadioButt->isOn()){
00440 unsigned short connType = ConnectionType::getType(connectionTypeCombo->currentText());
00441 if(!checkConnection_INTRA(connType))
00442 return;
00443 }
00444 else{
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
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
00480 if(minDelay != -1 && maxDelay != -1)
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
00489 accept();
00490 }
00491
00492
00493
00494
00495 void ConnectionPropertiesDialog::paramSelectionChanged(){
00496 unsigned short connType = ConnectionType::getType(connectionTypeCombo->currentText());
00497 loadParameterTable(connType);
00498 }
00499
00500
00501
00502
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
00518
00519
00520
00521
00522
00523 bool ConnectionPropertiesDialog::checkConnection_INTER(unsigned int fromLayerID, unsigned int toLayerID, unsigned short connectionType){
00524
00525
00526 if((connectionType == ConnectionType::OnCentreOffSurround) || (connectionType == ConnectionType::OffCentreOnSurround)){
00527
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
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
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
00560 QString errorString = "";
00561 if(overlap >= outerWidth)
00562 errorString += "Overlap has to be less than OuterWidth.\n";
00563
00564 if(outerWidth < 1)
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
00586 if(errorString != ""){
00587 QMessageBox::warning(this, "Parameter Error(s)", errorString);
00588 return false;
00589 }
00590
00591
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)
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
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);
00621 Utilities::roundTwoDecimalPlaces(requiredConnAreaLength);
00622
00623
00624 if(!((requiredConnAreaWidth == fromWidth_Pts) && (requiredConnAreaLength == fromLength_Pts))){
00625
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
00637
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
00644 setParameterValue("Outer width", newOuterWidth);
00645 setParameterValue("Outer length", newOuterLength);
00646 setParameterValue("Inner width", innerWidth * (newOuterWidth/outerWidth));
00647 setParameterValue("Inner length", innerLength * (newOuterLength/outerLength));
00648
00649
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
00657 return true;
00658 }
00659
00660
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
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
00678 if(errorString != ""){
00679 QMessageBox::warning(this, "Parameter Error(s)", errorString);
00680 return false;
00681 }
00682 return true;
00683 }
00684
00685
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
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
00719 if(errorString != ""){
00720 QMessageBox::warning(this, "Parameter Error(s)", errorString);
00721 return false;
00722 }
00723 return true;
00724 }
00725
00726
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
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
00744 if(errorString != ""){
00745 QMessageBox::warning(this, "Parameter Error(s)", errorString);
00746 return false;
00747 }
00748 return true;
00749 }
00750
00751
00752 else if(connectionType == ConnectionType::Virtual){
00753
00754
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 ){
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
00776 else if (connectionType == ConnectionType::SIMNOSComponent){
00777 double averageWeight = getParameterValue("Average weight");
00778 double weightRange = getParameterValue("Weight range");
00779
00780
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
00789
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
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
00804 if(fromWidth != toWidth)
00805 errorString += "From and to neuron groups must be the same width for SIMNOS Component connections.\n";
00806
00807
00808 if(errorString != ""){
00809 QMessageBox::warning(this, "Parameter Error(s)", errorString);
00810 return false;
00811 }
00812 return true;
00813 }
00814
00815
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
00825 bool ConnectionPropertiesDialog::checkConnection_INTRA(unsigned short connectionType){
00826
00827
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
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
00872 if(errorString != ""){
00873 QMessageBox::warning(this, "Parameter Error(s)", errorString);
00874 return false;
00875 }
00876 return true;
00877 }
00878
00879
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
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
00913 if(errorString != ""){
00914 QMessageBox::warning(this, "Parameter Error(s)", errorString);
00915 return false;
00916 }
00917 return true;
00918 }
00919
00920
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
00930
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)
00936 connectionTypeCombo->insertItem(ConnectionType::getDescription(interTypeArray[i]));
00937 }
00938
00939 if(ConnectionType::NumberInterTypes > 0){
00940 loadParameterTable(interTypeArray[0]);
00941 }
00942
00943 else
00944 connParamTable->setNumRows(0);
00945
00946
00947 delete [] interTypeArray;
00948 }
00949
00950
00951
00952
00953
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
00962 if(ConnectionType::NumberIntraTypes > 0){
00963 loadParameterTable(intraTypeArray[0]);
00964 }
00965
00966 else
00967 connParamTable->setNumRows(0);
00968
00969
00970 delete [] intraTypeArray;
00971 }
00972
00973
00974
00975 double ConnectionPropertiesDialog::getParameterValue(QString paramName){
00976 for(int i=0; i<connParamTable->numRows(); i++){
00977 if(connParamTable->text(i, 0) == paramName){
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
00996 void ConnectionPropertiesDialog::loadLayerNames(){
00997 Query query = dbInterface->getQuery();
00998 query.reset();
00999
01000 if(editMode){
01001
01002 query<<"SELECT Name FROM NeuronGroups WHERE NeuronGrpID = "<<fromNeurGrpID;
01003 Result fromLayerResult= query.store();
01004 Row fromLayerRow(*fromLayerResult.begin());
01005 QString fromLayerString((std::string)fromLayerRow["Name"] + " [" + QString::number(fromNeurGrpID) + "]");
01006 fromLayerCombo->insertItem(fromLayerString);
01007
01008
01009 query.reset();
01010 query<<"SELECT Name FROM NeuronGroups WHERE NeuronGrpID = "<<toNeurGrpID;
01011 Result toLayerResult= query.store();
01012 Row toLayerRow(*toLayerResult.begin());
01013 QString toLayerString((std::string)toLayerRow["Name"] + " [" + QString::number(toNeurGrpID) + "]");
01014 toLayerCombo->insertItem(toLayerString);
01015 }
01016 else{
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
01031
01032 void ConnectionPropertiesDialog::loadParameterTable(unsigned short connType){
01033
01034 map<string, string> tempParamMap;
01035 ConnectionType::getParameters(tempParamMap, connType);
01036
01037
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
01052 void ConnectionPropertiesDialog::setParameterValue(QString paramName, double value){
01053 for(int i=0; i<connParamTable->numRows(); i++){
01054 if(connParamTable->text(i, 0) == paramName){
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
01063 }
01064
01065
01066