Skip to content

Commit

Permalink
Merge pull request #812 from lucianopaz/master
Browse files Browse the repository at this point in the history
Record conductances or input currents from multisynapse models.
  • Loading branch information
heplesser committed Mar 14, 2018
2 parents 3dde08e + fb5210a commit 8de91ad
Show file tree
Hide file tree
Showing 18 changed files with 1,885 additions and 252 deletions.
101 changes: 88 additions & 13 deletions models/aeif_cond_alpha_multisynapse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,56 @@
#include "doubledatum.h"
#include "integerdatum.h"


namespace nest // template specialization must be placed in namespace
{

/* ----------------------------------------------------------------
* Recordables map
* ---------------------------------------------------------------- */

nest::RecordablesMap< nest::aeif_cond_alpha_multisynapse >
nest::aeif_cond_alpha_multisynapse::recordablesMap_;

namespace nest // template specialization must be placed in namespace
{
// Override the create() method with one call to RecordablesMap::insert_()
// for each quantity to be recorded.
template <>
void
RecordablesMap< aeif_cond_alpha_multisynapse >::create()
DynamicRecordablesMap< aeif_cond_alpha_multisynapse >::create(
aeif_cond_alpha_multisynapse& host )
{
// use standard names wherever you can for consistency!
insert_( names::V_m,
&aeif_cond_alpha_multisynapse::
get_y_elem_< aeif_cond_alpha_multisynapse::State_::V_M > );
insert( names::V_m,
host.get_data_access_functor( aeif_cond_alpha_multisynapse::State_::V_M ) );

insert( names::w,
host.get_data_access_functor( aeif_cond_alpha_multisynapse::State_::W ) );

host.insert_conductance_recordables();
}

Name
aeif_cond_alpha_multisynapse::get_g_receptor_name( size_t receptor )
{
std::stringstream receptor_name;
receptor_name << "g_" << receptor + 1;
return Name( receptor_name.str() );
}

void
aeif_cond_alpha_multisynapse::insert_conductance_recordables( size_t first )
{
for ( size_t receptor = first; receptor < P_.E_rev.size(); ++receptor )
{
size_t elem = aeif_cond_alpha_multisynapse::State_::G
+ receptor
* aeif_cond_alpha_multisynapse::State_::NUM_STATE_ELEMENTS_PER_RECEPTOR;
recordablesMap_.insert(
get_g_receptor_name( receptor ), this->get_data_access_functor( elem ) );
}
}

insert_( names::w,
&aeif_cond_alpha_multisynapse::
get_y_elem_< aeif_cond_alpha_multisynapse::State_::W > );
DataAccessFunctor< aeif_cond_alpha_multisynapse >
aeif_cond_alpha_multisynapse::get_data_access_functor( size_t elem )
{
return DataAccessFunctor< aeif_cond_alpha_multisynapse >( this, elem );
}

/* ----------------------------------------------------------------
Expand Down Expand Up @@ -377,7 +404,7 @@ aeif_cond_alpha_multisynapse::aeif_cond_alpha_multisynapse()
, S_( P_ )
, B_( *this )
{
recordablesMap_.create();
recordablesMap_.create( *this );
}

aeif_cond_alpha_multisynapse::aeif_cond_alpha_multisynapse(
Expand All @@ -387,6 +414,7 @@ aeif_cond_alpha_multisynapse::aeif_cond_alpha_multisynapse(
, S_( n.S_ )
, B_( n.B_, *this )
{
recordablesMap_.create( *this );
}

aeif_cond_alpha_multisynapse::~aeif_cond_alpha_multisynapse()
Expand Down Expand Up @@ -647,6 +675,53 @@ aeif_cond_alpha_multisynapse::handle( DataLoggingRequest& e )
B_.logger_.handle( e );
}

void
aeif_cond_alpha_multisynapse::set_status( const DictionaryDatum& d )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
ptmp.set( d ); // throws if BadProperty
State_ stmp = S_; // temporary copy in case of errors
stmp.set( d ); // throws if BadProperty

// We now know that (ptmp, stmp) are consistent. We do not
// write them back to (P_, S_) before we are also sure that
// the properties to be set in the parent class are internally
// consistent.
Archiving_Node::set_status( d );

/*
* Here is where we must update the recordablesMap_ if new receptors
* are added!
*/
DynamicRecordablesMap< aeif_cond_alpha_multisynapse > rtmp =
recordablesMap_; // temporary copy in case of errors
if ( ptmp.E_rev.size() > P_.E_rev.size() ) // Number of receptors increased
{
for ( size_t receptor = P_.E_rev.size(); receptor < ptmp.E_rev.size();
++receptor )
{
size_t elem = aeif_cond_alpha_multisynapse::State_::G
+ receptor * aeif_cond_alpha_multisynapse::State_::
NUM_STATE_ELEMENTS_PER_RECEPTOR;
rtmp.insert(
get_g_receptor_name( receptor ), get_data_access_functor( elem ) );
}
}
else if ( ptmp.E_rev.size() < P_.E_rev.size() )
{ // Number of receptors decreased
for ( size_t receptor = ptmp.E_rev.size(); receptor < P_.E_rev.size();
++receptor )
{
rtmp.erase( get_g_receptor_name( receptor ) );
}
}

// if we get here, temporaries contain consistent set of properties
P_ = ptmp;
S_ = stmp;
recordablesMap_ = rtmp;
}

} // namespace nest

#endif // HAVE_GSL
58 changes: 24 additions & 34 deletions models/aeif_cond_alpha_multisynapse.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

// Generated includes:
#include "config.h"
#include <sstream>

#ifdef HAVE_GSL

Expand Down Expand Up @@ -212,9 +213,10 @@ class aeif_cond_alpha_multisynapse : public Archiving_Node
void calibrate();
void update( Time const&, const long, const long );

// The next two classes need to be friends to access the State_ class/member
friend class RecordablesMap< aeif_cond_alpha_multisynapse >;
friend class UniversalDataLogger< aeif_cond_alpha_multisynapse >;
// The next three classes need to be friends to access the State_ class/member
friend class DynamicRecordablesMap< aeif_cond_alpha_multisynapse >;
friend class DynamicUniversalDataLogger< aeif_cond_alpha_multisynapse >;
friend class DataAccessFunctor< aeif_cond_alpha_multisynapse >;

// ----------------------------------------------------------------

Expand Down Expand Up @@ -312,7 +314,7 @@ class aeif_cond_alpha_multisynapse : public Archiving_Node
Buffers_( const Buffers_&, aeif_cond_alpha_multisynapse& );

//! Logger for all analog data
UniversalDataLogger< aeif_cond_alpha_multisynapse > logger_;
DynamicUniversalDataLogger< aeif_cond_alpha_multisynapse > logger_;

/** buffers and sums up incoming spikes/currents */
std::vector< RingBuffer > spikes_;
Expand Down Expand Up @@ -361,16 +363,6 @@ class aeif_cond_alpha_multisynapse : public Archiving_Node
unsigned int refractory_counts_;
};

// Access functions for UniversalDataLogger -------------------------------

//! Read out state vector elements, used by UniversalDataLogger
template < State_::StateVecElems elem >
double
get_y_elem_() const
{
return S_.y_[ elem ];
}

// Data members -----------------------------------------------------------

/**
Expand All @@ -386,8 +378,25 @@ class aeif_cond_alpha_multisynapse : public Archiving_Node
Buffers_ B_;
/** @} */

// Access functions for UniversalDataLogger -------------------------------

//! Mapping of recordables names to access functions
static RecordablesMap< aeif_cond_alpha_multisynapse > recordablesMap_;
DynamicRecordablesMap< aeif_cond_alpha_multisynapse > recordablesMap_;

// Data Access Functor getter
DataAccessFunctor< aeif_cond_alpha_multisynapse > get_data_access_functor(
size_t elem );
inline double
get_state_element( size_t elem )
{
return S_.y_[ elem ];
};

// Utility function that inserts the synaptic conductances to the
// recordables map

Name get_g_receptor_name( size_t receptor );
void insert_conductance_recordables( size_t first = 0 );
};

inline port
Expand Down Expand Up @@ -434,25 +443,6 @@ aeif_cond_alpha_multisynapse::get_status( DictionaryDatum& d ) const
( *d )[ names::recordables ] = recordablesMap_.get_list();
}

inline void
aeif_cond_alpha_multisynapse::set_status( const DictionaryDatum& d )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
ptmp.set( d ); // throws if BadProperty
State_ stmp = S_; // temporary copy in case of errors
stmp.set( d ); // throws if BadProperty

// We now know that (ptmp, stmp) are consistent. We do not
// write them back to (P_, S_) before we are also sure that
// the properties to be set in the parent class are internally
// consistent.
Archiving_Node::set_status( d );

// if we get here, temporaries contain consistent set of properties
P_ = ptmp;
S_ = stmp;
}

} // namespace

#endif // HAVE_GSL
Expand Down
104 changes: 89 additions & 15 deletions models/aeif_cond_beta_multisynapse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,55 @@
#include "doubledatum.h"
#include "integerdatum.h"

namespace nest // template specialization must be placed in namespace
{

/* ----------------------------------------------------------------
* Recordables map
* ---------------------------------------------------------------- */

nest::RecordablesMap< nest::aeif_cond_beta_multisynapse >
nest::aeif_cond_beta_multisynapse::recordablesMap_;

namespace nest // template specialization must be placed in namespace
{
// Override the create() method with one call to RecordablesMap::insert_()
// for each quantity to be recorded.
// Override the create() method with one call to
// DynamicRecordablesMap::insert() for each quantity to be recorded.
template <>
void
RecordablesMap< aeif_cond_beta_multisynapse >::create()
DynamicRecordablesMap< aeif_cond_beta_multisynapse >::create(
aeif_cond_beta_multisynapse& host )
{
// use standard names wherever you can for consistency!
insert_( names::V_m,
&aeif_cond_beta_multisynapse::
get_y_elem_< aeif_cond_beta_multisynapse::State_::V_M > );
insert( names::V_m,
host.get_data_access_functor( aeif_cond_beta_multisynapse::State_::V_M ) );

insert( names::w,
host.get_data_access_functor( aeif_cond_beta_multisynapse::State_::W ) );

host.insert_conductance_recordables();
}

Name
aeif_cond_beta_multisynapse::get_g_receptor_name( size_t receptor )
{
std::stringstream receptor_name;
receptor_name << "g_" << receptor + 1;
return Name( receptor_name.str() );
}

insert_( names::w,
&aeif_cond_beta_multisynapse::
get_y_elem_< aeif_cond_beta_multisynapse::State_::W > );
void
aeif_cond_beta_multisynapse::insert_conductance_recordables( size_t first )
{
for ( size_t receptor = first; receptor < P_.E_rev.size(); ++receptor )
{
size_t elem = aeif_cond_beta_multisynapse::State_::G
+ receptor
* aeif_cond_beta_multisynapse::State_::NUM_STATE_ELEMENTS_PER_RECEPTOR;
recordablesMap_.insert(
get_g_receptor_name( receptor ), this->get_data_access_functor( elem ) );
}
}

DataAccessFunctor< aeif_cond_beta_multisynapse >
aeif_cond_beta_multisynapse::get_data_access_functor( size_t elem )
{
return DataAccessFunctor< aeif_cond_beta_multisynapse >( this, elem );
}

/* ----------------------------------------------------------------
Expand Down Expand Up @@ -388,7 +414,7 @@ aeif_cond_beta_multisynapse::aeif_cond_beta_multisynapse()
, S_( P_ )
, B_( *this )
{
recordablesMap_.create();
recordablesMap_.create( *this );
}

aeif_cond_beta_multisynapse::aeif_cond_beta_multisynapse(
Expand All @@ -398,6 +424,7 @@ aeif_cond_beta_multisynapse::aeif_cond_beta_multisynapse(
, S_( n.S_ )
, B_( n.B_, *this )
{
recordablesMap_.create( *this );
}

aeif_cond_beta_multisynapse::~aeif_cond_beta_multisynapse()
Expand Down Expand Up @@ -686,6 +713,53 @@ aeif_cond_beta_multisynapse::handle( DataLoggingRequest& e )
B_.logger_.handle( e );
}

void
aeif_cond_beta_multisynapse::set_status( const DictionaryDatum& d )
{
Parameters_ ptmp = P_; // temporary copy in case of errors
ptmp.set( d ); // throws if BadProperty
State_ stmp = S_; // temporary copy in case of errors
stmp.set( d ); // throws if BadProperty

// We now know that (ptmp, stmp) are consistent. We do not
// write them back to (P_, S_) before we are also sure that
// the properties to be set in the parent class are internally
// consistent.
Archiving_Node::set_status( d );

/*
* Here is where we must update the recordablesMap_ if new receptors
* are added!
*/
DynamicRecordablesMap< aeif_cond_beta_multisynapse > rtmp =
recordablesMap_; // temporary copy in case of errors
if ( ptmp.E_rev.size() > P_.E_rev.size() ) // Number of receptors increased
{
for ( size_t receptor = P_.E_rev.size(); receptor < ptmp.E_rev.size();
++receptor )
{
size_t elem = aeif_cond_beta_multisynapse::State_::G
+ receptor * aeif_cond_beta_multisynapse::State_::
NUM_STATE_ELEMENTS_PER_RECEPTOR;
rtmp.insert(
get_g_receptor_name( receptor ), get_data_access_functor( elem ) );
}
}
else if ( ptmp.E_rev.size() < P_.E_rev.size() )
{ // Number of receptors decreased
for ( size_t receptor = ptmp.E_rev.size(); receptor < P_.E_rev.size();
++receptor )
{
rtmp.erase( get_g_receptor_name( receptor ) );
}
}

// if we get here, temporaries contain consistent set of properties
P_ = ptmp;
S_ = stmp;
recordablesMap_ = rtmp;
}

} // namespace nest

#endif // HAVE_GSL
Loading

0 comments on commit 8de91ad

Please sign in to comment.