SpikeStream Nemo Plugin  0.2
NemoLoader.cpp
Go to the documentation of this file.
00001 //SpikeStream includes
00002 #include "Globals.h"
00003 #include "NemoLoader.h"
00004 #include "NeuronGroup.h"
00005 #include "SpikeStreamSimulationException.h"
00006 #include "SpikeStreamIOException.h"
00007 #include "Util.h"
00008 using namespace spikestream;
00009 
00010 //Qt includes
00011 #include <QDebug>
00012 
00013 //Other includes
00014 #include <vector>
00015 #include <iostream>
00016 using namespace std;
00017 
00018 // Outputs verbose debugging behaviour about the loading of the network.
00019 //#define DEBUG_NEURONS
00020 //#define DEBUG_SYNAPSES
00021 
00022 //Neuron type IDs in database. FIXME: WOULD BE BETTER TO USE THE NAME
00023 #define IZHIKEVICH_EXCITATORY_NEURON_ID 1
00024 #define IZHIKEVICH_INHIBITORY_NEURON_ID 2
00025 
00026 
00028 NemoLoader::NemoLoader(){
00029         //Open up log file if logging is enabled
00030         #if defined(DEBUG_NEURONS) || defined(DEBUG_SYNAPSES)
00031                 logFile = new QFile(Globals::getSpikeStreamRoot() + "/log/NemoLoader.log");
00032                 if(logFile->open(QFile::WriteOnly | QFile::Truncate))
00033                         logTextStream = new QTextStream(logFile);
00034                 else{
00035                         throw SpikeStreamIOException("Cannot open log file for NemoLoader.");
00036                 }
00037         #endif//DEBUG_NEURONS || DEBUG_SYNAPSES
00038 }
00039 
00040 
00042 NemoLoader::~NemoLoader(){
00043         //Clean up log file if logging is enabled
00044         #if defined(DEBUG_NEURONS) || defined(DEBUG_SYNAPSES)
00045                 logFile->close();
00046                 delete logFile;
00047                 delete logTextStream;
00048         #endif//DEBUG_NEURONS || DEBUG_SYNAPSES
00049 }
00050 
00051 
00052 /*----------------------------------------------------------*/
00053 /*-----                 PUBLIC METHODS                 -----*/
00054 /*----------------------------------------------------------*/
00055 
00057 nemo_network_t NemoLoader::buildNemoNetwork(Network* network, QHash<unsigned, synapse_id*>& volatileConGrpMap, const bool* stop){
00058         //Initialize the nemo network
00059         nemo_network_t nemoNet = nemo_new_network();
00060 
00061         //Check that list of volatie connection is empty
00062         if(!volatileConGrpMap.isEmpty())
00063                 throw SpikeStreamSimulationException("Volatile connection group map should have been cleared when simulation was unloaded.");
00064 
00065         //Create the random number generator (from: nemo/examples/random1k.cpp)
00066         rng_t rng;
00067         urng_t ranNumGen( rng, boost::uniform_real<double>(0, 1) );//Constructor of the random number generator
00068 
00069         //Calculate progress
00070         QList<NeuronGroup*> neurGrpList = network->getNeuronGroups();
00071         QList<ConnectionGroup*> conGrpList = network->getConnectionGroups();
00072         int totalSteps = neurGrpList.size() + conGrpList.size();
00073         int stepsCompleted = 0;
00074 
00075         //Add the neuron groups
00076         for(int i=0; i<neurGrpList.size() && !*stop; ++i){
00077                 unsigned int neurTypeID = neurGrpList.at(i)->getInfo().getNeuronTypeID();
00078                 if(neurTypeID == IZHIKEVICH_EXCITATORY_NEURON_ID)
00079                         addExcitatoryNeuronGroup(neurGrpList.at(i), nemoNet, ranNumGen);
00080                 else if(neurTypeID == IZHIKEVICH_INHIBITORY_NEURON_ID)
00081                         addInhibitoryNeuronGroup(neurGrpList.at(i), nemoNet, ranNumGen);
00082                 else
00083                         throw SpikeStreamSimulationException("Neuron group type " + QString::number(neurTypeID) + " is not supported by Nemo");
00084 
00085                 //Update progress
00086                 ++stepsCompleted;
00087                 emit progress(stepsCompleted, totalSteps);
00088         }
00089 
00090         //Add the connection groups that are not disabled */
00091         for(int i=0; i<conGrpList.size() && !*stop; ++i){
00092                 if(conGrpList.at(i)->getParameter("Disable") == 0.0)
00093                         addConnectionGroup(conGrpList.at(i), nemoNet, volatileConGrpMap);
00094 
00095                 //Update progress
00096                 ++stepsCompleted;
00097                 emit progress(stepsCompleted, totalSteps);
00098         }
00099 
00100         //Return the new network
00101         return nemoNet;
00102 }
00103 
00104 
00105 /*----------------------------------------------------------*/
00106 /*-----                PRIVATE METHODS                 -----*/
00107 /*----------------------------------------------------------*/
00108 
00110 void NemoLoader::addConnectionGroup(ConnectionGroup* conGroup, nemo_network_t nemoNetwork, QHash<unsigned, synapse_id*>& volatileConGrpMap){
00111         //Extract parameters
00112         unsigned char learning = 0;
00113         synapse_id* synapseIDArray = NULL;
00114         if(conGroup->getParameter("Learning") != 0.0){
00115                 learning = 1;
00116                 synapseIDArray = new synapse_id[conGroup->size()];
00117                 volatileConGrpMap[conGroup->getID()] = synapseIDArray;
00118         }
00119         double weightFactor = conGroup->getParameter("weight_factor");
00120 
00121         //Work through each connection
00122         unsigned conCntr = 0;
00123         nemo_status_t result;
00124         synapse_id newNemoSynapseID;
00125         ConnectionIterator endConGrp = conGroup->end();
00126         for(ConnectionIterator conIter = conGroup->begin(); conIter != endConGrp; ++conIter){
00127                 //Add synapse
00128                 result = nemo_add_synapse(nemoNetwork, conIter->getFromNeuronID(), conIter->getToNeuronID(), conIter->getDelay(), weightFactor * conIter->getWeight(), learning, &newNemoSynapseID);
00129                 #ifdef DEBUG_SYNAPSES
00130                         (*logTextStream)<<"nemo_add_synapse(nemoNetwork, "<<conIter->getFromNeuronID()<<", "<<conIter->getToNeuronID()<<", "<<conIter->getDelay()<<", "<<(weightFactor * conIter->getWeight())<<", "<<learning<<", "<<newNemoSynapseID<<");"<<endl;
00131                 #endif//DEBUG_SYNAPSES
00132                 if(result != NEMO_OK)
00133                         throw SpikeStreamException("Error code returned from Nemo when adding synapse." + QString(nemo_strerror()));
00134 
00135                 //Store link between connection group ID and map linking nemo connection IDs and SpikeStream connection IDs
00136                 if(learning){
00137                         synapseIDArray[conCntr] = newNemoSynapseID;
00138                         ++conCntr;
00139                 }
00140         }
00141 }
00142 
00143 
00145 void NemoLoader::addExcitatoryNeuronGroup(NeuronGroup* neuronGroup, nemo_network_t nemoNetwork, urng_t& ranNumGen){
00146         //Extract parameters
00147         float a = neuronGroup->getParameter("a");
00148         float b = neuronGroup->getParameter("b");
00149         float c_1 = neuronGroup->getParameter("c_1");
00150         float d_1 = neuronGroup->getParameter("d_1");
00151         float d_2 = neuronGroup->getParameter("d_2");
00152         float v = neuronGroup->getParameter("v");
00153         float sigma = neuronGroup->getParameter("sigma");
00154 
00155         //Add neurons to the network
00156         float c, d, u, rand1, rand2;
00157         for(NeuronMap::iterator iter = neuronGroup->begin(); iter != neuronGroup->end(); ++iter){
00158                 //Calculate random parameters
00159                 rand1 = ranNumGen();
00160                 rand2 = ranNumGen();
00161                 c = v + c_1 * rand1 * rand1;
00162                 d = d_1 - d_2 * rand2 * rand2;
00163                 u = b * v;
00164 
00165                 //Add the neuron to the network
00166                 #ifdef DEBUG_NEURONS
00167                         (*logTextStream)<<"nemo_add_neuron(nemoNetwork, "<<iter.value()->getID()<<", "<<a<<", "<<b<<", "<<c<<", "<<d<<", "<<u<<", "<<v<<", "<<sigma<<");"<<endl;
00168                 #endif//DEBUG_NEURONS
00169                 nemo_status_t result = nemo_add_neuron_iz(nemoNetwork, iter.value()->getID(), a, b, c, d, u, v, sigma);
00170                 if(result != NEMO_OK)
00171                         throw SpikeStreamException("Error code returned from Nemo when adding neuron." + QString(nemo_strerror()));
00172         }
00173 }
00174 
00175 
00177 void NemoLoader::addInhibitoryNeuronGroup(NeuronGroup* neuronGroup, nemo_network_t nemoNetwork, urng_t& ranNumGen){
00178         //Extract parameters
00179         float a_1 = neuronGroup->getParameter("a_1");
00180         float a_2 = neuronGroup->getParameter("a_2");
00181         float b_1 = neuronGroup->getParameter("b_1");
00182         float b_2 = neuronGroup->getParameter("b_2");
00183         float d = neuronGroup->getParameter("d");
00184         float v = neuronGroup->getParameter("v");
00185         float sigma = neuronGroup->getParameter("sigma");
00186 
00187         //Add neurons to the network
00188         float a, b, u, rand1, rand2;
00189         for(NeuronMap::iterator iter = neuronGroup->begin(); iter != neuronGroup->end(); ++iter){
00190                 //Calculate random parameters
00191                 rand1 = ranNumGen();
00192                 rand2 = ranNumGen();
00193                 a = a_1 + a_2 * rand1;
00194                 b = b_1 - b_2 * rand2;
00195                 u = b * v;
00196 
00197                 //Add neuron to the network
00198                 #ifdef DEBUG_NEURONS
00199                         (*logTextStream)<<"nemo_add_neuron(nemoNetwork, "<<iter.value()->getID()<<", "<<a<<", "<<b<<", "<<v<<", "<<d<<", "<<u<<", "<<v<<", "<<sigma<<");"<<endl;
00200                 #endif//DEBUG_NEURONS
00201                 nemo_status_t result = nemo_add_neuron_iz(nemoNetwork, iter.value()->getID(), a, b, v, d, u, v, sigma);
00202                 if(result != NEMO_OK)
00203                         throw SpikeStreamException("Error code returned from Nemo when adding neuron." + QString(nemo_strerror()));
00204         }
00205 }
00206 
00208 void NemoLoader::printConnection(unsigned source, unsigned targets[], unsigned delays[], float weights[], unsigned char is_plastic[], size_t length){
00209         for(size_t i=0; i<length; ++i){
00210                 if(is_plastic[i])
00211                         cout<<"Connection from: "<<source<<"; to: "<<targets[i]<<"; delay: "<<delays[i]<<"; weight: "<<weights[i]<<" is plastic: true"<<endl;
00212                 else
00213                         cout<<"Connection from: "<<source<<"; to: "<<targets[i]<<"; delay: "<<delays[i]<<"; weight: "<<weights[i]<<" is plastic: false"<<endl;
00214         }
00215 }
00216 
00217 
 All Classes Files Functions Variables Typedefs Defines