Blame LFPy-2.0.7/examples/example_EEG.py

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()