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 "ConnectionMatrixLoader.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 #include "ConnectionType.h"
00028 #include "NeuronGroupType.h"
00029
00030
00031 #include <qmessagebox.h>
00032 #include <qfile.h>
00033
00034
00035 #include <mysql++.h>
00036 #include <cmath>
00037 using namespace std;
00038 using namespace mysqlpp;
00039
00040
00041
00042 #define LOAD_CONNECTION_MATRIX_DEBUG
00043
00044
00045
00046 ConnectionMatrixLoader::ConnectionMatrixLoader(DBInterface* netDBInter){
00047
00048 networkDBInterface = netDBInter;
00049 }
00050
00051
00052
00053 ConnectionMatrixLoader::~ConnectionMatrixLoader(){
00054 #ifdef MEMORY_DEBUG
00055 cout<<"DELETING CONNECTION MATRIX LOADER"<<endl;
00056 #endif//MEMORY_DEBUG
00057 }
00058
00059
00060
00061
00062
00063
00064
00065 bool ConnectionMatrixLoader::loadConnectionMatrix(QString& fileName){
00066
00067 neurGrpID = 0;
00068 connGrpID = 0;
00069 neuronType = 0;
00070 synapseType = 0;
00071 neurGrpWidth = 0;
00072 neurGrpLength = 0;
00073 neurParamTable = "";
00074 numNeur = 0;
00075 connectionCount = 0;
00076 rowNum = 0;
00077 errorState = false;
00078
00079
00080 bool firstLine = true;
00081
00082
00083 QFile file(fileName);
00084
00085
00086 if ( file.open( IO_ReadOnly ) ) {
00087 QTextStream stream( &file );
00088 QString fileLine;
00089
00090 while ( !stream.atEnd() && !errorState) {
00091 fileLine = stream.readLine();
00092 #ifdef LOAD_CONNECTION_MATRIX_DEBUG
00093 cout<<"Reading line: \""<<fileLine<<"\""<<endl;
00094 #endif//LOAD_PATTERN_DEBUG
00095
00096
00097 QStringList neuronList = QStringList::split(",", fileLine);
00098
00099 #ifdef LOAD_CONNECTION_MATRIX_DEBUG
00100 cout<<"Matrix contains "<<numNeur<<" neurons."<<endl;
00101 #endif//LOAD_PATTERN_DEBUG
00102
00103
00104 if(firstLine){
00105
00106 numNeur = neuronList.size();
00107
00108
00109 createNeuronGroup();
00110 if(neurGrpID == 0 || errorState){
00111 file.close();
00112 deleteDatabaseEntries(neurGrpID, connGrpID);
00113 return false;
00114 }
00115
00116
00117 createConnectionGroup(fileName);
00118 if(connGrpID == 0 || errorState){
00119 file.close();
00120 deleteDatabaseEntries(neurGrpID, connGrpID);
00121 return false;
00122 }
00123
00124
00125 firstLine = false;
00126 }
00127
00128
00129 addConnections(neuronList);
00130 ++rowNum;
00131
00132 }
00133
00134 file.close();
00135
00136
00137 if(rowNum != numNeur){
00138 deleteDatabaseEntries(neurGrpID, connGrpID);
00139 showError("ConnectionMatrixLoader: Matrix not square");
00140 return false;
00141 }
00142
00143
00144 if(errorState){
00145 deleteDatabaseEntries(neurGrpID, connGrpID);
00146 return false;
00147 }
00148
00149
00150
00151 try{
00152 Query query = networkDBInterface->getQuery();
00153 if(connectionCount == 0){
00154 query.reset();
00155 query<<"DELETE FROM ConnectionGroups WHERE ConnGrpID = "<<connGrpID;
00156 query.execute();
00157 }
00158 else{
00159
00160 query.reset();
00161 query<<"SELECT ParameterTableName FROM SynapseTypes WHERE TypeID = "<<synapseType;
00162 Result tableNameRes = query.store();
00163 Row tableNameRow (*tableNameRes.begin());
00164
00165
00166 query.reset();
00167 query<<"INSERT INTO "<<(std::string)tableNameRow["ParameterTableName"]<<" (ConnGrpID) VALUES ("<<connGrpID<<")";
00168 query.execute();
00169 }
00170 }
00171 catch (const BadQuery& er) {
00172 QString errorString = "ConnectionMatrixLoader: MySQL++ BadQuery thrown creating neuron group: \"";
00173 errorString += er.what();
00174 errorString += "\"";
00175 showError(errorString);
00176 deleteDatabaseEntries(neurGrpID, connGrpID);
00177 return false;
00178 }
00179 catch (const Exception& er) {
00180 QString errorString = "ConnectionMatrixLoader: MySQL++ Exception thrown creating neuron group: \"";
00181 errorString += er.what();
00182 errorString += "\"";
00183 showError(errorString);
00184 deleteDatabaseEntries(neurGrpID, connGrpID);
00185 return false;
00186 }
00187 catch(std::exception& er){
00188 QString errorString = "ConnectionMatrixLoader: std::exception thrown creating neuron group\"";
00189 errorString += er.what();
00190 errorString += "\"";
00191 showError(errorString);
00192 deleteDatabaseEntries(neurGrpID, connGrpID);
00193 return false;
00194 }
00195
00196 #ifdef LOAD_CONNECTION_MATRIX_DEBUG
00197 cout<<"Connection matrix loading complete. "<<connectionCount<<" connections loaded. "<<endl;
00198 #endif//LOAD_PATTERN_DEBUG
00199 }
00200 else{
00201 showError("ConnectionMatrixLoader: Error opening file.");
00202 return false;
00203 }
00204
00205
00206 return true;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 void ConnectionMatrixLoader::addConnections(QStringList& neuronIDList){
00216 try{
00217 Query query = networkDBInterface->getQuery();
00218 double connWeight;
00219
00220
00221
00222 for(unsigned int colNum=0; colNum<neuronIDList.size(); ++colNum){
00223 connWeight = Utilities::getDouble(neuronIDList[colNum].ascii());
00224 connWeight *= 127.0;
00225 if(connWeight > 0){
00226
00227
00228 query.reset();
00229 query<<"INSERT INTO Connections (PreSynapticNeuronID, PostSynapticNeuronID, Delay, Weight, ConnGrpID) VALUES ("<<(startNeurID + rowNum)<<", "<<(startNeurID + colNum)<<", "<<0<<", "<<connWeight<<", "<<connGrpID<<")";
00230 query.execute();
00231 ++connectionCount;
00232 }
00233 }
00234 }
00235 catch (const BadQuery& er) {
00236 QString errorString = "ConnectionMatrixLoader: MySQL++ BadQuery thrown creating neuron group: \"";
00237 errorString += er.what();
00238 errorString += "\"";
00239 showError(errorString);
00240 }
00241 catch (const Exception& er) {
00242 QString errorString = "ConnectionMatrixLoader: MySQL++ Exception thrown creating neuron group: \"";
00243 errorString += er.what();
00244 errorString += "\"";
00245 showError(errorString);
00246 }
00247 catch(std::exception& er){
00248 QString errorString = "ConnectionMatrixLoader: std::exception thrown creating neuron group\"";
00249 errorString += er.what();
00250 errorString += "\"";
00251 showError(errorString);
00252 }
00253 }
00254
00255
00256
00257
00258 void ConnectionMatrixLoader::createConnectionGroup(const QString& fileName){
00259
00260
00261
00262 ostringstream xmlStrStream;
00263 xmlStrStream<<"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
00264 xmlStrStream<<"<connection_parameters>";
00265
00266
00267 xmlStrStream<<"<parameter>";
00268 xmlStrStream<<"<description>"<<"Connection Matrix file name"<<"</description>";
00269 xmlStrStream<<"<value>"<<fileName<<"</value>";
00270 xmlStrStream<<"</parameter>";
00271 xmlStrStream<<"</connection_parameters>";
00272
00273 try{
00274 Query query = networkDBInterface->getQuery();
00275
00276
00277 query.reset();
00278 query<<"SELECT MIN(TypeID) from SynapseTypes";
00279 Result minTypeIDRes = query.store();
00280 Row minTypeIDRow(*(minTypeIDRes.begin()));
00281 synapseType = Utilities::getUInt((std::string)minTypeIDRow["MIN(TypeID)"]);
00282
00283
00284 query.reset();
00285 ostringstream strbuf;
00286 strbuf<<"INSERT INTO ConnectionGroups (FromNeuronGrpID, ToNeuronGrpID, ConnType, SynapseType, Parameters) VALUES ("<<neurGrpID<<", "<<neurGrpID<<", "<<ConnectionType::SimpleCortex<<", "<<synapseType<<", \""<<mysqlpp::escape<<xmlStrStream.str()<<"\" )";
00287 query.exec(strbuf.str());
00288
00289
00290 query.reset();
00291 query<<"SELECT MAX(ConnGrpID) from ConnectionGroups";
00292 Result grpIDResult = query.store();
00293 Row row(*(grpIDResult.begin()));
00294 connGrpID = Utilities::getUInt((string)row["MAX(ConnGrpID)"]);
00295 }
00296 catch (const BadQuery& er) {
00297 QString errorString = "ConnectionMatrixLoader: MySQL++ BadQuery thrown creating neuron group: \"";
00298 errorString += er.what();
00299 errorString += "\"";
00300 showError(errorString);
00301 }
00302 catch (const Exception& er) {
00303 QString errorString = "ConnectionMatrixLoader: MySQL++ Exception thrown creating neuron group: \"";
00304 errorString += er.what();
00305 errorString += "\"";
00306 showError(errorString);
00307 }
00308 catch(std::exception& er){
00309 QString errorString = "ConnectionMatrixLoader: std::exception thrown creating neuron group\"";
00310 errorString += er.what();
00311 errorString += "\"";
00312 showError(errorString);
00313 }
00314 }
00315
00316
00317
00318
00319 void ConnectionMatrixLoader::createNeuronGroup(){
00320 int neuronCount = 0;
00321 try{
00322 Query query = networkDBInterface->getQuery();
00323
00324
00325 neurGrpWidth = (unsigned int)floor(sqrt(numNeur));
00326 neurGrpLength = numNeur/neurGrpWidth;
00327
00328
00329 if( (neurGrpWidth * neurGrpLength) != numNeur){
00330 showError("Neuron width * length does not equal number of neurons.");
00331 return;
00332 }
00333
00334 #ifdef LOAD_CONNECTION_MATRIX_DEBUG
00335 cout<<"Neuron group width = "<<neurGrpWidth<<"; neuron group length = "<<neurGrpLength<<endl;
00336 #endif//LOAD_PATTERN_DEBUG
00337
00338
00339 query.reset();
00340 query<<"SELECT NeuronID FROM Neurons WHERE X >="<<0<<" AND X <= "<<neurGrpWidth<<" AND Y >= "<<0<<" AND Y <= "<<neurGrpLength<<" AND Z = "<<0;
00341 Result zLayerResult = query.store();
00342 if(zLayerResult.size() > 0){
00343 showError("ConnectionMatrixLoader: CONFLICT WITH EXISTING LAYERS");
00344 return;
00345 }
00346
00347
00348
00349 query.reset();
00350 query<<"SELECT MIN(TypeID) from NeuronTypes";
00351 Result minTypeIDRes = query.store();
00352 Row minTypeIDRow(*(minTypeIDRes.begin()));
00353 neuronType = Utilities::getUInt((std::string)minTypeIDRow["MIN(TypeID)"]);
00354
00355
00356 query.reset();
00357 query<<"INSERT INTO NeuronGroups (Name, NeuronGrpType, NeuronType, X, Y, Z, Width, Length, Spacing, TaskID) VALUES (\""<<"Untitled"<<"\", "<<NeuronGroupType::RectangularLayer2D<<", "<<neuronType<<", "<<0<<", "<<0<<", "<<0<<", "<<neurGrpWidth<<", "<<neurGrpLength<<", "<<1<<", -1)";
00358 query.execute();
00359
00360
00361 query.reset();
00362 query<<"SELECT MAX(NeuronGrpID) from NeuronGroups";
00363 Result neurGrpIDRes = query.store();
00364 Row neurGrpIDRow(*(neurGrpIDRes.begin()));
00365 neurGrpID = Utilities::getUInt((std::string)neurGrpIDRow["MAX(NeuronGrpID)"]);
00366
00367
00368
00369
00370 for(unsigned int i=0; i<neurGrpLength; ++i){
00371 for(unsigned int j=0; j<neurGrpWidth; ++j){
00372 query.reset();
00373 query<<"INSERT INTO Neurons (X, Y, Z, NeuronGrpID) VALUES ("<<j<<", "<<i<<", "<<0<<", "<<neurGrpID<<")";
00374 query.execute();
00375 ++neuronCount;
00376 }
00377 }
00378
00379
00380 query.reset();
00381 query<<"SELECT MIN(NeuronID) from Neurons WHERE NeuronGrpID = "<<neurGrpID;
00382 Result startIDRes = query.store();
00383 Row startIDRow(*(startIDRes.begin()));
00384 startNeurID = Utilities::getUInt((std::string)startIDRow["MIN(NeuronID)"]);
00385
00386
00387
00388 query.reset();
00389 query<<"SELECT ParameterTableName FROM NeuronTypes WHERE TypeID = "<<neuronType;
00390 Result tableNameRes = query.store();
00391 Row tableNameRow (*tableNameRes.begin());
00392 neurParamTable = (std::string)tableNameRow["ParameterTableName"];
00393
00394
00395 query.reset();
00396 query<<"INSERT INTO "<<neurParamTable<<" (NeuronGrpID) VALUES ("<<neurGrpID<<")";
00397 query.execute();
00398
00399
00400 query.reset();
00401 query<<"INSERT INTO NoiseParameters (NeuronGrpID) VALUES ("<<neurGrpID<<")";
00402 query.execute();
00403
00404 }
00405 catch (const BadQuery& er) {
00406 QString errorString = "ConnectionMatrixLoader: MySQL++ BadQuery thrown creating neuron group: \"";
00407 errorString += er.what();
00408 errorString += "\"";
00409 showError(errorString);
00410 deleteDatabaseEntries(neurGrpID, 0);
00411 }
00412 catch (const Exception& er) {
00413 QString errorString = "ConnectionMatrixLoader: MySQL++ Exception thrown creating neuron group: \"";
00414 errorString += er.what();
00415 errorString += "\"";
00416 showError(errorString);
00417 deleteDatabaseEntries(neurGrpID, 0);
00418 }
00419 catch(std::exception& er){
00420 QString errorString = "ConnectionMatrixLoader: std::exception thrown creating neuron group\"";
00421 errorString += er.what();
00422 errorString += "\"";
00423 showError(errorString);
00424 deleteDatabaseEntries(neurGrpID, 0);
00425 }
00426
00427 #ifdef LOAD_CONNECTION_MATRIX_DEBUG
00428 cout<<neuronCount<<" neurons added to database."<<endl;
00429 #endif//LOAD_CONNECTION_MATRIX_DEBUG
00430 }
00431
00432
00433
00434 void ConnectionMatrixLoader::deleteDatabaseEntries(unsigned int nGrpID, unsigned int cGrpID){
00435 try{
00436 Query query = networkDBInterface->getQuery();
00437
00438
00439 if(neurGrpID > 0){
00440
00441 query.reset();
00442 query<<"DELETE FROM Neurons WHERE NeuronGrpID = "<<nGrpID;
00443 query.execute();
00444
00445
00446 query.reset();
00447 query<<"DELETE FROM NeuronGroups WHERE NeuronGrpID = "<<nGrpID;
00448 query.execute();
00449
00450
00451 if(neurParamTable != ""){
00452 query.reset();
00453 query<<"DELETE FROM "<<neurParamTable<<" WHERE NeuronGrpID = "<<nGrpID;
00454 query.execute();
00455 }
00456
00457
00458 query.reset();
00459 query<<"DELETE FROM NoiseParameters WHERE NeuronGrpID = "<<nGrpID;
00460 query.execute();
00461
00462
00463 neurGrpID = 0;
00464 }
00465
00466
00467 if(connGrpID > 0){
00468
00469 query.reset();
00470 query<<"DELETE FROM Connections WHERE ConnGrpID = "<<cGrpID;
00471 query.execute();
00472
00473
00474 query.reset();
00475 query<<"DELETE FROM ConnectionGroups WHERE ConnGrpID = "<<cGrpID;
00476 query.execute();
00477
00478
00479 connGrpID = 0;
00480 }
00481 }
00482 catch (const BadQuery& er) {
00483 QString errorString = "ConnectionMatrixLoader: MySQL++ BadQuery thrown deleting database entries: \"";
00484 errorString += er.what();
00485 errorString += "\"";
00486 showError(errorString);
00487 }
00488 catch (const Exception& er) {
00489 QString errorString = "ConnectionMatrixLoader: MySQL++ Exception thrown deleting database entries: \"";
00490 errorString += er.what();
00491 errorString += "\"";
00492 showError(errorString);
00493 }
00494 catch(std::exception& er){
00495 QString errorString = "ConnectionMatrixLoader: std::exception thrown deleting database entries: \"";
00496 errorString += er.what();
00497 errorString += "\"";
00498 showError(errorString);
00499 }
00500 }
00501
00502
00503
00504
00505 void ConnectionMatrixLoader::showError(const char* errMsg){
00506 cerr<<errMsg<<endl;
00507 QMessageBox::critical( 0, "Connection Matrix Loader Error", errMsg);
00508 errorState = true;
00509 }
00510
00511
00512
00513
00514 void ConnectionMatrixLoader::showError(const QString& errMsg){
00515 cerr<<errMsg<<endl;
00516 QMessageBox::critical( 0, "Connection Matrix Loader Error", errMsg);
00517 errorState = true;
00518 }
00519