# Ball and stick 1: Basic cell sources: [Ball and stick 1: Basic cell](https://neuronsimulator.github.io/nrn/tutorials/ball-and-stick-1.html) ###### tags: `NEURON` `Computational Neuroscience` 細胞模型架構: + Sections:一顆細胞的結構 + Topology:sections之間的連結 + Geometry:sections在3D空間中的位置 + Biophysics:sections的離子通道和細胞膜特性 + Synapses:細胞上的突觸,所具備的選擇性功能 ## 目錄 + [一、載入NEURON](https://hackmd.io/g6klZmmYTimC9Vt2_8y61Q?view#%E4%B8%80%E3%80%81%E8%BC%89%E5%85%A5NEURON) + [二、定義細胞型態](https://hackmd.io/g6klZmmYTimC9Vt2_8y61Q?view#%E4%BA%8C%E3%80%81%E5%AE%9A%E7%BE%A9%E7%B4%B0%E8%83%9E%E5%9E%8B%E6%85%8B) + [三、儀表化](https://hackmd.io/g6klZmmYTimC9Vt2_8y61Q?view#%E4%B8%89%E3%80%81%E5%84%80%E8%A1%A8%E5%8C%96) + [四、來模擬!](https://hackmd.io/g6klZmmYTimC9Vt2_8y61Q?view#%E5%9B%9B%E3%80%81%E4%BE%86%E6%A8%A1%E6%93%AC%EF%BC%81) + [五、結果可視化](https://hackmd.io/g6klZmmYTimC9Vt2_8y61Q?view#%E4%BA%94%E3%80%81%E7%B5%90%E6%9E%9C%E5%8F%AF%E8%A6%96%E5%8C%96) + [六、模擬的效應](https://hackmd.io/g6klZmmYTimC9Vt2_8y61Q?view#%E5%85%AD%E3%80%81%E6%A8%A1%E6%93%AC%E7%9A%84%E6%95%88%E6%87%89) --- ## 一、載入NEURON 第一步驟,載入模組們 ```python= from neuron import h from neuron.units import ms, mV, µm ``` 此外,我們可以將hoc一同載入,讓我們可以有更多高階的調整方案 ```python=3 h.load_file("stdrun.hoc") ``` ## 二、定義細胞型態 ### Section 上次我們講到了一個section代表一顆細胞,這邊我們先來設定section裡的神經元(soma)和樹突(dendrite)。 ```python= soma = h.Section(name='soma') dend = h.Section(name='dend') ``` 利用上篇所提及的`psection`(顯示該區段內資訊),來看看他們的說明 ```python=3 h.psection(sec=soma) h.psection(sec=dend) ``` ``` soma { nseg=1 L=100 Ra=35.4 /*location 0 attached to cell 0*/ /* First segment only */ insert morphology { diam=500} insert capacitance { cm=1} } dend { nseg=1 L=100 Ra=35.4 /*location 0 attached to cell 1*/ /* First segment only */ insert morphology { diam=500} insert capacitance { cm=1} } ``` ### Topology 現在我們使用`connect`做更進一步的連接神經元和神經樹突。 ```python=5 dend.connect(soma(1)) ``` ``` dend ``` 查看`psection`說明,會發現其中多了一行"soma connect dend",就代表連接成功了 ```python=6 h.psection(sec=dend) ``` ``` dend { nseg=1 L=100 Ra=35.4 soma connect dend (0), 1 /* First segment only */ insert morphology { diam=500} insert capacitance { cm=1} } ``` 接著,我們可以透過`topology`來觀察連接情況 ```python=7 h.topology() ``` ``` |-| soma(0-1) `| dend(0-1) ``` --- 接下來我們來做點更大的,今天我們有一個Class叫做BallandStick,裡面我們設定有一個soma和一個dend。同時我們設定`__repr__`作為細胞的代表名稱。 ```python= class BallAndStick: def __init__(self): self.soma = h.Section(name="soma", cell=self) self.dend = h.Section(name="dend", cell=self) def __repr__(self): return "BallAndStick" ``` 將class套在`my_cell`這個變數上,並且來看soma和dend的連接狀況。 ```python=8 my_cell = BallAndStick() h.topology() ``` ``` |-| BallAndStick.soma(0-1) |-| BallAndStick.dend(0-1) ``` 然而,這樣的狀況下不管是哪個變數呼叫class,他們的細胞名稱都會被定義為"BallandStick",這樣不行啊啊啊!因此我們得在`__repr__`這裡做點手腳。 ```python= class BallAndStick: def __init__(self, gid): self._gid = gid self.soma = h.Section(name="soma", cell=self) self.dend = h.Section(name="dend", cell=self) def __repr__(self): return "BallAndStick[{}]".format(self._gid) ``` 顯而易見,`gid`主要就是在幫不同細胞標籤,它會接收`BallAndStick`中的引數,使每個呼叫class的變數(細胞)具有不同的編號。 ```python=9 my_cell = BallAndStick(0) my_other_cell = BallAndStick(1) h.topology() ``` ``` |-| BallAndStick[0].soma(0-1) |-| BallAndStick[0].dend(0-1) |-| BallAndStick[1].soma(0-1) |-| BallAndStick[1].dend(0-1) ``` 最後我們將神經元和神經樹突用`connect`連接。 ```python= class BallAndStick: def __init__(self, gid): self._gid = gid self.soma = h.Section(name="soma", cell=self) self.dend = h.Section(name="dend", cell=self) self.dend.connect(self.soma) def __repr__(self): return "BallAndStick[{}]".format(self._gid) my_cell = BallAndStick(0) my_other_cell = BallAndStick(1) h.topology() ``` ``` |-| BallAndStick[0].soma(0-1) `| BallAndStick[0].dend(0-1) |-| BallAndStick[1].soma(0-1) `| BallAndStick[1].dend(0-1) ``` 把`my_other_cell`刪除後,僅留下`my_cell` ```python=14 del my_other_cell h.topology ``` ``` |-| BallAndStick[0].soma(0-1) `| BallAndStick[0].dend(0-1) ``` ### Geometry 圓柱表面積 = $2*\pi*r*h$ 這裡做的是高和直徑一樣的圓柱型 = $4*\pi*r^2$ 設表面積為500平方微米 $$\pi dl=\pi d^2=4\pi(\frac{d}{2})^2=4\pi r^2 $$ 得到圓柱體的半徑為6.2078微米,直徑為12.617微米。 ```python= soma.L = soma.diam = 12.6157 dend.L = 200 dend.diam = 1 print("Surface area of soma = {}".format(soma(0.5).area())) ``` ``` Surface area of soma = 500.00296377255506 ``` 來看看效果 ```python=5 shape_window = h.PlotShape() shape_window.exec_menu('Show Diam') ``` <center> ![](https://i.imgur.com/oN4mLF3.png =50%x) </center> --- 下面我們同樣利用class來做個完整的設定,同時在class中直接設定直徑大小。 ```python= class BallAndStick: def __init__(self, gid): self._gid = gid self.soma = h.Section(name="soma", cell=self) self.dend = h.Section(name="dend", cell=self) self.dend.connect(self.soma) self.soma.L = self.soma.diam = 12.6157 * µm self.dend.L = 200 * µm self.dend.diam = 1 * µm def __repr__(self): return "BallAndStick[{}]".format(self._gid) my_cell = BallAndStick(0) ``` 算算看表面積為何,使用的函式為`area()`。 ```python=16 my_cell.soma(0.5).area() ``` ``` 500.0029545802403 ``` 接下來我們利用matplot來看看形狀。 <center> ![](https://i.imgur.com/ar7cb6g.png =50%x) </center> ### Biophysics 電阻:$R \propto \displaystyle{\frac{V}{I}}$,電阻與電阻率、長度呈正比,與截面積呈反比 電容:$C = \displaystyle{\frac{Q}{V}}$,每增加1伏特的電位差可以多儲存1庫倫電荷 電導:$G = \displaystyle{\frac{I}{V}}$,一物體或電路,兩點間傳輸電流能力強弱的測量值 Hodgkin-Huxley model:說明神經組織產生動作電位與傳遞動作電位的整個離子機制。 $$I_m(t) = I_{ionic}(t)+C_m\displaystyle{\frac{dV(t)}{dt}} $$ $I_m$:通過細胞膜表面的電流 $I_{ionic}$:總離子電流 $V$:由靜止電位起的膜電位變化 $C_m$:每單位面積的膜電容 $$I_{ionic} = I_{Na}+I_K+I_{leak} $$ $I_{Na}$:鈉離子電流 $I_K$:鉀離子電流 $I_{leak}$:其他離子 下面為各類生理物理學上的設定,這裡我們以HH模型為範例。 ```python= for sec in h.allsec(): sec.Ra = 100 # 膜電阻(Ohm * cm) sec.cm = 1 # 膜電容(micro Farads / cm^2) # Insert active Hodgkin-Huxley current in the soma soma.insert('hh') for seg in soma: seg.hh.gnabar = 0.12 # 鈉離子電導(S/cm2) seg.hh.gkbar = 0.036 # 鉀離子電導(S/cm2) seg.hh.gl = 0.0003 # 洩漏電導(S/cm2) seg.hh.el = -54.3 # 反轉電位(mV) # Insert passive current in the dendrite dend.insert('pas') for seg in dend: seg.pas.g = 0.001 # 被動電導(S/cm2) seg.pas.e = -65 # 洩漏反轉電位(mV) ``` 再次叫出細胞的說明,可以發現很多改變。 ```python=18 for sec in h.allsec(): # 細胞中每個section h.psection(sec=sec) ``` ``` soma { nseg=1 L=12.6157 Ra=100 /*location 0 attached to cell 0*/ /* First segment only */ insert morphology { diam=12.6157} insert capacitance { cm=1} insert hh { gnabar_hh=0.12 gkbar_hh=0.036 gl_hh=0.0003 el_hh=-54.3} insert na_ion { ena=50} insert k_ion { ek=-77} } dend { nseg=1 L=200 Ra=100 soma connect dend (0), 1 /* First segment only */ insert morphology { diam=1} insert capacitance { cm=1} insert pas { g_pas=0.001 e_pas=-65} } ``` --- 為了方便理解,我們可以在class中做更精細的整理 ```python= class BallAndStick: def __init__(self, gid): self._gid = gid self._setup_morphology() self._setup_biophysics() # 細胞的型態 def _setup_morphology(self): self.soma = h.Section(name="soma", cell=self) self.dend = h.Section(name="dend", cell=self) self.dend.connect(self.soma) self.all = self.soma.wholetree() # all代表整個section self.soma.L = self.soma.diam = 12.6157 * µm self.dend.L = 200 * µm self.dend.diam = 1 * µm # 細胞的生理物理性質 def _setup_biophysics(self): for sec in self.all: sec.Ra = 100 # Axial resistance in Ohm * cm sec.cm = 1 # Membrane capacitance in micro Farads / cm^2 self.soma.insert("hh") for seg in self.soma: seg.hh.gnabar = 0.12 # Sodium conductance in S/cm2 seg.hh.gkbar = 0.036 # Potassium conductance in S/cm2 seg.hh.gl = 0.0003 # Leak conductance in S/cm2 seg.hh.el = -54.3 * mV # Reversal potential # Insert passive current in the dendrite self.dend.insert("pas") for seg in self.dend: seg.pas.g = 0.001 # Passive conductance in S/cm2 seg.pas.e = -65 * mV # Leak reversal potential def __repr__(self): return "BallAndStick[{}]".format(self._gid) ``` 來看說明 ```python=38 for sec in h.allsec(): print("%s: %s" % (sec, ", ".join(sec.psection()["density_mechs"].keys()))) ``` ``` BallAndStick[0].soma: hh BallAndStick[0].dend: pas ``` ## 三、儀表化 上面我們設定完了一顆細胞,接下來我們利用刺激,觀察他的動態變化,後續我們皆利用上面完成的class做設定。 首先我們於樹突給予一個刺激。 ```python=40 stim = h.IClamp(my_cell.dend(1)) ``` 我們可以利用`get_segment()`查看膜片鉗是插在細胞的哪個位置。 ```python=41 stim.get_segment() ``` ``` BallAndStick[0].dend(1) ``` 設定模擬開始後5ms才送出刺激,送出刺激整個過程為1ms,刺激強度為1nA。 ```python=42 stim.delay = 5 stim.dur = 1 stim.amp = 0.1 ``` 要記錄的東西有 1. 神經本體的膜電位 2. 紀錄時間的間隔 ```python=45 soma_v = h.Vector() # 設陣列 soma_v.record(my_cell.soma(0.5)._ref_v) # 紀錄膜電位 t = h.Vector() # 設陣列 t.record(h._ref_t) # 紀錄時間 ``` ## 四、來模擬! ```python=49 h.finitialize(-65 * mV) # 初始膜電位為65mV simdur = 25.0 # 整個過程為25ms h.tstop = simdur h.run() ``` ## 五、結果可視化 ```python=53 from matplotlib import pyplot pyplot.figure(figsize=(8,4)) # Default figsize is (8,6) pyplot.plot(t, some_v) pyplot.xlabel('time (ms)') pyplot.ylabel('mV') pyplot.show() ``` <center> ![](https://i.imgur.com/LCSgsi9.png =70%x) </center> ## 六、進階模擬 ### 強度變化 上圖僅送出一次刺激,接下來以for迴圈做刺激強度變化。剛剛強度設0.1nA,這次從0.075nA慢慢疊加:0.075nA, 0.150nA, 0.225nA, 0.300nA ```python=59 pyplot.figure(figsize=(8,4)) colors = ['green', 'blue', 'red', 'black'] for i in range(4): stim.amp = (i+1)*0.075 h.tstop = simdur h.run() pyplot.plot(t_vec, soma_v, color=colors[i], label=str(round(stim.amp, 3))+'mV') pyplot.legend() pyplot.xlabel('time (ms)') pyplot.ylabel('mV') pyplot.show() # 最大值有到40mV!!! ``` <center> ![](https://i.imgur.com/t2UOatx.png =70%x) </center> ### 樹突與神經元本體的比較 上面都是神經元本體的情況,接下來加入樹突的情況。可以發現樹突的電位較神經元本體小很多,符合電訊號leaking的情形。 ```python=72 dend_v = h.Vector() # Membrane potential vector dend_v.record(my_cell.dend(0.5)._ref_v) pyplot.figure(figsize=(8,4)) colors = ['green', 'blue', 'red', 'black'] for i in range(4): stim.amp = (i+1)*0.075 h.tstop = simdur h.run() soma_plot=pyplot.plot(t, soma_v, color=colors[i], label=str(round(stim.amp, 3))+'mV') dend_plot=pyplot.plot(t, dend_v, linestyle="--", color=colors[i]) pyplot.legend() pyplot.xlabel('time (ms)') pyplot.ylabel('mV') pyplot.show() ``` <center> ![](https://i.imgur.com/HQwmhsb.png =70%x) </center> ### nseg的變化影響 來比較一下樹突區室的多寡帶來的影響,可以發現樹突區室較多的情況下,達到最大伏特的時間延後、最大值變小。 ```python=88 pyplot.figure(figsize=(8,4)) colors = ['green', 'blue', 'red', 'black'] for j in range(2): if(j==0): dend.nseg=101 else: dend.nseg=1 for i in range(4): stim.amp = (i+1)*0.075 h.tstop = simdur h.run() if(j==1): soma_plot=pyplot.plot(t_vec, v_vec, color=colors[i], linewidth=(j+1)*0.6, label=str(round(stim.amp, 3))+'mV') else: soma_plot=pyplot.plot(t_vec, v_vec, color=colors[i], linewidth=(j+1)*0.6) dend_plot=pyplot.plot(t_vec, dend_v_vec, linestyle="--", linewidth=(j+1)*0.5, color=colors[i]) pyplot.legend() pyplot.xlabel('time (ms)') pyplot.ylabel('mV') pyplot.show() ``` <center> ![](https://i.imgur.com/pPrpIoO.png =70%x) </center>