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 "NeuronParametersDialog.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 #include "SpikeStreamMainWindow.h"
00028
00029
00030 #include <qlayout.h>
00031 #include <qfile.h>
00032 #include <qlabel.h>
00033 #include <qmessagebox.h>
00034
00035
00036 #include <mysql++.h>
00037 #include <iostream>
00038 using namespace std;
00039 using namespace mysqlpp;
00040
00041
00042
00043 NeuronParametersDialog::NeuronParametersDialog(QWidget *parent, DBInterface* netDBInter, SimulationManager* simMan) : QDialog(parent, "NeurParamDlg", false){
00044
00045 networkDBInterface = netDBInter;
00046
00047
00048 simulationManager = simMan;
00049
00050
00051 this->setCaption("Neuron Parameters");
00052
00053
00054 editPixmap = new QPixmap(SpikeStreamMainWindow::workingDirectory + "/images/edit_parameters.xpm");
00055
00056
00057 unsigned int maxTableWidth = 0;
00058
00059
00060 QVBoxLayout *verticalBox = new QVBoxLayout(this, 2, 2);
00061
00062
00063 try{
00064 Query query = networkDBInterface->getQuery();
00065 query.reset();
00066 query<<"SELECT TypeID, Description, ParameterTableName FROM NeuronTypes";
00067 Result neuronTypesResult = query.store();
00068 for(Result::iterator neurTypesIter = neuronTypesResult.begin(); neurTypesIter != neuronTypesResult.end(); ++neurTypesIter){
00069 Row neuronTypesRow(*neurTypesIter);
00070 unsigned short neuronTypeID = Utilities::getUShort((std::string) neuronTypesRow["TypeID"]);
00071
00072
00073 paramTableMap[neuronTypeID] = new ParameterTable(this, neuronTypeID, (std::string)neuronTypesRow["ParameterTableName"]);
00074 paramTableMap[neuronTypeID]->setShowGrid(false);
00075 paramTableMap[neuronTypeID]->setSorting(false);
00076 paramTableMap[neuronTypeID]->setSelectionMode(QTable::NoSelection);
00077 paramTableMap[neuronTypeID]->verticalHeader()->hide();
00078 paramTableMap[neuronTypeID]->setLeftMargin(0);
00079 paramTableHeaderMap[neuronTypeID] = paramTableMap[neuronTypeID]->horizontalHeader();
00080
00081
00082 unsigned int tempTotalColumnWidth = 0;
00083
00084
00085 unsigned int insertionPoint = paramTableMap[neuronTypeID]->numCols();
00086 paramTableMap[neuronTypeID]->insertColumns(insertionPoint, 1);
00087 paramTableHeaderMap[neuronTypeID]->setLabel( insertionPoint, "Edit" );
00088 paramTableMap[neuronTypeID]->setColumnWidth( insertionPoint, 30);
00089 editColumn = insertionPoint;
00090 tempTotalColumnWidth += 30;
00091
00092
00093 insertionPoint = paramTableMap[neuronTypeID]->numCols();
00094 paramTableMap[neuronTypeID]->insertColumns(insertionPoint, 1);
00095 paramTableHeaderMap[neuronTypeID]->setLabel(insertionPoint, "NeuronGrpID" );
00096 paramTableMap[neuronTypeID]->setColumnWidth(insertionPoint, 90);
00097 neurGrpIDColumn = insertionPoint;
00098 tempTotalColumnWidth += 90;
00099
00100
00101 insertionPoint = paramTableMap[neuronTypeID]->numCols();
00102 paramTableMap[neuronTypeID]->insertColumns(insertionPoint, 1);
00103 paramTableHeaderMap[neuronTypeID]->setLabel(insertionPoint, "Name");
00104 paramTableMap[neuronTypeID]->setColumnWidth(insertionPoint, 90);
00105 nameColumn = insertionPoint;
00106 tempTotalColumnWidth += 90;
00107
00108
00109 paramStartColumn = paramTableMap[neuronTypeID]->numCols();
00110
00111
00112
00113
00114
00115
00116
00117 map<const char*, double, charKeyCompare> tempValueMap;
00118
00119
00120 fieldNamesMap[neuronTypeID] = new QStringList();
00121 valueNamesMap[neuronTypeID] = new QStringList();
00122
00123
00124 query.reset();
00125 query<<"SHOW COLUMNS FROM "<<((std::string)neuronTypesRow["ParameterTableName"]);
00126 Result showResult = query.store();
00127 for(Result::iterator iter = showResult.begin(); iter != showResult.end(); ++iter){
00128 Row showRow(*iter);
00129
00130
00131 QString fieldName((std::string)showRow["Field"]);
00132
00133
00134 if(fieldName.contains("_desc")){
00135
00136 (*fieldNamesMap[neuronTypeID]) += fieldName.section("_", 0, 0);
00137
00138
00139 unsigned int insertionPoint = paramTableMap[neuronTypeID]->numCols();
00140 paramTableMap[neuronTypeID]->insertColumns(insertionPoint, 1);
00141 QString headerText((std::string)showRow["Default"]);
00142 tempTotalColumnWidth += headerText.length() * 7;
00143 paramTableHeaderMap[neuronTypeID]->setLabel( insertionPoint, headerText );
00144 paramTableMap[neuronTypeID]->setColumnWidth( insertionPoint, headerText.length() * 7);
00145
00146
00147 descriptionColumnMap[neuronTypeID][headerText.ascii()] = insertionPoint;
00148
00149
00150 paramDescMap[neuronTypeID][(*fieldNamesMap[neuronTypeID]).last().ascii()] = paramTableHeaderMap[neuronTypeID]->label(insertionPoint).ascii();
00151
00152
00153 descParamMap[neuronTypeID][paramTableHeaderMap[neuronTypeID]->label(insertionPoint).ascii()] = (*fieldNamesMap[neuronTypeID]).last().ascii();
00154
00155 }
00156 else if(fieldName.contains("_val")){
00157
00158 QString valueName = fieldName.section("_", 0, 0);
00159
00160
00161 (*valueNamesMap[neuronTypeID]) += valueName;
00162
00163
00164 QString valueType((std::string)showRow["Type"]);
00165 if(valueType == "tinyint(1)")
00166 checkBoxMap[neuronTypeID][(*valueNamesMap[neuronTypeID]).last().ascii()] = true;
00167 else{
00168
00169 double defaultValue = Utilities::getDouble((std::string)showRow["Default"]);
00170
00171
00172 tempValueMap[valueName.ascii()] = defaultValue;
00173 }
00174 }
00175 }
00176
00177
00178
00179
00180 for(map<const char*, double>::iterator iter = tempValueMap.begin(); iter != tempValueMap.end(); ++iter){
00181 defaultValueMap[neuronTypeID][ paramDescMap[neuronTypeID][iter->first] ] = iter->second;
00182 }
00183
00184
00185 tempTotalColumnWidth += 10;
00186 if(tempTotalColumnWidth > maxTableWidth)
00187 maxTableWidth = tempTotalColumnWidth;
00188
00189
00190 QHBoxLayout *labelBox = new QHBoxLayout();
00191 QString labelString((std::string)neuronTypesRow["Description"]);
00192 labelString += " Parameters";
00193 tableLabelMap[neuronTypeID] = new QLabel(labelString, this);
00194 tableLabelMap[neuronTypeID] ->setPaletteForegroundColor(QColor(0,86,126));
00195 labelBox->addSpacing(5);
00196 labelBox->addWidget(tableLabelMap[neuronTypeID]);
00197 labelBox->addStretch(5);
00198
00199 verticalBox->addLayout(labelBox);
00200
00201
00202 verticalBox->addWidget(paramTableMap[neuronTypeID]);
00203
00204
00205 connect (paramTableMap[neuronTypeID], SIGNAL(parameterTableClicked(int, int, unsigned short)), this, SLOT(parameterTableClicked(int, int, unsigned short)));
00206
00207
00208 connect (paramTableMap[neuronTypeID], SIGNAL(parameterTableValueChanged(int, int, unsigned short)), this, SLOT(parameterTableValueChanged(int, int, unsigned short)));
00209 }
00210 }
00211 catch (const BadQuery& er) {
00212 cerr<<"NeuronParametersDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00213 QString errorString = "Bad query when loading information about neuron parameters: \"";
00214 errorString += er.what();
00215 errorString += "\"";
00216 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00217 }
00218 catch (const Exception& er) {
00219 cerr<<"NeuronParametersDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00220 QString errorString = "Exception thrown loading information about neuron parameters: \"";
00221 errorString += er.what();
00222 errorString += "\"";
00223 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00224 }
00225 catch(std::exception& er){
00226 cerr<<"NeuronParametersDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00227 QString errorString = "Exception thrown loading information about neuron parameters: \"";
00228 errorString += er.what();
00229 errorString += "\"";
00230 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00231 }
00232
00233
00234
00235 if(maxTableWidth < 1200)
00236 this->resize(maxTableWidth, 200);
00237 else
00238 this->resize(1200, 200);
00239
00240
00241
00242 QHBoxLayout *buttonBox = new QHBoxLayout();
00243 QPushButton *okButton = new QPushButton("Ok", this);
00244 buttonBox->addWidget(okButton);
00245 connect (okButton, SIGNAL(clicked()), this, SLOT(okButtonPressed()));
00246
00247 applyButton = new QPushButton("Apply", this);
00248 buttonBox->addWidget(applyButton);
00249 connect (applyButton, SIGNAL(clicked()), this, SLOT(applyButtonPressed()));
00250
00251 QPushButton *defaultsButton = new QPushButton("Load Defaults", this);
00252 buttonBox->addWidget(defaultsButton);
00253 connect (defaultsButton, SIGNAL(clicked()), this, SLOT(defaultsButtonPressed()));
00254
00255 QPushButton *cancelButton = new QPushButton("Cancel", this);
00256 buttonBox->addWidget(cancelButton);
00257 connect (cancelButton, SIGNAL(clicked()), this, SLOT(cancelButtonPressed()));
00258
00259 verticalBox->addLayout(buttonBox);
00260 }
00261
00262
00263
00264 NeuronParametersDialog::~NeuronParametersDialog(){
00265 #ifdef MEMORY_DEBUG
00266 cout<<"DESTROYING NEURON PARAMETERS DIALOG"<<endl;
00267 #endif//MEMORY_DEBUG
00268
00269
00270 delete editPixmap;
00271
00272
00273 for(map<unsigned short, QStringList*>::iterator iter = fieldNamesMap.begin(); iter != fieldNamesMap.end(); ++iter)
00274 delete iter->second;
00275
00276 for(map<unsigned short, QStringList*>::iterator iter = valueNamesMap.begin(); iter != valueNamesMap.end(); ++iter)
00277 delete iter->second;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 bool NeuronParametersDialog::loadNeuronParameters(){
00287
00288 for(map<unsigned short, ParameterTable*>::iterator iter = paramTableMap.begin(); iter != paramTableMap.end(); ++iter)
00289 iter->second->setNumRows(0);
00290
00291
00292 parameterValuesChanged = false;
00293
00294
00295 applyButton->setEnabled(false);
00296
00297
00298 try{
00299 Query query = networkDBInterface->getQuery();
00300 query.reset();
00301 query<<"SELECT TypeID, ParameterTableName FROM NeuronTypes";
00302 Result neuronTypesResult = query.store();
00303 for(Result::iterator neurTypesIter = neuronTypesResult.begin(); neurTypesIter != neuronTypesResult.end(); ++neurTypesIter){
00304 Row neuronTypesRow(*neurTypesIter);
00305 unsigned short neuronTypeID = Utilities::getUShort((std::string) neuronTypesRow["TypeID"]);
00306
00307
00308 query.reset();
00309 if(fieldNamesMap[neuronTypeID]->size() > 0){
00310 query<<"SELECT NeuronGrpID, ";
00311 for(unsigned int i=0; i<fieldNamesMap[neuronTypeID]->size() - 1; ++i){
00312 query<<(*fieldNamesMap[neuronTypeID])[i]<<"_val, ";
00313 }
00314 query<<(*fieldNamesMap[neuronTypeID])[fieldNamesMap[neuronTypeID]->size() - 1]<<"_val FROM "<<((std::string)neuronTypesRow["ParameterTableName"]);
00315 }
00316 else
00317 query<<"SELECT NeuronGrpID FROM "<<((std::string)neuronTypesRow["ParameterTableName"]);
00318 Result valueResult = query.store();
00319
00320
00321 for(Result::iterator iter = valueResult.begin(); iter != valueResult.end(); ++iter){
00322 Row valueRow(*iter);
00323
00324
00325 int currentRowNumber = paramTableMap[neuronTypeID]->numRows();
00326 paramTableMap[neuronTypeID]->insertRows(currentRowNumber, 1);
00327
00328
00329 paramTableMap[neuronTypeID]->setPixmap(currentRowNumber, editColumn, *editPixmap);
00330
00331
00332 paramTableMap[neuronTypeID]->setItem(currentRowNumber, neurGrpIDColumn, new QTableItem(paramTableMap[neuronTypeID], QTableItem::Never, (std::string)valueRow["NeuronGrpID"]));
00333
00334
00335 query.reset();
00336 query<<"SELECT Name FROM NeuronGroups WHERE NeuronGrpID = "<<(std::string)valueRow["NeuronGrpID"];
00337 Result nameResult = query.store();
00338 Row nameRow = *nameResult.begin();
00339 paramTableMap[neuronTypeID]->setItem(currentRowNumber, nameColumn, new QTableItem(paramTableMap[neuronTypeID], QTableItem::Never, (std::string)nameRow["Name"]));
00340
00341
00342 for(unsigned int i=0; i<fieldNamesMap[neuronTypeID]->size(); ++i){
00343 QString valueQueryName = (*fieldNamesMap[neuronTypeID])[i] + "_val";
00344
00345 if(checkBoxMap[neuronTypeID].count((*fieldNamesMap[neuronTypeID])[i])){
00346 unsigned int booleanValue = Utilities::getInt((std::string)valueRow[valueQueryName.ascii()]);
00347 QCheckTableItem *tempCheckTableItem = new QCheckTableItem( paramTableMap[neuronTypeID], QString(""));
00348
00349 if(booleanValue == 0)
00350 tempCheckTableItem->setChecked(false);
00351 else if(booleanValue == 1)
00352 tempCheckTableItem->setChecked(true);
00353 paramTableMap[neuronTypeID]->setItem(currentRowNumber, paramStartColumn + i, tempCheckTableItem);
00354 }
00355 else{
00356 paramTableMap[neuronTypeID]->setItem(currentRowNumber, paramStartColumn + i,
00357 new QTableItem(paramTableMap[neuronTypeID], QTableItem::Never, (std::string)valueRow[valueQueryName.ascii()]));
00358 }
00359 }
00360 }
00361 }
00362 }
00363 catch (const BadQuery& er) {
00364 cerr<<"NeuronParametersDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00365 QString errorString = "Bad query when loading neuron parameters: \"";
00366 errorString += er.what();
00367 errorString += "\"";
00368 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00369 return false;
00370 }
00371 catch (const Exception& er) {
00372 cerr<<"NeuronParametersDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00373 QString errorString = "Exception thrown loading neuron parameters: \"";
00374 errorString += er.what();
00375 errorString += "\"";
00376 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00377 return false;
00378 }
00379 catch(std::exception& er){
00380 cerr<<"NeuronParametersDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00381 QString errorString = "Exception thrown loading neuron parameters: \"";
00382 errorString += er.what();
00383 errorString += "\"";
00384 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00385 return false;
00386 }
00387
00388
00389
00390 for(map<unsigned short, ParameterTable*>::iterator iter = paramTableMap.begin(); iter != paramTableMap.end(); ++iter){
00391 if(iter->second->numRows() <= 0){
00392 iter->second->hide();
00393 tableLabelMap[iter->first]->hide();
00394 }
00395 else{
00396 iter->second->show();
00397 tableLabelMap[iter->first]->show();
00398 }
00399 }
00400
00401
00402 return true;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412 void NeuronParametersDialog::applyButtonPressed(){
00413
00414 storeNeuronParameters();
00415
00416
00417 simulationManager->setNeuronParameters();
00418
00419
00420 parameterValuesChanged = false;
00421 applyButton->setEnabled(false);
00422 }
00423
00424
00425
00426 void NeuronParametersDialog::cancelButtonPressed(){
00427 this->hide();
00428 }
00429
00430
00431
00432
00433 void NeuronParametersDialog::defaultsButtonPressed(){
00434 }
00435
00436
00437
00438
00439 void NeuronParametersDialog::okButtonPressed(){
00440 if(parameterValuesChanged){
00441
00442 storeNeuronParameters();
00443
00444
00445 simulationManager->setNeuronParameters();
00446 }
00447 this->hide();
00448 }
00449
00450
00451
00452
00453 void NeuronParametersDialog::parameterTableClicked(int row, int col, unsigned short typeID){
00454 if(col == editColumn){
00455
00456 unsigned int neuronGrpID = 0;
00457
00458
00459 map<const char*, double, charKeyCompare> descValueMap;
00460
00461 try{
00462 neuronGrpID = Utilities::getUInt(paramTableMap[typeID]->item(row, neurGrpIDColumn)->text().ascii());
00463 for(int i=paramStartColumn; i<paramTableMap[typeID]->numCols(); ++i){
00464
00465 if(checkBoxMap[typeID].count(descParamMap[typeID][paramTableHeaderMap[typeID]->label(i).ascii()]) == 0 ){
00466 double tempVal = Utilities::getDouble(paramTableMap[typeID]->text(row, i).ascii());
00467 descValueMap[paramTableHeaderMap[typeID]->label(i).ascii()] = tempVal;
00468 }
00469 }
00470 }
00471 catch(std::exception& er){
00472 cerr<<"NeuronParametersDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00473 QString errorString = "Exception thrown loading information for Edit Parameters Dialog: \"";
00474 errorString += er.what();
00475 errorString += "\"";
00476 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00477 return;
00478 }
00479
00480
00481 EditNeuronParametersDialog *edParamDlg = new EditNeuronParametersDialog(this, descValueMap, &defaultValueMap[typeID], neuronGrpID);
00482 if ( edParamDlg->exec() == QDialog::Accepted ) {
00483
00484 map<const char*, QLineEdit*, charKeyCompare> *tempMap = edParamDlg->getDescriptionLineEditMap();
00485
00486
00487 for(map<const char*, QLineEdit*>::iterator iter = tempMap->begin(); iter != tempMap->end(); ++iter){
00488
00489 QString parameterText = iter->second->text();
00490
00491
00492 int columnNumber = descriptionColumnMap[typeID][iter->first];
00493
00494
00495 paramTableMap[typeID]->setItem(row, columnNumber, new QTableItem(paramTableMap[typeID], QTableItem::Never, parameterText));
00496 }
00497
00498
00499 parameterValuesChanged = true;
00500
00501
00502 applyButton->setEnabled(true);
00503 }
00504
00505
00506 delete edParamDlg;
00507 }
00508 }
00509
00510
00511
00512
00513 void NeuronParametersDialog::parameterTableValueChanged(int, int, unsigned short){
00514
00515 parameterValuesChanged = true;
00516 applyButton->setEnabled(true);
00517 }
00518
00519
00520
00521
00522
00523
00524
00525 void NeuronParametersDialog::storeNeuronParameters(){
00526 try{
00527 Query query = networkDBInterface->getQuery();
00528
00529
00530 for(map<unsigned short, ParameterTable*>::iterator paramTableIter = paramTableMap.begin(); paramTableIter != paramTableMap.end(); ++paramTableIter){
00531
00532
00533 for(int rowNum=0; rowNum< paramTableIter->second->numRows(); ++rowNum){
00534 QString neurGrpIDText = paramTableIter->second->text(rowNum, neurGrpIDColumn);
00535 unsigned short neurTypeID = paramTableIter->first;
00536
00537
00538 QString queryString = "UPDATE ";
00539 queryString += paramTableIter->second->getParameterTableName();
00540 queryString += " SET ";
00541
00542 for(unsigned int i = 0; i < fieldNamesMap[neurTypeID]->size(); ++i){
00543 QString valueName = (*fieldNamesMap[neurTypeID])[i] + "_val";
00544 QString valueText = "";
00545
00546
00547 if(checkBoxMap[neurTypeID].count((*valueNamesMap[neurTypeID])[i])){
00548 QCheckTableItem * item = (QCheckTableItem*)paramTableIter->second->item(rowNum, i + paramStartColumn);
00549 if(item->isChecked())
00550 valueText = "1";
00551 else
00552 valueText = "0";
00553 }
00554 else {
00555 valueText = paramTableIter->second->text(rowNum, i+paramStartColumn);
00556 }
00557
00558 queryString += valueName;
00559 queryString += " = ";
00560 queryString += valueText;
00561 queryString += ", ";
00562 }
00563
00564
00565 queryString.remove(queryString.length() - 2, 2);
00566
00567
00568 queryString += " WHERE NeuronGrpID = ";
00569 queryString += neurGrpIDText;
00570
00571
00572 query.reset();
00573 query<<queryString;
00574 query.execute();
00575 }
00576 }
00577 }
00578 catch (const BadQuery& er) {
00579 cerr<<"NeuronParametersDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00580 QString errorString = "Bad query when storing neuron parameters: \"";
00581 errorString += er.what();
00582 errorString += "\"";
00583 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00584 }
00585 catch (const Exception& er) {
00586 cerr<<"NeuronParametersDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00587 QString errorString = "Exception thrown storing neuron parameters: \"";
00588 errorString += er.what();
00589 errorString += "\"";
00590 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00591 }
00592 catch(std::exception& er){
00593 cerr<<"NeuronParametersDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00594 QString errorString = "Exception thrown storing neuron parameters: \"";
00595 errorString += er.what();
00596 errorString += "\"";
00597 QMessageBox::critical( 0, "Neuron Parameters Error", errorString);
00598 }
00599 }
00600
00601