def dendrite_time_stepper(time_vec, I_drive, L3, tau_di): with open('../master_rate_matrix.soen', 'rb') as data_file: data_array_imported = pickle.load(data_file) I_di_list__imported = data_array_imported['I_di_list'] I_drive_vec__imported = data_array_imported['I_drive_vec'] master_rate_matrix__imported = data_array_imported['master_rate_matrix'] p = physical_constants() Phi0 = p['Phi0'] I_fq = Phi0 / L3 I_di_vec = np.zeros([len(time_vec), 1]) for ii in range(len(time_vec) - 1): dt = time_vec[ii + 1] - time_vec[ii] if I_drive[ii] > 18.6e-6: ind1 = (np.abs(np.asarray(I_drive_vec__imported) - I_drive[ii])).argmin() ind2 = ( np.abs(np.asarray(I_di_list__imported[ind1]) - I_di_vec[ii])).argmin() rate = master_rate_matrix__imported[ind1, ind2] # linear interpolation # rate = np.interp(I_drive[ii],I_drive_vec__imported,master_rate_matrix__imported[:,ind2]) else: rate = 0 I_di_vec[ii + 1] = rate * I_fq * dt + (1 - dt / tau_di) * I_di_vec[ii] return I_di_vec
def inter_fluxon_interval__fit(I, mu1, mu2, V0): Ic = 40e-6 R = 4.125 V_fq_vec = (Ic * R) * ((I / Ic)**mu1 - 1)**(mu2) + V0 p = physical_constants() ifi_vec = p['Phi0'] / V_fq_vec return ifi_vec
#%% import numpy as np from matplotlib import pyplot as plt from scipy.signal import find_peaks from scipy.signal import savgol_filter # from soen_sim import input_signal, synapse, dendrite, neuron from _plotting import plot_dend_rate_array, plot_dend_time_traces from _functions import cv, save_session_data, read_wr_data from util import physical_constants import pickle p = physical_constants() plt.close('all') #%% set case num_jjs = 2 # 2 or 4 #%% inputs # DR loop inductances (in all cases, left side has additional 10pH through which flux is coupled (M = k*sqrt(L1*L2); in this case k = 1, L1 = 200pH, L2 = 10pH)) dL = 1 # pH L_left_list = np.arange(7, 13 + dL, dL) # pH L_right_list = np.flip(np.arange(17, 23 + dL, dL)) # pH num_L = len(L_right_list) # dendritic firing junction bias current dI = 2 # uA
def t_fq(I, Ic, R, mu1, mu2): p = physical_constants() t_fq_vec = (p['Phi0'] / (Ic * R)) * ((I / Ic)**mu1 - 1)**(-mu2) return t_fq_vec
def dendritic_time_stepper(time_vec, R, I_drive, I_b, Ic, M_direct, Lm2, Ldr1, Ldr2, L1, L2, L3, tau_di, mu_1, mu_2): p = physical_constants() Phi0 = p['Phi0'] prefactor = Ic * R / Phi0 I_fq = Phi0 / L3 #initial approximations Lj0 = Ljj(Ic, 0) Iflux = 0 Idr2_prev = ((Lm2 + Ldr1 + Lj0) * I_b[0] + M_direct * Iflux) / (Lm2 + Ldr1 + Ldr2 + 2 * Lj0 + (Lm2 + Ldr1 + Lj0) * (Ldr2 + Lj0) / L1) Idr1_prev = I_b[0] - (1 + (Ldr2 + Lj0) / L1) * Idr2_prev Ij2_prev = I_b[1] Ij3_prev = I_b[2] I_di_vec = np.zeros([len(time_vec), 1]) # Idr1_next, Idr2_next, Ij2_next, Ij3_next, I1, I2, I3 = dendrite_current_splitting(Ic,0,I_b[0],I_b[1],I_b[2],M_direct,Lm2,Ldr1,Ldr2,L1,L2,L3,Idr1_prev,Idr2_prev,Ij2_prev,Ij3_prev) # print('Idr1 = {}uA, Idr2 = {}uA, Ij2 = {}uA, Ij3 = {}uA'.format(Idr1_next*1e6,Idr2_next*1e6,Ij2_next*1e6,Ij3_next*1e6)) for ii in range(len(time_vec) - 1): dt = time_vec[ii + 1] - time_vec[ii] #dendrite_current_splitting(Ic, Iflux, Ib1, Ib2, Ib3, M, Lm2,Ldr1,Ldr2,L1,L2,L3,Idr1_prev,Idr2_prev,Ij2_prev,Ij3_prev) Idr1_next, Idr2_next, Ij2_next, Ij3_next, I1, I2, I3 = dendrite_current_splitting( Ic, I_drive[ii + 1], I_b, M_direct, Lm2, Ldr1, Ldr2, L1, L2, L3, Idr1_prev, Idr2_prev, Ij2_prev, Ij3_prev) # I_di_sat = I_di_sat_of_I_dr_2(Idr2_next) Ljdr2 = Ljj(Ic, Idr2_next) Lj2 = Ljj(Ic, Ij2_next) Lj3 = Ljj(Ic, Ij3_next) # Ljdr2 = Ljj(Ic,0) # Lj2 = Ljj(Ic,0) # Lj3 = Ljj(Ic,0) Idr1_prev = Idr1_next Idr2_prev = Idr2_next Ij2_prev = Ij2_next #(Lj3/(L2+Lj2))*I_di_vec[ii] Ij3_prev = Ij3_next # I_j_df_fluxon_soen = Phi0/(L1+Ldr2+Ljdr2+Lj2) # I_j_2_fluxon_soen = Phi0/(Lj2+L_pp) # I_j_3_fluxon_soen = Phi0/(L3+Lj3) I_loop2_from_di = (Lj3 / (L2 + Lj2)) * I_di_vec[ii] I_loop1_from_loop2 = (Lj2 / (L1 + Ljdr2 + Ldr2)) * I_loop2_from_di # print('I_loop2_from_di = {}uA, I_loop1_from_loop2 = {}uA'.format(I_loop2_from_di*1e6,I_loop1_from_loop2*1e6)) Idr2_next -= I_loop1_from_loop2 Ij2_next -= I_loop2_from_di Ij3_next -= I_di_vec[ii] - I_loop2_from_di L_ppp = Lj3 * L3 / (Lj3 + L3) L_pp = L2 + L_ppp L_p = Lj2 * L_pp / (Lj2 + L_pp) # print('L_p = {}pH, L_pp = {}pH, L_ppp = {}pH'.format(L_p*1e12,L_pp*1e12,L_ppp*1e12)) large_number = 1e9 I_flux_1 = 6e-6 I_flux_2 = 20e-6 Ij2_next += I_flux_1 # (Phi0/(L1+L_p))*(L_pp)/(Lj2+L_pp)#(Lj3/(L2+Lj2))*I_di_vec[ii] # print('Ij2_next += {}uA'.format(1e6*(Phi0/(L1+L_p))*(L_pp)/(Lj2+L_pp))) # Ij3_next += (Phi0/L_pp)*(L3/(L3+Lj3)) + (Phi0/(L1+L_p))*L3/(Lj3+L3) - I_di_vec[ii] Ij3_next += I_flux_2 # (Phi0/L_pp)*(L3/(L3+Lj3)) # print('Ij3_next += {}uA'.format(1e6*(Phi0/L_pp)*(L3/(L3+Lj3)))) # print('term_1 = {}; term_2 = {}'.format( (Phi0/L_pp)*(L3/(L3+Lj3)) , (Phi0/(L1+L_p))*L3/(Lj3+L3) ) ) if Idr2_next > Ic: factor_1 = inter_fluxon_interval( Idr2_next) # ( (Idr2_next/Ic)**mu_1 - 1 )**(-mu_2) else: factor_1 = large_number if Ij2_next > Ic: factor_2 = inter_fluxon_interval( Ij2_next) # ( (Ij2_next/Ic)**mu_1 - 1 )**(-mu_2) else: factor_2 = large_number if Ij3_next > Ic: factor_3 = inter_fluxon_interval( Ij3_next) # ( (Ij3_next/Ic)**mu_1 - 1 )**(-mu_2) else: factor_3 = large_number # print('factor_1 = {}, factor_2 = {}, factor_3 = {}'.format(factor_1,factor_2,factor_3)) r_tot = (factor_1 + factor_2 + factor_3)**(-1) I_di_vec[ii + 1] = r_tot * I_fq * dt + (1 - dt / tau_di) * I_di_vec[ii] return I_di_vec
def run_sim(self): sim_params = self.synapse_model_params tf = sim_params['tf'] dt = sim_params['dt'] time_vec = np.arange(0, tf + dt, dt) p = physical_constants() # input_spike_times = self.input_spike_times #setup input signal if hasattr(self, 'input_signal'): self.input_spike_times = self.input_signal.spike_times else: self.input_spike_times = [] #here currents are in uA. they are converted to A before passing back I_sy = self.synaptic_bias_current * 1e6 #these values obtained by fitting to spice simulations #see matlab scripts in a4/calculations/nC/phenomenological_modeling... if 'gamma1' in sim_params: gamma1 = sim_params['gamma1'] else: gamma1 = 0.9 if 'gamma2' in sim_params: gamma2 = sim_params['gamma2'] else: gamma2 = 0.158 if 'gamma3' in sim_params: gamma3 = sim_params['gamma3'] else: gamma3 = 3 / 4 #these fits were obtained by comparing to spice simulations #see matlab scripts in a4/calculations/nC/phenomenological_modeling... # tau_rise = (1.294*I_sy-43.01)*1e-9 tau_rise = (0.038359 * I_sy**2 - 0.778850 * I_sy - 0.441682) * 1e-9 self.integration_loop_total_inductance = self.integration_loop_self_inductance + self.integration_loop_output_inductance _reference_inductance = 775e-9 #inductance at which I_0 fit was performed _scale_factor = _reference_inductance / self.integration_loop_total_inductance #I_0 = (0.06989*I_sy**2-3.948*I_sy+53.73)*_scale_factor #from earlier model assuming 10uA spd # I_0 = (0.006024*I_sy**2-0.202821*I_sy+1.555543)*_scale_factor # in terms of currents I_0 = 1e6 * (2.257804 * I_sy**2 - 76.01606 * I_sy + 583.005805) * p[ 'Phi0'] / self.integration_loop_total_inductance # in terms of n_fq #I_si_sat is actually a function of I_b (loop_current_bias). The fit I_si_sat(I_b) has not yet been performed (20200319) I_si_sat = 19.7 tau_fall = self.integration_loop_time_constant # I_si_vec = synaptic_response_function(time_vec,input_spike_times,I_0,I_si_sat,gamma1,gamma2,gamma3,tau_rise,tau_fall) I_si_vec = np.zeros([len(time_vec), 1]) for ii in range(len(time_vec)): I_si_vec[ii] = synapse_time_stepper(time_vec, ii, self.input_spike_times, I_0, I_si_sat, gamma1, gamma2, gamma3, tau_rise, tau_fall) self.I_si = I_si_vec * 1e-6 self.time_vec = time_vec return self