def testLocEquality(self): self.loadTree() loc1 = MorphLoc((4,.5), self.tree) loc2 = MorphLoc((4,.5), self.tree) loc3 = MorphLoc((4,.7), self.tree) assert loc1 == (4,.5) and (4,.5) == loc1 assert loc1 == {'node': 4, 'x':.5} and {'node': 4, 'x':.5} == loc1 assert loc1 == loc2 and loc2 == loc1 assert loc1 != (4,.7) and (4,.7) != loc1 assert loc1 != {'node': 5, 'x':.5} and {'node': 5, 'x':.5} != loc1 assert loc1 != loc3 and loc3 != loc1 loc4 = MorphLoc((1,.5), self.tree) assert loc4 == (1,.8) and loc4 != (4,.5)
def calcImpedanceMatrix(self, locarg, i_amp=0.001, t_dur=100., pplot=False): if isinstance(locarg, list): locs = [MorphLoc(loc, self) for loc in locarg] elif isinstance(locarg, str): locs = self.getLocs(locarg) else: raise IOError('`locarg` should be list of locs or string') z_mat = np.zeros((len(locs), len(locs))) for ii, loc0 in enumerate(locs): for jj, loc1 in enumerate(locs): self.initModel(dt=self.dt, t_calibrate=self.t_calibrate, v_eq=self.v_eq, factor_lambda=self.factor_lambda) self.addIClamp(loc0, i_amp, 0., t_dur) self.storeLocs([loc0, loc1], 'rec locs') # simulate res = self.run(t_dur) # voltage deflections # v_trans = res['v_m'][1][-int(1./self.dt)] - self[loc1['node']].e_eq v_trans = res['v_m'][1][-int(1. / self.dt)] - res['v_m'][1][0] # compute impedances z_mat[ii, jj] = v_trans / i_amp if pplot: import matplotlib.pyplot as pl pl.figure() pl.plot(res['t'], res['v_m'][1]) pl.show() return z_mat
def calcImpedanceKernelMatrix(self, locarg, i_amp=0.001, dt_pulse=0.1, t_max=100.): tk = np.arange(0., t_max, self.dt) if isinstance(locarg, list): locs = [MorphLoc(loc, self) for loc in locarg] elif isinstance(locarg, str): locs = self.getLocs(locarg) else: raise IOError('`locarg` should be list of locs or string') zk_mat = np.zeros((len(tk), len(locs), len(locs))) for ii, loc0 in enumerate(locs): for jj, loc1 in enumerate(locs): loc1 = locs[jj] self.initModel(dt=self.dt, t_calibrate=self.t_calibrate, v_eq=self.v_eq, factor_lambda=self.factor_lambda) self.addIClamp(loc0, i_amp, 0., dt_pulse) self.storeLocs([loc0, loc1], 'rec locs') # simulate res = self.run(t_max) # voltage deflections v_trans = res['v_m'][1][1:] - self[loc1['node']].e_eq # compute impedances zk_mat[:, ii, jj] = v_trans / (i_amp * dt_pulse) return tk, zk_mat
def addAMPASynapse(self, loc, g_max, tau): loc = MorphLoc(loc, self) # create the synapse syn = h.AlphaSynapse(self.sections[loc['node']](loc['x'])) syn.tau = tau syn.gmax = g_max # store the synapse self.syns.append(syn)
def addExpSyn(self, loc, tau, e_r): loc = MorphLoc(loc, self) # create the synapse syn = h.exp_AMPA_NMDA(self.sections[loc['node']](loc['x'])) syn.tau = tau syn.e = e_r # store the synapse self.syns.append(syn)
def addDoubleExpCurrent(self, loc, tau1, tau2): loc = MorphLoc(loc, self) # create the synapse syn = h.epsc_double_exp(self.sections[loc['node']](loc['x'])) syn.tau1 = tau1 syn.tau2 = tau2 # store the synapse self.syns.append(syn)
def addShunt(self, loc, g, e_r): loc = MorphLoc(loc, self) # create the shunt shunt = h.Shunt(self.sections[loc['node']](loc['x'])) shunt.g = g shunt.e = e_r # store the shunt self.shunts.append(shunt)
def addIClamp(self, loc, amp, delay, dur): loc = MorphLoc(loc, self) # create the current clamp iclamp = h.IClamp(self.sections[loc['node']](loc['x'])) iclamp.delay = delay + self.t_calibrate # ms iclamp.dur = dur # ms iclamp.amp = amp # nA # store the iclamp self.iclamps.append(iclamp)
def addDoubleExpSynapse(self, loc, tau1, tau2, e_r): loc = MorphLoc(loc, self) # create the synapse syn = h.Exp2Syn(self.sections[loc['node']](loc['x'])) syn.tau1 = tau1 syn.tau2 = tau2 syn.e = e_r # store the synapse self.syns.append(syn)
def addVClamp(self, loc, e_c, dur): loc = MorphLoc(loc, self) # add the voltage clamp vclamp = h.SEClamp(self.sections[loc['node']](loc['x'])) vclamp.rs = 0.01 vclamp.dur1 = dur vclamp.amp1 = e_c # store the vclamp self.vclamps.append(vclamp)
def addNMDASynapse(self, loc, tau, tau_nmda, e_r=0., nmda_ratio=1.7): loc = MorphLoc(loc, self) # create the synapse syn = h.exp_AMPA_NMDA(self.sections[loc['node']](loc['x'])) syn.tau = tau syn.tau_NMDA = tau_nmda syn.e = e_r syn.NMDA_ratio = nmda_ratio # store the synapse self.syns.append(syn)
def setSynLocs(self): global SYN_NODE_IND, SYN_XCOMP # set computational tree self.setCompTree() self.treetype = 'computational' # define the locations locs = [MorphLoc((SYN_NODE_IND, x), self, set_as_comploc=True) for x in SYN_XCOMP] self.storeLocs(locs, name='syn locs') self.storeLocs([(1., 0.5)], name='soma loc') # set treetype back self.treetype = 'original'
def runExperiment(self, loc, g_max_ampa, g_max_nmda, n_syn=10, with_ap=False, delta_t=0., loc_=None, n_syn_=20): """ Simulate the experiment with `n_syn` synapses at `loc` `with_ap` as ``True`` elicits ap with strong current pulse at soma """ global EL, T_MAX, DT, T0, DELTA_T loc = MorphLoc(loc, self) self.initModel(dt=DT, t_calibrate=200., v_init=EL, factor_lambda=1.) # add the synapses self.setActivation(loc, n_syn, g_max_ampa, g_max_nmda, t0=T0) if loc_ is not None: loc_ = MorphLoc(loc_, self) self.setActivation(loc_, n_syn_, g_max_ampa, g_max_nmda, t0=T0 - DELTA_T) # add current clap if with_ap: self.addIClamp((1, .5), 4., T0 + delta_t, 1.) # set recording locs rec_locs = [(1, .5), loc] if loc_ is not None: rec_locs.append(loc_) self.storeLocs(rec_locs, name='rec locs') # run the simulation res = self.run(T_MAX, pprint=True) # delete the model self.deleteModel() return res
def reduceModel(self, pprint=False): global SYN_NODE_IND, SYN_XCOMP locs = [MorphLoc((1, .5), self, set_as_comploc=True)] + \ [MorphLoc((SYN_NODE_IND, x), self, set_as_comploc=True) for x in SYN_XCOMP] # creat the reduced compartment tree ctree = self.createCompartmentTree(locs) # create trees to derive fitting matrices sov_tree, greens_tree = self.getZTrees() # compute the steady state impedance matrix z_mat = greens_tree.calcImpedanceMatrix(locs)[0].real # fit the conductances to steady state impedance matrix ctree.computeGMC(z_mat, channel_names=['L']) if pprint: np.set_printoptions(precision=1, linewidth=200) print(('Zmat original (MOhm) =\n' + str(z_mat))) print( ('Zmat fitted (MOhm) =\n' + str(ctree.calcImpedanceMatrix()))) # get SOV constants alphas, phimat = sov_tree.getImportantModes(locarg=locs, sort_type='importance', eps=1e-12) # n_mode = len(locs) # alphas, phimat = alphas[:n_mode], phimat[:n_mode, :] importance = sov_tree.getModeImportance(sov_data=(alphas, phimat), importance_type='full') # fit the capacitances from SOV time-scales # ctree.computeC(-alphas*1e3, phimat, weight=importance) ctree.computeC(-alphas[:1] * 1e3, phimat[:1, :], importance=importance[:1]) if pprint: print(('Taus original (ms) =\n' + str(np.abs(1. / alphas)))) lambdas, _, _ = ctree.calcEigenvalues() print(('Taus fitted (ms) =\n' + str(np.abs(1. / lambdas)))) return ctree
def addSinClamp(self, loc, amp, delay, dur, bias, freq, phase): loc = MorphLoc(loc, self) # create the current clamp iclamp = h.SinClamp(self.sections[loc['node']](loc['x'])) iclamp.delay = delay + self.t_calibrate # ms iclamp.dur = dur # ms iclamp.pkamp = amp # nA iclamp.bias = bias # nA iclamp.freq = freq # Hz iclamp.phase = phase # rad # store the iclamp self.iclamps.append(iclamp)
def addOUClamp(self, loc, tau, mean, stdev, delay, dur, seed=None): seed = np.random.randint(1e16) if seed is None else seed loc = MorphLoc(loc, self) # create the current clamp if tau > 1e-9: iclamp = h.OUClamp(self.sections[loc['node']](loc['x'])) iclamp.tau = tau else: iclamp = h.WNclamp(self.sections[loc['node']](loc['x'])) iclamp.mean = mean # nA iclamp.stdev = stdev # nA iclamp.delay = delay + self.t_calibrate # ms iclamp.dur = dur # ms iclamp.seed_usr = seed # ms iclamp.dt_usr = self.dt # ms # store the iclamp self.iclamps.append(iclamp)
def addNMDASynapse(self, loc, g_max, e_rev, c_mg, dur_rel, amp_rel): loc = MorphLoc(loc, self) # create the synapse syn = h.NMDA_Mg_T(self.sections[loc['node']](loc['x'])) syn.gmax = g_max syn.Erev = e_rev syn.mg = c_mg # create the presynaptic segment for release pre = h.Section(name='pre %d' % len(self.pres)) pre.insert('release_BMK') pre(0.5).release_BMK.dur = dur_rel pre(0.5).release_BMK.amp = amp_rel # connect h.setpointer(pre(0.5).release_BMK._ref_T, 'C', syn) # store the synapse self.nmdas.append(syn) self.pres.append(pre)
def addDoubleExpNMDASynapse(self, loc, tau1, tau2, tau1_nmda, tau2_nmda, e_r=0., nmda_ratio=1.7): loc = MorphLoc(loc, self) # create the synapse syn = h.double_exp_AMPA_NMDA(self.sections[loc['node']](loc['x'])) syn.tau1 = tau1 syn.tau2 = tau2 syn.tau1_NMDA = tau1_nmda syn.tau2_NMDA = tau2_nmda syn.e = e_r syn.NMDA_ratio = nmda_ratio # store the synapse self.syns.append(syn)
def addOUReversal(self, loc, tau, mean, stdev, g_val, delay, dur, seed=None): seed = np.random.randint(1e16) if seed is None else seed loc = MorphLoc(loc, self) # create the current clamp iclamp = h.OUReversal(self.sections[loc['node']](loc['x'])) iclamp.tau = tau # ms iclamp.mean = mean # mV iclamp.stdev = stdev # mV iclamp.g = g_val # uS iclamp.delay = delay + self.t_calibrate # ms iclamp.dur = dur # ms iclamp.seed_usr = seed # ms iclamp.dt_usr = self.dt # ms # store the iclamp self.iclamps.append(iclamp)
def testLocFunctionality(self): self.loadTree() # locs in the original tree self.tree.treetype = 'original' locs = [MorphLoc({'node': 1, 'x': .5}, self.tree), MorphLoc({'node': 4, 'x': .5}, self.tree), MorphLoc({'node': 5, 'x': .5}, self.tree), MorphLoc({'node': 7, 'x': .5}, self.tree), MorphLoc({'node': 6, 'x': .5}, self.tree), MorphLoc({'node': 8, 'x': .5}, self.tree)] # set the computational tree self.tree.setCompTree(eps=1.) self.tree.treetype = 'computational' for loc in locs: loc._setComputationalLoc() assert locs[0].comp_loc == locs[0].loc assert locs[1].comp_loc == locs[1].loc assert locs[2].comp_loc == {'node': 6, 'x': .25} assert locs[3].comp_loc == {'node': 8, 'x': .25} assert locs[4].comp_loc == {'node': 6, 'x': .75} assert locs[5].comp_loc == {'node': 8, 'x': .75}
def findNMDAThreshold(self, loc, n_syns, g_max_ampa, g_max_nmda, delta_t=0., with_TTX=False, with_ap=False, at_soma=False, pplot=False, loc_=None, n_syn_=20): """ Extrac nmda spike threshold Returns ------- n_syn_thr: int threshold number of synapses to activate res_nmda: dict of np.ndarray contains 'amp', 'width' and 'surf' of waveform elicited by second stimulus for each activation level res_sim: list of dict contains the voltage traces for each simulation at_soma: bool If ``True``, the threshold is measured at the soma. Otherwise at the dendritic synapse. """ global T0, DELTA_T, DT assert 0 not in n_syns lll = MorphLoc(loc, self) print("\n--> Distance to soma = %.2f um \n" % self.distancesToSoma([lll])[0]) if with_TTX: self.addTTX() ix_thr = 0 if at_soma else 1 # extract baseline AP if with_ap: v_ap = self.extractAP(loc) ix_spike = (int((T0 + delta_t) / DT), int( (T0 + delta_t + 5.) / DT)) res_sim = [] res_nmda = {'amp': [], 'width': [], 'surf': []} for nn in n_syns: res = self.runExperiment(loc, g_max_ampa, g_max_nmda, n_syn=nn, delta_t=delta_t, with_ap=with_ap, loc_=loc_, n_syn_=n_syn_) if with_ap: res['v_m_'] = subtractAP(res['v_m'], v_ap, ix_spike, ix_thr) else: res['v_m_'] = copy.deepcopy(res['v_m']) res_sim.append(res) amp, width, surf = calcAmpWidthSurface(res['v_m_'][ix_thr], T0 + DELTA_T, dt=DT) res_nmda['amp'].append(amp) res_nmda['width'].append(width) res_nmda['surf'].append(surf) if pplot: pl.figure() ax = pl.subplot(121) ax.set_title('soma') ax.plot(res['t'], res['v_m'][0], 'b') ax.plot(res['t'], res['v_m_'][0], 'r--') ax = pl.subplot(122) ax.set_title('dend') ax.plot(res['t'], res['v_m'][1], 'b') ax.plot(res['t'], res['v_m_'][1], 'r--') pl.show() for key, val in res_nmda.items(): res_nmda[key] = np.array(val) # nmda threshold as steepest surface increase n_syn_thr = deviationThrFromLinear(res_nmda['surf']) return n_syn_thr, res_nmda, res_sim