Source code for teili.building_blocks.chain

# -*- coding: utf-8 -*-
"""This is a simple syn-fire chain of neurons

Attributes:
    chain_params (dict): Dictionary of default parameters for syn-fire
        chain

Todo:
    * Update docstrings
        Not all Description of attributes are set. Please provide meaningful
            docstrings

Example:
    To use the syn-fire chain building block in your simulation you need
    to create an object of the class by:

    >>> from teili.building_blocks.chain import Chain
    >>> my_bb = Chain(name='my_chain')

    If you want to change the underlying neuron and synapse model you need to
    provide a different equation_builder class:

    >>> from teili.models.neuron_models import DPI
    >>> from teili.models.synapse_models import DPISyn
    >>> my_bb = Chain(name='my_chain',
                      neuron_eq_builder=DPI,
                      synapse_eq_builder=DPISyn)

    If you want to change the default parameters of your building block
    you need to define a dictionary, which you pass to the building_block

    >>> chain_params = {'num_chains': 4,
                        'num_neurons_per_chain': 15,
                        'synChaCha1e_weight': 4,
                        'synInpCha1e_weight': 1,
                        'gChaGroup_refP': 1 * ms}
    >>> my_bb = Chain(name='my_chain', block_params=chain_params)
"""
# @Author: Alpha Renner
# @Date:   2018-06-01 18:45:19

import os
import numpy as np
from datetime import datetime

from brian2 import ms, SpikeGeneratorGroup, SpikeMonitor

from matplotlib.pyplot import xlim, figure, xlabel, \
    ylabel, plot, subplot

from teili.models.neuron_models import ExpAdaptIF
from teili.models.synapse_models import ReversalSynV

from teili.building_blocks.building_block import BuildingBlock
from teili.core.groups import Neurons, Connections
#=========================================================================


chain_params = {'num_chains': 4,
                'num_neurons_per_chain': 15,
                'synChaCha1e_weight': 4,
                'synInpCha1e_weight': 1,
                'gChaGroup_refP': 1 * ms}


[docs]class Chain(BuildingBlock): """This is a simple syn-fire chain of neurons. Attributes: gChaGroup_refP (str, optional): Parameter specifying the refractory period. group (dict): List of keys of neuron population. inputGroup (SpikeGenerator): SpikeGenerator obj. to stimulate syn-fire chain. num_chains (int, optional): Number of chains to generate. num_neurons_per_chain (int, optional): Number of neurons within one chain. spikemon_cha (brian2 SpikeMonitor obj.): Description. spikemon_cha_inp (brian2 SpikeMonitor obj.): Description. standalone_params (dict): Keys for all standalone parameters necessary for cpp code generation. synapse (TYPE): Description. synChaCha1e_weight (int, optional): Parameter specifying the recurrent weight. synInpCha1e_weight (int, optional): Parameter specifying the input weight. """ def __init__(self, name, neuron_eq_builder=ExpAdaptIF, synapse_eq_builder=ReversalSynV, block_params=chain_params, num_inputs=1, verbose=False): """Summary Args: name (str, required): Base name for building block. neuron_eq_builder (teili.models.builder obj, optional): Neuron equation builder object. synapse_eq_builder (teili.models.builder obj, optional): Synapse equation builder object. block_params (dict, optional): Dictionary of parameters such as synChaCha1e_weight or gChaGroup_refP. num_inputs (int, optional): Number of inputs from different source populations. verbose (bool, optional): Debug flag. """ self.num_chains = block_params['num_chains'] self.num_neurons_per_chain = block_params['num_neurons_per_chain'] self.synChaCha1e_weight = block_params['synChaCha1e_weight'] self.synInpCha1e_weight = block_params['synInpCha1e_weight'] self.gChaGroup_refP = block_params['gChaGroup_refP'] BuildingBlock.__init__(self, name, neuron_eq_builder, synapse_eq_builder, block_params, verbose) self.Groups, self.Monitors,\ self.standalone_params = gen_chain(name, neuron_eq_builder, synapse_eq_builder, self.numChains, self.num_neurons_per_chain, num_inputs, self.synChaCha1e_weight, self.synInpCha1e_weight, self.gChaGroup_refP, debug=self.debug) self.input_group = self.Groups['gChaInpGroup'] self.group = self.Groups['gChaGroup'] self.synapse = self.Groups['synChaCha1e'] self.spikemon_cha = self.Monitors['spikemon_cha'] self.spikemon_cha_inp = self.Monitors['spikemon_cha_inp']
[docs] def plot(self, savedir=None): """Simple function to plot recorded state and spikemonitors. Args: savedir (str, optional): Path to directory to save plot. Returns: matplotlib.pyplot object: Returns figure. """ if len(self.spikemon_cha.t) < 1: print( 'Monitor is empty, have you run the Network and added the monitor to the Network?') return duration = max(self.spikemon_cha.t + 10 * ms) # Cha plots fig = figure() subplot(211) plot(self.spikemon_cha.t / ms, self.spikemon_cha.i, '.k') xlabel('Time [ms]') ylabel('i_Cha') # ylim([0,0]) xlim([0, duration / ms]) subplot(212) plot(self.spikemon_cha_inp.t / ms, self.spikemon_cha_inp.i, '.k') xlabel('Time [ms]') ylabel('i_Cha_Inp') xlim([0, duration / ms]) if savedir is not None: fig.savefig(os.path.join(savedir, self.name + '_' + datetime.now().strftime('%Y%m%d_%H%M%S') + '.png')) return fig
[docs]def gen_chain(groupname='Cha', neuron_eq_builder=ExpAdaptIF(1), synapse_eq_builder=ReversalSynV(), num_chains=4, num_neurons_per_chain=15, num_inputs=1, synChaCha1e_weight=4, synInpCha1e_weight=1, gChaGroup_refP=1 * ms, debug=False): """Creates chains of neurons Args: groupname (str, optional): Base name for building block. neuron_eq_builder (TYPE, optional): Neuron equation builder object. synapse_eq_builder (TYPE, optional): Synapse equation builder object. num_chains (int, optional): Number of chains to generate. num_neurons_per_chain (int, optional): Number of neurons within one chain. num_inputs (int, optional): Number of inputs from different source populations. synChaCha1e_weight (int, optional): Parameter specifying the recurrent weight. synInpCha1e_weight (int, optional): Parameter specifying the input weight. gChaGroup_refP (TYPE, optional): Parameter specifying the refractory period. debug (bool, optional): Debug flag. Returns: Groups (dictionary): Keys to all neuron and synapse groups. Monitors (dictionary): Keys to all spike- and statemonitors. standalone_params (dictionary): Dictionary which holds all parameters to create a standalone network. """ # empty input SpikeGenerator ts_cha_inp = np.asarray([]) * ms ind_cha_inp = np.asarray([]) gChaInpGroup = SpikeGeneratorGroup(num_chains, indices=ind_cha_inp, times=ts_cha_inp, name='g' + groupname + 'Inp') gChaGroup = Neurons(num_neurons_per_chain * num_chains, equation_builder=neuron_eq_builder(num_inputs), refractory=gChaGroup_refP, name='g' + groupname, debug=debug) synChaCha1e = Connections(gChaGroup, gChaGroup, equation_builder=synapse_eq_builder, method='euler', name='s' + groupname + '' + groupname + '1e') synChaCha1e.connect('i+1==j and (j%numNeuronsPerChain)!=0') synInpCha1e = Connections(gChaInpGroup, gChaGroup, equation_builder=synapse_eq_builder, method='euler', name='sInp' + groupname + '1e') for i_cha in range(num_chains): synInpCha1e.connect(i=i_cha, j=i_cha * num_neurons_per_chain) # change some parameters synChaCha1e.weight = synChaCha1e_weight synInpCha1e.weight = synInpCha1e_weight spikemon_cha_inp = SpikeMonitor( gChaInpGroup, name='spikemon' + groupname + '_cha_inp') spikemon_cha = SpikeMonitor(gChaGroup, name='spikemon' + groupname + '_cha') Monitors = { 'spikemon_cha_inp': spikemon_cha_inp, 'spikemon_cha': spikemon_cha } Groups = { 'gChaGroup': gChaGroup, 'gChaInpGroup': gChaInpGroup, 'synChaCha1e': synChaCha1e, 'synInpCha1e': synInpCha1e } standalone_params = [synChaCha1e.name + '_weight'] return Groups, Monitors, standalone_params