ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

GENESIS多尺度建模实战:从离子通道到网络仿真

GENESIS多尺度建模实战:从离子通道到网络仿真 做计算神经科学的同行应该都绕不开GENESIS这个名字。这套细胞电生理仿真软件从上世纪80年代末用到现在经历了几个技术时代依然有人在使用原因其实很简单它在多尺度建模上的支撑能力直到今天依然是很多商业软件不太容易替代的。尤其是当你需要把离子通道的分子级行为、一个神经元的房室电生理特性以及几十上百个神经元构成的小网络活动串在同一套模型里跑的时候GENESIS的老练就体现出来了。这篇博客我会直接把多尺度模型从“概念”拉到“能跑起来”的层面用一套完整实操路径说明白为什么GENESIS适合干这件事、多尺度模型的各个尺度怎么拼装、具体脚本怎么写、参数怎么给、结果怎么导出并打印成论文能用的PDF。适合正在做神经元建模又不想被GUI软件限制住的研究生也适合想把手头单细胞模型扩展成网络模型的老手参考。我自己的习惯是用GENESIS做海马锥体细胞的多尺度仿真所以下面的例子会围绕这个场景展开但思路和方法在其他神经元类型上同样可以直接迁移。我不打算讲教科书上的仿真理论只讲实际操作中一定要知道的东西以及我踩过的那些坑。1. 先搞清楚GENESIS在这个项目里承担什么1.1 为什么选GENESIS而不是直接写微分方程很多人第一次听到“多尺度模型”第一反应是“这不就是解方程组嘛”于是想直接用Python、MATLAB自己写一套数值积分器。这个思路在小规模场景下完全可行比如只模拟一个几十房室的神经元手写代码甚至更灵活。但一旦进入多尺度麻烦就来了你的模型里不只有膜电位的时间演化还有几十种离子通道的门控变量、突触前囊泡释放概率、树突棘内的钙浓度变化、甚至某些生化信号通路的级联反应。这些过程的时间常数从几十微秒到几秒不等空间上又分布在不同的房室和亚细胞结构里如果全部自己用通用语言实现代码量会迅速膨胀而且非常容易出错。GENESIS的核心优势在于它把“房室compartment”、“通道channel”、“突触synapse”、“扩散diffusion”、“化学反应ksim”这些电生理建模的基本单元做成了内建对象你只需要用脚本语言把这些对象连接起来就可以表达复杂的多尺度模型。它不需要你重新发明轮子也不需要你去处理底层的数值积分算法细节——当然前提是你知道该改哪个参数。还有一个很实际的原因GENESIS的脚本本身带有一套事件驱动机制可以在同一套仿真流程里同时处理化学信号与电信号。这一点对于做钙信号与电活动耦合的人来说特别重要因为钙离子浓度不是一个简单的被动跟随量它会反过来调制钾通道、NMDA受体等电生理元件的状态形成真正的闭环反馈。1.2 多尺度模型要“多”到什么程度在GENESIS的语境里多尺度通常意味着三件事空间尺度、时间尺度和层级结构。空间尺度上模型可以包含从纳米级的离子通道蛋白构象到微米级的树突棘和胞体再到毫米级的神经元网络。GENESIS的房室模型天然支持这种空间嵌套一个胞体房室可以包含多个通道对象一个树突可以由几十个链接起来的房室构成一个网络又可以包含几十上百个这样完整的神经元。时间尺度上离子通道的门控动力学时间常数通常在毫秒量级钙扩散和生化反应则在几十毫秒到秒量级而突触可塑性相关的分子级联甚至可能持续数分钟。GENESIS允许不同机制使用不同的数值求解步长并且能在同一仿真时刻把不同尺度的状态同步起来这是自建代码最难处理的部分之一。层级结构上多尺度模型强调的是“自底向上的涌现”。你不只是把几个方程拼在一起而是希望从离子通道的行为中涌现出单神经元的放电模式再从多个神经元的放电模式中涌现出网络振荡。GENESIS的Object-Oriented结构非常适合表达这种层级关系——它本来就是一个以对象为节点的树状结构。注意多尺度建模的难度并不在于“把两个方程组放在一个程序里”而在于不同尺度之间耦合关系的建模以及数值稳定性控制。你把尺度堆得越多对时间步长和数值格式的选择就越挑剔。这点后面会专门展开。2. 模型设计思路把不同尺度“缝”起来2.1 从分子到细胞离子通道与膜方程多尺度模型的底层永远是细胞膜的离子电流平衡方程。这个方程在GENESIS里的表达不是写在代码里的一个抽象公式而是通过房室对象和通道对象之间的连接来实现的。一个标准的房室对象拥有膜电容Cm、膜电阻Rm和静息电位Em等属性。通道对象比如钠通道、钾通道、泄漏通道通过消息机制连接到房室上并把自己的电导和反转电位贡献给膜方程。GENESIS会自动在每一步积分时调用这些通道的速率函数更新门控变量再把这个电流反馈给膜电位。举一个最经典的海马CA1锥体细胞模型片段create compartment /cell/soma setfield /cell/soma Cm 1e-8 Rm 100e6 Ra 1.0 Em -0.06 create hh_na_channel /cell/soma/Na setfield /cell/soma/Na gmax 0.35 Ena 0.05 create hh_k_channel /cell/soma/K setfield /cell/soma/K gmax 0.09 Ek -0.08 // 把房室电压传给通道 addmsg /cell/soma /cell/soma/Na VOLTAGE Vm addmsg /cell/soma /cell/soma/K VOLTAGE Vm // 把通道电流传回房室 addmsg /cell/soma/Na /cell/soma CHANNEL Gk Ek addmsg /cell/soma/K /cell/soma CHANNEL Gk Ek这一段代码里最值得注意的是单位。GENESIS内部统一使用SI单位制电压的单位是伏特V电导单位是西门子S电容单位是法拉F时间单位是秒。也就是说你在脚本里写-0.06代表的是-60mV。很多新手第一次跑出来的模型完全不放电排查半天发现是把-60mV写成了-60模型里的静息电位直接变成-60V那当然什么都跑不对。这个从分子到细胞的层面核心要解决的是“通道怎么让细胞放电”的问题。你给的gmax、Ena、Ek、门控动力学参数决定了动作电位的幅度、时程和不应期。如果你要做更精细的通道亚型比如T型钙通道、HCN通道、SK钾通道GENESIS允许你自定义通道的速率方程用tabchannel或者更底层的hh_channel对象进行描述。2.2 从细胞到网络突触连接与群体活动把单个神经元跑出动作电位只是第一步。多尺度模型的第二个关键是网络层面神经元之间的突触连接怎样产生群体行为。GENESIS的突触模型通常包含AMPA、NMDA、GABA_A和GABA_B这几类常见的受体动力学。突触对象本身接收来自前神经元动作电位的事件再按照受体类型的时间常数产生突触电流注射到后神经元的某个房室上。以AMPA突触为例一个最简单的配置是这样的create synchan /cell/dend/AMPA setfield /cell/dend/AMPA tau1 0.005 tau2 0.0025 gmax 0.5e-9 Ek 0.0 // 把突触通道插入树突房室并接收来自上游神经元的事件 addmsg /cell/dend /cell/dend/AMPA CHANNEL Gk Ek addmsg /pre/cell/axon /cell/dend/AMPA SPIKE这里tau1和tau2是突触电流的上升和衰减时间常数单位同样是秒。AMPA的反转电位接近0V所以在偏正电位下产生兴奋性突触后电位EPSP。NMDA受体的配置会复杂一些因为它还带有电压依赖的镁离子阻断效应需要一条额外的消息把后膜电位传给突触对象GENESIS提供了类似addmsg /cell/dend /cell/dend/NMDA VOLTAGE Vm这样的接口来处理。当几个神经元用这样的突触互相连起来仿真就开始走向“网络层”了。你可以定义一个包含几十个细胞的网络给每个细胞不同的参数扰动加入刺激模式然后观察整个群体是否出现同步振荡、gamma节律或者theta节律。GENESIS的网络脚本跑起来之后你会真正感觉到“涌现”是什么意思单个细胞可能只是普通的放电但连成网络之后整个群体的放电频率、相位关系完全不是单细胞层面可以预测的。2.3 让模型动起来的数值细节时间步长怎么取多尺度模型最容易翻车的地方就是时间步长。电生理的快速动力学比如钠通道的激活要求仿真步长dt足够小一般取0.1毫秒即1e-4秒甚至更小但你要同时模拟一个钙扩散过程它的时间常数是几百毫秒如果也强行用1e-4秒的步长去积分仿真会慢得让人崩溃。GENESIS里处理这个问题的方式是使用多时间尺度积分机制。你可以通过setstep命令为不同的对象设置不同的步长然后再统一推进整个仿真。一个常见的配置是把电生理对象放在快变量组fast组把生化反应对象放在慢变量组slow组setstep /cell 1e-5 setstep /cell/ca_conc 1e-3 reset step 1.0注意慢变量组的步长必须能被快变量组的步长整除或者说仿真调度器按最小公倍数同步否则异步行进会产生时间上的错位误差。实际处理时我一般把电生理步长设为0.02毫秒钙和生化反应步长设为0.5毫秒仿真推进1秒大约需要几百到几千步速度完全可以接受。经验之谈不要为了追求数值稳定而无脑缩小一切步长。步长太小仿真时间成倍增加而且很多通道的门控变量在高精度下并不显著改善结果步长太大则可能出现振荡式的不稳定。我通常把步长设为最快门控时间常数的五分之一到十分之一然后在正式批量跑之前做一次收敛性验证。3. 实操过程以海马CA1锥体细胞多尺度模型为例3.1 搭建细胞模型骨架我们直接进入干活环节。下面这套流程是在我自己的项目里反复使用的你可以把它当成一个基础模板。首先建立细胞的基本形态。为了展示多尺度的连接方式我不会做一个只有一个房室的简化胞体而是建立一个包含胞体、近端树突、远端树突和轴突的简化房室结构create neutral /cell create compartment /cell/soma create compartment /cell/dend create compartment /cell/axon // 形态与电学参数 setfield /cell/soma Cm 1e-8 Rm 100e6 Ra 1.0 Em -0.06 setfield /cell/dend Cm 1e-8 Rm 100e6 Ra 2.0 Em -0.06 setfield /cell/axon Cm 1e-8 Rm 200e6 Ra 1.0 Em -0.06 // 房室之间通过轴向电阻连接 addmsg /cell/soma /cell/dend RAXIAL Ra addmsg /cell/soma /cell/axon RAXIAL Ra这里RAXIAL类型的连接用于模拟相邻房室之间沿轴向的电流传播。房室树越细Ra越大信号衰减越明显这是CA1锥体细胞树突计算特性的基础。接着为胞体和树突加入离子通道。为了让模型有趣一点我会在胞体上放传统的钠、钾通道在树突上放一个钙通道和一个钙激活钾通道SK-like通道这样钙信号就能直接调节电活动形成闭环。create hh_na_channel /cell/soma/Na setfield /cell/soma/Na gmax 0.4 Ena 0.05 create hh_k_channel /cell/soma/K setfield /cell/soma/K gmax 0.12 Ek -0.08 create calcium_channel /cell/dend/Ca setfield /cell/dend/Ca gmax 0.05 Eca 0.12 addmsg /cell/soma /cell/soma/Na VOLTAGE Vm addmsg /cell/soma /cell/soma/K VOLTAGE Vm addmsg /cell/dend /cell/dend/Ca VOLTAGE Vm addmsg /cell/soma/Na /cell/soma CHANNEL Gk Ek addmsg /cell/soma/K /cell/soma CHANNEL Gk Ek addmsg /cell/dend/Ca /cell/dend CHANNEL Gk Ek钙通道开通之后钙离子会流入细胞内。这部分钙不能凭空消失需要有一个钙浓度对象去追踪它这正是连接电生理和生化信号的关键桥梁。3.2 加入多尺度耦合钙信号与生化反应在GENESIS中处理钙扩散和浓度变化一般用CaConc对象或者更复杂的calsim。这里用CaConc来模拟树突棘内钙浓度的动态变化create ca_conc /cell/dend/Ca_conc setfield /cell/dend/Ca_conc B 4.0e-3 tau 0.080CaConc对象接收来自钙通道的钙电流把它转化为胞内游离钙浓度的变化。这个浓度反过来会影响钙激活钾通道的开放概率所以还要建一个钙激活钾通道并把钙浓度传给它create SKChannel /cell/dend/SK setfield /cell/dend/SK gmax 0.01 Ek -0.085 addmsg /cell/dend/Ca_conc /cell/dend/SK CONC Ca addmsg /cell/dend/SK /cell/dend CHANNEL Gk Ek到这里模型已经出现了两个尺度之间的双向耦合膜电位决定了钙通道的开放钙通道流入的钙离子改变了胞内钙浓度钙浓度又通过SK通道改变膜电位。这个负反馈环路在生物学上的意义是后超极化AHP和放电频率适应——一个非常经典的多尺度电生理-化学耦合现象。再往里走一步可以接一个更复杂的生化信号通路。GENESIS里做生化反应通常借助ksim机制它可以表达一组反应方程比如某个激酶被钙离子激活后磷酸化钾通道从而改变其电导。ksim的配置方式和精神与CaConc类似本质上是把一组常微分方程挂到仿真调度器上并在每步与电生理系统交换变量。create ksim /cell/dend/cascade setfield /cell/dend/cascade reactions 4 ... // 定义具体反应速率常数 addmsg /cell/dend/Ca_conc /cell/dend/cascade CONC Ca addmsg /cell/dend/cascade /cell/dend/SK MODULATE factor需要注意的是生化级联反应的时间常数往往很长这时必须把ksim放在慢变量组。使用setstep /cell/dend/cascade 1e-3单独设置它的积分步长避免拖慢整个仿真。3.3 扩展成小网络并跑完仿真有了单细胞模型扩展成网络是比较机械的工作。我习惯用脚本循环来创建多个细胞并给每个细胞加一点膜电阻的随机扰动模拟生物个体差异int i for (i 0; i 40; i i 1) copy /cell /net/neuron[i] setfield /net/neuron[i]/soma Rm {100e6 (rand 50e6)} end然后定义突触连接。下面这段把每个细胞的下标偏移一个位置连接到另一个细胞形成一个简单的环形网络。这种拓扑虽然简单但可以跑出很有意义的同步现象create synchan /net/syn[i] ... addmsg /net/neuron[i]/axon /net/syn[i] SPIKE addmsg /net/syn[i] /net/neuron[(i1) % 40]/dend CHANNEL Gk Ek仿真流程最后是这样收尾的reset setstep /net 2e-5 setstep /net/neuron[i]/dend/Ca_conc 1e-3 setstep /net/neuron[i]/dend/cascade 1e-3 // 给一小部分细胞一个初始脉冲刺激 step 0.02 setfield /net/neuron[0]/soma inject 1e-9 step 0.5 setfield /net/neuron[0]/soma inject 0 step 0.5当你跑完这段脚本然后用绘图工具查看胞体膜电位轨迹时应该能看到一个比较完整的放电和适应现象同时钙浓度曲线会呈现缓慢的累积与回落。如果钙激活钾通道的权重设置合理放电间隔会从密集逐渐变稀疏这就是典型的频率适应。4. 结果导出与打印PDF命令行出图工作流4.1 数据落盘把仿真结果写出来GENESIS本身不是绘图工具它的强项是仿真引擎。所以我从来不会指望在GENESIS界面里直接得到一张论文级的图。常规操作是把仿真数据用print命令导出为文本文件再用GNUPLOT或者Python matplotlib进行后处理出图。导出膜电位时间序列的写法如下create fileout /out/vm setfield /out/vm filename vm_all_cells.txt addmsg /net/neuron[0]/soma /out/vm SAVE Vm setfield /out/vm interval 1e-4 ... reset step 1.0这里interval字段控制采样间隔。你会得到一个文本文件每一行是一个时间点的膜电位数值也可以把多个变量导出到同一文件用空格或Tab分隔。需要注意fileout对象必须在仿真开始之前完成消息连接否则你可能跑了半天回来看文件是空的别问我怎么知道的。4.2 用gnuplot把曲线打印成PDF拿到文本数据之后生成PDF是很快的事情。GNUPLOT本身支持在命令行直接输出PDF这也是我目前最常用的论文底图工作流。下面这个命令直接把仿真数据打印成PDFset terminal pdfcairo enhanced color size 10cm,6cm linewidth 2 set output vm_trace.pdf set xlabel Time (s) set ylabel Membrane potential (V) set xrange [0:1] plot vm_all_cells.txt using 1:2 with lines title soma Vm关键在于pdfcairo这个终端类型它生成的PDF是矢量图放到论文里放大也不会糊。如果GNUPLOT版本比较老没有pdfcairo也可以退一步用set terminal pdf但渲染效果和中文支持会差一些所以我倾向于直接把字体和标签全部用英文避免字体兼容性的干扰。如果你觉得GNUPLOT的控制粒度不够当然可以用Python读入文本文件再出图。但我个人在跑大批量参数扫描时还是喜欢GNUPLOT因为它脚本化程度高、启动快改个参数重新出图非常顺手。4.3 出图参数与论文级排版建议出PDF的时候有几个容易忽略的细节我一次性给你列清楚。第一坐标轴单位。因为GENESIS内部是SI单位导出的电压是伏特时间单位是秒。出图时我通常会做一次换算把纵轴乘以1000变成毫伏横轴乘以1000变成毫秒这样图和正文里的单位一致审稿人看着舒服。这个换算既可以在GNUPLOT的using语句里直接做也可以用awk先处理文本文件。第二多变量对照。把膜电位、钙浓度、突触电流放在同一个PDF里最好用multiplot或者分别输出多个PDF再拼图。我一般会把每个变量存成一个单独的文件然后在GNUPLOT里用multiplot控制三个子图共享时间轴这样趋势对照非常直观而且后续替换数据重新出图只需要重新执行一遍gp脚本。第三关于“打印PDF命令”这个需求还要提醒一点不要指望GENESIS的print命令直接生成PDF。GENESIS的print是输出文本数据用的和打印成PDF文件是两码事。如果你在脚本里写print /out/vm它只会把数据打到终端或文本文件上。真正的PDF生成一定是在后处理环节用专门的图形工具来完成的。这套文本导出后处理出图的流程看上去比GUI点几下麻烦但实际上高度可重复对做参数扫描的人尤其友好。5. 常见问题与排查技巧5.1 单位问题为什么膜电位看起来非常不对劲这是我见过最多的问题没有之一。GENESIS整个系统强制使用SI单位所以-60mV必须写成-0.061纳法写成1e-9电导0.1西门子写成0.1而不是100毫西门子。一个典型的错误是把在其他软件里照抄的参数比如用mV、mS、nF直接填进GENESIS脚本结果模型不是静息电位偏移就是根本不放电。排查方法也很简单跑完一小段仿真后把膜电位数值打印出来检查静息电位是否和你设置的Em一致。如果差了几个数量级基本可以判定是单位换算错误。此外还要注意时间常数tau的单位是秒而不是毫秒。synchan里的tau1 0.005代表5毫秒不是5微秒别弄反了。5.2 数值不稳定和运行太慢数值不稳定的典型表现是膜电位在几个时间步内跳出合理范围要么爆到1e30要么瞬间变成负无穷。这时候第一优先检查步长是不是太大了。如果你的钠通道门控时间常数在0.1毫秒量级而dt设在1毫秒那模型不炸才怪。把步长缩小到0.02毫秒再跑基本能解决。但缩小步长会带来另一个问题运行太慢。特别是当网络规模达到几十个神经元、每个神经元又有多个树突房室和通道时仿真速度会直线下降。这时你可以用setstep把生化反应和钙浓度这些慢过程分开。另外开启编译模式compiled mode比解释执行模式快很多GENESIS有这个选项启动脚本时记得用编译模式跑性能差距通常在5倍以上。5.3 模型标定问题书是给参数了你的细胞就是不放电很多初学者拿着文献里的参数建模型跑出来却发现细胞非常“沉默”怎么刺激都不放电。原因往往是文献给的参数是某一特定条件下测量得到的直接套用不等于这个模型在你这套环境下就能工作。最简单的调参思路是先验证静息电位是否正确把所有电流关掉看Em再逐步打开泄漏通道、钾通道、钠通道每开一个通道就跑一遍观察膜电位行为是否符合预期。不要一上来就全塞进去出了问题根本不知道是哪个环节的原因。另外注入电流的幅度也是经常被忽视的因素。CA1锥体细胞的输入阻抗可能在100MΩ上下你注入一个1pA的电流膜电位变化只有0.1mV当然不放电。我一般先用setfield inject 1e-9作为初始试探值再上下调整电流幅度找到阈值附近的行为这样模型敏感性一目了然。还有一个窝心的细节synchan的gmax单位是西门子通常电导都在nS量级也就是1e-9。如果你按pS量级漏了小数位突触传递会弱到几乎看不见。写脚本之前先把每个参数的物理量纲写到注释里养成习惯能省不少排查时间。5.4 调试技巧善用trace和单步执行GENESIS提供了trace和step相关的调试命令。当模型行为异常时我会先跑一小段比如step 0.001然后用print把关键变量的当前值输出逐段检查问题出现的时间点。这个方法虽然原始但极其有效。尤其多尺度模型里因为不同尺度的变量更新顺序不同用单步执行可以看到每一步里电信号和化学信号是怎么交互的这比单纯看最终曲线更能定位问题。另外如果你在脚本里用了大量循环来创建网络我建议在for循环里加几个echo打印当前创建的细胞编号确认连接关系没有错位。网络模型里最隐蔽的错误往往是消息连接连错了对象比如把突触连到了胞体而不是树突或者把两个细胞的轴突连成了电突触。这类错误很难从最终群体放电图上直接看出来但单步调试的时候非常明显。最后再分享一个我个人的习惯每次开始一个新模型项目我会单独写一个最简单的“最小可用模型”脚本里面只有一个房室、一个钠通道、一个钾通道跑通之后再把形态、多尺度耦合、网络连接一层层加进去。这样一旦某一步出问题你永远知道是刚加进去的哪部分引起的。多尺度模型本身复杂度已经够高了不要再用“一次写完再调”的方式来给自己增加难度。这个习惯帮我省下的时间比我写过的任何脚本都要多。
返回列表