Beispiel #1
0
def scale_input_theory(input_theory, clamp_type, baseline, scale, dt):
    ''' Scales the theoretical current or dynamic input with a scaling factor. An unit is also added
        to the input uA for current and mS for dynamic input. 
        
        INPUT
        input_theory (array or tuple): theoretical input that has to be scaled; (g_exc, g_inh) if dynamic
        clamp_type (str): 'current' or 'dynamic'
        baseline (float or tuple): baseline if dynamic (base_exc, base_inh) #NOTE Not fully implemented
        scale (float): scaling factor
        dt (float): time step of the simulation in milliseconds

        OUTPUT
        inj_input (brian2.TimedArray): the scaled input
    '''
    if clamp_type == 'current':
        baseline = np.ones_like(input_theory, dtype=float) * baseline
        scaled_input = (baseline + input_theory * scale) * b2.uamp
        inject_input = b2.TimedArray(scaled_input, dt=dt * b2.ms)

    elif clamp_type == 'dynamic':
        g_exc, g_inh = input_theory
        g_inh = (baseline + g_inh * scale) * b2.mS
        g_exc = (baseline + g_exc * scale) * b2.mS
        g_exc = b2.TimedArray(g_exc, dt=dt * b2.ms)
        g_inh = b2.TimedArray(g_inh, dt=dt * b2.ms)
        inject_input = (g_exc, g_inh)

    return inject_input
Beispiel #2
0
    def figure2():

        fig = plt.figure(figsize=(10, 6))
        gs = GridSpec(6, 1)
        gs.update(left=0.1, right=0.95)
        ax1 = plt.subplot(gs[:2])
        ax2 = plt.subplot(gs[2])
        ax3 = plt.subplot(gs[3:5])
        ax4 = plt.subplot(gs[5])
        ax = [ax1, ax2, ax3, ax4]

        start_time = time()

        I_sm1 = b2.TimedArray([0, 2, 0, 5, 0, 10, 0]*b2.pA, dt=100*b2.ms)
        par_sim['I_sm'] = I_sm1
        state_monitor = simulate_Thl_cell_fig2(par, par_sim)

        plot_data(state_monitor, ax[0])
        plot_current(state_monitor, ax[1])

        I_sm2 = b2.TimedArray([0, 0, -0.5, 0, 0, -1, 0, 0]*b2.pA, dt=100*b2.ms)
        par_sim['I_sm'] = I_sm2
        par['i_ext'] = 0.0
        state_monitor = simulate_Thl_cell_fig2(par, par_sim)
        print("Done in {}".format(time() - start_time))

        plot_data(state_monitor, ax[2])
        plot_current(state_monitor, ax[3], xlabel="Time [ms]")

        [ax[i].set_xticks([]) for i in range(3)]
        [ax[i].set_xlim([0, 1000]) for i in range(4)]
        plt.savefig(join("data", "figure2.png"))
        plt.show()
def HH_Step(I_tstart=20,
            I_tend=180,
            I_amp=7,
            tend=200,
            do_plot=True,
            model='HH'):

    # 1ms sampled step current
    tmp = np.zeros(np.round(tend)) * b2.uamp
    tmp[int(I_tstart):int(I_tend)] = I_amp * b2.uamp
    curr = b2.TimedArray(tmp, dt=1. * b2.ms)
    # Neuron Model

    if model == "HH":
        rec = HH_Neuron(curr, tend * b2.ms)

        if do_plot:
            plot_data_S(
                rec,
                title="Step current",
            )
    else:
        rec = HH_Neuron_Adapt(curr, tend * b2.ms, model)

        if do_plot:
            plot_data_Adapt(
                rec,
                title="Step current",
            )

    return rec
Beispiel #4
0
def run_brian_sim(stim, dt, init_values, param_dict, method = 'exact'):
    # Model specification
    eqs = brian2.Equations("")
    eqs += brian2.Equations("dV/dt = 1 / C * (Ie(t) + I_0 + I_1 - G * (V - El)) : volt (unless refractory)")
    eqs += brian2.Equations("dTh_s/dt = -b_s * Th_s : volt (unless refractory)")
    eqs += brian2.Equations("dTh_v/dt = a_v * (V - El) - b_v * (Th_v - Th_inf) : volt (unless refractory)")
    eqs += brian2.Equations("dI_0/dt = -k_0 * I_0 : amp (unless refractory)")
    eqs += brian2.Equations("dI_1/dt = -k_1 * I_1 : amp (unless refractory)")
    reset = ""
    reset = "\n".join([reset, "V = a_r * V + b_r"])
    reset = "\n".join([reset, "Th_s = Th_s + a_s"])
    reset = "\n".join([reset, "Th_v = Th_v"])
    reset = "\n".join([reset, "I_0 = R_0 * I_0 * exp(-k_0 * (t_ref - dt)) + A_0"])
    reset = "\n".join([reset, "I_1 = R_1 * I_1 * exp(-k_1 * (t_ref - dt)) + A_1"])
    threshold = "V > Th_v + Th_s"
    refractory = param_dict['t_ref']

    Ie = brian2.TimedArray(stim, dt=dt)
    nrn = brian2.NeuronGroup(1, eqs, method=method, reset=reset, threshold=threshold, refractory=refractory, namespace=param_dict)
    nrn.V = init_values['V'] * brian2.units.volt
    nrn.Th_s = init_values['Th_s'] * brian2.units.volt
    nrn.Th_v = init_values['Th_v'] * brian2.units.volt
    nrn.I_0 = init_values['I_0'] * brian2.units.amp
    nrn.I_1 = init_values['I_1'] * brian2.units.amp

    monvars = ['V','Th_s','Th_v','I_0','I_1',]
    mon = brian2.StateMonitor(nrn, monvars, record=True)

    num_step = len(stim)
    brian2.defaultclock.dt = dt
    brian2.run(num_step * dt)

    return (mon.t / brian2.units.second, mon.V[0] / brian2.units.volt, mon.Th_s[0] / brian2.units.volt, mon.Th_v[0] / brian2.units.volt, mon.I_0[0] / brian2.units.amp, mon.I_1[0] / brian2.units.amp, )
def hhStep(itStart=20, itEnd=180, iAmp=7,
            tEnd=200,dt = 1, doPlot=True):

    """Run the Hodgkin-Huley neuron for a step current input.

    Args:
        itStart (float, optional): start of current step [ms]
        itEnd (float, optional): start of end step [ms]
        iAmp (float, optional): amplitude of current step [uA]
        tEnd (float, optional): the simulation time of the model [ms]
        doPlot (bool, optional): plot the resulting simulation

    Returns:
        StateMonitor: Brian2 StateMonitor with valStatorded fields
        ['vm', 'i_e', 'm', 'n', 'h']
    """

    # dt sampled simulation
    tmp = np.zeros(tEnd) * b2.uamp
    tmp[int(itStart):int(itEnd)] = iAmp * b2.uamp
    curr = b2.TimedArray(tmp, dt=dt*b2.ms)

    valStat = hhNeuron(curr, tEnd * b2.ms)

    if doPlot:
        plotData(
            valStat,
            title="Step current",
        )

    return valStat
Beispiel #6
0
def get_spikes_current(t_spikes, unit_time, amplitude, append_zero=True):
    """Creates a two dimensional TimedArray wich has one column for each value in t_spikes.
    All values in each column are 0 except one, the spike time as specified in t_spikes is set to amplitude.
    Note: This function is provided to easily insert pulse currents into a cable. For other use of
    spike input, search the Brian2 documentation for SpikeGeneration.

    Args:
        t_spikes (int): list of spike times
        unit_time (Quantity, Time): unit of t_spikes . e.g. 1*brian2.ms
        amplitude (Quantity, Current):  amplitude of the spike. All spikes have the sampe amplitude
        append_zero (bool, optional): if true, 0Amp is appended at t_end+1. Without that trailing 0,
            Brian reads out the last value in the array for all indices > t_end.

    Returns:
        TimedArray: Brian2.TimedArray
    """
    assert isinstance(t_spikes, list), "t_spikes must be of type list"
    assert b2.units.fundamentalunits.have_same_dimensions(amplitude, b2.amp), \
        "amplitude must have the dimension of current e.g. brian2.uamp"
    nr_spikes = len(t_spikes)
    t_max = max(t_spikes)
    tmp_size = 1 + t_max  # +1 for t=0
    if append_zero:
        tmp_size += 1
    tmp = np.zeros((tmp_size, nr_spikes)) * b2.amp
    for i in range(nr_spikes):
        tmp[t_spikes[i], i] = amplitude
    curr = b2.TimedArray(tmp, dt=1. * unit_time)
    return curr
Beispiel #7
0
def neuron_sim(stim_V=0.8):
    """simulating the neuron using brian2 library"""
    # initiate stimuli timing
    stimulus = br2.TimedArray(
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, stim_V, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        dt=100 * br2.ms)
    # initiating neurons
    eqs = '''
    dv/dt =  (-v + stimulus(t)-0.1*rand()) / tau  : 1
    tau : second
    '''
    # creating neuron group
    G = br2.NeuronGroup(10, eqs, dt=0.2 * br2.ms)
    # creating different tau's for the neuron model
    G.tau = np.linspace(10, 100, 10) * br2.ms
    # defining state monitor to record voltage
    M = br2.StateMonitor(G, 'v', record=True)
    # creating network
    net = br2.Network(G, M)
    # storing initial state
    net.store()
    # np array to contain data
    data = np.zeros(shape=(10, 10000, 4))
    # producing four repetitions
    for trial in range(4):
        net.restore()  # Restore the initial state
        net.run(2 * br2.second)
        # store the results
        data[:, :, trial] = M.v

    return data
Beispiel #8
0
def hhSinus(iFreq=0.01, iOffset=0.5, iAmp=7., tEnd=600, dt=.1, doPlot=True):
    """
    Run the HH model for a sinusoidal current

    Args:
        tEnd (float, optional): the simulation time of the model [ms]
        iFreq (float, optional): frequency of current sinusoidal [kHz]
        iOffset (float, optional): DC offset of current [nA]
        iAmp (float, optional): amplitude of sinusoidal [nA]
        doPlot (bool, optional): plot the resulting simulation

    Returns:
        StateMonitor: Brian2 StateMonitor with input current (I) and
        voltage (V) valStatorded
    """

    # dt sampled sinusoidal function
    t = np.arange(0, tEnd, dt)
    tmp = (iAmp * np.sin(2.0 * np.pi * iFreq * t) + iOffset) * b2.uamp
    curr = b2.TimedArray(tmp, dt=dt * b2.ms)

    valStat = hhNeuron(curr, tEnd * b2.ms)

    if doPlot:
        plotData(
            valStat,
            title="Sinusoidal current",
        )

    return valStat
Beispiel #9
0
def hhRamp(itStart=30, itEnd=270, iAmp=20., tEnd=300, dt=.1, doPlot=True):
    """
    Run the HH model for a sinusoidal current

    Args:
        tEnd (float, optional): the simulation time of the model [ms]
        itStart (float, optional): start of current ramp [ms]
        itEnd (float, optional): end of the current ramp [ms]
        iAmp (float, optional): final amplitude of current ramp [uA]
        doPlot (bool, optional): plot the resulting simulation

    Returns:
        StateMonitor: Brian2 StateMonitor with input current (I) and
        voltage (V) valStatorded
    """

    # dt sampled sinusoidal function
    t = np.arange(0, tEnd, dt)
    tmp = np.zeros_like(t)
    index_start = np.searchsorted(t, itStart)
    index_end = np.searchsorted(t, itEnd)
    tmp[index_start:index_end] = np.arange(0, index_end-index_start, 1.0) \
        / (index_end-index_start) * iAmp
    curr = b2.TimedArray(tmp * b2.uamp, dt=dt * b2.ms)

    valStat = hhNeuron(curr, tEnd * b2.ms)

    if doPlot:
        plotData(
            valStat,
            title="Sinusoidal current",
        )

    return valStat
Beispiel #10
0
def get_step_current(t_start, t_end, unit_time, amplitude, append_zero=True):

    """Creates a step current. If t_start == t_end, then a single
    entry in the values array is set to amplitude.
    Args:
        t_start (int): start of the step
        t_end (int): end of the step
        unit_time (Brian2 unit): unit of t_start and t_end. e.g. 0.1*brian2.ms
        amplitude (Quantity): amplitude of the step. e.g. 3.5*brian2.uamp
        append_zero (bool, optional): if true, 0Amp is appended at t_end+1.
        Without that trailing 0, Brian reads out the last value in the array (=amplitude) for all indices > t_end.
    Returns:
        TimedArray: Brian2.TimedArray
    """

    assert isinstance(t_start, int), "t_start_ms must be of type int"
    assert isinstance(t_end, int), "t_end must be of type int"
    assert b2.units.fundamentalunits.have_same_dimensions(amplitude, b2.amp), \
        "amplitude must have the dimension of current e.g. brian2.uamp"
    tmp_size = 1 + t_end  # +1 for t=0
    if append_zero:
        tmp_size += 1
    tmp = np.zeros((tmp_size, 1)) * b2.amp
    tmp[t_start: t_end + 1, 0] = amplitude
    curr = b2.TimedArray(tmp, dt=1. * unit_time)
    return curr
def HH_ExitatoryInhibitory(durationOfExperiment=1000,
                           step=1,
                           pExitatory=.4,
                           pInhibitory=.2,
                           iExitatory=5,
                           iInhibitatory=-2,
                           plotCurrent=False):

    # create the current vector
    timeVector = np.arange(0, durationOfExperiment, step)
    currentVector = []
    for i in timeVector:
        randomP = rand.random()
        addCurrent = 0
        if randomP < pExitatory:
            addCurrent += iExitatory

        randomP = rand.random()
        if randomP < pInhibitory:
            addCurrent += iInhibitatory

        currentVector.append(addCurrent)

    currentForBrian = b2.TimedArray(currentVector * b2.uamp, dt=step * b2.ms)

    rec = HH_Neuron(currentForBrian, durationOfExperiment * b2.ms)

    if plotCurrent:
        plt.figure()
        plt.plot(currentVector)
        plt.show()

    return rec
Beispiel #12
0
def get_ramp_current(t_start, t_end, unit_time, amplitude_start, amplitude_end, append_zero=True):
    """Creates a ramp current. If t_start == t_end, then ALL entries are 0.

    Args:
        t_start (int): start of the ramp
        t_end (int): end of the ramp
        unit_time (Brian2 unit): unit of t_start and t_end. e.g. 0.1*brian2.ms
        amplitude_start (Quantity): amplitude of the ramp at t_start. e.g. 3.5*brian2.uamp
        amplitude_end (Quantity): amplitude of the ramp at t_end. e.g. 4.5*brian2.uamp
        append_zero (bool, optional): if true, 0Amp is appended at t_end+1.
            Without that trailing 0, Brian reads out the last value in the
            array (=amplitude_end) for all indices > t_end.

    Returns:
        TimedArray: Brian2.TimedArray
    """
    assert isinstance(t_start, int), "t_start_ms must be of type int"
    assert isinstance(t_end, int), "t_end must be of type int"
    assert b2.units.fundamentalunits.have_same_dimensions(amplitude_start, b2.amp), \
        "amplitude must have the dimension of current e.g. brian2.uamp"
    assert b2.units.fundamentalunits.have_same_dimensions(amplitude_end, b2.amp), \
        "amplitude must have the dimension of current e.g. brian2.uamp"
    tmp_size = 1 + t_end  # +1 for t=0
    if append_zero:
        tmp_size += 1
    tmp = np.zeros((tmp_size, 1)) * b2.amp
    if t_end > t_start:  # if deltaT is zero, we return a zero current
        slope = (amplitude_end - amplitude_start) / float((t_end - t_start))
        ramp = [amplitude_start + t * slope for t in range(0, (t_end - t_start) + 1)]
        tmp[t_start: t_end + 1, 0] = ramp

    curr = b2.TimedArray(tmp, dt=1. * unit_time)
    return curr
Beispiel #13
0
def only_input_step_current(t_start,
                            t_end,
                            unit_time,
                            amplitude,
                            append_zero=True):

    tmp_size = 1 + t_end  # +1 for t=0
    if append_zero:
        tmp_size += 1
    tmp = np.zeros((tmp_size, 2)) * b2.amp
    tmp[t_start:t_end + 1, 0] = amplitude
    curr = b2.TimedArray(tmp, dt=1. * unit_time)
    return curr
Beispiel #14
0
 def train(self, stimuli, labels, batch_size=50, num_reps=100, learning_rate=1e-3, verbose=False):
     num_samples = int(np.unique(stimuli['index']).shape[0] / self.number_of_neurons)
     self.make_classification_network(batch_size, 'batch')
     self.make_train_network(batch_size, 'train')
     for ind in range(num_reps):
         if verbose:
             print(f'train rep #{ind+1}/{num_reps}')
         batch, batch_labels = return_subset(
             batch_size, stimuli, labels,
             num_samples=num_samples,
             num_neurons=self.number_of_neurons)
         self.networks['batch']['net'].restore()
         correct, decisions = self.accuracy('batch', batch, batch_labels, return_decision=True)
         v_max_times = np.argmax(self.networks['batch']['v_mon'].v, 1)
         if (correct.shape[0] == correct.sum()):
             if verbose:
                 print('No mistakes detected')
             continue
         v_max_t = v_max_times[~correct].max()
         self.networks['train']['net'].restore()
         self.networks['train']['synapses'].w = np.tile(self.weights, reps=batch_size)
         self.networks['train']['driving'].set_spikes(batch['index'], batch['time'] * ms)
         counts = self.networks['train']['count_mat'].copy()
         counts[
             (batch['time'] * 10).astype(int),
             batch['index'].astype(int)] = batch['count']
         counts = b2.TimedArray(values=counts, dt=b2.defaultclock.dt)
         if (v_max_t != 0):
             self.networks['train']['net'].run(v_max_t * ms)
             voltage_contribs = self.networks['train']['v_mon'].v
             try:
                 voltage_contribs = voltage_contribs[
                     range(voltage_contribs.shape[0]), np.repeat(v_max_times, self.number_of_neurons)]. \
                     reshape(batch_size, self.number_of_neurons)[~correct]
                 weight_upd = (voltage_contribs
                               * (batch_labels - decisions)[~correct, np.newaxis]).mean(0) * learning_rate
                 self.weights += weight_upd
             except:
                 print(f"Error occured on:")
                 print(f"Learning rate: {learning_rate}")
                 print(f"Threshold: {self.threshold}")
                 print(f"Num neurons: {self.number_of_neurons}\n\n")
                 print(f"""voltage_contribs: {voltage_contribs.shape}
                 v_max_times: {v_max_times.shape}
                 number_of_neurons: {self.number_of_neurons}
                 batch_size: {batch_size}
                 correct: {correct.sum()}""")
                 continue
         elif verbose:
             print('Aww Crap')
Beispiel #15
0
 def plot_response(self, stimuli, stim_num):
     sample = stimuli[stimuli['index'] == stim_num]
     network = self.networks['plot']
     network['net'].restore()
     network['driving'].set_spikes(sample['index'], sample['time'] * ms)
     network['synapses'].w = self.weights
     counts = network['count_mat'].copy()
     counts[
         (sample['time'] * 10).astype(int),
         sample['index'].astype(int)] = sample['count']
     counts = b2.TimedArray(values=counts, dt=b2.defaultclock.dt)
     network['net'].run(self.stimulus_duration)
     v = network['v_mon'].v[0]
     plt.figure()
     plt.plot(v)
     plt.hlines(xmin=0, xmax=self.stimulus_duration * 10, y=self.threshold, colors='k', linestyles='dashed')
Beispiel #16
0
 def accuracy(self, network_name, stimuli, labels, return_decision=False):
     network = self.networks[network_name]
     network['net'].restore()
     network['driving'].set_spikes(stimuli['index'], stimuli['time'] * ms)
     network['synapses'].w = np.tile(self.weights, reps=network['number_of_stimuli'])
     counts = network['count_mat'].copy()
     counts[
         (stimuli['time'] * 10).astype(int),
         stimuli['index'].astype(int)] = stimuli['count']
     counts = b2.TimedArray(values=counts, dt=b2.defaultclock.dt)
     network['net'].run(self.stimulus_duration)
     decisions = network['spike_mon'].count != 0
     correct = (decisions == labels)
     if return_decision:
         return correct, decisions
     else:
         return correct
Beispiel #17
0
def get_sinusoidal_current(t_start,
                           t_end,
                           unit_time,
                           amplitude,
                           frequency,
                           direct_current,
                           phase_offset=0.,
                           append_zero=True):
    """
    Creates a sinusoidal current. If t_start == t_end, then ALL entries are 0.

    :param int t_start: start of the sine wave
    :param int t_end: end of the sine wave
    :param unit_time: unit of t_start and t_end. e.g. 0.1*ms
    :param amplitude: maximum amplitude of the sinus e.g. 3.0*uamp
    :param frequency: Frequency of the sine. e.g. 0.5*kHz
    :param direct_current: DC-component (=offset) of the current, e.g. 1.5*uamp
    :param float phase_offset: phase at t_start. Default = 0
    :param bool append_zero: if true, 0Amp is appended at t_end+1. Without that trailing 0, Brian reads out the last value in the array for all indices > t_end.
    :return: Brian2.TimedArray
    """

    assert isinstance(t_start, int), "t_start_ms must be of type int"
    assert isinstance(t_end, int), "t_end must be of type int"
    assert b2.units.fundamentalunits.have_same_dimensions(amplitude, b2.amp), \
        "amplitude must have the dimension of current. e.g. brian2.uamp"
    assert b2.units.fundamentalunits.have_same_dimensions(direct_current, b2.amp), \
        "direct_current must have the dimension of current. e.g. brian2.uamp"
    assert b2.units.fundamentalunits.have_same_dimensions(frequency, b2.Hz), \
        "frequency must have the dimension of 1/Time. e.g. brian2.Hz"

    tmp_size = 1 + t_end  # +1 for t=0
    if append_zero:
        tmp_size += 1
    tmp = np.zeros((tmp_size, 1)) * b2.amp
    if t_end > t_start:  # if deltaT is zero, we return a zero current
        phi = range(0, (t_end - t_start) + 1)
        phi = phi * unit_time * frequency
        phi = phi * 2. * math.pi + phase_offset
        c = numpy.sin(phi)
        c = (direct_current + c * amplitude)
        tmp[t_start:t_end + 1, 0] = c
    curr = b2.TimedArray(tmp, dt=1. * unit_time)
    return curr
Beispiel #18
0
def get_ou_current(I0,
                   Delta_sigma=2.0,
                   sigma_0=1.0,
                   plot=False,
                   unit_time=1 * b2.ms,
                   len_current=1000):
    tau = 1.0  # ms
    #Delta_T = 1.0/20  #ms, sampling freq = 20 kHz
    Delta_T = 1.0 / 10  #ms, sampling freq = 20 kHz
    #sigma = 1.0  # unitless
    # sigma_0 = 1.0  # unitless
    Delta_sigma = 2.0  # unitless
    f = 0.2 * 0.001  # kHz

    len = int(len_current / Delta_T)  # length of arrays: I and time
    I = numpy.zeros(len)  # nA
    time = numpy.arange(0, len_current, Delta_T)  # ms
    sigma = numpy.zeros(len)  # unitless

    I[0] = I0
    for counter in range(1, len):
        sigma[counter] = sigma_0 * (
            1 + Delta_sigma * numpy.sin(2 * numpy.pi * f * time[counter]))
        I[counter] = I[counter -
                       1] + (I0 - I[counter - 1]) / tau * Delta_T + numpy.sqrt(
                           2 * sigma[counter]**2 * Delta_T /
                           tau) * numpy.random.normal()  # N(0,1)

    if plot:
        plt.plot(time, I, lw=2)

        plt.plot(time, I0 * (1 - numpy.exp(-time / tau)), color='red', lw=2)

        plt.figure()
        plt.plot(time, sigma, color='green', lw=2)
        plt.grid()

        plt.show()

    I = I / 100 * b2.namp
    I = b2.TimedArray(I, dt=1. * unit_time)

    return I
Beispiel #19
0
    def initialize_inputs(self, freq):
        print(" -  Initializing stimuli ...")

        # type : video
        _V1_mats = {}

        io.loadmat(os.path.abspath(self.input_mat_path), _V1_mats)
        self.w_coord = _V1_mats['w_coord']
        self.z_coord = _V1_mats['z_coord']
        # Fill ISI with N-1 times frameduration of zeros
        dense_stimulus = _V1_mats['stimulus']

        try:
            frameduration = b2.double(_V1_mats['frameduration'])
            # Assuming different stimulus at every frame
            sparse_stimulus = dense_stimulus
        except:
            # Assuming frameduration = 15 ms and different stimulus at 60 ms intervals
            soa = 60  # in ms
            stimulus_epoch_duration = 15  # in ms, duration of Burbank whole stimulus
            soa_in_n_frames = int(soa / stimulus_epoch_duration)
            sparse_stimulus = np.tile(np.zeros_like(dense_stimulus),
                                      (1, soa_in_n_frames))
            sparse_stimulus[:, 0::soa_in_n_frames] = dense_stimulus
            frameduration = stimulus_epoch_duration
        frames = b2.TimedArray(
            np.transpose(sparse_stimulus), dt=frameduration * ms
        )  # video_data has to be shape (frames, neurons), dt=frame duration
        self.frames = frames
        exec('self.factor = %s' % freq)
        self.i_patterns[len(
            self.i_patterns
        )] = frames.values * self.factor  # These must be final firing rates
        _all_stim = np.squeeze(_V1_mats['stimulus'])
        if len(_all_stim.shape) == 2:
            slash_indices = [
                idx for idx, ltr in enumerate(self.input_mat_path)
                if ltr == '/'
            ]
            print(' -  One video stimulus found in file ' +
                  self.input_mat_path[slash_indices[-1] + 1:])
Beispiel #20
0
def run_brian_sim(stim, dt, init_values, param_dict, method = 'exact'):
    # Model specification
    eqs = brian2.Equations("")
    eqs += brian2.Equations("dV/dt = 1 / C * (Ie(t) - G * (V - El)) : volt (unless refractory)")
    reset = ""
    reset = "\n".join([reset, "V = V_reset"])
    threshold = "V > Th_inf"
    refractory = param_dict['t_ref']

    Ie = brian2.TimedArray(stim, dt=dt)
    nrn = brian2.NeuronGroup(1, eqs, method=method, reset=reset, threshold=threshold, refractory=refractory, namespace=param_dict)
    nrn.V = init_values['V'] * brian2.units.volt

    monvars = ['V',]
    mon = brian2.StateMonitor(nrn, monvars, record=True)

    num_step = len(stim)
    brian2.defaultclock.dt = dt
    brian2.run(num_step * dt)

    return (mon.t / brian2.units.second, mon.V[0] / brian2.units.volt, )
def LIF_Step(I_tstart=20, I_tend=70, I_amp=1.005, tend=100):
    """Run the LIF and give a step current input.

    Args:
        tend (float): the simulation time of the model [ms]
        I_tstart (float): start of current step [ms]
        I_tend (float): start of end step [ms]
        I_amp (float): amplitude of current step [nA]

    """

    # 1ms sampled step current
    tmp = np.zeros(tend) * b2.namp
    tmp[int(I_tstart):int(I_tend)] = I_amp * b2.namp
    curr = b2.TimedArray(tmp, dt=1. * b2.ms)

    do_plot(
        LIF_Neuron(curr, tend * b2.ms),
        title="Step current",
    )

    return True
def LIF_Sinus(I_freq=0.1, I_offset=0.5, I_amp=0.5, tend=100, dt=.1):
    """
    Run the LIF for a sinusoidal current

    Args:
        tend (float): the simulation time of the model [ms]
        I_freq (float): frequency of current sinusoidal [kHz]
        I_offset (float): DC offset of current [nA]
        I_amp (float): amplitude of sinusoidal [nA]

    """

    # dt sampled sinusoidal function
    t = np.arange(0, tend, dt)
    tmp = (I_amp * np.sin(2.0 * np.pi * I_freq * t) + I_offset) * b2.namp
    curr = b2.TimedArray(tmp, dt=dt * b2.ms)

    do_plot(
        LIF_Neuron(curr, tend * b2.ms),
        title="Sinusoidal current",
    )

    return True
Beispiel #23
0
    def plot():
        current_unit = b2.uA
        start_time = time()
        i_stim = [1.67]
        _, ax = plt.subplots(len(i_stim) + 3, figsize=(10, 7), sharex=True)
        for ii in range(len(i_stim)):

            input_current = b2.TimedArray([0, i_stim[ii], 0, i_stim[ii], 0] *
                                          b2.uA,
                                          dt=200 * b2.ms)
            # input_current = get_step_current(50,
            #                                  200,
            #                                  b2.ms,
            #                                  i_stim[ii] * current_unit)
            par['iapp'] = input_current
            st_mon = simulate_MSN_cell(par, par_sim)
            plot_data(st_mon, ax[ii], lw=1, c='k')
            plot_h(st_mon, ax[-2])
            plot_m(st_mon, ax[-3])
            plot_current(st_mon, ax[-1], current_unit)
        print("Done in {:.3f}".format(time() - start_time))
        plt.tight_layout()
        plt.savefig('data/figure_1.png')
        plt.close()
Beispiel #24
0
def simulate_passive_cable(current_injection_location=DEFAULT_INPUT_LOCATION,
                           input_current=DEFAULT_INPUT_CURRENT,
                           length=CABLE_LENGTH,
                           diameter=CABLE_DIAMETER,
                           r_longitudinal=R_LONGITUDINAL,
                           r_transversal=R_TRANSVERSAL,
                           e_leak=E_LEAK,
                           initial_voltage=E_LEAK,
                           capacitance=CAPACITANCE,
                           nr_compartments=200,
                           simulation_time=5 * b2.ms):
    """Builds a multicompartment cable and numerically approximates the cable equation.

    Args:
        t_spikes (int): list of spike times
        current_injection_location (list): List [] of input locations (Quantity, Length): [123.*b2.um]
        input_current (TimedArray): TimedArray of current amplitudes. One column per current_injection_location.
        length (Quantity): Length of the cable: 0.8*b2.mm
        diameter (Quantity): Diameter of the cable: 0.2*b2.um
        r_longitudinal (Quantity): The longitudinal (axial) resistance of the cable: 0.5*b2.kohm*b2.mm
        r_transversal (Quantity): The transversal resistance (=membrane resistance): 1.25*b2.Mohm*b2.mm**2
        e_leak (Quantity): The reversal potential of the leak current (=resting potential): -70.*b2.mV
        initial_voltage (Quantity): Value of the potential at t=0: -70.*b2.mV
        capacitance (Quantity): Membrane capacitance: 0.8*b2.uF/b2.cm**2
        nr_compartments (int): Number of compartments. Spatial discretization: 200
        simulation_time (Quantity): Time for which the dynamics are simulated: 5*b2.ms

    Returns:
        (StateMonitor, SpatialNeuron): The state monitor contains the membrane voltage in a
        Time x Location matrix. The SpatialNeuron object specifies the simulated neuron model
        and gives access to the morphology. You may want to use those objects for
        spatial indexing: myVoltageStateMonitor[mySpatialNeuron.morphology[0.123*b2.um]].v
    """
    assert isinstance(input_current,
                      b2.TimedArray), "input_current is not of type TimedArray"
    assert input_current.values.shape[1] == len(current_injection_location),\
        "number of injection_locations does not match nr of input currents"

    cable_morphology = b2.Cylinder(diameter=diameter,
                                   length=length,
                                   n=nr_compartments)
    # Im is transmembrane current
    # Iext is  injected current at a specific position on dendrite
    EL = e_leak
    RT = r_transversal
    eqs = """
    Iext = current(t, location_index): amp (point current)
    location_index : integer (constant)
    Im = (EL-v)/RT : amp/meter**2
    """
    cable_model = b2.SpatialNeuron(morphology=cable_morphology,
                                   model=eqs,
                                   Cm=capacitance,
                                   Ri=r_longitudinal)
    monitor_v = b2.StateMonitor(cable_model, "v", record=True)

    # inject all input currents at the specified location:
    nr_input_locations = len(current_injection_location)
    input_current_0 = np.insert(
        input_current.values, 0, 0.,
        axis=1) * b2.amp  # insert default current: 0. [amp]
    current = b2.TimedArray(input_current_0, dt=input_current.dt * b2.second)
    for current_index in range(nr_input_locations):
        insert_location = current_injection_location[current_index]
        compartment_index = int(
            np.floor(insert_location / (length / nr_compartments)))
        # next line: current_index+1 because 0 is the default current 0Amp
        cable_model.location_index[compartment_index] = current_index + 1

    # set initial values and run for 1 ms
    cable_model.v = initial_voltage
    b2.run(simulation_time)
    return monitor_v, cable_model
samples, labels = convert_all_samples(orig_samples)
print(f'Conversion took {sec_to_str(time.time()-t)}')
# %%
threshold = 0.3
weights = np.random.normal(0, 1e-3, num_neurons)
init_w = weights.copy()
t = time.time()
print('Setting up network')
duration = 500
tau = 2 * ms
count = np.zeros((duration * 10, num_samples * num_neurons), int)
count[(samples['times'] * 10).astype(int), samples['inds'].astype(int)] = samples['counts']
eqs = 'dv/dt = -v / tau : 1'
target = b2.NeuronGroup(num_samples, eqs, threshold='v>threshold', reset='v=0')
driving = b2.SpikeGeneratorGroup(num_samples * num_neurons, samples['inds'], samples['times'] * ms)
counts = b2.TimedArray(count, dt=b2.defaultclock.dt)
synapses = b2.Synapses(driving, target, 'w: 1', on_pre='v+=w*counts(t, i)')
i = np.arange(num_samples * num_neurons)
j = np.array([[i] * num_neurons for i in range(num_samples)]).flatten()
synapses.connect(j=j, i=i)
synapses.w = np.tile(weights, num_samples)

s = b2.SpikeMonitor(target, record=True)
print(f'Finished network setup, took {sec_to_str(time.time()-t)}')
b2.run(duration * ms)

decision = s.count != 0
correct = decision == labels

print(correct.mean())
Beispiel #26
0
def simulation(
    test_mode=True,
    runname=None,
    num_epochs=None,
    progress_interval=None,
    progress_assignments_window=None,
    progress_accuracy_window=None,
    record_spikes=False,
    monitoring=False,
    permute_data=False,
    size=400,
    resume=False,
    stdp_rule="original",
    custom_namespace=None,
    timer=None,
    tc_theta=None,
    total_input_weight=None,
    use_premade_weights=False,
    supervised=False,
    feedback=False,
    profile=False,
    clock=None,
    store=None,
    **kwargs,
):
    metadata = get_metadata(store)
    if not resume:
        metadata.nseen = 0
        metadata.nprogress = 0

    if test_mode:
        random_weights = False
        use_premade_weights = True
        ee_STDP_on = False
        if num_epochs is None:
            num_epochs = 1
        if progress_interval is None:
            progress_interval = 1000
        if progress_assignments_window is None:
            progress_assignments_window = 0
        if progress_accuracy_window is None:
            progress_accuracy_window = 1000000
    else:
        random_weights = not resume
        ee_STDP_on = True
        if num_epochs is None:
            num_epochs = 3
        if progress_interval is None:
            progress_interval = 1000
        if progress_assignments_window is None:
            progress_assignments_window = 1000
        if progress_accuracy_window is None:
            progress_accuracy_window = 1000

    log.info("Brian2STDPMNIST/simulation.py")
    log.info("Arguments =============")
    metadata["args"] = record_arguments(currentframe(), locals())
    log.info("=======================")

    # load MNIST
    training, testing = get_labeled_data()
    config.classes = np.unique(training["y"])
    config.num_classes = len(config.classes)

    # configuration
    np.random.seed(0)
    modulefilename = getframeinfo(currentframe()).filename
    config.data_path = os.path.dirname(os.path.abspath(modulefilename))
    config.random_weight_path = os.path.join(config.data_path, "random/")
    runpath = os.path.join("runs", runname)
    config.weight_path = os.path.join(runpath, "weights/")
    os.makedirs(config.weight_path, exist_ok=True)
    if test_mode:
        log.info("Testing run {}".format(runname))
    elif resume:
        log.info("Resuming training run {}".format(runname))
    else:
        log.info("Training run {}".format(runname))

    if test_mode:
        config.output_path = os.path.join(runpath, "output_test/")
    else:
        config.output_path = os.path.join(runpath, "output/")
    os.makedirs(config.output_path, exist_ok=True)

    if test_mode:
        data = testing
    else:
        data = training

    if permute_data:
        sample = np.random.permutation(len(data["y"]))
        data["x"] = data["x"][sample]
        data["y"] = data["y"][sample]

    num_examples = int(len(data["y"]) * num_epochs)
    n_input = data["x"][0].size
    n_data = data["y"].size
    if num_epochs < 1:
        n_data = int(np.ceil(n_data * num_epochs))
        data["x"] = data["x"][:n_data]
        data["y"] = data["y"][:n_data]

    # -------------------------------------------------------------------------
    # set parameters and equations
    # -------------------------------------------------------------------------
    # log.info('Original defaultclock.dt = {}'.format(str(b2.defaultclock.dt)))
    if clock is None:
        clock = 0.5
    b2.defaultclock.dt = clock * b2.ms
    metadata["dt"] = b2.defaultclock.dt
    log.info("defaultclock.dt = {}".format(str(b2.defaultclock.dt)))

    n_neurons = {
        "Ae": size,
        "Ai": size,
        "Oe": config.num_classes,
        "Oi": config.num_classes,
        "Xe": n_input,
        "Ye": config.num_classes,
    }
    metadata["n_neurons"] = n_neurons

    single_example_time = 0.35 * b2.second
    resting_time = 0.15 * b2.second
    total_example_time = single_example_time + resting_time
    runtime = num_examples * total_example_time
    metadata["total_example_time"] = total_example_time

    input_population_names = ["X"]
    population_names = ["A"]
    connection_names = ["XA"]
    config.save_conns = ["XeAe"]
    config.plot_conns = ["XeAe"]
    forward_conntype_names = ["ee"]
    recurrent_conntype_names = ["ei_rec", "ie_rec"]
    stdp_conn_names = ["XeAe"]

    # TODO: add --dc15 option
    total_weight = {}
    if total_input_weight is None:
        total_weight[
            "XeAe"] = n_neurons["Xe"] / 10.0  # standard dc15 value was 78.0
    else:
        total_weight["XeAe"] = total_input_weight

    theta_init = {}

    if supervised:
        input_population_names += ["Y"]
        population_names += ["O"]
        connection_names += ["YO", "AO"]
        config.save_conns += ["YeOe", "AeOe"]
        config.plot_conns += ["AeOe"]
        stdp_conn_names += ["AeOe"]
        total_weight["AeOe"] = n_neurons["Ae"] / 5.0  # TODO: refine?
        theta_init["O"] = 15.0 * b2.mV

    if feedback:
        connection_names += ["OA"]
        config.save_conns += ["OeAe"]
        config.plot_conns += ["OeAe"]
        stdp_conn_names += ["OeAe"]
        total_weight["OeAe"] = n_neurons["Oe"] / 5.0  # TODO: refine?

    delay = {}  # TODO: potentially specify by connName?
    delay["ee"] = (0 * b2.ms, 10 * b2.ms)
    delay["ei"] = (0 * b2.ms, 5 * b2.ms)
    delay["ei_rec"] = (0 * b2.ms, 0 * b2.ms)
    delay["ie_rec"] = (0 * b2.ms, 0 * b2.ms)

    input_intensity = 2.0
    if test_mode:
        input_label_intensity = 0.0
    else:
        input_label_intensity = 10.0

    initial_weight_matrices = get_initial_weights(n_neurons)

    # TODO: put all configuration/setup variables in config object
    #       and save to the store for future reference
    # metadata["config"] = config

    neuron_groups = {}
    connections = {}
    spike_monitors = {}
    state_monitors = {}
    network_operations = []

    # -------------------------------------------------------------------------
    # create network population and recurrent connections
    # -------------------------------------------------------------------------
    for subgroup_n, name in enumerate(population_names):
        log.info(f"Creating neuron group {name}")
        subpop_e = name + "e"
        subpop_i = name + "i"
        const_theta = False
        neuron_namespace = {}
        if name == "A" and tc_theta is not None:
            neuron_namespace["tc_theta"] = tc_theta * b2.ms
        if name == "O":
            neuron_namespace["tc_theta"] = 1e6 * b2.ms
        if test_mode:
            const_theta = True
            if name == "O":
                # TODO: move to a config variable
                neuron_namespace["tc_theta"] = 1e5 * b2.ms
                const_theta = False
        nge = neuron_groups[subpop_e] = DiehlAndCookExcitatoryNeuronGroup(
            n_neurons[subpop_e],
            const_theta=const_theta,
            timer=timer,
            custom_namespace=neuron_namespace,
        )
        ngi = neuron_groups[subpop_i] = DiehlAndCookInhibitoryNeuronGroup(
            n_neurons[subpop_i])

        if not random_weights:
            theta_saved = load_theta(name)
            if len(theta_saved) != n_neurons[subpop_e]:
                raise ValueError(
                    f"Requested size of neuron population {subpop_e} "
                    f"({n_neurons[subpop_e]}) does not match size of "
                    f"saved data ({len(theta_saved)})")
            neuron_groups[subpop_e].theta = theta_saved
        elif name in theta_init:
            neuron_groups[subpop_e].theta = theta_init[name]

        for connType in recurrent_conntype_names:
            log.info(f"Creating recurrent connections for {connType}")
            preName = name + connType[0]
            postName = name + connType[1]
            connName = preName + postName
            conn = connections[connName] = DiehlAndCookSynapses(
                neuron_groups[preName],
                neuron_groups[postName],
                conn_type=connType)
            conn.connect()  # all-to-all connection
            minDelay, maxDelay = delay[connType]
            if maxDelay > 0:
                deltaDelay = maxDelay - minDelay
                conn.delay = "minDelay + rand() * deltaDelay"
            # TODO: the use of connections with fixed zero weights is inefficient
            # "random" connections for AeAi is matrix with zero everywhere
            # except the diagonal, which contains 10.4
            # "random" connections for AiAe is matrix with 17.0 everywhere
            # except the diagonal, which contains zero
            # TODO: these weights appear to have been tuned,
            #       we may need different values for the O layer
            weightMatrix = None
            if use_premade_weights:
                try:
                    weightMatrix = load_connections(connName,
                                                    random=random_weights)
                except FileNotFoundError:
                    log.info(
                        f"Requested premade {'random' if random_weights else ''} "
                        f"weights, but none found for {connName}")
            if weightMatrix is None:
                log.info("Using generated initial weight matrices")
                weightMatrix = initial_weight_matrices[connName]
            conn.w = weightMatrix.flatten()

        log.debug(f"Creating spike monitors for {name}")
        spike_monitors[subpop_e] = b2.SpikeMonitor(nge, record=record_spikes)
        spike_monitors[subpop_i] = b2.SpikeMonitor(ngi, record=record_spikes)
        if monitoring:
            log.debug(f"Creating state monitors for {name}")
            state_monitors[subpop_e] = b2.StateMonitor(
                nge,
                variables=True,
                record=range(0, n_neurons[subpop_e], 10),
                dt=0.5 * b2.ms,
            )

    if test_mode and supervised:
        # make output neurons more sensitive
        neuron_groups["Oe"].theta = 5.0 * b2.mV  # TODO: refine

    # -------------------------------------------------------------------------
    # create TimedArray of rates for input examples
    # -------------------------------------------------------------------------
    input_dt = 50 * b2.ms
    n_dt_example = int(round(single_example_time / input_dt))
    n_dt_rest = int(round(resting_time / input_dt))
    n_dt_total = int(n_dt_example + n_dt_rest)
    input_rates = np.zeros((n_data * n_dt_total, n_neurons["Xe"]),
                           dtype=np.float16)
    log.info("Preparing input rate stream {}".format(input_rates.shape))
    for j in range(n_data):
        spike_rates = data["x"][j].reshape(n_neurons["Xe"]) / 8
        spike_rates *= input_intensity
        start = j * n_dt_total
        input_rates[start:start + n_dt_example] = spike_rates
    input_rates = input_rates * b2.Hz
    stimulus_X = b2.TimedArray(input_rates, dt=input_dt)
    total_data_time = n_data * n_dt_total * input_dt

    # -------------------------------------------------------------------------
    # create TimedArray of rates for input labels
    # -------------------------------------------------------------------------
    if "Y" in input_population_names:
        input_label_rates = np.zeros((n_data * n_dt_total, n_neurons["Ye"]),
                                     dtype=np.float16)
        log.info("Preparing input label rate stream {}".format(
            input_label_rates.shape))
        if not test_mode:
            label_spike_rates = to_categorical(data["y"], dtype=np.float16)
        else:
            label_spike_rates = np.ones(n_data)
        label_spike_rates *= input_label_intensity
        for j in range(n_data):
            start = j * n_dt_total
            input_label_rates[start:start +
                              n_dt_example] = label_spike_rates[j]
        input_label_rates = input_label_rates * b2.Hz
        stimulus_Y = b2.TimedArray(input_label_rates, dt=input_dt)

    # -------------------------------------------------------------------------
    # create input population and connections from input populations
    # -------------------------------------------------------------------------
    for k, name in enumerate(input_population_names):
        subpop_e = name + "e"
        # stimulus is repeated for duration of simulation
        # (i.e. if there are multiple epochs)
        neuron_groups[subpop_e] = b2.PoissonGroup(
            n_neurons[subpop_e],
            rates=f"stimulus_{name}(t % total_data_time, i)")
        log.debug(f"Creating spike monitors for {name}")
        spike_monitors[subpop_e] = b2.SpikeMonitor(neuron_groups[subpop_e],
                                                   record=record_spikes)

    for name in connection_names:
        log.info(f"Creating connections between {name[0]} and {name[1]}")
        for connType in forward_conntype_names:
            log.debug(f"connType {connType}")
            preName = name[0] + connType[0]
            postName = name[1] + connType[1]
            connName = preName + postName
            stdp_on = ee_STDP_on and connName in stdp_conn_names
            nu_factor = 10.0 if name in ["AO"] else None
            conn = connections[connName] = DiehlAndCookSynapses(
                neuron_groups[preName],
                neuron_groups[postName],
                conn_type=connType,
                stdp_on=stdp_on,
                stdp_rule=stdp_rule,
                custom_namespace=custom_namespace,
                nu_factor=nu_factor,
            )
            conn.connect()  # all-to-all connection
            minDelay, maxDelay = delay[connType]
            if maxDelay > 0:
                deltaDelay = maxDelay - minDelay
                conn.delay = "minDelay + rand() * deltaDelay"
            weightMatrix = None
            if use_premade_weights:
                try:
                    weightMatrix = load_connections(connName,
                                                    random=random_weights)
                except FileNotFoundError:
                    log.info(
                        f"Requested premade {'random' if random_weights else ''} "
                        f"weights, but none found for {connName}")
            if weightMatrix is None:
                log.info("Using generated initial weight matrices")
                weightMatrix = initial_weight_matrices[connName]
            conn.w = weightMatrix.flatten()
            if monitoring:
                log.debug(f"Creating state monitors for {connName}")
                state_monitors[connName] = b2.StateMonitor(
                    conn,
                    variables=True,
                    record=range(0, n_neurons[preName] * n_neurons[postName],
                                 1000),
                    dt=5 * b2.ms,
                )

    if ee_STDP_on:

        @b2.network_operation(dt=total_example_time, order=1)
        def normalize_weights(t):
            for connName in connections:
                if connName in stdp_conn_names:
                    # log.debug(
                    #     "Normalizing weights for {} " "at time {}".format(connName, t)
                    # )
                    conn = connections[connName]
                    connweights = np.reshape(
                        conn.w, (len(conn.source), len(conn.target)))
                    colSums = connweights.sum(axis=0)
                    ok = colSums > 0
                    colFactors = np.ones_like(colSums)
                    colFactors[ok] = total_weight[connName] / colSums[ok]
                    connweights *= colFactors
                    conn.w = connweights.flatten()

        network_operations.append(normalize_weights)

    def record_cumulative_spike_counts(t=None):
        if t is None or t > 0:
            metadata.nseen += 1
        for name in population_names + input_population_names:
            subpop_e = name + "e"
            count = pd.DataFrame(spike_monitors[subpop_e].count[:][None, :],
                                 index=[metadata.nseen])
            count = count.rename_axis("tbin")
            count = count.rename_axis("neuron", axis="columns")
            store.append(f"cumulative_spike_counts/{subpop_e}", count)

    @b2.network_operation(dt=total_example_time, order=0)
    def record_cumulative_spike_counts_net_op(t):
        record_cumulative_spike_counts(t)

    network_operations.append(record_cumulative_spike_counts_net_op)

    def progress():
        log.debug("Starting progress")
        starttime = time.process_time()
        labels = get_labels(data)
        log.info("So far seen {} examples".format(metadata.nseen))
        store.append(
            f"nseen",
            pd.Series(data=[metadata.nseen], index=[metadata.nprogress]))
        metadata.nprogress += 1
        assignments_window, accuracy_window = get_windows(
            metadata.nseen, progress_assignments_window,
            progress_accuracy_window)
        for name in population_names + input_population_names:
            log.debug(f"Progress for population {name}")
            subpop_e = name + "e"
            csc = store.select(f"cumulative_spike_counts/{subpop_e}")
            spikecounts_present = spike_counts_from_cumulative(
                csc,
                n_data,
                metadata.nseen,
                n_neurons[subpop_e],
                start=-accuracy_window)
            n_spikes_present = spikecounts_present["count"].sum()
            if n_spikes_present > 0:
                spikerates = (
                    spikecounts_present.groupby("i")["count"].mean().astype(
                        np.float32))
                # this reindex no longer necessary?
                spikerates = spikerates.reindex(np.arange(n_neurons[subpop_e]),
                                                fill_value=0)
                spikerates = add_nseen_index(spikerates, metadata.nseen)
                store.append(f"rates/{subpop_e}", spikerates)
                store.flush()
                fn = os.path.join(config.output_path,
                                  "spikerates-summary-{}.pdf".format(subpop_e))
                plot_rates_summary(store.select(f"rates/{subpop_e}"),
                                   filename=fn,
                                   label=subpop_e)
            if name in population_names:
                if not test_mode:
                    spikecounts_past = spike_counts_from_cumulative(
                        csc,
                        n_data,
                        metadata.nseen,
                        n_neurons[subpop_e],
                        end=-accuracy_window,
                        atmost=assignments_window,
                    )
                    n_spikes_past = spikecounts_past["count"].sum()
                    log.debug(
                        "Assignments based on {} spikes".format(n_spikes_past))
                    if name == "O":
                        assignments = pd.DataFrame({
                            "label":
                            np.arange(n_neurons[subpop_e], dtype=np.int32)
                        })
                    else:
                        assignments = get_assignments(spikecounts_past, labels)
                    assignments = add_nseen_index(assignments, metadata.nseen)
                    store.append(f"assignments/{subpop_e}", assignments)
                else:
                    assignments = store.select(f"assignments/{subpop_e}")
                if n_spikes_present == 0:
                    log.debug(
                        "No spikes in present interval - skipping accuracy estimate"
                    )
                else:
                    log.debug(
                        "Accuracy based on {} spikes".format(n_spikes_present))
                    predictions = get_predictions(spikecounts_present,
                                                  assignments, labels)
                    accuracy = get_accuracy(predictions, metadata.nseen)
                    store.append(f"accuracy/{subpop_e}", accuracy)
                    store.flush()
                    accuracy_msg = (
                        "Accuracy [{}]: {:.1f}%  ({:.1f}–{:.1f}% 1σ conf. int.)\n"
                        "{:.1f}% of examples have no prediction\n"
                        "Accuracy excluding non-predictions: "
                        "{:.1f}%  ({:.1f}–{:.1f}% 1σ conf. int.)")

                    log.info(
                        accuracy_msg.format(subpop_e, *accuracy.values.flat))
                    fn = os.path.join(config.output_path,
                                      "accuracy-{}.pdf".format(subpop_e))
                    plot_accuracy(store.select(f"accuracy/{subpop_e}"),
                                  filename=fn)
                    fn = os.path.join(config.output_path,
                                      "spikerates-{}.pdf".format(subpop_e))
                    plot_quantity(
                        spikerates,
                        filename=fn,
                        label=f"spike rate {subpop_e}",
                        nseen=metadata.nseen,
                    )
                theta = theta_to_pandas(subpop_e, neuron_groups,
                                        metadata.nseen)
                store.append(f"theta/{subpop_e}", theta)
                fn = os.path.join(config.output_path,
                                  "theta-{}.pdf".format(subpop_e))
                plot_quantity(
                    theta,
                    filename=fn,
                    label=f"theta {subpop_e} (mV)",
                    nseen=metadata.nseen,
                )
                fn = os.path.join(config.output_path,
                                  "theta-summary-{}.pdf".format(subpop_e))
                plot_theta_summary(store.select(f"theta/{subpop_e}"),
                                   filename=fn,
                                   label=subpop_e)
        if not test_mode or metadata.nseen == 0:
            for conn in config.save_conns:
                log.info(f"Saving connection {conn}")
                conn_df = connections_to_pandas(connections[conn],
                                                metadata.nseen)
                store.append(f"connections/{conn}", conn_df)
            for conn in config.plot_conns:
                log.info(f"Plotting connection {conn}")
                subpop = conn[-2:]
                if "O" in conn:
                    assignments = None
                else:
                    try:
                        assignments = store.select(
                            f"assignments/{subpop}",
                            where="nseen == metadata.nseen")
                        assignments = assignments.reset_index("nseen",
                                                              drop=True)
                    except KeyError:
                        assignments = None
                fn = os.path.join(config.output_path,
                                  "weights-{}.pdf".format(conn))
                plot_weights(
                    connections[conn],
                    assignments,
                    theta=None,
                    filename=fn,
                    max_weight=None,
                    nseen=metadata.nseen,
                    output=("O" in conn),
                    feedback=("O" in conn[:2]),
                    label=conn,
                )
            if monitoring:
                for km, vm in spike_monitors.items():
                    states = vm.get_states()
                    with open(
                            os.path.join(config.output_path,
                                         f"saved-spikemonitor-{km}.pickle"),
                            "wb",
                    ) as f:
                        pickle.dump(states, f)

                for km, vm in state_monitors.items():
                    states = vm.get_states()
                    with open(
                            os.path.join(config.output_path,
                                         f"saved-statemonitor-{km}.pickle"),
                            "wb",
                    ) as f:
                        pickle.dump(states, f)

        log.debug("progress took {:.3f} seconds".format(time.process_time() -
                                                        starttime))

    if progress_interval > 0:

        @b2.network_operation(dt=total_example_time * progress_interval,
                              order=2)
        def progress_net_op(t):
            # if t < total_example_time:
            #    return None
            progress()

        network_operations.append(progress_net_op)

    # -------------------------------------------------------------------------
    # run the simulation and set inputs
    # -------------------------------------------------------------------------
    log.info("Constructing the network")
    net = b2.Network()
    for obj_list in [
            neuron_groups, connections, spike_monitors, state_monitors
    ]:
        for key in obj_list:
            net.add(obj_list[key])

    for obj in network_operations:
        net.add(obj)

    log.info("Starting simulations")

    net.run(runtime,
            report="text",
            report_period=(60 * b2.second),
            profile=profile)

    b2.device.build(directory=os.path.join("build", runname),
                    compile=True,
                    run=True,
                    debug=False)

    if profile:
        log.debug(b2.profiling_summary(net, 10))

    # -------------------------------------------------------------------------
    # save results
    # -------------------------------------------------------------------------

    log.info("Saving results")
    progress()
    if not test_mode:
        record_cumulative_spike_counts()
        save_theta(population_names, neuron_groups)
        save_connections(connections)
max_power = np.amax(spectral_power)
power_range = max_power - min_power
spectral_power_normalised = (spectral_power - min_power) / power_range

# emphasise components extending horizontally, in time
kernel_len = 4
kernel = np.ones((1, kernel_len))
spectral_input = ndimage.convolve(spectral_power_normalised, kernel)
spectral_input[spectral_input < 0.7 * kernel_len] = 0

plt.figure()
plt.imshow(spectral_input, aspect='auto', origin='lower')
plt.savefig('figures/%s_spectral_input.png' % input_name)

dt = (bins[1] - bins[0]) * b2.second
sound_input = b2.TimedArray(spectral_input.T, dt=dt)

eqs = '''
dv/dt = (I-v)/(10*ms) : 1
I = sound_input(t, i): 1
'''
anf = b2.NeuronGroup(N=n_freqs, model=eqs, reset='v=0', threshold='v>1')
m = b2.SpikeMonitor(anf)

print("Building and running simulation...")
b2.run(sound.duration, report='stdout')
print("Done!")

print("Writing spike files...")
indices = np.array(m.i)
times = np.array(m.t)
Beispiel #28
0
amp_w1_3 = nfs_param['amp_w1 (nA)'] * b2.nA
tau_w1_3 = nfs_param['tau_w1 (ms)'] * b2.ms
amp_w2_3 = nfs_param['amp_w2 (nA)'] * b2.nA
tau_w2_3 = nfs_param['tau_w2 (ms)'] * b2.ms

amp_vt1_3 = nfs_param['amp_vt1 (mV)'] * b2.mV
tau_vt1_3 = nfs_param['tau_vt1 (ms)'] * b2.ms
amp_vt2_3 = nfs_param['amp_vt2 (mV)'] * b2.mV
tau_vt2_3 = nfs_param['tau_vt2 (ms)'] * b2.ms

tau_exc_3 = params.conn_param['L23_L23']['exc_nfs']['tau_syn'] * b2.ms
tau_inh_3 = params.conn_param['L23_L23']['nfs_nfs']['tau_syn'] * b2.ms

#####
I_newexc = np.loadtxt('Iexc.txt') * b2.namp
Iexc_ext = b2.TimedArray(I_newexc, dt=1. * b2.ms)

I_newfs = np.loadtxt('Ifs.txt') * b2.namp
Ifs_ext = b2.TimedArray(I_newfs, dt=1. * b2.ms)

I_newnfs = np.loadtxt('Infs.txt') * b2.namp
Infs_ext = b2.TimedArray(I_newnfs, dt=1. * b2.ms)

####

################ forming populations #############

pops = {}

pops['L23exc'] = b2.NeuronGroup(params.size['L23']['exc'],
                                model=model_eqs_1,
Beispiel #29
0
    def __init__(self, num_neurons, tau, threshold, duration=500):
        # TODO: Include t_max and v_max variables in the brian model, have them updated per-spike and try to create a custom event when t=t(end) to update the model weights
        #
        self.duration = duration * ms
        self.num_neurons = num_neurons
        self.threshold = threshold
        self.tau = tau * ms

        # Helper variables
        self._count_mat = np.zeros((duration * 10, self.num_neurons), int)
        # Synaptic efficacies
        self.weights = np.random.normal(0, 1e-3, num_neurons)

        # Model definition
        b2.start_scope()
        eqs = 'dv/dt = -v / tau: 1'
        self.counts = b2.TimedArray(self._count_mat, dt=b2.defaultclock.dt)

        # Evaluation network
        self.target = b2.NeuronGroup(1,
                                     eqs,
                                     threshold='v>threshold',
                                     reset='v=0',
                                     namespace={
                                         'tau': self.tau,
                                         'threshold': self.threshold
                                     })
        self.driving = b2.SpikeGeneratorGroup(self.num_neurons, [0], [0] * ms)

        self.spike_response = 'v+=w*counts(t, i)'
        self.synapses = b2.Synapses(self.driving,
                                    self.target,
                                    'w: 1',
                                    on_pre=self.spike_response)
        self.synapses.connect(i=list(range(self.num_neurons)), j=0)
        self.synapses.w = self.weights

        self.voltage = b2.StateMonitor(self.target, 'v', record=True)
        self.spikes = b2.SpikeMonitor(self.target, record=True)

        self.net = b2.Network(self.target, self.driving, self.synapses,
                              self.voltage, self.spikes)
        self.net.store()

        # Training network
        self.target_train = b2.NeuronGroup(self.num_neurons,
                                           eqs,
                                           namespace={'tau': self.tau})
        self.driving_train = b2.SpikeGeneratorGroup(self.num_neurons, [0],
                                                    [0] * ms)

        self.train_response = 'v+=1*counts(t, i)'
        self.synapses_train = b2.Synapses(self.driving_train,
                                          self.target_train,
                                          'w: 1',
                                          on_pre=self.train_response)
        self.synapses_train.connect(condition='i==j')
        self.synapses_train.w = self.weights

        self.voltage_train = b2.StateMonitor(self.target_train,
                                             'v',
                                             record=True)

        self.net_train = b2.Network(self.target_train, self.driving_train,
                                    self.synapses_train, self.voltage_train)
        self.net_train.store()

        self.debug_0 = 0  # For debugging problematic samples
Beispiel #30
0
S = br.Synapses(G, G, on_pre='v_post += 0.2')
S.connect(i=0, j=1)

M = br.StateMonitor(G, 'v', record=True)

br.run(100 * br.ms)

plt.plot(M.t / br.ms, M.v[0], label='Neuron 0')
plt.plot(M.t / br.ms, M.v[1], label='Neuron 1')
plt.xlabel('Time (ms)')
plt.ylabel('v')

#legend();

import brian2 as br

ta = br.TimedArray([1, 2, 3, 4] * br.mV, dt=0.1 * br.ms)
#print(ta(0.3*br.ms))
G = br.NeuronGroup(1, 'v = ta(t) : volt')
mon = br.StateMonitor(G, 'v', record=True)
net = br.Network(G, mon)
net.run(1 * br.ms)  # doctest: +ELLIPSIS
print(mon[0].v)

ta2d = TimedArray([[1, 2], [3, 4], [5, 6]] * mV, dt=0.1 * ms)
G = NeuronGroup(4, 'v = ta2d(t, i%2) : volt')
mon = StateMonitor(G, 'v', record=True)
net = Network(G, mon)
net.run(0.2 * ms)  # doctest: +ELLIPSIS
print(mon.v[:])