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 "LayerManager.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 #include "NeuronGroupType.h"
00028 #include "GlobalVariables.h"
00029 #include "DeviceTypes.h"
00030
00031
00032 #include <cmath>
00033 #include <iostream>
00034 using namespace std;
00035 using namespace mysqlpp;
00036
00037
00038
00039 class EditNeuronGroupException : public exception{
00040 virtual const char* what() const throw(){
00041 return "Error during editing of neuron group.";
00042 }
00043 } editNeuronGroupException;
00044
00045
00046
00047 LayerManager::LayerManager(DBInterface *netDBInter, DBInterface* devDBInter){
00048
00049 networkDBInterface = netDBInter;
00050 deviceDBInterface = devDBInter;
00051
00052
00053 srand(randomSeed);
00054
00055
00056 progressDialog = new QProgressDialog(0, "Creating layers", true);
00057 }
00058
00059
00060
00061 LayerManager::~LayerManager(){
00062 #ifdef MEMORY_DEBUG
00063 cout<<"DELETING LAYER MANAGER!"<<endl;
00064 #endif//MEMORY_DEBUG
00065
00066 delete progressDialog;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 int LayerManager::createLayer(const NeuronGroup &neuronGrp){
00078
00079
00080 switch(neuronGrp.neuronGrpType){
00081 case (NeuronGroupType::RectangularLayer2D):
00082 return create2DRectangularLayer(neuronGrp);
00083 case (NeuronGroupType::RectangularLayer3D):
00084 return create3DRectangularLayer(neuronGrp);
00085 case (NeuronGroupType::SIMNOSComponentLayer):
00086 return createSIMNOSComponentLayer(neuronGrp);
00087 default:
00088 cerr<<"CONNECTION TYPE NOT RECOGNIZED"<<endl;
00089 return -1;
00090 }
00091 }
00092
00093
00094
00095 void LayerManager::deleteLayers(vector<unsigned int> layerIDs){
00096 Query query = networkDBInterface->getQuery();
00097
00098 vector<unsigned int>::iterator iter;
00099 for(iter = layerIDs.begin(); iter < layerIDs.end(); ++iter){
00100
00101 query.reset();
00102 query<<"DELETE FROM NeuronGroups WHERE NeuronGrpID=\'"<<*iter<<"\'";
00103 query.execute();
00104
00105
00106 query.reset();
00107 query<<"DELETE FROM Neurons WHERE NeuronGrpID=\'"<<*iter<<"\'";
00108 query.execute();
00109
00110
00111
00112
00113 query.reset();
00114 query<<"SELECT ParameterTableName FROM NeuronTypes";
00115 Result tableNameRes = query.store();
00116 for(Result::iterator paramTableIter = tableNameRes.begin(); paramTableIter != tableNameRes.end(); ++paramTableIter){
00117 Row tableNameRow (*paramTableIter);
00118 query.reset();
00119 query<<"DELETE FROM "<<(std::string)tableNameRow["ParameterTableName"]<<" WHERE NeuronGrpID= "<<*iter;
00120 query.execute();
00121 }
00122
00123
00124 query.reset();
00125 query<<"DELETE FROM NoiseParameters WHERE NeuronGrpID=\'"<<*iter<<"\'";
00126 query.execute();
00127 }
00128 }
00129
00130
00131
00132
00133 void LayerManager::setConnectionWidget(ConnectionWidget* connWidg){
00134 connectionWidget = connWidg;
00135 }
00136
00137
00138
00139
00140 void LayerManager::setNeuronGrpName(unsigned int neuronGrpID, QString name){
00141 Query query = networkDBInterface->getQuery();
00142 query.reset();
00143 query<<"UPDATE NeuronGroups SET Name = \""<<name<<"\" WHERE NeuronGrpID = "<<neuronGrpID;
00144 query.execute();
00145 }
00146
00147
00148
00149
00150
00151 bool LayerManager::setNeuronGrpSpacingPosition(const unsigned int neuronGrpID, const NeuronGroup &oldNeurGrp, const NeuronGroup &newNeurGrp){
00152
00153
00154
00155 int actualWidth = newNeurGrp.spacing * (newNeurGrp.width - 1);
00156 int actualLength = newNeurGrp.spacing * (newNeurGrp.length - 1);
00157
00158
00159 Query query = networkDBInterface->getQuery();
00160 query.reset();
00161 query<<"SELECT NeuronID FROM Neurons WHERE X >="<<newNeurGrp.xPos<<" AND X <= "<<(newNeurGrp.xPos+actualWidth)<<" AND Y >= "<<newNeurGrp.yPos<<" AND Y <= "<<(newNeurGrp.yPos + actualLength)<<" AND Z = "<<newNeurGrp.zPos<<" AND NeuronGrpID != "<<neuronGrpID;
00162 Result layerResult = query.store();
00163 if(layerResult.size() > 0)
00164 return false;
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 query.reset();
00177 query<<"SELECT MIN(NeuronID) FROM Neurons WHERE NeuronGrpID = "<<neuronGrpID;
00178 Result minNeuronIDRes = query.store();
00179 Row minNeuronIDRow(*minNeuronIDRes.begin());
00180
00181
00182 unsigned int startNeuronID = Utilities::getUInt((std::string)minNeuronIDRow["MIN(NeuronID)"]);
00183 unsigned int neuronIDCount = startNeuronID;
00184
00185
00186 progressDialog->setTotalSteps(newNeurGrp.width*newNeurGrp.length);
00187 progressDialog->setLabelText("Updating Layer");
00188 int progressCounter = 0;
00189
00190
00191 for(unsigned int i=0; i<newNeurGrp.length; ++i){
00192 for(unsigned int j=0; j<newNeurGrp.width; ++j){
00193 query.reset();
00194 query<<"UPDATE Neurons SET X = "<<(newNeurGrp.xPos + (j*newNeurGrp.spacing))<<", Y = "<<(newNeurGrp.yPos + (i*newNeurGrp.spacing))<<", Z = "<<newNeurGrp.zPos<<" WHERE X = "<<(oldNeurGrp.xPos + (j*oldNeurGrp.spacing))<<" AND Y = "<<(oldNeurGrp.yPos + (i*oldNeurGrp.spacing))<<" AND Z = "<<oldNeurGrp.zPos<<" AND NeuronID = "<<neuronIDCount;
00195
00196 ResNSel updateResult = query.execute();
00197
00198
00199 if(updateResult.rows == 1 || neuronIDCount == startNeuronID){
00200 ++neuronIDCount;
00201 ++progressCounter;
00202 if(progressCounter % 100 == 0)
00203 progressDialog->setProgress(progressCounter);
00204 }
00205 else{
00206 cerr<<"LayerManager: NEURON HAS BEEN PASSED OVER DURING SPACING/POSITION CHANGE. NEURONGROUP: "<<neuronGrpID<<"; i="<<i<<"; j="<<j<<"; neuronIDCount="<<neuronIDCount<<endl;
00207 cerr<<"Old Neuron group holder: x="<<oldNeurGrp.xPos<<"; y="<<oldNeurGrp.yPos<<"; z="<<oldNeurGrp.zPos<<"; spacing="<<oldNeurGrp.spacing<<"; width="<<oldNeurGrp.width<<"; length="<<oldNeurGrp.length<<endl;
00208 cerr<<"New Neuron group holder: x="<<newNeurGrp.xPos<<"; y="<<newNeurGrp.yPos<<"; z="<<newNeurGrp.zPos<<"; spacing="<<newNeurGrp.spacing<<"; width="<<newNeurGrp.width<<"; length="<<newNeurGrp.length<<endl;
00209 throw editNeuronGroupException;
00210 }
00211 }
00212 }
00213 progressDialog->reset();
00214
00215
00216 query.reset();
00217 query<<"UPDATE NeuronGroups SET Spacing = "<<newNeurGrp.spacing<<" WHERE NeuronGrpID = "<<neuronGrpID;
00218 query.execute();
00219
00220
00221 query<<"UPDATE NeuronGroups SET X = "<<newNeurGrp.xPos<<", Y = "<<newNeurGrp.yPos<<", Z = "<<newNeurGrp.zPos<<" WHERE NeuronGrpID = "<<neuronGrpID;
00222 query.execute();
00223 return true;
00224 }
00225
00226
00227
00228
00229 void LayerManager::setNeuronGrpType(unsigned int neuronGrpID, unsigned short neuronType){
00230 try{
00231 Query query = networkDBInterface->getQuery();
00232 query.reset();
00233
00234
00235 query<<"UPDATE NeuronGroups SET NeuronType = "<<neuronType<<" WHERE NeuronGrpID = "<<neuronGrpID;
00236 query.execute();
00237
00238
00239
00240 query.reset();
00241 query<<"SELECT TypeID, ParameterTableName FROM NeuronTypes";
00242 Result neurTypesRes = query.store();
00243 for(Result::iterator iter = neurTypesRes.begin(); iter != neurTypesRes.end(); ++iter){
00244 Row neurTypeRow (*iter);
00245 unsigned short neuronTypeID = Utilities::getUShort((std::string) neurTypeRow["TypeID"]);
00246
00247
00248 query.reset();
00249 query<<"DELETE FROM "<<(std::string)neurTypeRow["ParameterTableName"]<<" WHERE NeuronGrpID = "<<neuronGrpID;
00250 query.execute();
00251
00252
00253 if(neuronTypeID == neuronType){
00254 query.reset();
00255 query<<"INSERT INTO "<<(std::string)neurTypeRow["ParameterTableName"]<<"(NeuronGrpID) VALUES("<<neuronGrpID<<")";
00256 query.execute();
00257 }
00258 }
00259 }
00260 catch(Exception ex){
00261 cerr<<"Exception thrown whilst setting the neuron group type: "<<ex.what()<<endl;
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270
00271 int LayerManager::create2DRectangularLayer(const NeuronGroup &neuronGrp){
00272
00273 progressDialog->reset();
00274 progressDialog->setTotalSteps(neuronGrp.width*neuronGrp.length);
00275
00276
00277 bool layerConflict = false;
00278
00279
00280
00281 int actualWidth = neuronGrp.spacing * (neuronGrp.width - 1);
00282 int actualLength = neuronGrp.spacing * (neuronGrp.length - 1);
00283
00284
00285 Query query = networkDBInterface->getQuery();
00286 query.reset();
00287 query<<"SELECT NeuronID FROM Neurons WHERE X >="<<neuronGrp.xPos<<" AND X <= "<<(neuronGrp.xPos+actualWidth)<<" AND Y >= "<<neuronGrp.yPos<<" AND Y <= "<<(neuronGrp.yPos + actualLength)<<" AND Z = "<<neuronGrp.zPos;
00288 Result zLayerResult = query.store();
00289 if(zLayerResult.size() >0){
00290 layerConflict = true;
00291 cout<<"CONFLICT WITH EXISTING LAYERS"<<endl;
00292 progressDialog->reset();
00293 return -1;
00294 }
00295
00296
00297
00298 query.reset();
00299 query<<"INSERT INTO NeuronGroups (Name, NeuronGrpType, NeuronType, X, Y, Z, Width, Length, Spacing, TaskID) VALUES (\""<<neuronGrp.name<<"\", "<<neuronGrp.neuronGrpType<<", "<<neuronGrp.neuronType<<", "<<neuronGrp.xPos<<", "<<neuronGrp.yPos<<", "<<neuronGrp.zPos<<", "<<neuronGrp.width<<", "<<neuronGrp.length<<", "<<neuronGrp.spacing<<", -1)";
00300 query.execute();
00301
00302
00303 query.reset();
00304 query<<"SELECT MAX(NeuronGrpID) from NeuronGroups";
00305 Result grpIDResult = query.store();
00306 Row row(*(grpIDResult.begin()));
00307 unsigned int neuronGrpID = row.at(0);
00308
00309
00310
00311
00312 int neuronCount = 0;
00313 for(unsigned int i=0; i<neuronGrp.length; ++i){
00314 for(unsigned int j=0; j<neuronGrp.width; ++j){
00315 query.reset();
00316 query<<"INSERT INTO Neurons (X, Y, Z, NeuronGrpID) VALUES ("<<(neuronGrp.xPos + (j*neuronGrp.spacing))<<", "<<(neuronGrp.yPos + (i*neuronGrp.spacing))<<", "<<neuronGrp.zPos<<", "<<neuronGrpID<<")";
00317 query.execute();
00318 ++neuronCount;
00319 if(neuronCount % 100 == 0)
00320 progressDialog->setProgress(neuronCount);
00321 if(progressDialog->wasCancelled())
00322 break;
00323 }
00324 }
00325
00326
00327
00328 query.reset();
00329 query<<"SELECT ParameterTableName FROM NeuronTypes WHERE TypeID = "<<neuronGrp.neuronType;
00330 Result tableNameRes = query.store();
00331 Row tableNameRow (*tableNameRes.begin());
00332
00333
00334 query.reset();
00335 query<<"INSERT INTO "<<(std::string)tableNameRow["ParameterTableName"]<<" (NeuronGrpID) VALUES ("<<neuronGrpID<<")";
00336 query.execute();
00337
00338
00339 query.reset();
00340 query<<"INSERT INTO NoiseParameters (NeuronGrpID) VALUES ("<<neuronGrpID<<")";
00341 query.execute();
00342
00343
00344 progressDialog->cancel();
00345
00346 return neuronGrpID;
00347 }
00348
00349
00350
00351 int LayerManager::create3DRectangularLayer(const NeuronGroup &neuronGrp){
00352
00353 unsigned int depth = 5;
00354 double density = 0.5;
00355
00356
00357 unsigned int totalSteps = (unsigned int) ((double)neuronGrp.width * (double)neuronGrp.length * (double)depth * density);
00358 progressDialog->setTotalSteps(totalSteps);
00359
00360
00361 Query query = networkDBInterface->getQuery();
00362 query.reset();
00363 query<<"INSERT INTO NeuronGroups (Name, NeuronGrpType, NeuronType, X, Y, Z, Width, Length, Spacing, TaskID) VALUES (\""<<neuronGrp.name<<"\", "<<neuronGrp.neuronGrpType<<", "<<neuronGrp.neuronType<<", "<<neuronGrp.xPos<<", "<<neuronGrp.yPos<<", "<<neuronGrp.zPos<<", "<<neuronGrp.width<<", "<<neuronGrp.length<<", "<<neuronGrp.spacing<<", -1)";
00364 query.execute();
00365
00366
00367 query.reset();
00368 query<<"SELECT MAX(NeuronGrpID) from NeuronGroups";
00369 Result grpIDResult = query.store();
00370 Row row(*(grpIDResult.begin()));
00371 unsigned int neuronGrpID = Utilities::getUInt((std::string)row["MAX(NeuronGrpID)"]);
00372 unsigned int neuronCount = 0;
00373
00374
00375 for(int zPos = neuronGrp.zPos; zPos < (int)(neuronGrp.zPos + depth); ++zPos){
00376 for(int yPos = neuronGrp.yPos; yPos < (int)(neuronGrp.yPos + neuronGrp.length); ++yPos){
00377 for(int xPos = neuronGrp.xPos; xPos < (int)(neuronGrp.xPos + neuronGrp.width); ++xPos){
00378
00379 if(evaluatePlaceNeuronProbability(density)){
00380
00381 query.reset();
00382 query<<"SELECT NeuronID From Neurons WHERE X = "<<xPos<<" AND Y = "<<yPos<<" AND Z = "<<zPos;
00383 Result alreadyExistsResult = query.store();
00384 if(alreadyExistsResult.size() == 0){
00385
00386 query.reset();
00387 query<<"INSERT INTO Neurons (X, Y, Z, NeuronGrpID) VALUES ("<<xPos<<", "<<yPos<<", "<<zPos<<", "<<neuronGrpID<<")";
00388 query.execute();
00389 ++neuronCount;
00390 if(neuronCount % 100 == 0)
00391 progressDialog->setProgress(neuronCount);
00392 if(progressDialog->wasCancelled())
00393 break;
00394 }
00395 }
00396 }
00397 }
00398 }
00399
00400
00401 progressDialog->setProgress(totalSteps);
00402
00403
00404 if(neuronCount <= 0){
00405 cout<<"LayerManager: No neurons have been created, probably due to conflicts with existing neurons"<<endl;
00406 query.reset();
00407 query<<"DELETE FROM NeuronGroups WHERE NeuronGrpID = "<<neuronGrpID;
00408 query.execute();
00409 return -1;
00410 }
00411
00412
00413
00414
00415 query.reset();
00416 query<<"SELECT ParameterTableName FROM NeuronTypes WHERE TypeID = "<<neuronGrp.neuronType;
00417 Result tableNameRes = query.store();
00418 Row tableNameRow (*tableNameRes.begin());
00419
00420
00421 query.reset();
00422 query<<"INSERT INTO "<<(std::string)tableNameRow["ParameterTableName"]<<" (NeuronGrpID) VALUES ("<<neuronGrpID<<")";
00423 query.execute();
00424
00425
00426 query.reset();
00427 query<<"INSERT INTO NoiseParameters (NeuronGrpID) VALUES ("<<neuronGrpID<<")";
00428 query.execute();
00429
00430
00431 progressDialog->cancel();
00432
00433 return neuronGrpID;
00434 }
00435
00436
00437
00438
00439 int LayerManager::createSIMNOSComponentLayer(const NeuronGroup &neuronGrp){
00440
00441 int neuronGrpID = this->create2DRectangularLayer(neuronGrp);
00442
00443
00444 if(neuronGrpID < 0){
00445 cerr<<"LayerManager: FAILED TO CREATE LAYER WHILST CREATING SIMNOS COMPONENT LAYER"<<endl;
00446 return neuronGrpID;
00447 }
00448
00449
00450 Query deviceQuery = deviceDBInterface->getQuery();
00451 deviceQuery.reset();
00452 deviceQuery<<"SELECT ReceptorIDs FROM SIMNOSComponents WHERE ComponentID = "<<neuronGrp.componentID;
00453 Result simnosRes = deviceQuery.store();
00454 Row simnosRow (*simnosRes.begin());
00455
00456
00457
00458 QString receptorIDString = (std::string)simnosRow["ReceptorIDs"];
00459 if(receptorIDString.isEmpty()){
00460 cerr<<"LayerManager: NO RECEPTOR IDS FOR THIS COMPONENT"<<endl;
00461 return neuronGrpID;
00462 }
00463
00464
00465 unsigned int firstReceptorID = Utilities::getUInt(receptorIDString.section(',', 0, 0).ascii());
00466
00467 deviceQuery.reset();
00468 deviceQuery<<"SELECT DeviceDescription FROM SIMNOSSpikeReceptors WHERE ReceptorID = "<<firstReceptorID;
00469 Result receptorDevDesRes = deviceQuery.store();
00470 Row receptorDevDesRow(*receptorDevDesRes.begin());
00471
00472
00473 deviceQuery.reset();
00474 deviceQuery<<"SELECT Type FROM Devices WHERE Description = \""<<((std::string) receptorDevDesRow["DeviceDescription"])<<"\"";
00475 Result devTypeRes = deviceQuery.store();
00476 Row devTypeRow(*devTypeRes.begin());
00477 unsigned int deviceType = Utilities::getUInt((std::string)devTypeRow["Type"]);
00478
00479
00480
00481 if(DeviceTypes::isInputDevice(deviceType))
00482 connectionWidget->createConnections(neuronGrp.deviceNeuronGrpID, neuronGrpID, neuronGrp.componentID, true);
00483 else
00484 connectionWidget->createConnections(neuronGrpID, neuronGrp.deviceNeuronGrpID, neuronGrp.componentID, false);
00485
00486
00487 return neuronGrpID;
00488 }
00489
00490
00491
00492
00493
00494 bool LayerManager::evaluatePlaceNeuronProbability(double density){
00495 int threshold = (int)(density * (double)RAND_MAX);
00496 if(rand() < threshold)
00497 return true;
00498 return false;
00499 }
00500
00501