/***************************************************************************
* InternalSpike.cpp *
* ------------------- *
* copyright : (C) 2009 by Jesus Garrido and Richard Carrillo *
* email : jgarrido@atc.ugr.es *
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "../../include/spike/InternalSpike.h"
#include "../../include/spike/Interconnection.h"
#include "../../include/spike/Neuron.h"
#include "../../include/spike/PropagatedSpike.h"
#include "../../include/neuron_model/VectorNeuronState.h"
#include "../../include/neuron_model/NeuronModel.h"
#include "../../include/neuron_model/EventDrivenNeuronModel.h"
#include "../../include/simulation/Simulation.h"
#include "../../include/simulation/EventQueue.h"
#include "../../include/communication/OutputSpikeDriver.h"
#include "../../include/learning_rules/LearningRule.h"
#include "../../include/spike/Neuron.h"
#include "../../include/openmp/openmp.h"
InternalSpike::InternalSpike():Spike() {
}
InternalSpike::InternalSpike(double NewTime, Neuron * NewSource): Spike(NewTime,NewSource){
}
InternalSpike::~InternalSpike(){
}
void InternalSpike::ProcessEvent(Simulation * CurrentSimulation, int RealTimeRestriction){
if(RealTimeRestriction<2){
Neuron * neuron=this->GetSource(); // source of the spike
if (neuron->GetNeuronModel()->GetModelType() == EVENT_DRIVEN_MODEL){
EventDrivenNeuronModel * Model = (EventDrivenNeuronModel *) neuron->GetNeuronModel();
if(!Model->DiscardSpike(this)){
// Add the spike to simulation spike counter
CurrentSimulation->IncrementTotalSpikeCounter(neuron->get_OpenMP_queue_index());
neuron->GetVectorNeuronState()->NewFiredSpike(neuron->GetIndex_VectorNeuronState());
// If it is a valid spike (not discard), generate the next spike in this cell.
InternalSpike * NextSpike = Model->GenerateNextSpike(this);
if (NextSpike!=0){
CurrentSimulation->GetQueue()->InsertEvent(NextSpike->GetSource()->get_OpenMP_queue_index(),NextSpike);
}
CurrentSimulation->WriteSpike(this);
CurrentSimulation->WriteState(neuron->GetVectorNeuronState()->GetLastUpdateTime(neuron->GetIndex_VectorNeuronState()), neuron);
// Generate the output activity
for(int i=0; i<NumberOfOpenMPQueues; i++){
if (neuron->IsOutputConnected(i)){
PropagatedSpike * spike = new PropagatedSpike(this->GetTime() + neuron->PropagationStructure->SynapseDelay[i][0], neuron, 0, neuron->PropagationStructure->NDifferentDelays[i], i);
if(i==neuron->get_OpenMP_queue_index()){
CurrentSimulation->GetQueue()->InsertEvent(i,spike);
}else{
CurrentSimulation->GetQueue()->InsertEventInBuffer(omp_get_thread_num(),i,spike);
}
}
}
if(neuron->GetInputNumberWithPostSynapticLearning()>0){
int i;
Interconnection * inter;
if(RealTimeRestriction<1){
for (int i=0; i<neuron->GetInputNumberWithPostSynapticLearning(); ++i){
inter = neuron->GetInputConnectionWithPostSynapticLearningAt(i);
inter->GetWeightChange_withPost()->ApplyPostSynapticSpike(inter,this->time);
}
}
}
}
} else { // Time-driven model (no check nor update needed
// Add the spike to simulation spike counter
CurrentSimulation->IncrementTotalSpikeCounter(neuron->get_OpenMP_queue_index());
CurrentSimulation->WriteSpike(this);
CurrentSimulation->WriteState(neuron->GetVectorNeuronState()->GetLastUpdateTime(neuron->GetIndex_VectorNeuronState()), neuron);
// Generate the output activity
for(int i=0; i<NumberOfOpenMPQueues; i++){
if (neuron->IsOutputConnected(i)){
PropagatedSpike * spike = new PropagatedSpike(this->GetTime() + neuron->PropagationStructure->SynapseDelay[i][0], neuron, 0, neuron->PropagationStructure->NDifferentDelays[i], i);
if(i==neuron->get_OpenMP_queue_index()){
CurrentSimulation->GetQueue()->InsertEvent(i,spike);
}else{
CurrentSimulation->GetQueue()->InsertEventInBuffer(omp_get_thread_num(),i,spike);
}
}
}
if(neuron->GetInputNumberWithPostSynapticLearning()>0){
int i;
Interconnection * inter;
if(RealTimeRestriction<1){
for (int i=0; i<neuron->GetInputNumberWithPostSynapticLearning(); ++i){
inter = neuron->GetInputConnectionWithPostSynapticLearningAt(i);
inter->GetWeightChange_withPost()->ApplyPostSynapticSpike(inter,this->time);
}
}
}
}
}
}
void InternalSpike::ProcessEvent(Simulation * CurrentSimulation){
Neuron * neuron=this->GetSource(); // source of the spike
if (neuron->GetNeuronModel()->GetModelType() == EVENT_DRIVEN_MODEL){
EventDrivenNeuronModel * Model = (EventDrivenNeuronModel *) neuron->GetNeuronModel();
if(!Model->DiscardSpike(this)){
// Add the spike to simulation spike counter
CurrentSimulation->IncrementTotalSpikeCounter(neuron->get_OpenMP_queue_index());
neuron->GetVectorNeuronState()->NewFiredSpike(neuron->GetIndex_VectorNeuronState());
// If it is a valid spike (not discard), generate the next spike in this cell.
InternalSpike * NextSpike = Model->GenerateNextSpike(this);
if (NextSpike!=0){
CurrentSimulation->GetQueue()->InsertEvent(NextSpike->GetSource()->get_OpenMP_queue_index(),NextSpike);
}
CurrentSimulation->WriteSpike(this);
CurrentSimulation->WriteState(neuron->GetVectorNeuronState()->GetLastUpdateTime(neuron->GetIndex_VectorNeuronState()), neuron);
// Generate the output activity
for(int i=0; i<NumberOfOpenMPQueues; i++){
if (neuron->IsOutputConnected(i)){
//double time=(1+int(this->GetTime()*1000))*0.001;
//PropagatedSpike * spike = new PropagatedSpike(time + neuron->PropagationStructure->SynapseDelay[i][0], neuron, 0, neuron->PropagationStructure->NDifferentDelays[i], i);
PropagatedSpike * spike = new PropagatedSpike(this->GetTime() + neuron->PropagationStructure->SynapseDelay[i][0], neuron, 0, neuron->PropagationStructure->NDifferentDelays[i], i);
if(i==neuron->get_OpenMP_queue_index()){
CurrentSimulation->GetQueue()->InsertEvent(i,spike);
}else{
CurrentSimulation->GetQueue()->InsertEventInBuffer(omp_get_thread_num(),i,spike);
}
}
}
if(neuron->GetInputNumberWithPostSynapticLearning()>0){
int i;
Interconnection * inter;
for (int i=0; i<neuron->GetInputNumberWithPostSynapticLearning(); ++i){
inter = neuron->GetInputConnectionWithPostSynapticLearningAt(i);
inter->GetWeightChange_withPost()->ApplyPostSynapticSpike(inter,this->time);
}
}
}
} else { // Time-driven model (no check nor update needed
// Add the spike to simulation spike counter
CurrentSimulation->IncrementTotalSpikeCounter(neuron->get_OpenMP_queue_index());
CurrentSimulation->WriteSpike(this);
CurrentSimulation->WriteState(neuron->GetVectorNeuronState()->GetLastUpdateTime(neuron->GetIndex_VectorNeuronState()), neuron);
// Generate the output activity
for(int i=0; i<NumberOfOpenMPQueues; i++){
if (neuron->IsOutputConnected(i)){
PropagatedSpike * spike = new PropagatedSpike(this->GetTime() + neuron->PropagationStructure->SynapseDelay[i][0], neuron, 0, neuron->PropagationStructure->NDifferentDelays[i], i);
if(i==neuron->get_OpenMP_queue_index()){
CurrentSimulation->GetQueue()->InsertEvent(i,spike);
}else{
CurrentSimulation->GetQueue()->InsertEventInBuffer(omp_get_thread_num(),i,spike);
}
}
}
if(neuron->GetInputNumberWithPostSynapticLearning()>0){
int i;
Interconnection * inter;
for (int i=0; i<neuron->GetInputNumberWithPostSynapticLearning(); ++i){
inter = neuron->GetInputConnectionWithPostSynapticLearningAt(i);
inter->GetWeightChange_withPost()->ApplyPostSynapticSpike(inter,this->time);
}
}
}
}
void InternalSpike::PrintType(){
cout<<"InternalSpike"<<endl;
}