|
|
58cbabd |
# -*- coding: utf-8 -*-
|
|
|
58cbabd |
"""
|
|
|
58cbabd |
Example plot for LFPy: Single-synapse contribution to the EEG
|
|
|
58cbabd |
|
|
|
58cbabd |
Execution:
|
|
|
58cbabd |
|
|
|
58cbabd |
python example_EEG.py
|
|
|
58cbabd |
|
|
|
58cbabd |
Copyright (C) 2017 Computational Neuroscience Group, NMBU.
|
|
|
58cbabd |
|
|
|
58cbabd |
This program is free software: you can redistribute it and/or modify
|
|
|
58cbabd |
it under the terms of the GNU General Public License as published by
|
|
|
58cbabd |
the Free Software Foundation, either version 3 of the License, or
|
|
|
58cbabd |
(at your option) any later version.
|
|
|
58cbabd |
|
|
|
58cbabd |
This program is distributed in the hope that it will be useful,
|
|
|
58cbabd |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
58cbabd |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
58cbabd |
GNU General Public License for more details.
|
|
|
58cbabd |
"""
|
|
|
58cbabd |
import LFPy
|
|
|
58cbabd |
import numpy as np
|
|
|
58cbabd |
import matplotlib.pyplot as plt
|
|
|
58cbabd |
from matplotlib import colorbar
|
|
|
58cbabd |
|
|
|
58cbabd |
def plot_cell_to_ax(cell, ax, synidxs):
|
|
|
58cbabd |
for idx in range(cell.totnsegs):
|
|
|
58cbabd |
if idx == 0:
|
|
|
58cbabd |
ax.plot(cell.xmid[idx], cell.zmid[idx], 'ko')
|
|
|
58cbabd |
else:
|
|
|
58cbabd |
ax.plot([cell.xstart[idx], cell.xend[idx]],
|
|
|
58cbabd |
[cell.zstart[idx], cell.zend[idx]], c='k')
|
|
|
58cbabd |
|
|
|
58cbabd |
for synidx in synidxs:
|
|
|
58cbabd |
l, = ax.plot(cell.xmid[synidx], cell.zmid[synidx], '*',
|
|
|
58cbabd |
c="r", ms=10)
|
|
|
58cbabd |
ax.legend([l], ["Synapse"], frameon=False, bbox_to_anchor=[1, -0.1])
|
|
|
58cbabd |
|
|
|
58cbabd |
def plot_EEG_sphere(fig, eeg, x_eeg, y_eeg, z_eeg):
|
|
|
58cbabd |
from mpl_toolkits.mplot3d import Axes3D
|
|
|
58cbabd |
ax = fig.add_subplot(322, projection='3d',
|
|
|
58cbabd |
title="Max EEG potential\nat 4-sphere surface")
|
|
|
58cbabd |
vmax = 6
|
|
|
58cbabd |
vmin = -vmax
|
|
|
58cbabd |
clr = lambda phi: plt.cm.PRGn((phi - vmin) / (vmax - vmin))
|
|
|
58cbabd |
clrs = clr(eeg)
|
|
|
58cbabd |
surf = ax.plot_surface(x_eeg.reshape(num_theta, num_phi),
|
|
|
58cbabd |
y_eeg.reshape(num_theta, num_phi),
|
|
|
58cbabd |
z_eeg.reshape(num_theta, num_phi),
|
|
|
58cbabd |
rstride=1, cstride=1, facecolors=clrs,
|
|
|
58cbabd |
linewidth=0, antialiased=False)
|
|
|
58cbabd |
|
|
|
58cbabd |
ax.set_aspect('equal')
|
|
|
58cbabd |
ax.axis('off')
|
|
|
58cbabd |
ax.set_xlim3d(-65000, 65000)
|
|
|
58cbabd |
ax.set_ylim3d(-65000, 65000)
|
|
|
58cbabd |
ax.set_zlim3d(-65000, 65000)
|
|
|
58cbabd |
ax.view_init(10, 0)
|
|
|
58cbabd |
|
|
|
58cbabd |
# colorbar
|
|
|
58cbabd |
cax = fig.add_axes([0.65, 0.75, 0.25, 0.01])
|
|
|
58cbabd |
m = plt.cm.ScalarMappable(cmap=plt.cm.PRGn)
|
|
|
58cbabd |
ticks = np.linspace(vmin, vmax, 5) # global normalization
|
|
|
58cbabd |
m.set_array(ticks)
|
|
|
58cbabd |
cbar = fig.colorbar(m, cax=cax,
|
|
|
58cbabd |
extend='both', orientation='horizontal')
|
|
|
58cbabd |
cbar.outline.set_visible(False)
|
|
|
58cbabd |
cbar.set_ticks(ticks)
|
|
|
58cbabd |
cbar.set_label(r'$\phi$ (pV)', labelpad=1.)
|
|
|
58cbabd |
|
|
|
58cbabd |
if __name__ == '__main__':
|
|
|
58cbabd |
|
|
|
58cbabd |
# four_sphere properties
|
|
|
58cbabd |
radii = [79000., 80000., 85000., 90000.]
|
|
|
58cbabd |
sigmas = [0.3, 1.5, 0.015, 0.3]
|
|
|
58cbabd |
rad_tol = 1e-2
|
|
|
58cbabd |
|
|
|
58cbabd |
# simulate cell
|
|
|
58cbabd |
syn_loc = (0, 0, 1000)
|
|
|
58cbabd |
|
|
|
58cbabd |
cell_params = {'morphology': 'morphologies/L5_Mainen96_LFPy.hoc',
|
|
|
58cbabd |
'cm' : 1.0, # membrane capacitance
|
|
|
58cbabd |
'Ra' : 150, # axial resistance
|
|
|
58cbabd |
'tstart': 0.,
|
|
|
58cbabd |
'passive' : True, # switch on passive mechs
|
|
|
58cbabd |
'nsegs_method' : 'lambda_f',# method for setting number of segments,
|
|
|
58cbabd |
'lambda_f' : 100, # segments are isopotential at this frequency
|
|
|
58cbabd |
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -70}, # passive params
|
|
|
58cbabd |
'tstop': 40
|
|
|
58cbabd |
}
|
|
|
58cbabd |
|
|
|
58cbabd |
synapse_params = {'e': 0., # reversal potential
|
|
|
58cbabd |
'syntype': 'ExpSyn', # exponential synapse
|
|
|
58cbabd |
'tau': 5., # synapse time constant
|
|
|
58cbabd |
'weight': 0.001, # 0.001, # synapse weight
|
|
|
58cbabd |
'record_current': True # record synapse current
|
|
|
58cbabd |
}
|
|
|
58cbabd |
# create cell with parameters in dictionary
|
|
|
58cbabd |
cell = LFPy.Cell(**cell_params)
|
|
|
58cbabd |
pos = syn_loc
|
|
|
58cbabd |
synapse_params['idx'] = cell.get_closest_idx(x=pos[0], y=pos[1], z=pos[2])
|
|
|
58cbabd |
synapse = LFPy.Synapse(cell, **synapse_params)
|
|
|
58cbabd |
synapse.set_spike_times(np.array([5.]))
|
|
|
58cbabd |
|
|
|
58cbabd |
cell.simulate(rec_imem=True,
|
|
|
58cbabd |
rec_current_dipole_moment=True)
|
|
|
58cbabd |
|
|
|
58cbabd |
# compute dipole
|
|
|
58cbabd |
P = cell.current_dipole_moment
|
|
|
58cbabd |
|
|
|
58cbabd |
somapos = np.array([0., 0., 77500])
|
|
|
58cbabd |
r_soma_syns = [cell.get_intersegment_vector(idx0=0, idx1=i) for i in cell.synidx]
|
|
|
58cbabd |
r_mid = np.average(r_soma_syns, axis=0)
|
|
|
58cbabd |
r_mid = somapos + r_mid/2.
|
|
|
58cbabd |
|
|
|
58cbabd |
eeg_coords_top = np.array([[0., 0., radii[3] - rad_tol]])
|
|
|
58cbabd |
four_sphere_top = LFPy.FourSphereVolumeConductor(radii, sigmas, eeg_coords_top)
|
|
|
58cbabd |
pot_db_4s_top = four_sphere_top.calc_potential(P, r_mid)
|
|
|
58cbabd |
eeg_top = np.array(pot_db_4s_top) * 1e9
|
|
|
58cbabd |
|
|
|
58cbabd |
#measurement points
|
|
|
58cbabd |
# for nice plot use theta_step = 1 and phi_step = 1. NB: Long computation time.
|
|
|
58cbabd |
theta_step = 5
|
|
|
58cbabd |
phi_step = 5
|
|
|
58cbabd |
theta, phi_angle = np.mgrid[0.:180.:theta_step, 0.:360.+phi_step:phi_step]
|
|
|
58cbabd |
|
|
|
58cbabd |
num_theta = theta.shape[0]
|
|
|
58cbabd |
num_phi = theta.shape[1]
|
|
|
58cbabd |
theta = theta.flatten()
|
|
|
58cbabd |
phi_angle = phi_angle.flatten()
|
|
|
58cbabd |
|
|
|
58cbabd |
theta_r = np.deg2rad(theta)
|
|
|
58cbabd |
phi_angle_r = np.deg2rad(phi_angle)
|
|
|
58cbabd |
|
|
|
58cbabd |
x_eeg = (radii[3] - rad_tol) * np.sin(theta_r) * np.cos(phi_angle_r)
|
|
|
58cbabd |
y_eeg = (radii[3] - rad_tol) * np.sin(theta_r) * np.sin(phi_angle_r)
|
|
|
58cbabd |
z_eeg = (radii[3] - rad_tol) * np.cos(theta_r)
|
|
|
58cbabd |
eeg_coords = np.vstack((x_eeg, y_eeg, z_eeg)).T
|
|
|
58cbabd |
|
|
|
58cbabd |
# potential in 4S with db
|
|
|
58cbabd |
time_max = np.argmax(np.linalg.norm(P, axis=1))
|
|
|
58cbabd |
p = P[time_max, None]
|
|
|
58cbabd |
|
|
|
58cbabd |
four_sphere = LFPy.FourSphereVolumeConductor(radii, sigmas, eeg_coords)
|
|
|
58cbabd |
|
|
|
58cbabd |
pot_db_4s = four_sphere.calc_potential(p, r_mid)
|
|
|
58cbabd |
eeg = pot_db_4s.reshape(num_theta, num_phi)*1e9# from mV to pV
|
|
|
58cbabd |
|
|
|
58cbabd |
P_mag = np.sqrt(P[:, 0]**2 + P[:, 1]**2 + P[:, 2]**2)
|
|
|
58cbabd |
|
|
|
58cbabd |
plt.close('all')
|
|
|
58cbabd |
fig = plt.figure(figsize=[6, 8])
|
|
|
58cbabd |
fig.subplots_adjust(left=0.15, hspace=0.5, right=0.98, top=0.95)
|
|
|
58cbabd |
|
|
|
58cbabd |
morph_ax = fig.add_subplot(321, aspect=1, frameon=False,
|
|
|
58cbabd |
title="Cell and synapse",
|
|
|
58cbabd |
xticks=[], yticks=[])
|
|
|
58cbabd |
plot_cell_to_ax(cell, morph_ax, cell.synidx)
|
|
|
58cbabd |
|
|
|
58cbabd |
plot_EEG_sphere(fig, eeg, x_eeg, y_eeg, z_eeg)
|
|
|
58cbabd |
|
|
|
58cbabd |
ax_p = fig.add_subplot(312, title="Current dipole moment", ylabel="nA$\cdot\mu$m")
|
|
|
58cbabd |
ax_p.plot(cell.tvec, P[:, 0], label="P$_x$")
|
|
|
58cbabd |
ax_p.plot(cell.tvec, P[:, 1], label="P$_y$")
|
|
|
58cbabd |
ax_p.plot(cell.tvec, P[:, 2], label="P$_z$")
|
|
|
58cbabd |
ax_p.axvline(cell.tvec[time_max], c='gray', ls='--')
|
|
|
58cbabd |
ax_p.legend(frameon=False, ncol=4, bbox_to_anchor=[1, -0.1])
|
|
|
58cbabd |
|
|
|
58cbabd |
ax_eeg = fig.add_subplot(313, title="EEG at top", xlabel="Time (ms)",
|
|
|
58cbabd |
ylabel='pV')
|
|
|
58cbabd |
ax_eeg.plot(cell.tvec, eeg_top[0, :], 'k')
|
|
|
58cbabd |
|
|
|
58cbabd |
ax_eeg.axvline(cell.tvec[time_max], c='gray', ls='--')
|
|
|
58cbabd |
|
|
|
58cbabd |
# plt.savefig('example_EEG.pdf')
|
|
|
58cbabd |
plt.show()
|