Beispiel #1
0
    def __init__(self, tau=10.0, B=0.0, T=0.0, sum='sum(exc) - sum(inh)', noise=None):
        
        # Create the arguments
        parameters = """
    tau = %(tau)s : population
    B = %(B)s
    T = %(T)s : population
""" % {'tau': tau, 'B': B, 'T': T}

        # Equations for the variables
        if not noise:
            noise_def = ''
        else:
            noise_def = '+ ' + noise

        equations="""
    tau * dv/dt + v = %(sum)s + B %(noise)s : exponential
    r = pos(v - T)
""" % { 'sum' : sum, 'noise': noise_def}

        Neuron.__init__(self, parameters=parameters, equations=equations,
            name="Leaky-Integrator", description="Leaky-Integrator with positive transfer function and additive noise.")

        # For reporting
        self._instantiated.append(True)
Beispiel #2
0
    def __init__(self,
                 parameters,
                 equations,
                 inputs,
                 output=["BOLD"],
                 name="Custom BOLD model",
                 description=""):
        """
        See ANNarchy.extensions.bold.PredefinedModels.py for some example models.

        :param parameters: parameters of the model and their initial value.
        :param equations: equations defining the temporal evolution of variables.
        :param inputs: single variable or list of input signals (e.g. 'I_CBF' or ['I_CBF', 'I_CMRO2']).
        :param output: output variable of the model (default is 'BOLD').
        :param name: optional model name.
        :param description: optional model description.
        """
        # The processing in BoldMonitor expects lists, but the interface
        # should allow also single strings (if only one variable is considered)
        self._inputs = [inputs] if isinstance(inputs, str) else inputs
        self._output = [output] if isinstance(output, str) else output

        Neuron.__init__(self,
                        parameters=parameters,
                        equations=equations,
                        name=name,
                        description=description)

        self._model_instantiated = False  # activated by BoldMonitor
Beispiel #3
0
    def __init__(self, v_rest=-65.0, cm=1.0, tau_m=20.0, tau_refrac=0.0, tau_syn_E=5.0, tau_syn_I=5.0, v_thresh=-50.0, v_reset=-65.0, i_offset=0.0):
        # Create the arguments
        parameters = """
    v_rest = %(v_rest)s
    cm  = %(cm)s
    tau_m  = %(tau_m)s
    tau_refrac = %(tau_refrac)s
    tau_syn_E = %(tau_syn_E)s
    tau_syn_I = %(tau_syn_I)s
    v_thresh = %(v_thresh)s
    v_reset = %(v_reset)s
    i_offset = %(i_offset)s
""" % {'v_rest':v_rest, 'cm':cm, 'tau_m':tau_m, 'tau_refrac':tau_refrac, 'tau_syn_E':tau_syn_E, 'tau_syn_I':tau_syn_I, 'v_thresh':v_thresh, 'v_reset':v_reset, 'i_offset':i_offset}
        # Equations for the variables
        equations="""  
    gmax_exc = exp((tau_syn_E - dt/2.0)/tau_syn_E)
    gmax_inh = exp((tau_syn_I - dt/2.0)/tau_syn_I)  
    cm * dv/dt = cm/tau_m*(v_rest -v)   + alpha_exc - alpha_inh + i_offset : exponential, init=%(v_reset)s
    tau_syn_E * dg_exc/dt = - g_exc : exponential
    tau_syn_I * dg_inh/dt = - g_inh : exponential
    tau_syn_E * dalpha_exc/dt = gmax_exc * g_exc - alpha_exc  : exponential
    tau_syn_I * dalpha_inh/dt = gmax_inh * g_inh - alpha_inh  : exponential
"""  % {'v_reset':v_reset}

        spike = """
    v > v_thresh
"""
        reset = """
    v = v_reset
"""
        Neuron.__init__(self, parameters=parameters, equations=equations, spike=spike, reset=reset, refractory='tau_refrac',
            name="Integrate-and-Fire", description="Leaky integrate-and-fire model with fixed threshold and alpha post-synaptic currents.")

        # For reporting
        self._instantiated.append(True)
Beispiel #4
0
    def __init__(self, spike_times, name=None, copied=False):

        if not isinstance(spike_times, list):
            Global._error(
                'In a SpikeSourceArray, spike_times must be a Python list.')

        if isinstance(spike_times[0], list):  # several neurons
            nb_neurons = len(spike_times)
        else:  # a single Neuron
            nb_neurons = 1
            spike_times = [spike_times]

        # Create a fake neuron just to be sure the description has the correct parameters
        neuron = Neuron(parameters="",
                        equations="",
                        spike=" t == 0",
                        reset="",
                        name="Spike source",
                        description="Spike source array.")

        SpecificPopulation.__init__(self,
                                    geometry=nb_neurons,
                                    neuron=neuron,
                                    name=name,
                                    copied=copied)

        self.init['spike_times'] = spike_times
Beispiel #5
0
    def __init__(self, geometry, name=None, copied=False):
        """            
        :param geometry: population geometry as tuple. It must correspond to the image size and be fixed through the whole simulation.
        :param name: unique name of the population (optional).     
        """
        # Check geometry
        if isinstance(geometry, int) or len(geometry) == 1:
            Global._error(
                'The geometry of an ImagePopulation should be 2D (grayscale) or 3D (color).'
            )

        if len(geometry) == 3 and (geometry[2] != 3 and geometry[2] != 1):
            Global._error(
                'The third dimension of an ImagePopulation should be either 1 (grayscale) or 3 (color).'
            )

        if len(geometry) == 3 and geometry[2] == 1:
            geometry = (int(geometry[0]), int(geometry[1]))

        # Create the population
        Population.__init__(self,
                            geometry=geometry,
                            name=name,
                            neuron=Neuron(parameters="r = 0.0"),
                            copied=copied)
Beispiel #6
0
    def __init__(self, spike_times, name=None):

        if not isinstance(spike_times, list):
            Global._error('in SpikeSourceArray, spike_times must be a Python list.')
            exit(0)

        if isinstance(spike_times[0], list): # several neurons
            nb_neurons = len(spike_times)
        else: # a single Neuron
            nb_neurons = 1
            spike_times = [ spike_times ]

        # Create a fake neuron just to be sure the description has the correct parameters
        neuron = Neuron(
            parameters="""
                spike_times = 0.0
            """,
            equations="",
            spike=" t == spike_times",
            reset="",
            name="Spike source",
            description="Spikes source array."
        )

        Population.__init__(self, geometry=nb_neurons, neuron=neuron, name=name)

        # Do some sorting to save C++ complexity
        times = []
        for neur_times in spike_times:
            times.append(sorted(list(set(neur_times)))) # suppress doublons and sort

        self.init['spike_times'] = times
Beispiel #7
0
    def __init__(self, geometry, name=None, copied=False):
        """        
        *Parameters*:
    
        * *geometry*: population geometry as tuple. It must correspond to the image size and be fixed through the whole simulation.

        * *name*: unique name of the population (optional).
        
        About the geometry:
        
        * If the geometry is 2D, it corresponds to the (height, width) of the image. Only the luminance of the pixels will be represented (grayscale image).
    
        * If the geometry is 3D, the third dimension can be either 1 (grayscale) or 3 (color).
        
        If the third dimension is 3, each will correspond to the RGB values of the pixels.
        
        .. warning::
        
            Due to the indexing system of Numpy, a 640*480 image should be fed into a (480, 640) or (480, 640, 3) population.

        
        """   
        # Check geometry
        if isinstance(geometry, int) or len(geometry)==1:
            Global._error('The geometry of an ImagePopulation should be 2D (grayscale) or 3D (color).')
            
        if len(geometry)==3 and (geometry[2]!=3 and geometry[2]!=1):
            Global._error('The third dimension of an ImagePopulation should be either 1 (grayscale) or 3 (color).') 
                        
        if len(geometry)==3 and geometry[2]==1:
            geometry = (int(geometry[0]), int(geometry[1]))
            
        # Create the population     
        Population.__init__(self, geometry = geometry, name=name, neuron = Neuron(parameters="r = 0.0"), copied=copied)
Beispiel #8
0
    def __init__(self, population, name=None, scaling=1.0, refractory=None, copied=False):
        """
        :param population: the Population to convert. Its neuron type must be spiking.
        :param name: the (optional) name of the hybrid population.
        :param scaling: the scaling of the firing rate. Defines what a rate ``r`` of 1.0 means in Hz (default: 1.0).
        :param refractory: a refractory period in ms to ensure the ISI is not too high (default: None)
        """
        self.population = population
        self.refractory_init = refractory

        if not self.population.neuron_type.description['type'] == 'rate':
            Global._error('the population ' + self.population.name + ' must contain rate-coded neurons.')
            

        # Create the description, but it will not be used for generation
        Population.__init__(
            self, 
            geometry = self.population.geometry, 
            name=name, 
            neuron = Neuron(
                parameters="""
                    scaling = %(scaling)s : population
                """ % {'scaling': scaling} ,
                equations="""
                    p = Uniform(0.0, 1.0)
                    rates = p
                """,
                spike="rates>p",
                refractory=refractory
            ) ,
            copied=self.copied
        )

        self._specific = True
Beispiel #9
0
    def __init__(self,
                 geometry,
                 rates,
                 corr,
                 tau,
                 name=None,
                 refractory=None,
                 copied=False):
        """
        *Parameters*:

        * **geometry**: population geometry as tuple.

        * **rates**: rate in Hz of the population (must be a positive float)

        * **corr**: total correlation strength (float in [0, 1])

        * **tau**: correlation time constant in ms.

        * **name**: unique name of the population (optional).

        * **refractory**: refractory period in ms (careful: may break the correlation)
        """
        # Store parameters
        self.rates = float(rates)
        self.corr = corr
        self.tau = tau
        self.refractory_init = refractory

        # Correction of mu and sigma
        mu, sigma = self._rectify(self.rates, self.corr, tau)

        # Create the neuron
        corr_neuron = Neuron(
            parameters="""
                tau = %(tau)s : population
                mu = %(mu)s : population
                sigma = %(sigma)s : population
            """ % {
                'tau': tau,
                'mu': mu,
                'sigma': sigma
            },
            equations="""
                x += dt*(mu - x)/tau + sqrt(dt/tau) * sigma * Normal(0., 1.) : population, init=%(mu)s
                p = Uniform(0.0, 1.0) * 1000.0 / dt
            """ % {'mu': mu},
            spike="p < x",
            refractory=refractory,
            name="HomogeneousCorrelated",
            description="Homogeneous correlated spike trains.")

        SpecificPopulation.__init__(self,
                                    geometry=geometry,
                                    neuron=corr_neuron,
                                    name=name,
                                    copied=copied)
Beispiel #10
0
    def __init__(self, a=0.2, b=0.2, c=-65.0, d=2.0, v_thresh=30.0, i_offset=0.0, noise=0.0, tau_refrac=0.0, conductance="g_exc - g_inh"):
        # Extract which targets are defined in the conductance
        import re
        targets = re.findall(r'g_([\w]+)', conductance)
        # Create the arguments
        parameters = """
    noise = %(noise)s
    a = %(a)s
    b = %(b)s
    c = %(c)s
    d = %(d)s
    v_thresh = %(v_thresh)s
    i_offset = %(i_offset)s
    tau_refrac = %(tau_refrac)s
""" % {'a': a, 'b':b, 'c':c, 'd':d, 'v_thresh':v_thresh, 'i_offset':i_offset, 'noise':noise, 'tau_refrac':tau_refrac}
        # Equations for the variables
        equations="""
    I = %(conductance)s + noise * Normal(0.0, 1.0) + i_offset
    dv/dt = 0.04 * v^2 + 5.0 * v + 140.0 - u + I : init = %(c)s
    du/dt = a * (b*v - u) : init= %(u)s
""" % { 'conductance' : conductance, 'c':c , 'u': b*c}

    #     # Default behavior for the conductances (avoid warning)
    #     for target in targets:
    #         equations += """
    # g_%(target)s = 0.0""" % {'target' : target}

        spike = """
    v > v_thresh
"""
        reset = """
    v = c
    u += d
"""
        Neuron.__init__(self, parameters=parameters, equations=equations, spike=spike, reset=reset, refractory='tau_refrac',
            name="Izhikevich", description="Quadratic integrate-and-fire spiking neuron with adaptation.")

        # For reporting
        self._instantiated.append(True)
Beispiel #11
0
    def __init__(self,
                 rates,
                 schedule=0.,
                 period=-1.,
                 name=None,
                 copied=False):
        neuron = Neuron(parameters="",
                        equations=" r = 0.0",
                        name="Timed Array",
                        description="Timed array source.")
        # Geometry of the population
        geometry = rates.shape[1:]

        # Check the schedule
        if isinstance(schedule, (int, float)):
            if float(schedule) <= 0.0:
                schedule = Global.config['dt']
            schedule = [float(schedule * i) for i in range(rates.shape[0])]

        if len(schedule) > rates.shape[0]:
            Global._error(
                'TimedArray: the length of the schedule parameter cannot exceed the first dimension of the rates parameter.'
            )

        if len(schedule) < rates.shape[0]:
            Global._warning(
                'TimedArray: the length of the schedule parameter is smaller than the first dimension of the rates parameter (more data than time points). Make sure it is what you expect.'
            )

        SpecificPopulation.__init__(self,
                                    geometry=geometry,
                                    neuron=neuron,
                                    name=name,
                                    copied=copied)

        self.init['schedule'] = schedule
        self.init['rates'] = rates
        self.init['period'] = period
Beispiel #12
0
    def _create_adaptive(self):

        # Create the description, but it will not be used for generation
        Population.__init__(self,
                            geometry=self.population.geometry,
                            name=self.name,
                            neuron=Neuron(parameters="""
                    window = %(window)s : population
                    scaling = %(scaling)s : population
                    smooth = %(smooth)s : population
                """ % {
                                'window': self.window,
                                'scaling': self.scaling,
                                'smooth': self.smooth
                            },
                                          equations="r = 0.0"),
                            copied=self.copied)

        # Generate specific code
        omp_code = "#pragma omp parallel for private(pop%(id)s_nb, pop%(id)s_out)" if Global.config[
            'num_threads'] > 1 else ""
        code = """#pragma once

#include "pop%(id_pre)s.hpp"
extern PopStruct%(id_pre)s pop%(id_pre)s;

struct PopStruct%(id)s{
    // Number of neurons
    int size;
    bool _active;

    // Local parameter window
    %(float_prec)s  window ;
    std::vector< %(float_prec)s >  ad_window ;

    // Global parameter scaling
    %(float_prec)s  scaling ;

    // Global parameter smooth
    %(float_prec)s  smooth ;

    // Local variable r
    std::vector< %(float_prec)s > r ;
    std::vector< std::vector< %(float_prec)s > > recorded_r ;
    bool record_r ;

    // Store the last spikes
    std::vector< std::vector<long int> > last_spikes;
    std::vector< %(float_prec)s > isi;

    int get_size() { return size; }
    void set_size(int value) { size = value; }

    bool is_active() { return _active; }
    void set_active(bool value) { _active = value; }

    %(float_prec)s get_window() { return window; }
    void set_window(%(float_prec)s value) { window = value; }

    %(float_prec)s get_scaling() { return scaling; }
    void set_scaling(%(float_prec)s value) { scaling = value; }

    %(float_prec)s get_smooth() { return smooth; }
    void set_smooth(%(float_prec)s value) { smooth = value; }

    std::vector< %(float_prec)s > get_r() { return r; }
    void set_r(std::vector< %(float_prec)s > value) { r = value; }
    %(float_prec)s get_single_r(int rk) { return r[rk]; }
    void set_single_r(int rk, %(float_prec)s value) { r[rk] = value; }

    void init_population() {
        size = %(size)s;
        _active = true;

        last_spikes = std::vector< std::vector<long int> >(size, std::vector<long int>());
        ad_window = std::vector< %(float_prec)s >(size, window);
        isi = std::vector< %(float_prec)s >(size, 10000.0);
    }

    void update_rng() {

    }

    void update() {
        // Updating the local variables of Spike2Rate population %(id)s
        if(_active){
            int pop%(id)s_nb, pop%(id)s_out;
            %(omp_code)s
            for(int i = 0; i < size; i++){
                // Increase when spiking
                if (pop%(id_pre)s.last_spike[i] == t-1){
                    if(last_spikes[i].size() > 0)
                        isi[i] = %(float_prec)s(t-1 - last_spikes[i][last_spikes[i].size()-1]);
                    else
                        isi[i] = 10000.0;
                    last_spikes[i].push_back(t-1);
                }
                pop%(id)s_nb = 0;
                pop%(id)s_out = -1;
                for(int j=0; j < last_spikes[i].size(); j++){
                    if(last_spikes[i][j] >= t -1 - (long int)(ad_window[i]/dt) ){
                        pop%(id)s_nb++;
                    }
                    else{
                        pop%(id)s_out = j;
                    }
                }

                if (pop%(id)s_out > -1){
                    last_spikes[i].erase(last_spikes[i].begin(), last_spikes[i].begin()+pop%(id)s_out);
                }

                r[i] += dt*(1000.0/scaling / ad_window[i] * %(float_prec)s(pop%(id)s_nb) - r[i] ) / smooth;

                //ad_window[i] = clip(5.0*isi[i], 20.0*dt, window) ;
                ad_window[i] += dt * (clip(5.0*isi[i], 20.0*dt, window) - ad_window[i])/100.0;
                if (i==0)
                    std::cout << ad_window[i] << " " << isi[i] << std::endl;
            }
        }
    }
};
""" % {
            'id': self.id,
            'id_pre': self.population.id,
            'omp_code': omp_code,
            'size': self.size,
            'float_prec': Global.config['precision']
        }

        return code
Beispiel #13
0
    def __init__(self,
                 geometry,
                 name=None,
                 rates=None,
                 target=None,
                 parameters=None,
                 refractory=None,
                 copied=False):
        """
        *Parameters*:

        * **geometry**: population geometry as tuple.

        * **name**: unique name of the population (optional).

        * **rates**: mean firing rate of each neuron. It can be a single value (e.g. 10.0) or an equation (as string).

        * **target**: the mean firing rate will be the weighted sum of inputs having this target name (e.g. "exc").

        * **parameters**: additional parameters which can be used in the *rates* equation.

        * **refractory**: refractory period in ms.
        """
        if rates is None and target is None:
            Global._error(
                'A PoissonPopulation must define either rates or target.')

        self.target = target
        self.parameters = parameters
        self.refractory_init = refractory
        self.rates_init = rates

        if target is not None:  # hybrid population
            # Create the neuron
            poisson_neuron = Neuron(
                parameters="""
                %(params)s
                """ % {'params': parameters if parameters else ''},
                equations="""
                rates = sum(%(target)s)
                p = Uniform(0.0, 1.0) * 1000.0 / dt
                _sum_%(target)s = 0.0
                """ % {'target': target},
                spike="""
                    p < rates
                """,
                refractory=refractory,
                name="Hybrid",
                description=
                "Hybrid spiking neuron emitting spikes according to a Poisson distribution at a frequency determined by the weighted sum of inputs."
            )

        elif isinstance(rates, str):
            # Create the neuron
            poisson_neuron = Neuron(
                parameters="""
                %(params)s
                """ % {'params': parameters if parameters else ''},
                equations="""
                rates = %(rates)s
                p = Uniform(0.0, 1.0) * 1000.0 / dt
                _sum_exc = 0.0
                """ % {'rates': rates},
                spike="""
                    p < rates
                """,
                refractory=refractory,
                name="Poisson",
                description=
                "Spiking neuron with spikes emitted according to a Poisson distribution."
            )

        elif isinstance(rates, np.ndarray):
            poisson_neuron = Neuron(
                parameters="""
                rates = 10.0
                """,
                equations="""
                p = Uniform(0.0, 1.0) * 1000.0 / dt
                """,
                spike="""
                p < rates
                """,
                refractory=refractory,
                name="Poisson",
                description=
                "Spiking neuron with spikes emitted according to a Poisson distribution."
            )
        else:
            poisson_neuron = Neuron(
                parameters="""
                rates = %(rates)s
                """ % {'rates': rates},
                equations="""
                p = Uniform(0.0, 1.0) * 1000.0 / dt
                """,
                spike="""
                p < rates
                """,
                refractory=refractory,
                name="Poisson",
                description=
                "Spiking neuron with spikes emitted according to a Poisson distribution."
            )
        SpecificPopulation.__init__(self,
                                    geometry=geometry,
                                    neuron=poisson_neuron,
                                    name=name,
                                    copied=copied)

        if isinstance(rates, np.ndarray):
            self.rates = rates