Skip to content

Commit 71d599e

Browse files
author
alphacsc GitHub Action
committed
Update documentation
1 parent 139c849 commit 71d599e

File tree

342 files changed

+74675
-15873
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

342 files changed

+74675
-15873
lines changed
File renamed without changes.
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {
7+
"collapsed": false
8+
},
9+
"outputs": [],
10+
"source": [
11+
"%matplotlib inline"
12+
]
13+
},
14+
{
15+
"cell_type": "markdown",
16+
"metadata": {},
17+
"source": [
18+
"\n# Extracting cross-frequency coupling waveforms from rodent LFP data\n\nThis example illustrates how to learn univariate atoms on a univariate\ntime-serie. The data is a single LFP channel recorded on a rodent's striatum\n[1]_. Interestingly in this time-serie, the high frequency oscillations around\n80 Hz are modulated in amplitude by the low-frequency oscillation around 3 Hz,\na phenomenon known as cross-frequency coupling (CFC).\n\nThe convolutional sparse coding (CSC) model is able to learn the prototypical\nwaveforms of the signal, on which we can clearly see the CFC.\n\n.. [1] G. Dall\u00e9rac, M. Graupner, J. Knippenberg, R. C. R. Martinez,\n T. F. Tavares, L. Tallot, N. El Massioui, A. Verschueren, S. H\u00f6hn,\n J.B. Bertolus, et al. Updating temporal expectancy of an aversive event\n engages striatal plasticity under amygdala control.\n Nature Communications, 8:13920, 2017\n"
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"metadata": {
25+
"collapsed": false
26+
},
27+
"outputs": [],
28+
"source": [
29+
"# Authors: Tom Dupre La Tour <tom.duprelatour@telecom-paristech.fr>\n# Mainak Jas <mainak.jas@telecom-paristech.fr>\n# Umut Simsekli <umut.simsekli@telecom-paristech.fr>\n# Alexandre Gramfort <alexandre.gramfort@telecom-paristech.fr>\n#\n# License: BSD (3-clause)"
30+
]
31+
},
32+
{
33+
"cell_type": "markdown",
34+
"metadata": {},
35+
"source": [
36+
"Let us first load the data sample.\n\n"
37+
]
38+
},
39+
{
40+
"cell_type": "code",
41+
"execution_count": null,
42+
"metadata": {
43+
"collapsed": false
44+
},
45+
"outputs": [],
46+
"source": [
47+
"import mne\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# sample frequency\nsfreq = 350.\n\n# We load the signal. It is an LFP channel recorded on a rodent's striatum.\ndata = np.load('../rodent_striatum.npy')\nprint(data.shape)"
48+
]
49+
},
50+
{
51+
"cell_type": "markdown",
52+
"metadata": {},
53+
"source": [
54+
"As the data contains severe artifacts between t=0 and t=100, we use a\nsection not affected by artifacts.\n\n"
55+
]
56+
},
57+
{
58+
"cell_type": "code",
59+
"execution_count": null,
60+
"metadata": {
61+
"collapsed": false
62+
},
63+
"outputs": [],
64+
"source": [
65+
"data = data[:, 35000:]\n\n# We also remove the slow drift, which accounts for a lot of variance.\ndata = mne.filter.filter_data(data, sfreq, 1, None)\n\n# To make the most of parallel computing, we split the data into trials.\ndata = data.reshape(50, -1)\ndata /= data.std()"
66+
]
67+
},
68+
{
69+
"cell_type": "markdown",
70+
"metadata": {},
71+
"source": [
72+
"This sample contains CFC between 3 Hz and 80 Hz. This phenomenon can be\ndescribed with a comodulogram, computed for instance with the `pactools\n<http://pactools.github.io/>`_ Python library.\n\n"
73+
]
74+
},
75+
{
76+
"cell_type": "code",
77+
"execution_count": null,
78+
"metadata": {
79+
"collapsed": false
80+
},
81+
"outputs": [],
82+
"source": [
83+
"from pactools import Comodulogram\n\ncomod = Comodulogram(fs=sfreq, low_fq_range=np.arange(0.2, 10.2, 0.2),\n low_fq_width=2., method='duprelatour')\ncomod.fit(data)\ncomod.plot()\nplt.show()"
84+
]
85+
},
86+
{
87+
"cell_type": "markdown",
88+
"metadata": {},
89+
"source": [
90+
"We fit a CSC model on the data.\n\n"
91+
]
92+
},
93+
{
94+
"cell_type": "code",
95+
"execution_count": null,
96+
"metadata": {
97+
"collapsed": false
98+
},
99+
"outputs": [],
100+
"source": [
101+
"from alphacsc import learn_d_z\n\nparams = dict(\n n_atoms=3,\n n_times_atom=int(sfreq * 1.0), # 1000. ms\n reg=5.,\n n_iter=10,\n solver_z='l-bfgs',\n solver_z_kwargs=dict(factr=1e9),\n solver_d_kwargs=dict(factr=1e2),\n random_state=42,\n n_jobs=5,\n verbose=1)\n\n_, _, d_hat, z_hat, _ = learn_d_z(data, **params)"
102+
]
103+
},
104+
{
105+
"cell_type": "markdown",
106+
"metadata": {},
107+
"source": [
108+
"Plot the temporal patterns. Interestingly, we obtain prototypical\nwaveforms of the signal on which we can clearly see the CFC.\n\n"
109+
]
110+
},
111+
{
112+
"cell_type": "code",
113+
"execution_count": null,
114+
"metadata": {
115+
"collapsed": false
116+
},
117+
"outputs": [],
118+
"source": [
119+
"n_atoms, n_times_atom = d_hat.shape\nn_columns = min(6, n_atoms)\nn_rows = int(np.ceil(n_atoms // n_columns))\nfigsize = (4 * n_columns, 3 * n_rows)\nfig, axes = plt.subplots(n_rows, n_columns, figsize=figsize, sharey=True)\naxes = axes.ravel()\n\nfor kk in range(n_atoms):\n ax = axes[kk]\n time = np.arange(n_times_atom) / sfreq\n ax.plot(time, d_hat[kk], color='C%d' % kk)\n ax.set_xlim(0, n_times_atom / sfreq)\n ax.set(xlabel='Time (sec)', title=\"Temporal pattern %d\" % kk)\n ax.grid(True)\n\nfig.tight_layout()\nplt.show()"
120+
]
121+
}
122+
],
123+
"metadata": {
124+
"kernelspec": {
125+
"display_name": "Python 3",
126+
"language": "python",
127+
"name": "python3"
128+
},
129+
"language_info": {
130+
"codemirror_mode": {
131+
"name": "ipython",
132+
"version": 3
133+
},
134+
"file_extension": ".py",
135+
"mimetype": "text/x-python",
136+
"name": "python",
137+
"nbconvert_exporter": "python",
138+
"pygments_lexer": "ipython3",
139+
"version": "3.9.1"
140+
}
141+
},
142+
"nbformat": 4,
143+
"nbformat_minor": 0
144+
}
Binary file not shown.
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {
7+
"collapsed": false
8+
},
9+
"outputs": [],
10+
"source": [
11+
"%matplotlib inline"
12+
]
13+
},
14+
{
15+
"cell_type": "markdown",
16+
"metadata": {},
17+
"source": [
18+
"\n# Alpha CSC on empirical time-series with strong artifacts\n\nThis example illustrates how to learn univariate atoms on a univariate\ntime-serie affected by strong artifacts. The data is a single LFP channel\nrecorded on a rodent's striatum [1]_. Interestingly in this time-serie, the\nhigh frequency oscillations around 80 Hz are modulated in amplitude by the\nlow-frequency oscillation around 3 Hz, a phenomenon known as cross-frequency\ncoupling (CFC).\n\nThe convolutional sparse coding (CSC) model is able to learn the prototypical\nwaveforms of the signal, on which we can clearly see the CFC. However, when the\nCSC model is fitted on a data section with strong artifacts, the learned atoms\ndo not show the expected CFC waveforms. To solve this problem, another model\ncan be used, called alpha-CSC [2]_, which is less affected by strong artifacts\nin the data.\n\n.. [1] G. Dall\u00e9rac, M. Graupner, J. Knippenberg, R. C. R. Martinez,\n T. F. Tavares, L. Tallot, N. El Massioui, A. Verschueren, S. H\u00f6hn,\n J.B. Bertolus, et al. Updating temporal expectancy of an aversive event\n engages striatal plasticity under amygdala control.\n Nature Communications, 8:13920, 2017\n\n.. [2] Jas, M., Dupr\u00e9 La Tour, T., \u015eim\u015fekli, U., & Gramfort, A. (2017).\n `Learning the Morphology of Brain Signals Using Alpha-Stable Convolutional\n Sparse Coding\n <https://papers.nips.cc/paper/6710-learning-the-morphology-of-brain-signals-using-alpha-stable-convolutional-sparse-coding.pdf>`_.\n Advances in Neural Information Processing Systems (NIPS), pages 1099--1108.\n"
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"metadata": {
25+
"collapsed": false
26+
},
27+
"outputs": [],
28+
"source": [
29+
"# Authors: Tom Dupre La Tour <tom.duprelatour@telecom-paristech.fr>\n# Mainak Jas <mainak.jas@telecom-paristech.fr>\n# Umut Simsekli <umut.simsekli@telecom-paristech.fr>\n# Alexandre Gramfort <alexandre.gramfort@telecom-paristech.fr>\n#\n# License: BSD (3-clause)"
30+
]
31+
},
32+
{
33+
"cell_type": "markdown",
34+
"metadata": {},
35+
"source": [
36+
"Let us first load the data sample.\n\n"
37+
]
38+
},
39+
{
40+
"cell_type": "code",
41+
"execution_count": null,
42+
"metadata": {
43+
"collapsed": false
44+
},
45+
"outputs": [],
46+
"source": [
47+
"import mne\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# sample frequency\nsfreq = 350.\n\n# We load the signal. It is an LFP channel recorded on a rodent's striatum.\ndata = np.load('../rodent_striatum.npy')\nprint(data.shape)"
48+
]
49+
},
50+
{
51+
"cell_type": "markdown",
52+
"metadata": {},
53+
"source": [
54+
"Now let us take a closer look, plotting the 100 first seconds of the signal.\n\n"
55+
]
56+
},
57+
{
58+
"cell_type": "code",
59+
"execution_count": null,
60+
"metadata": {
61+
"collapsed": false
62+
},
63+
"outputs": [],
64+
"source": [
65+
"start, stop = [0, 100] # in seconds\nstart, stop = int(start * sfreq), int(stop * sfreq)\ntime = np.arange(start, stop) / sfreq\nplt.plot(time, data[0, start:stop])\nplt.show()"
66+
]
67+
},
68+
{
69+
"cell_type": "markdown",
70+
"metadata": {},
71+
"source": [
72+
"As we can see, the data contains severe artifacts. We will thus compare three\napproaches to tackle these artifacts:\n\n - First, we will fit a CSC model on a section not affected by artifacts.\n - Then, we will fit a CSC model on a section affected by artifacts.\n - Finally, we will fit an alpha-CSC model on a section affected by\n artifacts.\n\n"
73+
]
74+
},
75+
{
76+
"cell_type": "code",
77+
"execution_count": null,
78+
"metadata": {
79+
"collapsed": false
80+
},
81+
"outputs": [],
82+
"source": [
83+
"# Define a clean data section.\nstart, stop = [100, 600] # in seconds\nstart, stop = int(start * sfreq), int(stop * sfreq)\ndata_clean = data[:, start:stop].copy()\n\n# Define a dirty data section (same length).\nstart, stop = [0, 500] # in seconds\nstart, stop = int(start * sfreq), int(stop * sfreq)\ndata_dirty = data[:, start:stop].copy()\n\n# We also remove the slow drift, which accounts for a lot of variance.\ndata_clean = mne.filter.filter_data(data_clean, sfreq, 1, None)\ndata_dirty = mne.filter.filter_data(data_dirty, sfreq, 1, None)\n\n# To make the most of parallel computing, we split the data into trials.\ndata_clean = data_clean.reshape(50, -1)\ndata_dirty = data_dirty.reshape(50, -1)\n\n# We scale the data, since parameter alpha is scale dependant.\nscale = data_clean.std()\ndata_clean /= scale\ndata_dirty /= scale"
84+
]
85+
},
86+
{
87+
"cell_type": "markdown",
88+
"metadata": {},
89+
"source": [
90+
"This sample contains CFC between 3 Hz and 80 Hz. This phenomenon can be\ndescribed with a comodulogram, computed for instance with the `pactools\n<http://pactools.github.io/>`_ Python library.\n\n"
91+
]
92+
},
93+
{
94+
"cell_type": "code",
95+
"execution_count": null,
96+
"metadata": {
97+
"collapsed": false
98+
},
99+
"outputs": [],
100+
"source": [
101+
"from pactools import Comodulogram\n\ncomod = Comodulogram(fs=sfreq, low_fq_range=np.arange(0.2, 10.2, 0.2),\n low_fq_width=2., method='duprelatour')\ncomod.fit(data_clean)\ncomod.plot()\nplt.show()"
102+
]
103+
},
104+
{
105+
"cell_type": "markdown",
106+
"metadata": {},
107+
"source": [
108+
"Here we define the plotting function which display the learned atoms.\n\n"
109+
]
110+
},
111+
{
112+
"cell_type": "code",
113+
"execution_count": null,
114+
"metadata": {
115+
"collapsed": false
116+
},
117+
"outputs": [],
118+
"source": [
119+
"def plot_atoms(d_hat):\n n_atoms, n_times_atom = d_hat.shape\n n_columns = min(6, n_atoms)\n n_rows = int(np.ceil(n_atoms // n_columns))\n figsize = (4 * n_columns, 3 * n_rows)\n fig, axes = plt.subplots(n_rows, n_columns, figsize=figsize, sharey=True)\n axes = axes.ravel()\n\n # Plot the temporal pattern of the atom\n for kk in range(n_atoms):\n ax = axes[kk]\n time = np.arange(n_times_atom) / sfreq\n ax.plot(time, d_hat[kk], color='C%d' % kk)\n ax.set_xlim(0, n_times_atom / sfreq)\n ax.set(xlabel='Time (sec)', title=\"Temporal pattern %d\" % kk)\n ax.grid(True)\n\n fig.tight_layout()\n plt.show()"
120+
]
121+
},
122+
{
123+
"cell_type": "markdown",
124+
"metadata": {},
125+
"source": [
126+
"Then we define the common parameters of the different models.\n\n"
127+
]
128+
},
129+
{
130+
"cell_type": "code",
131+
"execution_count": null,
132+
"metadata": {
133+
"collapsed": false
134+
},
135+
"outputs": [],
136+
"source": [
137+
"common_params = dict(\n n_atoms=3,\n n_times_atom=int(sfreq * 1.0), # 1000. ms\n reg=3.,\n solver_z='l-bfgs',\n solver_z_kwargs=dict(factr=1e9),\n solver_d_kwargs=dict(factr=1e2),\n random_state=42,\n n_jobs=5,\n verbose=1)\n\n# number of iterations\nn_iter = 10\n\n# Parameter of the alpha-stable distribution for the alpha-CSC model.\n# 0 < alpha < 2\n# A value of 2 would correspond to the Gaussian noise model, as in vanilla CSC.\nalpha = 1.2"
138+
]
139+
},
140+
{
141+
"cell_type": "markdown",
142+
"metadata": {},
143+
"source": [
144+
"First, we fit a CSC model on the clean data. Interestingly, we obtain\nprototypical waveforms of the signal on which we can clearly see the CFC.\n\n"
145+
]
146+
},
147+
{
148+
"cell_type": "code",
149+
"execution_count": null,
150+
"metadata": {
151+
"collapsed": false
152+
},
153+
"outputs": [],
154+
"source": [
155+
"from alphacsc import learn_d_z, learn_d_z_weighted\n\nX = data_clean\n\n_, _, d_hat, z_hat, _ = learn_d_z(X, n_iter=n_iter, **common_params)\n\nplot_atoms(d_hat)"
156+
]
157+
},
158+
{
159+
"cell_type": "markdown",
160+
"metadata": {},
161+
"source": [
162+
"Then, if we fit a CSC model on the dirty data, the model is strongly affected\nby the artifacts, and we cannot see CFC anymore in the temporal waveforms.\n\n"
163+
]
164+
},
165+
{
166+
"cell_type": "code",
167+
"execution_count": null,
168+
"metadata": {
169+
"collapsed": false
170+
},
171+
"outputs": [],
172+
"source": [
173+
"X = data_dirty\n\n_, _, d_hat, z_hat, _ = learn_d_z(X, n_iter=n_iter, **common_params)\n\nplot_atoms(d_hat)"
174+
]
175+
},
176+
{
177+
"cell_type": "markdown",
178+
"metadata": {},
179+
"source": [
180+
"Finally, If we fit an alpha-CSC model on the dirty data, the model is less\naffected by the artifacts, and we are able to see CFC in the temporal\nwaveforms.\n\n"
181+
]
182+
},
183+
{
184+
"cell_type": "code",
185+
"execution_count": null,
186+
"metadata": {
187+
"collapsed": false
188+
},
189+
"outputs": [],
190+
"source": [
191+
"X = data_dirty\n\nd_hat, z_hat, tau = learn_d_z_weighted(\n X, n_iter_optim=n_iter, n_iter_global=3, n_iter_mcmc=300,\n n_burnin_mcmc=100, alpha=alpha, **common_params)\n\nplot_atoms(d_hat)"
192+
]
193+
}
194+
],
195+
"metadata": {
196+
"kernelspec": {
197+
"display_name": "Python 3",
198+
"language": "python",
199+
"name": "python3"
200+
},
201+
"language_info": {
202+
"codemirror_mode": {
203+
"name": "ipython",
204+
"version": 3
205+
},
206+
"file_extension": ".py",
207+
"mimetype": "text/x-python",
208+
"name": "python",
209+
"nbconvert_exporter": "python",
210+
"pygments_lexer": "ipython3",
211+
"version": "3.9.1"
212+
}
213+
},
214+
"nbformat": 4,
215+
"nbformat_minor": 0
216+
}

0 commit comments

Comments
 (0)