# 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>