/*
* volume_transmitter.cpp
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST 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 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "exceptions.h"
#include "volume_transmitter.h"
#include "network.h"
#include "dict.h"
#include "integerdatum.h"
#include "doubledatum.h"
#include "dictutils.h"
#include "arraydatum.h"
#include "connector.h"
#include "spikecounter.h"
#include <numeric>
/* ----------------------------------------------------------------
* Default constructor defining default parameters
* ---------------------------------------------------------------- */
nest::volume_transmitter::Parameters_::Parameters_()
: deliver_interval_(1) // in steps of mindelay
{}
/* ----------------------------------------------------------------
* Parameter and state extractions and manipulation functions
* ---------------------------------------------------------------- */
void nest::volume_transmitter::Parameters_::get(DictionaryDatum & d) const
{
def<long_t>(d, "deliver_interval", deliver_interval_);
}
void::nest::volume_transmitter::Parameters_::set(const DictionaryDatum & d)
{
updateValue<long_t>(d, "deliver_interval", deliver_interval_);
}
/* ----------------------------------------------------------------
* Default and copy constructor for volume transmitter
* ---------------------------------------------------------------- */
nest::volume_transmitter::volume_transmitter()
: Archiving_Node(),
P_()
{}
nest::volume_transmitter::volume_transmitter(const volume_transmitter & n)
: Archiving_Node(n),
P_(n.P_)
{}
void nest::volume_transmitter::init_state_(const Node &)
{}
void nest::volume_transmitter::init_buffers_()
{
B_.neuromodulatory_spikes_.clear();
B_.spikecounter_.clear();
B_.spikecounter_.push_back(spikecounter(0.0, 0.0)); // insert pseudo last dopa spike at t = 0.0
Archiving_Node::clear_history();
}
void nest::volume_transmitter::register_connector(Connector& c)
{
B_.targets_.push_back(&c);
}
void nest::volume_transmitter::calibrate()
{
// +1 as pseudo dopa spike at t_trig is inserted after trigger_update_weight
B_.spikecounter_.reserve(Scheduler::get_min_delay()*P_.deliver_interval_+1);
}
void nest::volume_transmitter::update(const Time&, const long_t from, const long_t to)
{
// spikes that arrive in this time slice are stored in spikecounter_
double_t t_spike;
double_t multiplicity;
for ( long_t lag = from; lag < to; ++lag )
{
multiplicity = B_.neuromodulatory_spikes_.get_value(lag);
if ( multiplicity > 0 )
{
t_spike = Time(Time::step(network()->get_slice_origin().get_steps() + lag + 1)).get_ms();
B_.spikecounter_.push_back(spikecounter(t_spike, multiplicity));
}
}
// all spikes stored in spikecounter_ are delivered to the target synapses
if ( ( network()->get_slice_origin().get_steps() + to ) % ( P_.deliver_interval_ * Scheduler::get_min_delay() ) == 0 )
{
double_t t_trig = Time(Time::step(network()->get_slice_origin().get_steps() + to)).get_ms();
if ( !B_.spikecounter_.empty() )
for ( index i = 0; i < B_.targets_.size(); ++i )
B_.targets_[i]->trigger_update_weight(B_.spikecounter_, t_trig);
// clear spikecounter
B_.spikecounter_.clear();
// as with trigger_update_weight dopamine trace has been updated to t_trig, insert pseudo last dopa spike at t_trig
B_.spikecounter_.push_back(spikecounter(t_trig, 0.0));
}
}
void nest::volume_transmitter::handle(SpikeEvent& e)
{
B_.neuromodulatory_spikes_.add_value(e.get_rel_delivery_steps(network()->get_slice_origin()),
static_cast<double_t>(e.get_multiplicity()));
}