def loadTSegmentTree(self): ''' Load point neuron model ''' self.tree = PhysTree(file_n=os.path.join(MORPHOLOGIES_PATH_PREFIX, 'Ttree_segments.swc')) # self.tree = PhysTree(file_n=os.path.join(MORPHOLOGIES_PATH_PREFIX, 'L23PyrBranco.swc')) # capacitance and axial resistance self.tree.setPhysiology(0.8, 100. / 1e6) # ion channels k_chan = channelcollection.Kv3_1() g_k = {1: 0.766 * 1e6} g_k.update({n.index: 0.034*1e6 / self.tree.pathLength((1,.5), (n.index,.5)) \ for n in self.tree if n.index != 1}) self.tree.addCurrent(k_chan, g_k, -85.) na_chan = channelcollection.Na_Ta() self.tree.addCurrent(na_chan, 1.71 * 1e6, 50., node_arg=[self.tree[1]]) # fit leak current self.tree.fitLeakCurrent(-75., 10.) # set equilibirum potententials self.tree.setEEq(-75.) # set computational tree self.tree.setCompTree()
def test_pickling(): # pickle and restore na_ta_channel = channelcollection.Na_Ta() s = pickle.dumps(na_ta_channel) new_na_ta_channel = pickle.loads(s) # multiple pickles s = pickle.dumps(na_ta_channel) s = pickle.dumps(na_ta_channel) new_na_ta_channel = pickle.loads(s) assert True # reaching this means we didn't encounter an error
def loadBall(self): ''' Load point neuron model ''' self.tree = PhysTree(file_n='test_morphologies/ball.swc') # capacitance and axial resistance self.tree.setPhysiology(0.8, 100. / 1e6) # ion channels k_chan = channelcollection.Kv3_1() self.tree.addCurrent(k_chan, 0.766 * 1e6, -85.) na_chan = channelcollection.Na_Ta() self.tree.addCurrent(na_chan, 1.71 * 1e6, 50.) # fit leak current self.tree.fitLeakCurrent(-75., 10.) # set equilibirum potententials self.tree.setEEq(-75.) # set computational tree self.tree.setCompTree()
def test_ionchannel_simplified(remove=True): if not os.path.exists('mech/'): os.mkdir('mech/') na = channelcollection.Na_Ta() p_o = na.computePOpen(-35.) assert np.allclose(p_o, 0.002009216860105564) l_s = na.computeLinSum(-35., 0., 50.) assert np.allclose(l_s, -0.00534261017220376) na.writeModFile('mech/') sk = channelcollection.SK() sk.writeModFile('mech/') if remove: shutil.rmtree('mech/')
def loadBall(self): self.greens_tree = GreensTree( file_n=os.path.join(MORPHOLOGIES_PATH_PREFIX, 'ball.swc')) # capacitance and axial resistance self.greens_tree.setPhysiology(0.8, 100. / 1e6) # ion channels k_chan = channelcollection.Kv3_1() self.greens_tree.addCurrent(k_chan, 0.766 * 1e6, -85.) na_chan = channelcollection.Na_Ta() self.greens_tree.addCurrent(na_chan, 1.71 * 1e6, 50.) # fit leak current self.greens_tree.fitLeakCurrent(-75., 10.) # set computational tree self.greens_tree.setCompTree() # set the impedances self.freqs = np.array([0.]) self.greens_tree.setImpedance(self.freqs) # create sov tree self.sov_tree = self.greens_tree.__copy__(new_tree=SOVTree()) self.sov_tree.calcSOVEquations(maxspace_freq=100.)
def test_expansionpoints(): kv3_1 = channelcollection.Kv3_1() na_ta = channelcollection.Na_Ta() e_hs = np.array([-75., -15.]) # test expansion point for channel with 1 state variable sv_hs = compartmentfitter.getExpansionPoints(e_hs, kv3_1) for svar, f_inf in kv3_1.f_varinf.items(): assert np.allclose(f_inf(e_hs), sv_hs[svar]) assert np.allclose(sv_hs['v'], e_hs) # test expansion point for channel with 2 state variables sv_hs = compartmentfitter.getExpansionPoints(e_hs, na_ta) v_act = np.array([-75., -15., -75., -75., -15., -15.]) v_inact = np.array([-75., -15., -75., -15., -75., -15.]) assert np.allclose(na_ta.f_varinf['m'](v_act), sv_hs['m']) assert np.allclose(na_ta.f_varinf['h'](v_inact), sv_hs['h']) assert not np.allclose(na_ta.f_varinf['h'](v_act), sv_hs['h']) assert np.allclose(v_act, sv_hs['v'])
def test_broadcasting(): na_ta = channelcollection.Na_Ta() v = np.array([-73.234, -50.325, -25.459]) s = np.array([0., 10., 20., 40.]) * 1j # error must be raised if arguments are not broadcastable with pytest.raises(ValueError): na_ta.computeLinSum(v, s) # check if broadcasting rules are applied correctly for voltage and frequency ll = na_ta.computeLinSum(v[:, None], s[None, :]) l1 = na_ta.computeLinear(v[:, None], s[None, :]) l2 = na_ta.computePOpen(v[:, None]) assert ll.shape == (3, 4) assert l1.shape == (3, 4) assert l2.shape == (3, 1) assert np.allclose(ll, (na_ta._getReversal(None) - v[:, None]) * l1 - l2) # check if broadcasting rules are applied correctly for state variables sv = {'m': .2, 'h': .4} ll = na_ta.computeLinSum(v[:, None], s[None, :], **sv) assert ll.shape == (3, 4) sv = {'m': np.array([0.1, 0.2, 0.3]), 'h': np.array([0.9, 0.6, 0.3])} with pytest.raises(ValueError): ll = na_ta.computeLinSum(v[:, None], s[None, :], **sv) sv_ = {'m': sv['m'][:, None], 'h': sv['h'][:, None]} ll = na_ta.computeLinSum(v[:, None], s[None, :], **sv_) assert ll.shape == (3, 4) sv__ = {'m': sv['m'][:, None, None], 'h': sv['h'][None, None, :]} l_ = na_ta.computeLinSum(v[:, None, None], s[None, :, None], **sv__) assert l_.shape == (3, 4, 3) for ii in range(4): assert np.allclose([ll[0, ii], ll[1, ii], ll[2, ii]], [l_[0, ii, 0], l_[1, ii, 1], l_[2, ii, 2]])
def testChannelFit(self): self.loadBall() locs = [(1, 0.5)] e_eqs = [-75., -55., -35., -15.] # create compartment tree ctree = self.greens_tree.createCompartmentTree(locs) ctree.addCurrent(channelcollection.Na_Ta(), 50.) ctree.addCurrent(channelcollection.Kv3_1(), -85.) # create tree with only leak greens_tree_pas = self.greens_tree.__copy__() greens_tree_pas[1].currents = {'L': greens_tree_pas[1].currents['L']} greens_tree_pas.setCompTree() greens_tree_pas.setImpedance(self.freqs) # compute the passive impedance matrix z_mat_pas = greens_tree_pas.calcImpedanceMatrix(locs)[0] # create tree with only potassium greens_tree_k = self.greens_tree.__copy__() greens_tree_k[1].currents = {key: val for key, val in greens_tree_k[1].currents.items() \ if key != 'Na_Ta'} # compute potassium impedance matrices z_mats_k = [] for e_eq in e_eqs: greens_tree_k.setEEq(e_eq) greens_tree_k.setCompTree() greens_tree_k.setImpedance(self.freqs) z_mats_k.append(greens_tree_k.calcImpedanceMatrix(locs)) # create tree with only sodium greens_tree_na = self.greens_tree.__copy__() greens_tree_na[1].currents = {key: val for key, val in greens_tree_na[1].currents.items() \ if key != 'Kv3_1'} # create state variable expansion points svs = [] e_eqs_ = [] na_chan = greens_tree_na.channel_storage['Na_Ta'] for e_eq1 in e_eqs: sv1 = na_chan.computeVarinf(e_eq1) for e_eq2 in e_eqs: e_eqs_.append(e_eq2) sv2 = na_chan.computeVarinf(e_eq2) svs.append({'m': sv2['m'], 'h': sv1['h']}) # compute sodium impedance matrices z_mats_na = [] for ii, sv in enumerate(svs): greens_tree_na.setEEq(e_eqs[ii % len(e_eqs)]) greens_tree_na[1].setExpansionPoint('Na_Ta', sv) greens_tree_na.setCompTree() greens_tree_na.setImpedance(self.freqs) z_mats_na.append(greens_tree_na.calcImpedanceMatrix(locs)) # compute combined impedance matrices z_mats_comb = [] for e_eq in e_eqs: self.greens_tree.setEEq(e_eq) self.greens_tree.setCompTree() self.greens_tree.setImpedance(self.freqs) z_mats_comb.append(self.greens_tree.calcImpedanceMatrix(locs)) # passive fit ctree.computeGMC(z_mat_pas) # get SOV constants for capacitance fit sov_tree = greens_tree_pas.__copy__(new_tree=SOVTree()) sov_tree.setCompTree() sov_tree.calcSOVEquations() alphas, phimat, importance = sov_tree.getImportantModes( locarg=locs, sort_type='importance', eps=1e-12, return_importance=True) # fit the capacitances from SOV time-scales ctree.computeC(-alphas[0:1].real * 1e3, phimat[0:1, :].real, weights=importance[0:1]) ctree1 = copy.deepcopy(ctree) ctree2 = copy.deepcopy(ctree) ctree3 = copy.deepcopy(ctree) ctree4 = copy.deepcopy(ctree) # fit paradigm 1 --> separate impedance matrices and separate fits # potassium channel fit for z_mat_k, e_eq in zip(z_mats_k, e_eqs): ctree1.computeGSingleChanFromImpedance('Kv3_1', z_mat_k, e_eq, self.freqs, other_channel_names=['L']) ctree1.runFit() # sodium channel fit for z_mat_na, e_eq, sv in zip(z_mats_na, e_eqs_, svs): ctree1.computeGSingleChanFromImpedance('Na_Ta', z_mat_na, e_eq, self.freqs, sv=sv, other_channel_names=['L']) ctree1.runFit() # fit paradigm 2 --> separate impedance matrices, same fit for z_mat_k, e_eq in zip(z_mats_k, e_eqs): ctree2.computeGSingleChanFromImpedance( 'Kv3_1', z_mat_k, e_eq, self.freqs, all_channel_names=['Kv3_1', 'Na_Ta']) for z_mat_na, e_eq, sv in zip(z_mats_na, e_eqs_, svs): ctree2.computeGSingleChanFromImpedance( 'Na_Ta', z_mat_na, e_eq, self.freqs, sv=sv, all_channel_names=['Kv3_1', 'Na_Ta']) ctree2.runFit() # fit paradigm 3 --> same impedance matrices for z_mat_comb, e_eq in zip(z_mats_comb, e_eqs): ctree3.computeGChanFromImpedance(['Kv3_1', 'Na_Ta'], z_mat_comb, e_eq, self.freqs) ctree3.runFit() # fit paradigm 4 --> fit incrementally for z_mat_na, e_eq, sv in zip(z_mats_na, e_eqs_, svs): ctree4.computeGSingleChanFromImpedance('Na_Ta', z_mat_na, e_eq, self.freqs, sv=sv) ctree4.runFit() for z_mat_comb, e_eq in zip(z_mats_comb, e_eqs): ctree4.computeGSingleChanFromImpedance( 'Kv3_1', z_mat_comb, e_eq, self.freqs, other_channel_names=['Na_Ta', 'L']) ctree4.runFit() # test if correct keys = ['L', 'Na_Ta', 'Kv3_1'] # soma surface (cm) for total conductance calculation a_soma = 4. * np.pi * (self.greens_tree[1].R * 1e-4)**2 conds = np.array( [self.greens_tree[1].currents[key][0] * a_soma for key in keys]) # compartment models conductances cconds1 = np.array([ctree1[0].currents[key][0] for key in keys]) cconds2 = np.array([ctree2[0].currents[key][0] for key in keys]) cconds3 = np.array([ctree3[0].currents[key][0] for key in keys]) cconds4 = np.array([ctree4[0].currents[key][0] for key in keys]) assert np.allclose(conds, cconds1) assert np.allclose(conds, cconds2) assert np.allclose(conds, cconds3) assert np.allclose(conds, cconds4) # rename for further testing ctree = ctree1 # frequency array ft = ke.FourrierTools(np.linspace(0., 50., 100)) freqs = ft.s # compute impedance matrix v_h = -42. # original self.greens_tree.setEEq(v_h) self.greens_tree.setCompTree() self.greens_tree.setImpedance(freqs) z_mat_orig = self.greens_tree.calcImpedanceMatrix([(1., .5)]) # potassium greens_tree_k.setEEq(v_h) greens_tree_k.setCompTree() greens_tree_k.setImpedance(freqs) z_mat_k = greens_tree_k.calcImpedanceMatrix([(1, .5)]) # sodium greens_tree_na.removeExpansionPoints() greens_tree_na.setEEq(v_h) greens_tree_na.setCompTree() greens_tree_na.setImpedance(freqs) z_mat_na = greens_tree_na.calcImpedanceMatrix([(1, .5)]) # passive greens_tree_pas.setCompTree() greens_tree_pas.setImpedance(freqs) z_mat_pas = greens_tree_pas.calcImpedanceMatrix([(1, .5)]) # reduced impedance matrices ctree.removeExpansionPoints() ctree.setEEq(v_h) z_mat_fit = ctree.calcImpedanceMatrix(freqs=freqs) z_mat_fit_k = ctree.calcImpedanceMatrix(channel_names=['L', 'Kv3_1'], freqs=freqs) z_mat_fit_na = ctree.calcImpedanceMatrix(channel_names=['L', 'Na_Ta'], freqs=freqs) z_mat_fit_pas = ctree.calcImpedanceMatrix(channel_names=['L'], freqs=freqs) assert np.allclose(z_mat_orig, z_mat_fit) assert np.allclose(z_mat_k, z_mat_fit_k) assert np.allclose(z_mat_na, z_mat_fit_na) assert np.allclose(z_mat_pas, z_mat_fit_pas) # test total current, conductance sv = svs[-1] p_open = sv['m']**3 * sv['h'] # with p_open given g1 = ctree[0].getGTot(ctree.channel_storage, channel_names=['L', 'Na_Ta'], p_open_channels={'Na_Ta': p_open}) i1 = ctree[0].getGTot(ctree.channel_storage, channel_names=['L', 'Na_Ta'], p_open_channels={'Na_Ta': p_open}) # with expansion point given ctree.setExpansionPoints({'Na_Ta': sv}) g2 = ctree[0].getGTot(ctree.channel_storage, channel_names=['L', 'Na_Ta']) i2 = ctree[0].getGTot(ctree.channel_storage, channel_names=['L', 'Na_Ta']) # with e_eq given g3 = ctree[0].getGTot(ctree.channel_storage, v=e_eqs[-1], channel_names=['L', 'Na_Ta']) i3 = ctree[0].getGTot(ctree.channel_storage, v=e_eqs[-1], channel_names=['L', 'Na_Ta']) # with e_eq stored ctree.setEEq(e_eqs[-1]) g4 = ctree[0].getGTot(ctree.channel_storage, channel_names=['L', 'Na_Ta']) i4 = ctree[0].getGTot(ctree.channel_storage, channel_names=['L', 'Na_Ta']) # check if correct assert np.abs(g1 - g2) < 1e-10 assert np.abs(g1 - g3) < 1e-10 assert np.abs(g1 - g4) < 1e-10 assert np.abs(i1 - i2) < 1e-10 assert np.abs(i1 - i3) < 1e-10 assert np.abs(i1 - i4) < 1e-10 # compare current, conductance g_ = ctree[0].getGTot(ctree.channel_storage, channel_names=['Na_Ta']) i_ = ctree[0].getITot(ctree.channel_storage, channel_names=['Na_Ta']) assert np.abs(g_ * (e_eqs[-1] - ctree[0].currents['Na_Ta'][1]) - i_) < 1e-10 # test leak fitting self.greens_tree.setEEq(-75.) self.greens_tree.setCompTree() ctree.setEEq(-75.) ctree.removeExpansionPoints() ctree.fitEL() assert np.abs(ctree[0].currents['L'][1] - self.greens_tree[1].currents['L'][1]) < 1e-10
def fitBall(self): self.loadBall() freqs = np.array([0.]) locs = [(1, 0.5)] e_eqs = [-75., -55., -35., -15.] # create compartment tree ctree = self.tree.createCompartmentTree(locs) ctree.addCurrent(channelcollection.Na_Ta(), 50.) ctree.addCurrent(channelcollection.Kv3_1(), -85.) # create tree with only leak greens_tree_pas = self.tree.__copy__(new_tree=GreensTree()) greens_tree_pas[1].currents = {'L': greens_tree_pas[1].currents['L']} greens_tree_pas.setCompTree() greens_tree_pas.setImpedance(freqs) # compute the passive impedance matrix z_mat_pas = greens_tree_pas.calcImpedanceMatrix(locs)[0] # create tree with only potassium greens_tree_k = self.tree.__copy__(new_tree=GreensTree()) greens_tree_k[1].currents = {key: val for key, val in greens_tree_k[1].currents.items() \ if key != 'Na_Ta'} # compute potassium impedance matrices z_mats_k = [] for e_eq in e_eqs: greens_tree_k.setEEq(e_eq) greens_tree_k.setCompTree() greens_tree_k.setImpedance(freqs) z_mats_k.append(greens_tree_k.calcImpedanceMatrix(locs)) # create tree with only sodium greens_tree_na = self.tree.__copy__(new_tree=GreensTree()) greens_tree_na[1].currents = {key: val for key, val in greens_tree_na[1].currents.items() \ if key != 'Kv3_1'} # create state variable expansion points svs = [] e_eqs_ = [] na_chan = greens_tree_na.channel_storage['Na_Ta'] for e_eq1 in e_eqs: sv1 = na_chan.computeVarinf(e_eq1) for e_eq2 in e_eqs: e_eqs_.append(e_eq2) sv2 = na_chan.computeVarinf(e_eq2) svs.append({'m': sv2['m'], 'h': sv1['h']}) # compute sodium impedance matrices z_mats_na = [] for ii, sv in enumerate(svs): greens_tree_na.setEEq(e_eqs[ii % len(e_eqs)]) greens_tree_na[1].setExpansionPoint('Na_Ta', sv) greens_tree_na.setCompTree() greens_tree_na.setImpedance(freqs) z_mats_na.append(greens_tree_na.calcImpedanceMatrix(locs)) # passive fit ctree.computeGMC(z_mat_pas) # get SOV constants for capacitance fit sov_tree = greens_tree_pas.__copy__(new_tree=SOVTree()) sov_tree.setCompTree() sov_tree.calcSOVEquations() alphas, phimat, importance = sov_tree.getImportantModes( locarg=locs, sort_type='importance', eps=1e-12, return_importance=True) # fit the capacitances from SOV time-scales ctree.computeC(-alphas[0:1].real * 1e3, phimat[0:1, :].real, weights=importance[0:1]) # potassium channel fit for z_mat_k, e_eq in zip(z_mats_k, e_eqs): ctree.computeGSingleChanFromImpedance('Kv3_1', z_mat_k, e_eq, freqs, other_channel_names=['L']) ctree.runFit() # sodium channel fit for z_mat_na, e_eq, sv in zip(z_mats_na, e_eqs_, svs): ctree.computeGSingleChanFromImpedance('Na_Ta', z_mat_na, e_eq, freqs, sv=sv, other_channel_names=['L']) ctree.runFit() ctree.setEEq(-75.) ctree.removeExpansionPoints() ctree.fitEL() self.ctree = ctree
def reduceExplicit(self): self.loadBall() freqs = np.array([0.]) locs = [(1, 0.5)] e_eqs = [-75., -55., -35., -15.] # create compartment tree ctree = self.tree.createCompartmentTree(locs) ctree.addCurrent(channelcollection.Na_Ta(), 50.) ctree.addCurrent(channelcollection.Kv3_1(), -85.) # create tree with only leak greens_tree_pas = self.tree.__copy__(new_tree=GreensTree()) greens_tree_pas[1].currents = {'L': greens_tree_pas[1].currents['L']} greens_tree_pas.setCompTree() greens_tree_pas.setImpedance(freqs) # compute the passive impedance matrix z_mat_pas = greens_tree_pas.calcImpedanceMatrix(locs)[0] # create tree with only potassium greens_tree_k = self.tree.__copy__(new_tree=GreensTree()) greens_tree_k[1].currents = {key: val for key, val in greens_tree_k[1].currents.items() \ if key != 'Na_Ta'} # compute potassium impedance matrices z_mats_k = [] for e_eq in e_eqs: greens_tree_k.setEEq(e_eq) greens_tree_k.setCompTree() greens_tree_k.setImpedance(freqs) z_mats_k.append(greens_tree_k.calcImpedanceMatrix(locs)) # create tree with only sodium greens_tree_na = self.tree.__copy__(new_tree=GreensTree()) greens_tree_na[1].currents = {key: val for key, val in greens_tree_na[1].currents.items() \ if key != 'Kv3_1'} # create state variable expansion points svs = [] e_eqs_ = [] na_chan = greens_tree_na.channel_storage['Na_Ta'] for e_eq1 in e_eqs: sv1 = na_chan.computeVarinf(e_eq1) for e_eq2 in e_eqs: e_eqs_.append(e_eq2) sv2 = na_chan.computeVarinf(e_eq2) svs.append({'m': sv2['m'], 'h': sv1['h']}) # compute sodium impedance matrices z_mats_na = [] for sv, eh in zip(svs, e_eqs_): greens_tree_na.setEEq(eh) greens_tree_na[1].setExpansionPoint('Na_Ta', sv) greens_tree_na.setCompTree() greens_tree_na.setImpedance(freqs) z_mats_na.append(greens_tree_na.calcImpedanceMatrix(locs)) # passive fit ctree.computeGMC(z_mat_pas) # potassium channel fit matrices fit_mats_k = [] for z_mat_k, e_eq in zip(z_mats_k, e_eqs): mf, vt = ctree.computeGSingleChanFromImpedance( 'Kv3_1', z_mat_k, e_eq, freqs, other_channel_names=['L'], action='return') fit_mats_k.append([mf, vt]) # sodium channel fit matrices fit_mats_na = [] for z_mat_na, e_eq, sv in zip(z_mats_na, e_eqs_, svs): mf, vt = ctree.computeGSingleChanFromImpedance( 'Na_Ta', z_mat_na, e_eq, freqs, sv=sv, other_channel_names=['L'], action='return') fit_mats_na.append([mf, vt]) return fit_mats_na, fit_mats_k
def testLinSum(self): na = channelcollection.Na_Ta() l_s_1 = na.computeLinSum(-35., 0., 50.) l_s_2 = self.computeLinSum(-35., 0., 50.) assert np.allclose(l_s_1, l_s_2)
def testPOpen(self): na = channelcollection.Na_Ta() p_o_1 = na.computePOpen(-35.) p_o_2 = self.computePOpen(-35.) assert np.allclose(p_o_1, p_o_2)