A Simplifed Introduction to NEURON Simulator
—(私的)NEURON 事始め—
Keiji Imoto
Department of Information Physiology
National Institute for Physiological Sciences
Okazaki 444-8787, Japan
13-March-2009
11-June-2010: correction of bugs in n12.hoc
12-April-2010: minor changes
06-July-2012: minor update
目次
はじめに
1
1
1.1
説明書の対象者
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.2
NEURON シミュレータの特徴 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
シミュレーションの基本
3
2.1
膜電位 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.2
イオンチャネル
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.3
微分法的式の計算方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.4
C 言語 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
hoc ファイルと oc インタープリタ
4
3.1
インタープリタとしての oc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
3.2
Section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
3.3
Connecting sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.4
Point Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
3.5
クラス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
3.6
NetCon、NetStim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
3.7
Voltage clamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
Morphology
24
4.1
section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
4.2
geometory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
4.3
segment の長さ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
Spikes
38
5.1
NetCon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
5.2
Raster Plot の描き方 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
NMODL
40
6.1
Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
6.2
例:常微分方程式を解いてみる . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
6.3
IntervalFire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
6.4
Synaptic transmission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
6.5
Synaptic plasticity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
6.6
NMDA receptor channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
50
NEURON の内部
53
7.1
初期化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
7.2
Integration の方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
2
3
4
5
6
7
7.3
Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
インストールの仕方
54
A.1
Windows の場合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
A.2
Mac OS の場合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
A.3
Linux の場合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
A.4
計算速度 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
hoc ファイル用のテキストエディタ
55
B.1
Emacs 系テキストエディタ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
B.2
Notepad++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
B.3
Coteditor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
References
56
付録 A
付録 B
付録 C
1 はじめに
Ted Carnevale と Michael Hines により開発され、現在も開発され続けている NEURON シミュレータは、
もっともポピュラーな神経細胞、神経ネットワークのシミュレータである。10 年以上の歴史があり、多くの
論文でも利用されている。基本的に NEURON は、神経細胞をコンパートメントに分け、コンパートメント i
の電位変化を、微分方程式
dVi
1 ∑
=−
Ii,j
dt
Ci j
で表し、これらを数値的に解くものである。神経細胞の形態を再現しようとするとコンパートメントの数が多
くなり、またそれぞれのコンパートメントに含まれるチャネルのキネティックスの定義にもよく微分方程式が
用いられるため、多数の微分方程式を並行して計算することが必要となる。NEURON はそのような機能を備
えたソフトウェアである。NEURON は現在もすこしずつ機能が付け足されてきており、多数の(モデル)神
経細胞からなるネットワークのシミュレーションも可能である。
このように NEURON は高度な性能を持つソフトウェアであるが、2006 年に The NEURON Book
(Canbridge University Press) が出版されるまで、まとまった入門書がなかったこともあり、なかなか取っ付
きにくいというのが一般的な印象だろうと思われる。筆者自身、何度か NEURON をコンピュータにインス
トールし、チュートリアルなどを試してみたが、結局使えるほどの理解を得るには至らなかった。問題点を考
え直してみたところ、少なくとも個人的には、プログラムの中核である oc インタープリタをどう使うのかが
わからない、ということが初歩のチュートリアル以上に進めない理由なのではないか、と思うようになった。
この(私的)事始めでは、GUI 部分を出来るだけ利用せず、NEURON の根幹である oc インタープリタを
動かすための hoc ファイルの理解を中心に説明を試みた。
1.1 説明書の対象者
この説明書は、ある程度プログラミングに経験のある人をターゲットにしている。例題を多く含めたので、
初心者でも書いてある内容を再現できるが、C/C++ 言語並びに数値計算についての基本的な知識があれば、
更に発展した NEURON の使用ができると期待している。
1.2 NEURON シミュレータの特徴
NEURON シミュレータの特徴として 3 つの点があげられる。
1. oc は NEURON の根幹となるインタープリタであり、非常に数多くの連立微分方程式の数値解を求め
ることができる。
2. mknrnmodl(システムによっては mknrndll)は、イオンチャネル等のコンポーネントを新たに作製し、
プログラムに組み込むことができる。
3. template 機能を用いて、object 指向的なプログラムが可能である。
2 は微分方程式等の詳細を記載した mod ファイルをシステムに組込む操作である。初歩的な機能要素は既
定のシステムに備わっているので、備わっていない機能要素を加える場合に必要。
また付属の機能として、次のようなものがある。
1
• CellBuilder: 神経細胞の複雑な形態を、円柱で近似されるコンパートメント(section と呼ばれている)
のつながりとしてプログラム化する。
• NetBuilder: 神経細胞間の情報伝達を event の伝達として処理するようにプログラム化する。
これらは GUI を主体とした部分であるが、複雑な構造やネットワークを作っていくには、むしろ古典的なテ
キストファイルを用いる方法の方が適している場合もある。
NEURON は(一旦学べば)比較的手軽に使用できるシミュレーション環境である。特に有用な課題は、
1. 複数のコンパートメント(section)からなる神経細胞での、イオンチャネル機能の検討。特にイオン
チャネル間の相互作用やクランプエラー等の測定誤差の理解に有用。
2. 細胞集団におけるスパイクの同期性等におよぼす要素の検討。但し、この種類のシミュレーションをパ
ソコンレベルのコンピュータで行なう場合には、単純化したモデルニューロンを使用する必要がある。
.
なお、文中の

はコメント、
は注意すべき事項を示す(dangerous bend 危険な曲がり道)。
2
2 シミュレーションの基本
2.1 膜電位
NEURON シミュレータは、神経細胞の電位変化のシミュレーションを得意とするプログラムである。細胞
をコンデンサと考え、それに蓄えられる電荷の量により膜電位が生じている、というのが基本的な考え方であ
る。蓄えられている電荷量を Q、静電容量(キャパシタンス)を C とすると、電位 V との関係は、
Q = CV
で表される。C を定数として扱い、この式の両辺を時間 t で微分すると、
dQ
dV
=C
dt
dt
となる。左辺は、細胞に出入りする電荷量の時間的変化量、すなわち電流 I である。電気生理学の習わしとし
て、細胞内に流れる電流を負の値として示すので、
I=−
dQ
dt
である。従って、電流 I と電位 V の関係は、
dV
1
=− I
dt
C
V (t) = V (0) −
1
C
∫
τ =t
Idτ
τ =0
となる。この式は、細胞の膜電位の初期値と、細胞に出入りする電流がわかれば、膜電位の時間的変化は計算
できることを示している。
神経細胞は複雑な形をしている。特樹状突起は長く伸びており、神経細胞を単なる球体のように扱うことは
出来ない。このため NEURON では神経細胞を球体、円柱体などの集まりとして考え、それぞれのコンパート
メントについて電位の微分方程式を解くという手法をとっている。またそれぞれの構成コンパートメントに入
出する電流にはさまざまな種類の電流が含まれる。電位依存性イオンチャネルを介する電流、神経伝達物質依
存性イオンチャネルを介する電流(シナプス電流がこれに相当する)、leak 電流(常に開いているイオンチャ
ネルを流れる電流)、近接のコンパートメントとの電流等が考えられる。神経細胞には多種類のイオンチャネ
ルが存在しているので、電流の種類数はかなりの数になると予想される。しかし現実には、それぞれのイオン
チャネルの分布などの情報はほとんどないことから、数種類のイオンチャネルでシミュレーションを行うこと
が普通である。i コンパートメント、j 電流の考えを含めると、冒頭で示した式となる。
1 ∑
dVi
=−
Ii,j
dt
Ci j
3
2.2 イオンチャネル
2.3 微分法的式の計算方法
2.4 C 言語
3 hoc ファイルと oc インタープリタ
3.1 インタープリタとしての oc
oc は、Windows/Cygwin の場合、nrngui のアイコンをクリックするか、コマンドプロンプトで neuron と
コマンド入力することで起動できる。Mac OS の場合、nrngui のアイコンをクリックするか、コマンドから
開く場合は、open -a nrngui で起動できる(ソースコードからコンパイルした場合は、異なる)。いずれの環
境の場合も、nrngui の場合は、nrngui.hoc がロードされ実行されている。Mac OS でコンパイルした場合や
Linux の場合は、PATH をしかるべく設定すれば、nrniv で起動できるはずである。
oc は、一行一行入力することも可能であるが、通常 hoc ファイルを読み込ませて作業を行う。その場合に
は、neuron hoc file name -とする。最後の’-’ を付けると、hoc ファイルの実行を終えても oc は終了しない。
hoc プログラム上の要点。
• 数値変数は宣言を必要としない。
• 数値変数は全て double(8 バイト実数)。整数として用いられる場合には truncate される。
• C 言語のように double i というように宣言すると、エラーとなる
• 配列の場合は数値でも double の宣言必要。配列要素の数は定数でなくてもよい。
• 数値変数を含め、変数は通常グローバル変数 global として扱われる。
• 数値変数を関数内に限局するには local の宣言が必要。
• 数値以外の変数には、色々なオブジェクトのレファレンス、文字列等があり、objref、strdef 等の宣
言を必要とする。*1
• オブジェクトのレファレンスを関数内で局所的に使用するには、objref の代わりに localobj を使用
する。(strdef の local 版はないようだ。)
• ポインターを使用することができる。
• シミュレーションの要素としては、コンパートメントである section、そこで局所的に起きる現象 point
process がある。section は global として扱われるようである。point process は単独で使用することは
出来ず、ある section の point process として使用される。概念的な point process を使用する場合は、
形式的に section を定義して用いる。
• 関数は、func()、proc() で定義される。func() は数値を返すのに対して、proc() は返り値なし。引数
は、数値の場合$1、文字列の場合$s1、objref の場合$o1 として表される。func()、proc() の括弧の中
には引数を書かない。
• main() は存在しない。各種の宣言(変数、関数、クラス)以外の部分が順番に実行される。
• 組込み関数がある(表 1)。例えば、printf() は、標準出力に文字列を出力する。
*1
クラスとは、鋳型もしくはひな形のことを指す。ひな形を元に実際に作られたもの(ここでは変数)がオブジェクト(インスタン
スとも言う)である。
4
• プログラムの流れを制御するステートメントとして、if、else、break、for、while 等が使用できる。
• forall、forsec 等が便利。
//-----------------------------------------------// n01.hoc:
a C-like hoc program
strdef s
s = "Hello, World!"
for t = 0, 3 {
printf("%d %s\n", t,
s)
}
//------------------------------------------------
. //
で始まる行はコメント行。//が行の途中で来れば、それ以降がコメント。また C 言語と同様に、/*
*/を使用できる。文字列の変数を使用する場合には、変数の宣言として strdef が必要。for にはいく通りか
の使用方法があるが、この使い方が最もよく用いられている様である。この場合、後の数(ここでは 3)が含
まれていることに注意。printf は、C 言語の場合とほぼ同じ。変数が double の場合でも、%f でよく %lf と
する必要はない様である。
ファイルへの出力の場合は、次のように行なう。
//-----------------------------------------------a C-like hoc program with text file output
// n02.hoc:
strdef s
s = "Hello, World!"
wopen("a.txt")
// open for write
for t = 0, 3 {
fprint("%d %s\n", t, s)
}
wopen()
//------------------------------------------------
.
ファイル IO(Input-Output)には、テキストファイルが用いられることが多い。書き込み用にファイ
ルを開く場合は、wopen(filename) を用い、閉じる場合は引数なしで wopen() を使用する。C 言語で用い
られる fprintf() ではなく fprint() であることに注意。ファイル IO には、File クラスを用いる方法もあり、
この場合はバイナリの読み書きがサポートされている。
実際に数値をファイルに書き出し、それをグラフを描くプログラム gc を用いてプロットしてみる。gc は
ホームメイドのプログラムで、コマンドで使用可。Windows 版と MacOS 版を用意してある。MacOS 版は
バイナリファイルのみ使用可。
//-----------------------------------------------// n03.hoc:
drowing a small graph
wopen("a.txt")
// open a file for "write"
tstop = 200
5
for t=0, tstop {
fprint("%f %f\n", t, sin(0.1*t))
}
wopen()
// close the output file
WinExec("gc a.txt")
//------------------------------------------------
.
プログラム中からコマンドを使ったり、他のプログラムを起動するには、system() を利用する。
Windows/Cygwin 環境では、WinExcec() を使用する。
binary ファイルの場合は下記のようになる。binary を用いる利点は、ファイルサイズがコンパクトで、読
み書きが速いことであるが、テキストエディタで内容がわからない欠点がある。
//-----------------------------------------------// n04.hoc:
drowing a small graph (binary file version)
objref fp
fp = new File()
fp.wopen("a.dat")
double a[2]
tstop = 200
for t=0, tstop {
a[0] = t
a[1] = sin(0.1 * t)
fp.vwrite(2, &a)
}
fp.close()
WinExec("gc a.dat")
//------------------------------------------------
. File
クラスを利用している。クラスを利用してオブジェクトを作成するには、まず objref aObject と
宣言をして、aObject = new Class() という構文でオブジェクトを作成する。入力にファイルを開く場合は
.ropen()、出力にファイルを開く場合は.wopen() を用いる。binary ファイルの読み書きには、.vread()、
.vwrite() を用いる。また、C 言語でおなじみの.seek()、.tell() も利用できる。
3.2 Section
いよいよ神経細胞のコンパートメント(section)を定義する。これには create というステートメントが
用いられる。内部的にはコンパートメントのオブジェクトが作成されるのだと推測される。先ず初めに 1 コ
ンパートメントを作成し、そこに Hodgkin-Huxley タイプの Na+ チャネル、K+ チャネル、leak チャネルの
パッケージである hh を挿入してみる。
//-----------------------------------------------6
//
n05.hoc:
a simple hh cell
create soma
soma insert hh
tstop = 200
dt = 0.01
v_init = -65
wopen("a.txt")
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
fprint("%f %f\n", t, soma.v(0.5))
}
wopen()
WinExec("gc a.txt &")
//------------------------------------------------
. hoc
ファイルでの操作は、いずれかの section に対して行なう場合が多い。一般的に、section statement
という形式が用いられる。finitialize()、fcurrent() は、シミュレーション計算の初期化を行なう。fad-
vance() は、1 ステップ計算を行なう。global 変数である時間 t は、fadvance() により dt(これも global
変数)だけ増加されるので、t を増加させる命令は不必要である。
出力ファイルを binary file にしたバージョン。
//-----------------------------------------------// n06.hoc:
a simple hh cell (binary version)
create soma
soma insert hh
tstop = 200
dt = 0.01
v_init = -65
objref fp
fp = new File()
fp.wopen("a.dat")
double a[2]
finitialize(v_init)
fcurrent()
7
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
fp.vwrite(2,&a)
}
fp.close()
WinExec("gc a.dat")
//-----------------------------------------------n05.hoc と n06.hoc では、soma の電位 v をプロットしているが、予想通り何もおきない。
これではつまらないし、うまくプログラムが動作しているかもわからないため、leak 電流の性質を変更して
みる。n05.hoc と n06.hoc では、soma や hh のパラメータは、既定値を用いており、hh の leak 電流の平衡
電位は、default の場合-54.3 mV であるが、この値を-30 mV に変更してみる。細胞はこの leak 電流のため
に脱分極し、Na+ チャネルの閾値に達して action potential を発生し、K+ チャネルにより再分極する。まさ
しく HH モデルの世界!なお hh の詳細は hh.mod で定義されている。
//-----------------------------------------------// n07.hoc:
a simple hh cell, with increased leak
create soma
soma insert hh
soma el_hh = -30
// added
tstop = 200
dt = 0.01
v_init = -65
objref fp
fp = new File()
fp.wopen("a.dat")
double a[2]
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
fp.vwrite(2,&a)
}
fp.close()
WinExec("gc a.dat")
8
40
20
0
-20
-40
-60
0
50
100
150
200
Fig.1 n07.hoc: a simple hh-type neuron
//------------------------------------------------

ここではシステムが動くことを確認するために hh.mod を用いているが、hh.mod は squid axon のモ
デルであり、6.3 ℃という低温での実験に合わせたパラメータを用いている。温度は global 変数 celsius で
設定できる。celsius は default で 6.3 に設定されているようである。温度は Q10 を通してチャネル等のキ
ネティックスに反映される。n07.hoc の場合、celsius = 37 とすると、action potential は発生しなくなっ
てしまう。なお、soma gnabar hh *= 3 として、Na チャネルの density を 3 倍に増加させると、action
potential は再び現れる。神経細胞用には、hh2.mod などが作られている。実際の計算にはそれらを用いた
方がよいと思われるが、mod ファイルをシステムに組込む作業が必要なので、当面は既に組込まれている
hh.mod を用いることとする。
(http://senselab.med.yale.edu/modeldb/ShowModel.asp?model=3817)
3.3 Connecting sections
次に、soma に apical dendrite を付け加える。create は同じ。connect でつなぐ。先にも述べたが、一般
的に hoc の命令文(statement)は、いずれかの section に対して行なわれ、形式的には、section statement
という形となる。複数の statement を {} で囲むことができる。ただし section と { の間に改行を入れないよ
うにする。section の情報は必ずしも明示的に示される訳ではない。access section により section の既定値
を設定できる。
//-----------------------------------------------// n08.hoc:
soma + dendrite
create soma, ap_dend
soma {
L = 30
diam = 30
nseg = 1
insert hh
9
el_hh = -30
}
ap_dend {
L = 500
diam = 2
nseg = 23
}
connect ap_dend(0), soma(1)
tstop = 200
dt = 0.01
v_init = -65
objref fp
double a[4]
fp = new File()
fp.wopen("a.dat")
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
a[2] = ap_dend.v(0.1)
a[3] = ap_dend.v(0.9)
fp.vwrite(4, &a)
}
fp.close()
WinExec("gc a.dat")
//------------------------------------------------
. soma
と ap dend の 2 つの section より成り立っている。nseg で section 内の segment の数を示す。
この値は奇数でなくてはならない。soma および ap dend の近位部から測って 0.1 と 0.9 の部分の電位変化を
プロットしている。活動電位が soma から ap dend に伝わっていることがわかる。
3.4 Point Process
3.4.1 AlphaSynapse
section とならんで重要な要素は、Point Process と呼ばれるものであり、シナプス入力(AlphaSynapse、
Exp2Syn)、current clamp(IClamp)、voltage clamp(VClapm)等がこれにあたる。これらの Point Process
10
20
0
-20
-40
-60
0
50
100
150
200
20
0
-20
-40
-60
80
85
90
95
Fig.2 n08.hoc: Potentials of soma (red), proximal dendrite(0.1) (blue), and distal dendrite(0.9)
(green). The lower panel is a magnification.
はクラスとして定義されており、section に加える場合は、insert ではなく、次の方法で行なう。
objref pp
section pp = new PointProcess(x )
x は、section での位置を示す。
dendrite にシナプス入力を入れる。soma の hh の leak 電流の平衡電位は、default の値に戻した。また
dendrite に soma の 1/10 の density で hh を加えた。
//-----------------------------------------------// n09.hoc
create soma, ap_dend
soma {
L = 30
diam = 30
nseg = 1
insert hh
}
ap_dend {
L = 500
diam = 2
nseg = 23
11
insert hh
gnabar_hh = 0.012
gkbar_hh
= 0.0036
gl_hh = 0.00003
}
connect ap_dend(0), soma(1)
// synaptic input
objref syn
ap_dend syn = new AlphaSynapse(0.5)
syn.onset = 5
syn.tau = 0.1
syn.gmax = 0.05
tstop = 20
dt = 0.01
v_init = -65
objref fp
double a[4]
fp = new File()
fp.wopen("a.dat")
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
a[2] = ap_dend.v(0.1)
a[3] = ap_dend.v(0.9)
fp.vwrite(4, &a)
}
fp.close()
WinExec("gc a.dat")
//------------------------------------------------
12
20
0
-20
-40
-60
0
5
10
15
20
Fig.3 n09.hoc: Synaptically evoked action potential. Synaptic input at dendrite(0.5). Potentials
at soma (red), proximal dendrite(0.1) (blue), and distal dendrite(0.9) (green)
3.5 クラス
同じような神経細胞をいちいち定義するのは手間がかかる。クラス(テンプレート;鋳型)を定義し、クラ
スからオブジェクト(インスタンス)を作成すると、手間が省ける。
クラスの定義は、begintemplate class name と endtemplate class name で囲んだ部分。変数を明示
的に初期化する関数 init() を用意することが必要である。public として宣言された変数、関数が外からアク
セスすることが出来る。
3.6 NetCon、NetStim
神経細胞間の情報伝達は、神経軸索をつたわる活動電位を計算することによりシミュレーションすることが
可能だが、いちいち計算しなくても伝達にかかる時間を delay として取り扱えば、計算量を大幅に減らすこと
ができる。NetCon は delay を考慮に入れたシグナル伝達を扱う pipe メカニズムである。
objref nc
nc = new NetCon(src pp, target pp, threshould, delay, weight)
もしくは、
src section nc = new NetCon(&src range value, target pp, threshould, delay, weight)
という形で定義される。ここで pp は point process を示す。src rannge value は、&v(0.5) の様に表す。
&soma.v(0.5) という表記はエラーとなる。
NetCon の情報は List() を用いて扱うと便利である。
objref nclist
nclist = new List()
nclist.append(new NetCon(src pp, target pp, threshould, delay, weight))
もしくは、
src section nclist.append(new NetCon(&src range value, target pp, threshould, delay, weight))
外部刺激に相当する Point Process メカニズムとして、NetStim クラスが用意されている。NetStim は、
NetCon の source としても target としても利用できる。パラメータとしては、interval、number、start、
noise などがある。
13
hh_neuron[0]
stim
hh_neuron[1]
esyn
esyn
soma.v
soma.v
NetCon
Fig.4 Two synaptically connected neurons.
//--------------------------------------// n10.hoc
//--------------------------------------//
class definition
begintemplate HHneuron
public soma, ap_dend, esyn
create soma, ap_dend
objref esyn
proc init(){
soma {
L = 30
soma.diam = 30
soma.nseg = 1
soma insert hh
}
ap_dend {
L = 500
diam = 2
nseg = 23
insert hh
gnabar_hh = 0.012
gkbar_hh
= 0.0036
gl_hh = 0.00003
14
}
connect ap_dend(0), soma(1)
ap_dend esyn = new Exp2Syn(0.5)
esyn.tau1 = 0.5
esyn.tau2 = 1.0
esyn.e = 0
}
endtemplate HHneuron
//--------------------------------------// cells
objref hh_neuron[2]
hh_neuron[0] = new HHneuron()
hh_neuron[1] = new HHneuron()
// synapse
objref stim
stim = new NetStim(0.5)
stim.interval = 20
stim.number = 3
stim.start = 20
stim.noise = 0
// connections
objref nclist
nclist = new List()
nclist.append( new NetCon(stim, hh_neuron[0].esyn, 0.0, 0, 0.02))
hh_neuron[0].soma nclist.append( new NetCon( &v(0.5), \
hh_neuron[1].esyn, 10, 1, 0.02))
//--------------------------------------tstop = 100
dt = 0.01
v_init = -65
objref fp
double a[3]
fp = new File()
fp.wopen("a.dat")
finitialize(v_init)
fcurrent()
15
20
0
-20
-40
-60
0
20
40
60
80
100
Fig.5 n10.hoc: Synaptically connected neurons
while(t<tstop){
fadvance()
a[0] = t
a[1] = hh_neuron[0].soma.v(0.5)
a[2] = hh_neuron[1].soma.v(0.5)
fp.vwrite(3, &a)
}
fp.close()
WinExec("gc a.dat")
//---------------------------------------
NetCon で weight のパラメータを 0.02 から-0.02 に変えてみると、次の結果が得られた (図 3.6)。Rebound
firing を示している。ただしこの神経細胞は Na+ チャネル、K+ チャネル、leak チャネルを持っているだけ
で、low-threshold タイプの Ca2+ チャネルを有しているわけではない。
3.7 Voltage clamp
単一コンパートメント(soma のみ)にシナプス入力がある場合に、voltage clamp で測定する場合のシミュ
レーション。
//--------------------------------------//
n11.hoc
//
create soma
objref esyn
objref vcl
16
40
20
0
-20
-40
-60
-80
-100
0
20
40
60
Fig.6 Inhibitory connection
soma {
L = 30
diam = 30
nseg = 1
esyn = new Exp2Syn(0.5)
insert hh
vcl = new VClamp(0.5)
}
// stimulation
objref stim
stim = new NetStim(0.5)
stim.interval = 50
stim.number = 2
stim.start = 50
stim.noise = 0
// synaptic connections
objref nclist
nclist = new List()
nclist.append( new NetCon(stim, esyn, 0.0, 0, 0.005))
//--------------------------------------tstop = 200
dt = 0.01
v_init = -65
17
80
100
vcl.dur[0] = 10
vcl.dur[1] = 10
vcl.dur[2] = 180
vcl.amp[0] = v_init
vcl.amp[1] = v_init
vcl.amp[2] = v_init
vcl.gain = 1000
vcl.tau1 = 0.01
vcl.tau2 = 0.01
objref fp
double a[3]
fp = new File()
fp.wopen("a.dat")
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
a[2] = 1000 * vcl.i
fp.vwrite(3, &a)
}
fp.close()
system("gc a.dat")
//--------------------------------------Voltage clamp で、シナプス電流の i-v relation を求める。基本的には上記のプログラムと同じ。holding
potential を変化させて繰り返しを行なっている。
//--------------------------------------//
n12.hoc
// iv in voltage-clamp mode
tstop = 50
dt = 0.01
vstart = -100
vstep = 10
ntrace = 20
npnt
// voltage step of holding potential
// number of traces
= tstop/dt
double a[npnt][ntrace+1]
18
200
100
0
-100
-200
-300
0
50
100
150
200
Fig.7 n11.hoc: Synaptic current measured in the voltage-clamp mode
objref vc, syn, ns, nc
create soma
soma {
diam = 30
L = 30
nseg = 1
insert pas
vc = new VClamp(0.5)
vc.dur[0] = 10
vc.dur[1] = 10
vc.dur[2] = 30
syn = new Exp2Syn(0.5)
syn.e = 0
}
ns = new NetStim()
ns.number = 1
ns.start = 10
ns.noise = 0
nc = new List()
nc.append(new NetCon(ns,syn, 0, 0, 0.001))
for i=1, ntrace {
v_init = vstart + vstep * (i-1)
vc.amp[0]=v_init
vc.amp[1]=v_init
19
// 1 nS
50
0
-50
-100
0
10
20
30
40
50
Fig.8 n12.hoc: A group of synaptic current traces in the voltage-clamp mode
vc.amp[2]=v_init
e_pas = v_init
finitialize(v_init)
fcurrent()
for j = 0, npnt-1 {
fadvance()
if(i==1) a[j][0] = t
a[j][i] = 100 * vc.i
}
}
objref fp
fp=new File()
fp.wopen("a.dat")
for j = 0, npnt-1 {
fp.vwrite(ntrace+1, &a[j][0])
}
fp.close()
system("gc a.dat")
//---------------------------------------
.
シナプス入力には Ex2Syn() を用いた。leak 電流には pas を用い、holding current を消すために、leak
電流の平衡電位が holding potential と同じであるとして計算している。2 次元の配列にデータを記録し、ま
とめてファイルに書き込んでいる。
soma より 10 本の dendrites がでており、soma で voltage clamp を行なった場合のシミュレーションは次
のようになる。
20
//--------------------------------------//
n13.hoc
//
create soma, dend[10]
objref esyn
objref vcl
soma {
L = 30
Ra = 100
nseg = 1
diam = 30
insert hh
vcl = new VClamp(0.5)
}
for i=0,9 {
dend[i] {
L = 300
Ra = 100
nseg = 21
diam=2
insert hh
gl_hh *= 2.3
}
}
dend[0] esyn = new Exp2Syn(0.75)
for i=0,9{
connect dend[i](0), soma(1)
}
// stimulation
objref stim
stim = new NetStim(0.5)
stim.interval = 50
stim.number = 2
stim.start = 50
stim.noise = 0
// synaptic connections
objref nclist
21
nclist = new List()
nclist.append( new NetCon(stim, esyn, 0.0, 0, 0.001))
//--------------------------------------tstop = 200
dt = 0.01
v_init = -65
vcl.dur[0] = 10
vcl.dur[1] = 10
vcl.dur[2] = 180
vcl.amp[0] = v_init
vcl.amp[1] = v_init
vcl.amp[2] = v_init
vcl.gain = 1000
vcl.tau1 = 0.1
vcl.tau2 = 0.1
objref fp
double a[4]
fp = new File()
fp.wopen("a.dat")
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
a[2] = dend[0].v(0.75)
a[3] = 100 * vcl.i
fp.vwrite(4, &a)
}
fp.close()
WinExec("gc a.dat")
//---------------------------------------
22
-20
-30
-40
-50
-60
-70
0
50
100
150
200
Fig.9 n13.hoc: Synaptic current measured in the voltage-clamp mode (green). Synaptic input at
dendrite[0](0.75). The voltage-clamp electrode is positioned at soma. Potentials at soma (red) and
dendrite[0](0.75) (blue). Currents are in nA, and magnified by a factor of 100.
23
4 Morphology
4.1 section
NEURON では、神経細胞の形態を円柱もしくは錐体の集まりとして表現している。それぞれのパーツは、
section と呼ばれる。表面として計算されるのは、円柱の側面に当たる部分であり、断面に当たる部分は考え
に入れられていない。soma も、球体・楕円体ではなく円柱として考えられる。半径 r の球の表面積は、4πr 2
で表されるが、長さ 2r、半径 r の円柱の側面の面積は、(2r) ∗ (2πr) なので、球の場合と同じになる。
長い円柱の場合、cable property を考慮に入れなくてはならない。NEURON では section を segment に分
割して計算する機能を備えている。nseg は分割の値であり、演算の技術的な理由で、この値は奇数でなくては
ならない。円柱の位置を示すには、分割された部分の番号ではなく、0 と 1 の間の値で示される Normalized
distance が用いられる。このために、nseg の値を変更しても、場所を示す値を変える必要はない。
nseg をどのような値にするかにより、計算の結果は異なってくる。通常は nseg = 3 程度でよいが、形態学
的なデータに基づく枝分かれのあるモデルの場合は、nseg ≥ 9 が必要であるとされている。
section のパラメータとしては、次のものがある。
• L // Length [µm]
• Ra // cytoplasmic registivity [Ωcm]
• nseg // discretization parameter
それぞれの segment でのパラメータである Range variable には次のようなものがある。
• diam // diameter
• cm // specific membrane capacitance [µf/cm2 ]
• v // membrane potential [mV]
• nai // internal sodium concentration [mM]
range variable が、distance に対して linear に変化する場合、dend01.diam(0:1) = 1.5:1.0 というように書
くことができる。このような値の設定は、各 segment 毎の値を入れているので、当然のことながら、nseg が
先に与えられなくてはならない。
Dendrite に分岐がある場合にそれらを単一の dendrite として計算を行なう Rall の Cable 理論では、
(dj )2/3 = (dk1 )2/3 + (dk2 )2/3 という条件を満たしている必要があった。
dk1
dj
dk2
Fig.10 Branching of dendrites
24
nseg = 1
nseg = 2
nseg = 3
Fig.11 Calculation is performed at thenodes with red markings
しかし NEURON では、演算をおこなう点(node)を section のつながりの部分にも置いており、section
間の条件は緩和されている。
4.2 geometory
神経細胞を模したモデルを作るには、soma、dendrite、axon などの section を create し、それらをつな
げばよい。section をつなぐには、connect child( 0 or 1), parent ( x ) を用いる。これは、parent connect
child( 0 or 1), x と書いても同じである。
この操作を簡便にするために、Menu → Build → Cell Builder が用意されている。より複雑な形態をした
神経細胞のデータ入力には、ファイルからの読み込で行なわれる。3 次元の座標(x, y, z)と半径 diam が与
えられている場合、pt3dadd() を用いる。
入力したあるいは読み込んだデータの確認には、
• section name psection() // parameters of a section
• forall psection() // parameters for all sections
• topology() // section connections
• Menu → Graph → Shape plot
が便利である。
実際に神経細胞の形態のデータを読み込むには、先ず dendrite を配列として create し、データを読み込
み、そして section を connect する。下記のような例を見ると参考になる。
• http://senselab.med.yale.edu/modeldb/ShowModel.asp?model=279 の tc200.geo、
これらの例では、ファイルからの読み込みの場合、hoc ファイルにプログラムコードとデータの数値が同一
のファイルに入っているという、普通のプログラムから考えると奇妙な成り立ちになっている。これは、比較
的初期の NEURON では、ファイルの入出力に制限(入力用にファイルが 1 つしか開けない)があったため
に、苦肉の策としてこのような形になったのではないかと思われる。しかしながら、これらのファイルは単に
読み込むだけで形態のデータを取り込めるので非常に便利である。
通常これらのデータは、section の長さ(L)、直径(diam)および Connection を定義しているが、nseg
や Ra 等を含めて他の定義は行なっていないことに注意する必要がある。
load_file("tc200.geo")
25
なお、ソースコードとデータを分け、テキスト形式のデータファイルからデータを読み込むには、File クラ
スを用いて、次のようなコードを適宜書き換えて使用すればよい。古典的な ropen() と fscan() の組み合わ
せは、動かない。(クラス関数の.ropen() と ropen() は別物らしい。)
//--------------------------------------objref fp
fp = new File()
fp.ropen("datafile.txt")
// open for read
while(1){
a = fp.scanvar()
// fscan() does not work
printf ("a = %f\n", a)
}
fp.close()
//---------------------------------------
4.3 segment の長さ
例を見ていると、100 µm を越えるような細長い section でも nseg=1 となっている。これでは具合が悪い
であろうということは想像に難くない。シグナルの減弱は距離と周波数に関係しており、e-fold の減弱が生じ
る長さは、
√
d
πf Ra Cm
1
λf ≈ 2
で表される。diam = 1 µm、Ra = 180 Ωcm、Cm = 1 µf/cm2 、Rm = 16,000 Ωcm2 とすると、λ100 ∼ 225
µm となる。segment の長さ(L/nseg)の λf に対する比率パラメータを、d lambda と呼ぶ。d lambda の
既定値は 0.1 である。(ただし、膜の時定数 τm が 8 ms 以下の場合はより小さい値を用いる必要がある。)目
安として、diam が 1 µm の場合、1 segment の長さは 20 µm 程度にするということになる。
自動的に nseg を決めるには、下のコードを用いる。これらの関数は stdlib.hoc に含まれている。
//--------------------------------------func lambda_f(){
return 1e5 * sqrt(diam/(4 * PI * $1 * Ra * cm))
}
proc geom_nseg(){
soma area (0.5)
nseg = int ((L/(0.1*lambda_f(100)) + 0.9)/2) * 2 + 1
}
//--------------------------------------読み込んだ形態データを確認するために、いくつかの手段が用意されている。
• psection() コマンドで section の情報を示すことができる。ある特定の section の情報が知りたい場
26
合は、section psection()、全ての section の情報が知りたい場合は、forall psection() を用いる。
SectionList を利用する場合は、forsec section list psection()。
• topology() コマンドで、section がどのように connect されているかを示す。
• 図で示す。図で示す方法には用途に応じていくつかのやり方があるようであるが、一番基本的な方法
は、Shape クラスを用いる方法である。
objref sh
sh = new Shape(mode)
引数は mode で、0 の場合 diam、1 の場合 centroid、2 の場合直線で示される。mode は図の menu で
変更可能。特定の section の色を変える方法は、section shape.color(color)。color は、2 が赤、3 が青
である。 Point process をマークするには、shape.point mark(point process, color) が便利。
なお、Graph が表示されている状態で、NEURON Main Menu →Window →Print File Window Manager
→Print →PostScript という操作により、図を PostScript(ps)ファイルに保存することができる。以後の
処理は、外枠などの余分な図形があるので、ps ファイルを import して GUI で操作編集できるソフトが便利。
ps ファイルまたは eps(encapsulated postscript)ファイルを読み込むことができるソフトは比較的限られて
いる。例えば、Adobe Illustrator(Windows, Mac OS)
、Corel Draw(Windows)
、Scribus*2(Linux, Mac
OS, Windows; Open Source)など。eps ファイフは bitmap データを含んでおり、PostScript の解釈をして
図を描くのではなく、この bitmap 情報を使用するソフト(Microsoft Office など)では、編集はできない。
tc200 のモデルを読み込み、dendrite に random に 30 個のシナプスを作る例。
//------------------------------//
n14.hoc
//
load_file("nrngui.hoc")
load_file("stdlib.hoc")
load_file("tc200geo.hoc")
//------------------------------nSyn=30
tstop = 200
dt = 0.01
v_init = -65
//--------------------------------------objref dendritic, dendritic_only
objref sh
objref r, locvec, tx
objref esyn[nSyn]
objref sref
*2
http://www.scribus.net/
27
objref nclist
strdef s
//------------------------------//
class definition
//
begintemplate TimeClock
public getSec
double jx[3]
strdef datetime
func getSec(){
// returns time in sec
system("date ’+%H %M %S’", datetime)
sscanf(datetime,"%d%d%d", &jx[0], &jx[1], &jx[2])
return (jx[0]*60 + jx[1])*60 + jx[2]
}
endtemplate TimeClock
//------------------------------//
utilities
//
func measureDist(){local dx localobj sr
dx = 0
sr = new SectionRef()
while(sr.has_parent){
dx += L
access sr.parent
sr = new SectionRef()
}
return dx
}
//------------------------------// Properties of dendrites
//
dendritic = new SectionList()
forall {
insert hh
Ra = 100
dendritic.append()
}
28
soma dendritic.remove()
forsec dendritic {
d = lambda_f(100)
nseg = int((L/(0.1*d))+0.9)/2*2+1
}
// total dendritic length
total_length=0
forsec dendritic {
total_length += L
}
print "Tolal dendrite length = ", total_length
//------------------------------// Shape Plot
sh = new Shape(1)
sh.size(-150, 150, -150, 150)
//------------------------------// stimulation
objref stim
stim = new NetStim(0.5)
stim.interval = 50
stim.number = 2
stim.start = 50
stim.noise = 0
nclist = new List()
//------------------------------// random generator
tx = new TimeClock()
r = new Random(tx.getSec())
r.uniform(0, total_length)
locvec = new Vector(nSyn)
locvec.setrand(r)
for k = 0, nSyn-1 {
l=0
29
l1 = 0
found = 0
forsec dendritic {
if(found==0){
l1 += L
if(l1>locvec.x(k)){
lx = (locvec.x(k)-l)/L
sref = new SectionRef()
print secname(), measureDist()
sref.sec {
esyn[k] = new Exp2Syn(lx)
sh.color(2)
}
sh.point_mark(esyn[k],3)
nclist.append( new NetCon(stim, esyn[k], 0.0, 0, 0.001))
found = 1
break
}
l = l1
}
}
}
sh.flush()
doEvents()
//------------------------------// main loop
objref fp
fp = new File()
fp.wopen("a.dat")
double a[2]
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
30
Fig.12 n14.hoc: tc neuron and random synapses
fp.vwrite(2, &a)
}
fp.close()
system("~/bin/gc a.dat")
//------------------------------------------------
Windows/Cygwin の場合、system(cmd) は動くが、system(cmd, string) にバグがあるようだ。そのバ
グを回避するために、次のコードを使用する。
begintemplate TimeClock
public getSec
double jx[3]
strdef datetime
31
func getSec(){
// returns time in sec
system("date ’+%H %M %S’ > tmp001.txt") // changed
ropen("tmp001.txt")
// added
getstr(datetime)
// added
ropen()
// added
system("rm tmp001.txt")
// added
sscanf(datetime,"%d%d%d", &jx[0], &jx[1], &jx[2])
return (jx[0]*60 + jx[1])*60 + jx[2]
}
endtemplate TimeClock
次に、n 次以上の dendrite 分岐に一様に synapse 入力がある場合を考える。mesureDis()、countBranch()
を呼ぶことにより access している section が変化しないように改良。シナプスの数は 100 個。synaptic
delay は正規分布の乱数を用い、平均 10 ms、標準偏差 1 ms としている。synaptic delay は負の数になると
エラーを起こすことに注意。
//------------------------------//
n15.hoc
//
load_file("nrngui.hoc")
load_file("tc200geo.hoc")
//------------------------------tstop = 200
dt = 0.01
v_init = -65
nSyn=100
// number of synapses
mdel = 10
// mean of synaptic delay
sdel = 1
// sd of synaptic delay
w = 0.001
// synaptic weight
br = 5
//--------------------------------------objref dendritic, dendriticN
objref sh
objref r, vloc, vdel, tx
objref esyn[nSyn]
objref sref
objref nc
32
strdef s
//------------------------------//
class definition
//
begintemplate TimeClock
public getSec
double jx[3]
strdef datetime
func getSec(){
// returns time in sec
system("date ’+%H %M %S’", datetime)
sscanf(datetime,"%d%d%d", &jx[0], &jx[1], &jx[2])
return (jx[0]*60 + jx[1])*60 + jx[2]
}
endtemplate TimeClock
//------------------------------//
utilities
//
func measureDist(){local dx localobj sr, srsave
dx = 0
srsave = new SectionRef()
sr = new SectionRef()
while(sr.has_parent){
dx += L
access sr.parent
sr = new SectionRef()
}
access srsave.sec
return dx
}
func countBranch(){local bx localobj sr, srsave
bx = 0
srsave = new SectionRef()
sr = new SectionRef()
while(sr.has_parent){
if(sr.nchild==2){
bx += 1
33
}
access sr.parent
sr = new SectionRef()
}
access srsave.sec
return bx
}
//------------------------------// Properties of dendrites
//
dendritic = new SectionList()
forall {
insert hh
Ra = 100
dendritic.append()
}
soma dendritic.remove()
forsec dendritic {
d = lambda_f(100)
nseg = int((L/(0.1*d))+0.9)/2*2+1
}
dendriticN = new SectionList()
total_length=0
forall {
if(countBranch()>=br){
dendriticN.append()
total_length += L
}
}
print "total length of \">=", br, "-branch\" dendrites = ", total_length
//------------------------------// Shape Plot
sh = new Shape(1)
//------------------------------34
// stimulation
objref stim
stim = new NetStim(0.5)
stim.interval = 50
stim.number = 2
stim.start = 50
stim.noise = 0
//------------------------------// random generator
tx = new TimeClock()
r = new Random(tx.getSec())
r.uniform(0, total_length)
// synaptic location
vloc = new Vector(nSyn)
vloc.setrand(r)
r.normal(mdel,sdel*sdel)
// synaptic delay
vdel = new Vector(nSyn)
vdel.setrand(r)
nc = new List()
for k = 0, nSyn-1 {
l=0
l1 = 0
found = 0
forsec dendriticN {
if(found==0){
l1 += L
if(l1>vloc.x(k)){
lx = (vloc.x(k)-l)/L
sref = new SectionRef()
print secname(), ", dist=", measureDist(), \
", br=", countBranch(), ", delay=", vdel.x(k)
sref.sec {
esyn[k] = new Exp2Syn(lx)
sh.color(2)
}
sh.point_mark(esyn[k],3)
35
nc.append(new NetCon(stim, esyn[k], 0.0, vdel.x(k), w))
found = 1
break
}
l = l1
}
}
}
sh.flush()
doEvents()
//------------------------------// main loop
objref fp
double a[2]
fp = new File()
fp.wopen("a.dat")
print "Sim Start"
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
a[1] = soma.v(0.5)
fp.vwrite(2, &a)
}
fp.close()
system("~/bin/gc a.dat &")
// -- end of file
36
Fig.13 n15.hoc; 100 random synapses
20
0
-20
-40
-60
0
50
100
150
200
Fig.14 赤:n14.hoc のトレース、青:n15.hoc のトレース
37
5 Spikes
5.1 NetCon
神経細胞集団の活動場合、膜電位 v の変化よりも活動電位あるいはスパイクのタイミング、数の方が解析の
対象となってくる。スパイクの記録は NetCon の.record() を用いて行なうことができる。神経細胞が List ク
ラスのオブジェクト cells であり、それぞれの神経細胞にあるポイントプロセス pp がスパイクを表すとする。
//------------------------------objref spikes
objref netcon, vec
spikes = new List()
for i=0, cells.count()-1 {
vec = new Vector()
netcon = new NetCon(cells.object(i).pp, nill)
netcon.record(vec)
spikes.append(vec)
}
objref netcon, vec
//------------------------------vec には、event が起きた実時間が記録される。スパイクのデータをファイルに記録するには、Vector ク
ラスの関数.vwrite(fp) が便利である。[データ数: 4-byte integer][4: 4-byte integer][データ 0: 8-byte
double][データ 1: 8-byte double].....[データ N: 8-byte double]という binary の形式でファイルに書か
れる。2 番目の値 4 は、データが double であることを示す。
//------------------------------objref fp
fp.wopen("a.nrb")
for i=0, spikes.count()-1 {
vec.vwrite(fp)
}
fp.close()
//-------------------------------
5.2 Raster Plot の描き方
ここではラスタープロットを描く関数を示す。local な変数はできるだけ local に宣言し、他の関数との混乱
を防ぐようにしている。使い方は、あらかじめ Graph オブジェクトを用意しておき、データファイル(たと
えば a.nrb)を読みこむ。
objref gr
38
gr = new Graph()
plotRaster(gr, ”a.nrb”)
//------------------------------//
plotRaster(Graph, String)
proc plotRaster(){ local nn, ts \
localobj fp, spikes, vec, spikey
fp = new File()
fp.ropen($s2)
if(!fp.isopen()){ return }
nn = 0
ts = 0
spikes = new List()
while(!fp.eof()){
vec = new Vector()
vec.vread(fp)
spikes.append(vec)
nn += 1
xx = vec.x(vec.size()-1)
if(ts < xx){ ts = xx }
}
fp.close()
$o1.view(0, 0, ts, nn, 100, 100, 400, 200)
$o1.erase_all()
for i=0, nn-1{
spikey = spikes.object(i).c
spikey.fill(i+1)
spikey.mark($o1, spikes.object(i), "|", 6)
}
}
//------------------------------この関数について特にコメントをすることはないが、NEURON における Vector の扱い方の参考になる。
39
6 NMODL
NMODL は NEURON 版の MODL(MOdel Description Language)である。MODL は NEURON だけで
なく Genesis などの他のシステムでも用いられており、NMODL で書かれたファイル(mod ファイル)は、原
則的には他のシステムでも利用可能である。mod ファイルの内部は、PARAMETER、STATE、ASSIGNED
等のいくつかのブロックに分かれている。ブロックの種類の中で NEURON ブロックは、NEURON に特有
のものである。
mod ファイルは、nocmodl により C 言語のファイルに変換されて、その後 gcc(C コンパイラ)によりコン
パイルされる。Windows の場合、nrnmech.dll が作成されて実行時に oc に組み込まれる。従って新たな mod
ファイルを使用する場合にも、oc インタープリタ本体のコンパイルをする必要はない。MacOS と Linux の
場合、special という名前の実行形式のスクリプトが生成される。このスクリプトは新たに作成されたダイナ
ミックライブラリ({umac, i686}/.libs/libnrnmech.so)を読み込む。
実際の操作は、Windows の場合、mknrndll のアイコンをクリックし、mod ファイルがあるディレクト
リを選択する。コマンドラインから操作を行う場合、mod ファイルが置かれているディレクトリに移動
して、$NEURONHOME/bin にある mknrndll という shell script を使えばよい。ただしこの scirpt では
NEURONHOME を示す変数 N が定義されていないので、
N=/cygdrive/c/nrn62
export N
の 2 行を付け加えなくてはならない。
Mac の場合は、mod ファイルのあるディレクトリ(フォルダ)のアイコンを mknrndll のアイコンに重ね
る。コマンドラインからの場合は、mod ファイルが置かれているディレクトリに移動し、open -a mknrndll
. とする(”.”は言うまでもなく current directory の意味)。そのディレクトリ内に umac(Mac Universal
BInary の意で、ppc と intel 系の両方の CPU で稼働できる)という名前のディレクトリが作成され、その中
に special という実行可能なファイルが作られる。
Mac の場合でも、ソースコードからコンパイルした場合には、アイコンや application bundle が作成され
ない場合がある。そのような場合は、nrniv などが含まれる bin ディレクトリにある nrnivmodl という名前の
シェルスクリプトを使用して、nrnivmodl . とする。”.”はあってもなくても構わないようだ。
6.1 Blocks
mod ファイルでコメントは、COMMENT と ENDCOMMENT で挟まれた行、あるいは”:”で始まる行で
ある。また VERBATIM と ENDVERBATIM に挟まれた行は、nocmodl で処理されることなくそのまま C
言語ファイルになる。
6.1.1 NEURON block
SUFFIX でモジュールの名前を定義する。RANGE で外からアクセスできる変数を示す。
40
6.1.2 ASSIGNED block
mod ファイル外で値をいれる変数、あるいは mod ファイル内で式の左側に来る変数。
6.1.3 STATE block
微分法的式などで用いられる変数。変数は ASSIGNED と STATE の両方で宣言することは出来ない。
6.1.4 INITIAL block
初期化ブロック。関数 finitialize(v init) から各 module の INITITAL block が使われる。
6.1.5 BREAKPOINT block
実際の計算の場所。微分方程式を解く場合は SOLVE を用いる。方法としては、cnexp(Crank-Nicolson
法)、runge(Runge-Kutta 法)、euler(Euler 法)、derivimplicit などが使用可能。これらの方法は、いずれ
も一定の dt を用いる fixed step method である。通常は cnexp。runge は求められる以上の精度のため使用
されない(時間がかかる)。
状況によって積分の細かさを変化させる adaptive integrator の方法としては、CVODE 法が利用可能で
ある。
6.1.6 DERIVATIVE block
ここには常微分方程式がくる。
6.1.7 NET RECEIVE block
NetCon のために拡張された部分らしい。event が起きた時に何をするかを記述する部分。
6.2 例:常微分方程式を解いてみる
試しに簡単な常微分方程式の数値解を求めるのに NEURON を使用してみる。まず簡単な常微分方程式で
試してみる。
z ′′ = −z
初期値は、z(0) = 0, z ′ (0) = 1 とする。z1 = z ′ と置くと、
z ′ = z1
z1′ = −z
連立の微分方程式として表すことが出来る。
:--------------------------------------: m01.mod:
a simple ODE
z(t)’’ = -z(t)
NEURON{
SUFFIX m01
RANGE z
41
}
STATE {z z1}
INITIAL{
z = 0
z1 = 1
}
BREAKPOINT{
SOLVE zstates METHOD cnexp
}
DERIVATIVE zstates {
z’ = z1
z1’ = -z
}
:--------------------------------------この mod ファイルを試すための hoc ファイル。
//--------------------------------------// m01.hoc:
test file for mo1.mod
create soma
soma insert m01
tstop = 100
dt = 0.01
v_init = -65
objref fp
fp = new File()
fp.wopen("a.dat")
double a[2]
finitialize(v_init)
fcurrent()
while(t<tstop){
fadvance()
a[0] = t
soma a[1] = z_m01
fp.vwrite(2,&a)
}
42
1.0
0.5
0.0
-0.5
-1.0
0
20
40
60
80
100
Fig.15 m01.hoc: m10.mod 内で cnexp を用いて数値計算。
1.5
1.0
0.5
0.0
-0.5
-1.0
-1.5
0
20
40
60
80
100
Fig.16 m01.hoc: m10.mod 内で異なる数値計算法を用いた。cnexp(赤; 緑に重なっている)、euler
(青)、runge(緑)。
fp.close()
WinExec("gc a.dat")
//---------------------------------------
6.3 IntervalFire
NEURON Book に掲載されている Interval File を掲載する。人工細胞であり、変数 m は、微分方程式
dm
= (m∞ − m)/τ
dt
43
に従い、その値が 1 を越えると fire して m = 0 に戻る。 外からに入力があると、m の値が w だけ変化する。
この式は解析的に解けて、m(t = 0) = 0 とすれば、
t
m = m∞ (1 − exp(− ))
τ
で示される。t = invl の時、m = 1 であるから、
m∞ =
1
1 − exp(− invl
τ )
である。
: ------------------------------------------------------------------------:
The NEURON Book pp. 309- 310
NEURON {
ARTIFICIAL_CELL IntervalFire
: name of the module
RANGE tau, m, invl
: accessible variables
}
PARAMETER {
tau = 5 (ms)
<1e-9,1e9>
invl = 10 (ms) <1e-9,1e9>
}
ASSIGNED {
: non-accessible variables
m
minf
t0 (ms)
}
INITIAL {
minf = 1/(1 - exp(-invl/tau)) : so natural spike interval is invl
m = 0
t0 = 0
net_send(firetime(), 1)
: set a self-event
: after time period of firetime()
}
NET_RECEIVE (w) {
m = M()
t0 = t
if (flag == 0) {
: *** event triggered by others ***
m = m + w
if (m > 1) {
m = 0
net_event(t)
: issue event
}
44
net_move(t+firetime())
}else{
: move the next event to t + firetime()
: *** self-triggered event ***
net_event(t)
: issue event
m = 0
net_send(firetime(), 1)
: next self-event
}
}
FUNCTION firetime()(ms) {
: m < 1 and minf > 1
firetime = tau*log((minf-m)/(minf - 1))
}
FUNCTION M() {
: to monitor m-value
M = minf + (m - minf)*exp(-(t - t0)/tau)
}
: -------------------------------------------------------------------------
. NetCon
に関しては十分な Reference がないので、この例は NetCon をどのように使用すればよいかを
理解するために、とても参考となる例である。ここで使用されている NetCon に関係する関数は下記の通り。
• net event(t1 ) 時間 t1 に event を発生させる。event は NetCon で定義された相手全てに伝えられる。
• net send(t2 , f lag) 現時点 t より t2 後に event を発生させる。f lag = 0 の場合は他に、f lag = 1 の
場合は self へ event が送られる。
• net move(t3 ) 詳細は不明。次に起きる予定の self event を t3 へと移動させるらしい。
INITIAL block では、m∞ の値を求めるとともに、m の値を初期化している。t0 は event が発生からの時間
を示す。さらに INITIAL block で net send() を用いて次の event が起きるように設定している。firetime()
は次の event が起きるまでの時間を計算する関数。ここでは invl でもよい。
event が起きた場合、NET RECEIVE block が実行される。引数 w は NetCon の weight であり、正負の
値を取ることができる。何を実行するはか、m の値に依存するが、m の値は常々計算されている訳ではない
ので、まずは明示的に m の値を(場合によっては計算して)入れる。event が起きた時刻として t0 をアップ
デートする。
f lag は event が自己由来か他由来かを示すフラグで、0 の場合は他、1 の場合は自己であることを示す。他か
らの event を受け取った場合、新しい m の値は m+w となる。もしそれが 1 を越えていたなら、net event()
で event を発生させる。m の値が変化したので、次の event 予定をキャンセルして、net move() を用いて
firetime()+t にセットし直す。
自己から発せられた event の場合は、event を発生させ、次の自己宛の event を net send() でセットする。
m の値は NET RECEIVE block でしか計算されない。m の挙動をしらべるため、関数 M を定義してい
る。M の値はアクセスされるたびに更新されている。関数 X の返す値は、X() ではなく X で示すことがで
きる。
45
6.4 Synaptic transmission
先ず標準の Point process である exp2syn の内容を検討する。event が起きたた場合に、2 つの指数関数
の和で表されるコンダクタンスの変化を示す。
: ------------------------------------------------------------------------:
nrn-6.1src/nrnoc/exp2syn.mod
NEURON {
POINT_PROCESS Exp2Syn
RANGE tau1, tau2, e, i
NONSPECIFIC_CURRENT i
RANGE g
GLOBAL total
}
UNITS {
(nA) = (nanoamp)
(mV) = (millivolt)
(uS) = (microsiemens)
}
PARAMETER {
tau1= 0.1 (ms) <1e-9,1e9>
tau2 = 10 (ms) <1e-9,1e9>
e=0 (mV)
}
ASSIGNED {
v (mV)
i (nA)
g (uS)
factor
total (uS)
}
STATE {
A (uS)
B (uS)
}
INITIAL {
LOCAL tp
46
total = 0
if (tau1/tau2 > .9999) {
: avoid tau1==tau2
tau1 = .9999*tau2
}
A = 0
B = 0
tp = (tau1*tau2)/(tau2 - tau1) * log(tau2/tau1)
factor = -exp(-tp/tau1) + exp(-tp/tau2)
factor = 1/factor
}
BREAKPOINT {
SOLVE state METHOD cnexp
g = B - A
i = g*(v - e)
}
DERIVATIVE state {
A’ = -A/tau1
B’ = -B/tau2
}
NET_RECEIVE(weight (uS)) {
A = A + weight*factor
B = B + weight*factor
total = total+weight
}
: -------------------------------------------------------------------------
. t=0
の時に入力があったとすると、コンダクタンス g の時間的な変化は、
(
)
t
t
g = f actor exp(−
) − exp(−
)
tau2
tau1
で表される。f actor は、g の最大値が 1 となるようにするための係数である。f actor の値を求めるために、g
が極値をとる t の値 tp を求める。
(
)
dg
1
t
1
t
= f actor −
exp(−
)+
exp(−
)
dt
tau2
tau2
tau1
tau1
47
t = tp の時 dg/dt = 0 であるから、
1
tp
1
tp
exp(−
)=
exp(−
)
tau2
tau2
tau1
tau1
tp
tp
tau1 exp(−
) = tau2 exp(−
)
tau2
tau1
tp
tp
log(tau1) −
= log(tau2) −
tau2
tau1
(
)
1
1
tau2
−
)
tp = log(
tau1 tau2
tau1
tau1 ∗ tau2
tau2
tp =
log(
)
tau2 − tau1
tau1
従って、
. NET RECEIVE block
(
)
tp
tp
f actor = 1/ exp(−
) − exp(−
)
tau2
tau1
で行なっていることは、状態の設定し直し(一種の初期化とも言える)であり、
各 time step での計算は、BREAKPOINT block(実態は DERIVATIVE block)で行なわれている。

元のソースコードでは、A = A + weight*factor の部分が、state discontinuity(A, A+weight*factor)
と書かれている。この state discontinuity() という関数は、微分方程式で変数が abrupt に変化した場合のト
ラブルを回避するためのものであるが、NET RECEIVE block の改良により用いる必要はなくなっている。
par
6.5 Synaptic plasticity
これも NEURON Book からの転載であるが、Use-dependent synaptic plasticity の例を示す。この
コードは、nrn-6.1/share/examples/niniv/netcon/gsyn.mod と同じもの。上記の例から推測されるように、
NET RECEIVE block で、event が起きればその時刻を記録しておき、次の event が起きた時に前の event
からの時間によってシナプス結合の強度を調節するようにすればよい。変数の記憶には、NetCon の機能が
用いられる。
: ------------------------------------------------------------------------:
The NEURON Book pp. 281-282
: ------------------------------------------------------------------------:
The NEURON Book pp. 281-282
NEURON {
POINT_PROCESS GSyn
RANGE tau1, tau2, e, i
RANGE Gtau1, Gtau2, Ginc
NONSPECIFIC_CURRENT i
RANGE g
}
UNITS {
48
(nA)
=
(nanoamp)
(mV)
=
(millivolt)
(umho)
=
(micromho)
}
PARAMETER {
tau1
= 1
(ms)
tau2
= 1.05 (ms)
Gtau1
= 20
(ms)
Gtau2
= 21
(ms)
Ginc
= 1
e
= 0
(mV)
}
ASSIGNED {
v
(mv)
i
(nA)
g
(umho)
factor
Gfactor
}
STATE {
A (umho)
B (umho)
}
INITIAL {
LOCAL tp
A = 0
B = 0
tp = (tau1*tau2)/(tau2-tau1) * log(tau2/tau1)
factor = -exp(-tp/tau1) + exp(-tp/tau2)
factor = 1/factor
tp = (Gtau1*Gtau2)/(Gtau2-Gtau1) * log(Gtau2/Gtau1)
Gfactor = -exp(-tp/Gtau1) + exp(-tp/Gtau2)
Gfactor = 1/Gfactor
}
BREAKPOINT {
SOLVE state METHOD cnexp
g = B - A
i = g * (v - e)
}
DERIVATIVE state {
49
A’ = -A/tau1
B’ = -B/tau2
}
NET_RECEIVE (weight (umho), w, G1, G2, t0 (ms)){
G1 = G1*exp(-(t-t0)/Gtau1)
G2 = G2*exp(-(t-t0)/Gtau2)
G1 = G1 + Ginc * Gfactor
G2 = G2 + Ginc * Gfactor
t0 = t
w = weight * (1 + G2 - G1)
A = A + w*factor
B = B + w*factor
}
: -------------------------------------------------------------------------
. NET RECEIVE block
の引数。引数の数が 1 の場合、NetCon の weight が渡される。引数が n + 1
個の場合、最初の引数は、NetCon の weight であり、残りの引数はこの mod の変数を NetCon で記憶し
ておくために用いられる。これらの引数は、通常の”call by value”ではなく、”call by reference”で渡される
ので、NET RECEIVE block で変更された値は NetCon で保存される。
6.6 NMDA receptor channel
NMDA receptor channel は Mg2+ block により電位依存性と活動依存性を示す。下記の mod ファイルは、
Gasparini et al, J Neurosci 24:11046-11056, 2004 による。state discontinuity() を取除く等の改変を行なっ
ている。
http://senselab.med.yale.edu/modeldb/ShowModel.asp?model=44050
: ------------------------------------------------------------------------NEURON {
POINT_PROCESS nmdanet
RANGE R, g, mg
NONSPECIFIC_CURRENT i
GLOBAL Cdur, Alpha, Beta, Erev, Rinf, Rtau
}
UNITS {
(nA) = (nanoamp)
(mV) = (millivolt)
(umho) = (micromho)
(mM) = (milli/liter)
}
PARAMETER {
50
Cdur
= 1
(ms)
: transmitter duration (rising phase)
Alpha
= 0.35 (/ms)
Beta
= 0.035 (/ms) : backward (unbinding) rate
Erev
= 0 (mV)
: reversal potential
mg
= 1 (mM)
: external magnesium concentration
(mV)
: postsynaptic voltage
: forward (binding) rate
}
ASSIGNED {
v
i
(nA)
: current = g*(v - Erev)
g
(umho)
: conductance
Rinf
Rtau
: steady state channels open
(ms)
: time constant of channel binding
synon
}
STATE {Ron Roff}
INITIAL {
Rinf = Alpha / (Alpha + Beta)
Rtau = 1 / (Alpha + Beta)
synon = 0
}
BREAKPOINT {
SOLVE release METHOD cnexp
g = mgblock(v)*(Ron + Roff)*1(umho)
i = g*(v - Erev)
}
DERIVATIVE release {
Ron’ = (synon*Rinf - Ron)/Rtau
Roff’ = -Beta*Roff
}
FUNCTION mgblock(v(mV)) {
TABLE
DEPEND mg
FROM -140 TO 80 WITH 1000
mgblock = 1 / (1 + exp(0.062 (/mV) * -v) * (mg / 3.57 (mM)))
}
NET_RECEIVE(weight, on, nspike, r0, t0 (ms)) {
if (flag == 0) { : a spike, so turn on if not already in a Cdur pulse
nspike = nspike + 1
51
if (!on) {
r0 = r0*exp(-Beta*(t - t0))
t0 = t
on = 1
synon = synon + weight
Ron =
Ron + r0
Roff = Roff - r0
}
net_send(Cdur, nspike)
}
if (flag == nspike) { : if this associated with last spike then turn off
r0 = weight*Rinf + (r0 - weight*Rinf)*exp(-(t - t0)/Rtau)
t0 = t
synon = synon - weight
Ron = Ron - r0
Roff = Roff + r0
on = 0
}
}
: ------------------------------------------------------------------------n12.hoc を NMDA receptor channel に変更して Voltage-clamp mode で I-V relationship を得ると、Ma2+
block の効果がわかる。
25
25
20
20
15
15
10
10
5
5
0
0
-5
0
10
20
30
40
50
52
-50
0
50
100
7 NEURON の内部
7.1 初期化
finitialize()
7.2 Integration の方法
7.3 Graph
53
付録 A
インストールの仕方
現在 (2012 年 7 月) の最新バージョンは 7.2。
インストールの方法は、http://www.neuron.yale.edu/neuron/install/install.html に記載されている。当
然のことながら OS によって異なる。Unix/Linux で開発されてきたプログラムなので、OS によってうまく
働かない機能があるようだ。
A.1 Windows の場合
Windows 用とは言うものの、Unix/Linux に似た環境を提供する Cygwin のサブセットを用いている。
nrn-n.n.setup.exe をダウンロードする。そのプログラムを起動しインストールを行う(この作業は管理者権限
が必要)
。インストールされた先を環境変数 PATH に加える。(コントロールパネル → システム → 詳細設定
→ 環境変数で、ユーザー環境変数に、例えば、PATH=%PATH%;C:Y
=nrn72 bin と設定する。%PATH% は
システムとして設定された PATH)。
注意すべき点として、cygwin では PATH の中に空白文字があるとトラブルの原因となるので、インストー
ル先は、C:Y
=Program Files の中に nrn70 を置くのではなく、C:Y
=nrn70 とか C:Y
=WIN32APPY
=nrn70 といっ
た所にするのがよい。
cygwin のサブセットがインストールされるので、C 言語のプログラムをコンパイルし走らせる事が出来る。
gcc.exe は含まれているが、g++.exe は含まれていないので、C++ 言語のプログラムの処理は出来ない。
また、cygwin のシステムや MinGW のシステムがインストールされていると、パスの検索で混乱を生じる
事がある。
A.2 Mac OS の場合
Mac OS の場合は、dmg ファイルをダウンロードして解凍し、NEURON-n.n のフォルダを Applications
フォルダにコピーするだけで完了。
PATH を/Applications/NEURON-n.n/nrn/umac/bin に通しておくと便利である。あるいは、$HOME
に bin ディレクトリをつくって PATH を通しておき、そこに nrniv 等の symbolic link を置く方法もある。
ln -s /Applications/NEURON-n.n /nrn/i686/bin/nrniv nrniv
ln -s /Applications/NEURON-n.n /nrn/i686/bin/nrngui nrngui
つ い で な が ら 、MacOS に お け る PATH の 設 定 の 仕 方 を 書 い て お く 。そ の な か で 、1,2,4 は
DYLD LIBRARY PATH の 設 定 に も 使 え る 。い う ま で も な い が 、1,2 は ユ ー ザ ー を 対 象 と し 、3,4 は
コンピュータ全体を対象としている。
1. ∼/.bash profile を使用。最も古典的な方法。コマンドラインからプログラムを起動する時は問題ない
が、アイコンをクリックして起動する場合に PATH を読み込まない、という問題が生ずる。
2. ∼/.MacOSX/environment.plist で設定。コマンドライン、アイコンの両方で OK。
3. /etc/paths
先に現れる方が優先度が高くなります。/etc/paths.d を使う事も可能。
54
4. /etc/launchd.conf で設定。
Mac OS の場合、開発環境がインストールしてあれば、ソースコードから簡単にコンパイルすることが出来
る。Snow Leopard もしくはそれ以前の OS では、開発環境は OS の DVD に含まれているが、デフォールト
ではインストールされていない。Lion では、ダウンロードする必要がある。NEURON のコンパイルの方法
は、上記のウェブサイトに書かれており、その通りすれば出来るはずである。Intel CPU のマシンであれば、–
enable-carbon のオプションは使用しない。トラブルがなければ 20 分程度で完了できる。–enable-carbon の
オプションをつけると umac ディレクトリが作成され、–enable-carbon のオプションをつけないと i686 ディ
レクトリが作成されるようである。
A.3 Linux の場合
インストールの方法は、Mac OS とほぼ同じ。
A.4 計算速度
計算速度に関しては正確に測定したことはないが、CPU のスペックが同じ程度であれば MacOS よりも
Windows の方が速いようである。MacOS の場合は、異なる CPU に使用できるようにしているために遅く
なっているのかと想像される。実際、ソースコードを–enable-carbon のオプションなしでコンパイルすると、
Intel CPU 専用のプログラムが作成され、実行速度は 1.5∼2 倍となった(MacBook Pro の場合)。また Core
2 Duo や Xeon などでは 64-bit で計算を行うようにコンパイルするのがよい(どのように設定する?)。
NEURON のコンパイルには、Windows/MacOS/Linux のいずれでも GNU C/C++ コンパイラを使用し
ている。 Intel コンパイラを使用すれば速度面での改善が予測される。iv(InterViews)なしではコンパイル
可能であるとの報告あり*3 。
付録 B
hoc ファイル用のテキストエディタ
hoc ファイルの作成・編集にはテキストエディタを用いる。notepad(Windows)や TextEdit(Mac OS)
などのテキストエディタでよいが、行番号がわかりやすい方がよく、また定義が色でハイライト(syntax
highlight)されるとさらに便利である。
B.1 Emacs 系テキストエディタ
Windows 用、Mac 用、Linux 用すべてあり
プログラマ好みのエディタである emacs は、様々な機能を有しており、また機能拡張も可能である。高機能
すぎて取っ付きにくい。hoc ファイルの syntax highlight を設定をするには、nrnhoc.el がある*4 。行番号の
表示には linum.el を使用。
*3
*4
http://www.neuron.yale.edu/phpBB/viewtopic.php?=6&t=116
http://homepages.inf.ed.ac.uk/sterratt/progs/neuron
55
B.2 Notepad++
Windows 用プログラム
行番号の表示あり。syntax highlight の機能はあるが、hoc ファイルでは働かない (設定ファイルが用意され
ていないのだろう)。
B.3 Coteditor
MacOS 用プログラム
行番号の表示あり。syntax highlight の機能はあるが、hoc ファイルでは働かない (設定ファイルが用意され
ていないのだろう)。
付録 C
References
• The NEURON Book. Carnevale NT & Hines ML, Cambridge University Press, 2006.
NEURON の開発者による説明書であり、NEURON の説明書としてはもっともまとまった本。ただし
この本だけでは情報が十分でないところもある。
• Programmer’s Reference。命令、関数等の詳細を調べるために便利。少ないながら example もある。
zip ファイルをダウンロードして使用することも可能。
http://www.neuron.yale.edu/neuron/docs/help/contents.html
• The NEURON Forum。NEURON に関する質問サイト。多くの質問に Carnevale 自身が回答してい
る。プログラムのちょっとした工夫等が書かれている。
http://www.neuron.yale.edu/phpBB/
• ModelDB。データ、プログラムのデータベース。大部分が NEURON 用のもの。
http://senselab.med.yale.edu/modeldb/
• Hines ML & Carnevale NT (2004) Discrete event simulation in the NEURON environment. Neurocomputing Volumes 58-60, Pages1117-1122.
56
ダウンロード

A Simplifed Introduction to NEURON Simulator