{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 跨频率耦合图解" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 引言\n", "先来通过一个交互式例子感受一下跨频率耦合,建立起一些直观的感受.\n", "\n", "```{note}\n", "点击下面的`Activate`,再点击`run`来启动交互\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "from ipywidgets import interactive\n", "import matplotlib.pyplot as plt\n", "from matplotlib.widgets import TextBox\n", "import numpy as np\n", "plt.rcParams['figure.figsize'] = (10.0, 10.0)\n", "def set_center_axis(ax):\n", " ax.spines['right'].set_color('none')\n", " ax.spines['top'].set_color('none')\n", " ax.spines['bottom'].set_position(('data', 0))\n", " ax.spines['left'].set_position(('data', 0))\n", "seconds = 1\n", "sample_rate =500\n", "def cfc_data(slow_ph=0,slow_ap=1,fast_ph=0,fast_ap=1):\n", " t = np.linspace(0, seconds, seconds*sample_rate)\n", " slow = np.sin(2*np.pi*5*t+slow_ph)*slow_ap\n", " fast = np.cos(2*np.pi*37*t+fast_ph)*fast_ap\n", " fast_am = 0.5*slow + 0.5\n", " x = slow + fast * fast_am + np.random.randn(*t.shape) * .05\n", " return slow,fast,fast_am,x,t\n", "def cfc_draw(slow_ph,slow_ap,fast_ph,fast_ap):\n", " slow,fast,fast_am,x,t=cfc_data(slow_ph,slow_ap,fast_ph,fast_ap)\n", " fig,(ax1,ax2,ax3,ax4)=plt.subplots(4,1)\n", " ax1.plot(t[:sample_rate], slow[:sample_rate])\n", " textstr = '\\n'.join((r'$slow=%.2f sin(2\\cdot5\\pi t+%.2f\\pi)$' % (slow_ap,slow_ph/np.pi ),))\n", " ax1.text(0.05,0.5,textstr,fontsize = 25)\n", " ax2.plot(t[:sample_rate], fast[:sample_rate])\n", " textstr = '\\n'.join((r'$fast=%.2f cos(2\\cdot37\\pi t+%.2f\\pi)$' % (fast_ap,fast_ph/np.pi ),))\n", " ax2.text(0.05,0.5,textstr,fontsize = 25)\n", " ax3.plot(t[:sample_rate], fast_am[:sample_rate])\n", " ax3.text(0.05,0.5,'$fast\\_am = 0.5\\cdot slow + 0.5$',fontsize = 25)\n", " ax4.plot(t[:sample_rate], x[:sample_rate])\n", " ax4.text(0.05,0.5,'$x=slow+fast\\cdot fast\\_am + 0.05random$',fontsize = 25)\n", " for ax in (ax1,ax2,ax3,ax4):\n", " set_center_axis(ax)\n", " \n", "def F(slow_ph,slow_ap,fast_ph,fast_ap):\n", " cfc_draw(slow_ph,slow_ap,fast_ph,fast_ap)\n", "interactive_plot = interactive(F,slow_ph=(0,2*np.pi,0.1*np.pi),slow_ap=(0,2,0.1),fast_ph=(0, 2*np.pi, 0.05*np.pi),fast_ap=(0,2,0.1))\n", "interactive_plot\n", "\n", "\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "# This cell has a remove-cell tag\n", "%matplotlib inline\n", "from ipywidgets import interactive\n", "import matplotlib.pyplot as plt\n", "from matplotlib.widgets import TextBox\n", "import numpy as np\n", "plt.rcParams['figure.figsize'] = (10.0, 10.0)\n", "def set_center_axis(ax):\n", " ax.spines['right'].set_color('none')\n", " ax.spines['top'].set_color('none')\n", " ax.spines['bottom'].set_position(('data', 0))\n", " ax.spines['left'].set_position(('data', 0))\n", "seconds = 60\n", "sample_rate =500\n", "def cfc_data(slow_ph=0,slow_ap=1,fast_ph=0,fast_ap=1):\n", " t = np.linspace(0, seconds, seconds*sample_rate)\n", " slow = np.sin(2*np.pi*5*t+slow_ph)*slow_ap\n", " fast = np.cos(2*np.pi*37*t+fast_ph)*fast_ap\n", " fast_am = 0.5*slow + 0.5\n", " x = slow + fast * fast_am + np.random.randn(*t.shape) * .05\n", " return slow,fast,fast_am,x,t\n", "def cfc_draw(slow_ph,slow_ap,fast_ph,fast_ap):\n", " slow,fast,fast_am,x,t=cfc_data(slow_ph,slow_ap,fast_ph,fast_ap)\n", " fig,(ax1,ax2,ax3,ax4)=plt.subplots(4,1)\n", " ax1.plot(t[:seconds*4], slow[:seconds*4])\n", " textstr = '\\n'.join((r'$slow=%.2f sin(2\\cdot5\\pi t+%.2f\\pi)$' % (slow_ap,slow_ph/np.pi ),))\n", " ax1.text(0.05,0.5,textstr,fontsize = 25)\n", " ax2.plot(t[:seconds*4], fast[:seconds*4])\n", " textstr = '\\n'.join((r'$fast=%.2f cos(2\\cdot37\\pi t+%.2f\\pi)$' % (fast_ap,fast_ph/np.pi ),))\n", " ax2.text(0.05,0.5,textstr,fontsize = 25)\n", " ax3.plot(t[:seconds*4], fast_am[:seconds*4])\n", " ax3.text(0.05,0.5,'$fast\\_am = 0.5\\cdot slow + 0.5$',fontsize = 25)\n", " ax4.plot(t[:seconds*4], x[:seconds*4])\n", " ax4.text(0.05,0.5,'$x=slow+fast\\cdot fast\\_am + 0.05random$',fontsize = 25)\n", " for ax in (ax1,ax2,ax3,ax4):\n", " set_center_axis(ax)" ] }, { "cell_type": "markdown", "metadata": { "tags": [ "remove-cell" ] }, "source": [ "下图中,slow是一个低频正弦信号,fast是一个高频余弦信号.您可以拖动下面的四个滑块来改变这两个信号的幅值和相位.x是上述两个信号的混合,试着拖动滑块,看一下对信号x会产生什么影响." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0723f6bcfbf24617a36b572cf248f4ac", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(FloatSlider(value=3.141592653589793, description='slow_ph', max=6.283185307179586, step=…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# This cell has a hide-cell tag\n", "def F(slow_ph,slow_ap,fast_ph,fast_ap):\n", " cfc_draw(slow_ph,slow_ap,fast_ph,fast_ap)\n", "interactive_plot = interactive(F,slow_ph=(0,2*np.pi,0.1*np.pi),slow_ap=(0,2,0.1),fast_ph=(0, 2*np.pi, 0.05*np.pi),fast_ap=(0,2,0.1))\n", "output = interactive_plot.children[-1]\n", "output.layout.height = '600px'\n", "interactive_plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "跨频率耦合一共有三种形式:\n", "1. 相-相耦合(phase-phase coupling,PPC);\n", "2. 相-幅耦合(phase-amplitude coupling,PAC);\n", "3. 幅-幅耦合(amplitude-amplitude coupling,AAC).\n", "\n", "上面的交互式例子展示的是低频相位调制高频幅度,属于相-幅耦合." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 如何对跨频率耦合现象进行分析和量化?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "目前研究得比较多的是相-幅耦合,其耦合程度可以用同步化指标$PAC$来计算:\n", "\n", "$$\n", "P A C=\\left|n^{-1} \\sum_{t=1}^{n} a_{t} e^{i \\phi_{t}}\\right|\n", "$$\n", "\n", "其中$n$表示时间点的总数,$t$表示时间点,$a_t$表示高频信号在$t$时刻的功率,$\\phi_t$表示低频信号在$t$时刻的相位,$i$为复数单位.\n", "\n", "那么,跨频率耦合分析可以分三步走:\n", "1. 将信号分为高频段和低频段;\n", "2. 从滤波后的信号中提取振幅和相位;\n", "3. 确定相位和振幅是否相关(计算PAC).\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 步骤一:将信号分为高频段和低频段" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "以上文交互式模组中的数据为例,进行分析." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[