00001 #ifndef Synapse_H_
00002 #define Synapse_H_
00003
00004 #include "EvSimObject.h"
00005 #include "SpikeResponse.h"
00006 #include "Neuron.h"
00007 #include "EvSimNetwork.h"
00008 #include "SimException.h"
00009
00010 #ifndef SWIG
00011
00012 #include <iostream>
00013 using std::cerr; using std::endl;
00014
00015 #endif
00016
00018 class SynapseFactory : public virtual EvSimObjectFactory {
00019 public:
00020
00021 virtual ~SynapseFactory() {};
00022
00023 virtual SpikeResponse *createSpikeResponseObject() const {return 0;};
00024 virtual SpikeResponse *createBackpropAPResponseObject() const {return 0;};
00025
00026 virtual bool usesSharedPSResponse() const {return false;};
00027
00028 virtual bool usesSharedBackpropAPResponse() const {return false;};
00029
00030 virtual bool managesDelay() const {
00031 return false;
00032 }
00033
00034 virtual Time getManagedDelay() const {
00035 return 0;
00036 }
00037
00038 virtual Time getBackpropAPDelay() const {
00039 return 0;
00040 }
00041
00042 };
00043
00045 class Synapse : public EvSimObject, public SynapseFactory {
00046 public:
00047
00048 double getPSR() {return psr;};
00049
00050 virtual void setBackpropAPResponse(SpikeResponse *bap_response) {};
00051
00052 virtual void setPostSynResponse(SpikeResponse *response) {};
00053
00054 virtual bool needsPostSynResponse() {return true;};
00055
00056 virtual bool needsBackpropAPResponse() {return true;};
00057
00058 virtual bool isPlastic() { return false; };
00059
00060 virtual bool isActive() {return false;}
00061
00062
00063 virtual void postMountAsMountedObj(EvSimNetwork &net, EvSimObject::ID self, EvSimObject::ID mountpoint)
00064 {
00065 mountToNeuron(net,self, mountpoint);
00066 }
00067
00068 virtual ~Synapse();
00069
00070 protected:
00071
00072 void updatePSR(double new_psr, Time) {
00073 psr = new_psr;
00074 }
00075
00076 void resetPSRs() {
00077 psr = 0;
00078 }
00079
00080
00081 Neuron * mountToNeuron(EvSimNetwork &net, EvSimObject::ID &self, EvSimObject::ID &nrn) {
00082 Neuron *nrn_obj = dynamic_cast<Neuron *>(net.getObject(nrn));
00083 if (!nrn_obj) {
00084 throw evesim::ConstructionException("ActiveSynapse::mountToNeuron",
00085 "Can not mount a Synapse object. The mountpoint must be of 'Neuron' type.");
00086 }
00087 if (nrn_obj->requiresActiveSynapse() && !isActive()) {
00088 throw evesim::ConstructionException("ActiveSynapse::mountToNeuron",
00089 "Can not mount the Synapse object which is not active. The mountpoint Neuron requires an active synapse.");
00090 }
00091
00092 update_id_t update_id = nrn_obj->registerInputSynapse(dynamic_cast<EvSimObject *>(this));
00093 net.causalUpdateLink(self, nrn, update_id);
00094 return nrn_obj;
00095 }
00096
00097 double psr;
00098 };
00099
00100
00102
00106 class ActiveSynapse : public Synapse {
00107 public:
00108
00109 ~ActiveSynapse();
00110
00111 virtual void postMountAsMountedObj(EvSimNetwork &net, EvSimObject::ID self, EvSimObject::ID mountpoint) {
00112 target_nrn = mountToNeuron(net, self, mountpoint);
00113 }
00114
00115 virtual bool isActive() {
00116 return true;
00117 }
00118
00119
00120 protected:
00121 Neuron *target_nrn;
00122
00123 void updatePSR(double new_psr, Time time) {
00124 psr_old = psr;
00125 psr = new_psr;
00126 target_nrn->updatePSR(psr, psr - psr_old, time);
00127 }
00128
00129 void resetPSRs() {
00130 psr = psr_old = 0;
00131 }
00132
00133 double psr_old;
00134 };
00135
00136
00137
00138 #endif