from neuron import h, init h.load_file("stdrun.hoc") import numpy as np import json import multiprocessing #calculate path length between two sections def fromtodistance(origin_segment, to_segment): h.distance(0, origin_segment.x, sec=origin_segment.sec) return h.distance(to_segment.x, sec=to_segment.sec) def createNMDAsyn(stim_seg, start, weight): # nmda params from Lajeunesse et al 2013 syn = h.Exp2Syn(stim_seg) syn.tau1 = 0.5 syn.tau2 = 13 syn.e = 0 stim = h.NetStim() stim.number = 1 stim.start = start con = h.NetCon(stim, syn) con.weight[0] = weight con.delay = 0 i_vec = h.Vector() i_vec.record(syn._ref_i) return i_vec, con, syn, stim def createAMPAsyn(stim_seg, start, weight): # ampa params from Lajeunesse et al 2013 syn = h.Exp2Syn(stim_seg) syn.tau1 = 0.1 syn.tau2 = 1.4 syn.e = 0 stim = h.NetStim() stim.number = 1 stim.start = start con = h.NetCon(stim, syn) con.weight[0] = weight con.delay = 0 i_vec = h.Vector() i_vec.record(syn._ref_i) return i_vec, con, syn, stim def setupRecordings(stim_seg, soma_seg): # basic recording vectors v_soma = h.Vector() t_vec = h.Vector() v_stim = h.Vector() v_soma.record(soma_seg._ref_v) v_stim.record(stim_seg._ref_v) t_vec.record(h._ref_t) return t_vec, v_stim, v_soma def setupCurrentRecordings_hay(seg): # currents found in apical segments of hay cell currents = {} currents['i_hcn'] = h.Vector() currents['i_hcn'].record(seg.Ih._ref_ihcn) currents['i_ca_lvast'] = h.Vector() currents['i_ca_lvast'].record(seg.Ca_LVAst._ref_ica) currents['i_im'] = h.Vector() currents['i_im'].record(seg.Im._ref_ik) currents['i_ca_hva'] = h.Vector() currents['i_ca_hva'].record(seg.Ca_HVA._ref_ica) currents['i_nata'] = h.Vector() currents['i_nata'].record(seg.NaTa_t._ref_ina) currents['i_ske2'] = h.Vector() currents['i_ske2'].record(seg.SK_E2._ref_ik) currents['i_skv3'] = h.Vector() currents['i_skv3'].record(seg.SKv3_1._ref_ik) return currents def setupCurrentRecordingsNoSK(seg): # currents found in apical segments of hay cell currents = {} currents['i_hcn'] = h.Vector() currents['i_hcn'].record(seg.Ih._ref_ihcn) currents['i_ca_lvast'] = h.Vector() currents['i_ca_lvast'].record(seg.Ca_LVAst._ref_ica) currents['i_im'] = h.Vector() currents['i_im'].record(seg.Im._ref_ik) currents['i_ca_hva'] = h.Vector() currents['i_ca_hva'].record(seg.Ca_HVA._ref_ica) currents['i_nata'] = h.Vector() currents['i_nata'].record(seg.NaTa_t._ref_ina) # currents['i_ske2'] = h.Vector() # currents['i_ske2'].record(seg.SK_E2._ref_ik) currents['i_skv3'] = h.Vector() currents['i_skv3'].record(seg.SKv3_1._ref_ik) return currents def conditionAndTest(stim_seg, soma_seg, Sc0, St0, dSt, start, lag, synType='AMPA'): # setup recordings t_vec, v_stim, v_soma = setupRecordings(stim_seg, soma_seg) # condition stim if synType == 'AMPA': cond_i, condCon, condSyn, condStim = createAMPAsyn(stim_seg, start, Sc0) test_i, testCon, testSyn, testStim = createAMPAsyn(stim_seg, start + lag, St0) else: cond_i, condCon, condSyn, condStim = createNMDAsyn(stim_seg, start, Sc0) test_i, testCon, testSyn, testStim = createNMDAsyn(stim_seg, start + lag, St0) out_vecs = setupCurrentRecordings_hay(stim_seg) # time h.tstop = start + 300 # find first St that generates spike didSpike = False while not didSpike: testCon.weight[0] = St0 print(str(St0)) h.run() ## check for spike if np.max(v_soma.as_numpy()) > 10: didSpike = True else: ## increment weight by 10% St0 = St0 + dSt # fill out output structure with traces out_vecs['t_vec'] = t_vec out_vecs['v_stim'] = v_stim out_vecs['v_soma'] = v_soma out_vecs['cond_i'] = cond_i out_vecs['test_i'] = test_i return St0, out_vecs def conditionAndTestNoSK(stim_seg, soma_seg, Sc0, St0, dSt, start, lag, synType='AMPA'): # setup recordings t_vec, v_stim, v_soma = setupRecordings(stim_seg, soma_seg) # condition stim if synType == 'AMPA': cond_i, condCon, condSyn, condStim = createAMPAsyn(stim_seg, start, Sc0) test_i, testCon, testSyn, testStim = createAMPAsyn(stim_seg, start + lag, St0) else: cond_i, condCon, condSyn, condStim = createNMDAsyn(stim_seg, start, Sc0) test_i, testCon, testSyn, testStim = createNMDAsyn(stim_seg, start + lag, St0) out_vecs = setupCurrentRecordingsNoSK(stim_seg) # time h.tstop = start + 300 # find first St that generates spike didSpike = False while not didSpike: testCon.weight[0] = St0 print(str(St0)) h.run() ## check for spike if np.max(v_soma.as_numpy()) > 10: didSpike = True else: ## increment weight by 10% St0 = St0 + dSt # fill out output structure with traces out_vecs['t_vec'] = t_vec out_vecs['v_stim'] = v_stim out_vecs['v_soma'] = v_soma out_vecs['cond_i'] = cond_i out_vecs['test_i'] = test_i return St0, out_vecs def findSc(stim_seg, soma_seg, start, sc, dWeight, synType='AMPA'): # setup recordings t_vec, v_stim, v_soma = setupRecordings(stim_seg, soma_seg) # condition stim if synType == 'AMPA': i_vec, condCon, condSyn, condStim = createAMPAsyn(stim_seg, start, sc) else: i_vec, condCon, condSyn, condStim = createNMDAsyn(stim_seg, start, sc) h.tstop = start + 300 # first pass, make sure it does produce spike h.run() if np.max(v_soma.as_numpy()) > 10: didSpike = True sc = sc - dWeight ## decrement weight until no spike while didSpike: print(str(sc)) condCon.weight[0] = sc h.run() ## check for spikes if np.max(v_soma.as_numpy()) < 10: didSpike = False ### back to suprathreshold weight sc = sc + dWeight else: sc = sc - dWeight return sc else: print("Error: started with a subthreshold weight") def getT2min(stim_seg, soma_seg, start, sc, synType='AMPA'): # setup recordings t_vec, v_stim, v_soma = setupRecordings(stim_seg, soma_seg) # condition stim if synType == 'AMPA': i_vec, condCon, condSyn, condStim = createAMPAsyn(stim_seg, start, sc) else: i_vec, condCon, condSyn, condStim = createNMDAsyn(stim_seg, start, sc) # run sim h.tstop = start + 300 h.run() indDend = np.argmin(v_stim.as_numpy()[int(h.dt*start):]) indSoma = np.argmin(v_soma.as_numpy()[int(h.dt*start):]) Tdend = t_vec[indDend+int(h.dt*start)] - start Tsoma = t_vec[indSoma+int(h.dt*start)] - start # return Tdend, Tsoma return indDend, indSoma def getTp(stim_seg, soma_seg, start, sc, synType='AMPA'): # setup recordings t_vec, v_stim, v_soma = setupRecordings(stim_seg, soma_seg) # condition stim if synType == 'AMPA': i_vec, condCon, condSyn, condStim = createAMPAsyn(stim_seg, start, sc) else: i_vec, condCon, condSyn, condStim = createNMDAsyn(stim_seg, start, sc) # run sim h.tstop = start + 300 h.run() # find where membrane potential returns to rest restVm = v_stim.as_numpy()[int(start*(1/h.dt) - 25*(1/h.dt))] a = v_stim.as_numpy() b = a[a > restVm - 0.1] c = b[b < restVm + 0.1] t = t_vec.as_numpy() t1 = t[a > restVm - 0.1] t2 = t1[b < restVm + 0.1] ## working backwards from end of sim see where stops being restVm diff = 0.02 ind = -2 while diff < 0.026: diff = t2[ind+1] - t2[ind] ind = ind - 1 Tp = t2[ind+2] - start # same for soma restVm_soma = v_soma.as_numpy()[int(start*(1/h.dt) - 25*(1/h.dt))] a = v_soma.as_numpy() b = a[a > restVm_soma - 0.1] c = b[b < restVm_soma + 0.1] t1 = t[a > restVm_soma - 0.1] t2 = t1[b < restVm_soma + 0.1] ## working backwards from end of sim see where stops being restVm diff = 0.02 ind = -2 while diff < 0.026: diff = t2[ind+1] - t2[ind] ind = ind - 1 Tp_soma = t2[ind+2] - start return Tp, Tp_soma def sweepLags(stim_seg, soma_seg, Sc0, St0, dSt, start, tP, dLag, synType='AMPA', outpath=None): # setup lag = 0 testWeights = [] lags = [] # main loop while (start + lag) <= (start + tP): lags.append(lag) if synType == 'AMPA': S, traces = conditionAndTest(stim_seg, soma_seg, Sc0, St0, dSt, start, lag) else: S, traces = conditionAndTest(stim_seg, soma_seg, Sc0, St0, dSt, start, lag, synType='NMDA') trace_lists = {} for key in traces.keys(): trace_lists[key] = traces[key].to_python() ## save output traces trace_file = outpath + str(stim_seg.sec) + '_lag' + str(np.round(lag,1)) + '_w' + str(np.round(S,3)) + '_traces.json' with open(trace_file, 'w') as fileObj: json.dump(trace_lists, fileObj) lag = lag + dLag testWeights.append(S) # output if outpath == None: return lags, testWeights else: outfile = outpath + str(stim_seg.sec) + '_lagSweep.json' out = {'lags' : lags, 'weights' : testWeights, 'stim_seg' : str(stim_seg), 'Sc0' : Sc0} with open(outfile, 'w') as fileObj: json.dump(out, fileObj) def conditionAndTestMulti(data): sec_num, sec_loc, Sc0, St0, dSt, start, lag, outpath = data from getCells import HayCell cell = HayCell() stim_seg = cell.apic[sec_num](sec_loc) soma_seg = cell.soma[0](0.5) print(str(stim_seg)) print('starting lag: ' + str(np.round(lag,1))) S, traces = conditionAndTest(stim_seg, soma_seg, Sc0, St0, dSt, start, lag) trace_lists = {} for key in traces.keys(): trace_lists[key] = traces[key].to_python() trace_lists['S'] = S trace_file = outpath + str(stim_seg.sec) + '_lag' + str(np.round(lag,1)) + '_w' + str(np.round(S,3)) + '_traces.json' with open(trace_file, 'w') as fileObj: json.dump(trace_lists, fileObj) print('DONE lag: ' + str(np.round(lag,1))) return S def conditionAndTestMultiNoSK(data): sec_num, sec_loc, Sc0, St0, dSt, start, lag, outpath = data from getCells import HayCell cell = HayCell() stim_seg = cell.apic[sec_num](sec_loc) soma_seg = cell.soma[0](0.5) ## remove SK_E2 channels for sec in h.allsec(): try: sec.uninsert('SK_E2') except: pass print(str(stim_seg)) print('starting lag: ' + str(np.round(lag,1))) S, traces = conditionAndTestNoSK(stim_seg, soma_seg, Sc0, St0, dSt, start, lag) trace_lists = {} for key in traces.keys(): trace_lists[key] = traces[key].to_python() trace_lists['S'] = S trace_file = outpath + str(stim_seg.sec) + '_lag' + str(np.round(lag,1)) + '_w' + str(np.round(S,3)) + '_traces.json' with open(trace_file, 'w') as fileObj: json.dump(trace_lists, fileObj) print('DONE lag: ' + str(np.round(lag,1))) return S def getLagData(sec_num, sec_loc, Sc0, St0, dSt, start, tP, dLag, outpath): data = [] lag = 0 while (start + lag) <= (start + tP): data_list = [sec_num, sec_loc, Sc0, St0, dSt, start, lag, outpath] data.append(data_list) lag = lag + dLag return data