Source code for emodelrunner.synapses.stimuli

"""Synapse Stimuli."""

# Copyright 2020-2022 Blue Brain Project / EPFL

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import random
from bluepyopt import ephys


[docs] class NrnNetStimStimulusCustom(ephys.stimuli.Stimulus): """Current stimulus based on current amplitude and time series. Attributes: total_duration (float): duration of run (ms) locations (list): synapse point processes locations to connect to interval (float): time between spikes (ms) number (int): average number of spikes start (float): most likely start time of first spike (ms) noise (float): fractional randomness (0 deterministic, 1 negexp interval distrubtion) connections (dict): contains simulator NetCon and NetStim so that they are persistent """ def __init__( self, locations=None, total_duration=None, interval=None, number=None, start=None, noise=0, ): """Constructor. Args: locations (list): synapse point processes locations to connect to total_duration (float): duration of run (ms) interval (float): time between spikes (ms) number (int): average number of spikes start (float): most likely start time of first spike (ms) noise (float): fractional randomness (0 deterministic, 1 negexp interval distrubtion) """ super().__init__() if total_duration is None: raise ValueError("NrnNetStimStimulus: Need to specify a total duration") self.total_duration = total_duration self.locations = locations self.interval = interval self.number = number self.start = start self.noise = noise self.connections = {}
[docs] def instantiate(self, sim=None, icell=None): """Instantiate stimuli and connections. Args: sim (bluepyopt.ephys.NrnSimulator): neuron simulator icell (neuron cell): cell instantiation in simulator """ if self.connections is None: self.connections = {} for location in self.locations: self.connections[location.name] = [] for synapse in location.instantiate(sim=sim, icell=icell): netstim = sim.neuron.h.NetStim() netstim.interval = ( synapse.interval if synapse.interval is not None else self.interval ) netstim.number = ( synapse.number if synapse.number is not None else self.number ) netstim.start = ( synapse.start if synapse.start is not None else self.start ) netstim.noise = ( synapse.noise if synapse.noise is not None else self.noise ) netcon = sim.neuron.h.NetCon( netstim, synapse.hsynapse, -30, synapse.delay, synapse.weight ) self.connections[location.name].append((netcon, netstim))
[docs] def destroy(self, sim=None): """Destroy stimulus. Args: sim (bluepyopt.ephys.NrnSimulator): neuron simulator """ # pylint: disable=unused-argument self.connections = None
def __str__(self): """String representation.""" # pylint: disable=consider-using-f-string return ( "Netstim at %s" % ",".join(location for location in self.locations) if self.locations is not None else "Netstim" )
[docs] class NrnVecStimStimulusCustom(ephys.stimuli.Stimulus): """Current stimulus based on stochastic current amplitude. Attributes: total_duration (float): time after which no synapses are allowed to fire (ms) locations (list): synapse point processes locations to connect to start (float): most likely start time of first spike (ms) seed (int): seed for random number generator vecstim_random (str): origin of the random nmb gener. can be "python" or "neuron" pre_spike_train (list): list of spike train. If None, will be generated by random numbers connections (dict): contains simulator NetCon and VecStim and time Vector so that they are persistent """ def __init__( self, locations=None, start=None, stop=None, seed=1, vecstim_random="python", pre_spike_train=None, ): """Constructor. Args: locations (list): synapse point processes locations to connect to start (float): most likely start time of first spike (ms) stop (float): time after which no synapses are allowed to fire (ms) seed (int): seed for random number generator vecstim_random (str): origin of the random nmb gener. can be "python" or "neuron" pre_spike_train (list): list of spike train. If None, will be generated by random numbers """ super().__init__() if stop is None: raise ValueError("NrnVecStimStimulus: Need to specify a stop time") # must be named total_duration because of ephys.protocols self.total_duration = stop self.locations = locations self.start = start self.seed = seed self.vecstim_random = vecstim_random self.pre_spike_train = pre_spike_train self.connections = {}
[docs] def instantiate(self, sim=None, icell=None): """Instantiate stimuli and connections. Args: sim (bluepyopt.ephys.NrnSimulator): neuron simulator icell (neuron cell): cell instantiation in simulator """ if self.connections is None: self.connections = {} if self.pre_spike_train is None: if self.vecstim_random == "python": random.seed(self.seed) else: rand = sim.neuron.h.Random(self.seed) rand.uniform(self.start, self.total_duration) for location in self.locations: self.connections[location.name] = [] for synapse in location.instantiate(sim=sim, icell=icell): # create spike_train if self.pre_spike_train is not None: spike_train = self.pre_spike_train else: if self.vecstim_random == "python": spike_train = [random.uniform(self.start, self.total_duration)] else: spike_train = [rand.repick()] t_vec = sim.neuron.h.Vector(spike_train) vecstim = sim.neuron.h.VecStim() vecstim.play(t_vec, sim.dt) netcon = sim.neuron.h.NetCon( vecstim, synapse.hsynapse, -30, synapse.delay, synapse.weight ) self.connections[location.name].append((netcon, vecstim, t_vec))
[docs] def destroy(self, sim=None): """Destroy stimulus. Args: sim (bluepyopt.ephys.NrnSimulator): neuron simulator """ # pylint: disable=unused-argument self.connections = None
def __str__(self): """String representation.""" # pylint: disable=consider-using-f-string return ( "Vecstim at %s" % ",".join(location for location in self.locations) if self.locations is not None else "Vecstim" )
[docs] class NetConSpikeDetector(ephys.stimuli.Stimulus): """Netcon linking output from pre-cell to post-cell's synapses. Attributes: total_duration (float): end time of connection (ms) locations (list): synapse point processes locations to connect to connections (dict): contains simulator NetCon so that they are persistent """ def __init__(self, total_duration=None, locations=None): """Constructor. Args: total_duration (float): end time of connection (ms) locations (list): synapse point processes locations to connect to """ self.total_duration = total_duration self.locations = locations self.connections = {}
[docs] def instantiate(self, sim, icell): """Instantiate connections. Args: sim (bluepyopt.ephys.NrnSimulator): neuron simulator icell (neuron cell): cell instantiation in simulator """ if self.connections is None: self.connections = {} for location in self.locations: self.connections[location.name] = [] for synapse in location.instantiate(sim=sim, icell=icell): # taken from bglibpy.cell.create_netcon_spikedetector # M. Hines magic to return a variable by reference to a python function netcon = sim.neuron.h.ref(None) icell.getCell().connect2target(synapse.hsynapse, netcon) netcon = netcon[0] netcon.weight[0] = synapse.weight netcon.delay = synapse.delay self.connections[location.name].append(netcon)
[docs] def destroy(self, sim=None): """Destroy stimulus. Args: sim (bluepyopt.ephys.NrnSimulator): neuron simulator """ # pylint: disable=unused-argument self.connections = None
def __str__(self): """String representation.""" # pylint: disable=consider-using-f-string return ( "NetconSpikeDetector at %s" % ",".join(location for location in self.locations) if self.locations is not None else "NetconSpikeDetector" )