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
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
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
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
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
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
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
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
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
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
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')
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')
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
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
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
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:])
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
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()
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())
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)
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,
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
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[:])