Blame LFPy-2.0.7/examples/example_ECoG_4sphere.py

5d3830a
# -*- coding: utf-8 -*-
5d3830a
"""
5d3830a
Example plot for LFPy: Single-synapse contribution to the potential through head
5d3830a
5d3830a
Copyright (C) 2017 Computational Neuroscience Group, NMBU.
5d3830a
5d3830a
This program is free software: you can redistribute it and/or modify
5d3830a
it under the terms of the GNU General Public License as published by
5d3830a
the Free Software Foundation, either version 3 of the License, or
5d3830a
(at your option) any later version.
5d3830a
5d3830a
This program is distributed in the hope that it will be useful,
5d3830a
but WITHOUT ANY WARRANTY; without even the implied warranty of
5d3830a
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5d3830a
GNU General Public License for more details.
5d3830a
"""
5d3830a
import LFPy
5d3830a
import numpy as np
5d3830a
import matplotlib.pyplot as plt
5d3830a
from os.path import join
5d3830a
5d3830a
# four-sphere properties
5d3830a
radii = [79000., 80000., 85000., 90000.]
5d3830a
radii_name = ["Brain", "CSF", "Skull", "Scalp"]
5d3830a
sigmas = [0.3, 1.5, 0.015, 0.3]
5d3830a
rad_tol = 1e-2
5d3830a
somapos = np.array([0., 0., 78750.])
5d3830a
5d3830a
xlim = [-1000, 1000]
5d3830a
ylim = [radii[0]-500, radii[1] + 500]
5d3830a
5d3830a
# cell with simplified morphology
5d3830a
cellParameters = {
5d3830a
    'morphology' : join("morphologies", 'example_morphology.hoc'),
5d3830a
    'tstart' : 0.,
5d3830a
    'tstop' : 5.,
5d3830a
    'dt' : 2**-4,
5d3830a
    'v_init' : -65,
5d3830a
    'cm' : 1.,
5d3830a
    'Ra' : 150.,
5d3830a
    'passive' : True,
5d3830a
    'passive_parameters' : {'g_pas' : 1./3E4, 'e_pas' : -65.},
5d3830a
    'pt3d' : True,
5d3830a
}
5d3830a
5d3830a
cell = LFPy.Cell(**cellParameters)
5d3830a
synidx = cell.get_closest_idx(z=200)
5d3830a
5d3830a
synapseParameters = {
5d3830a
    'idx' : synidx,
5d3830a
    'e' : 0,                                # reversal potential
5d3830a
    'syntype' : 'Exp2Syn',                   # synapse type
5d3830a
    'tau1' : 0.1,                              # syn. rise time constant
5d3830a
    'tau2' : 1.,                              # syn. decay time constant
5d3830a
    'weight' : 0.002,                        # syn. weight
5d3830a
    'record_current' : True                 # syn. current record
5d3830a
}
5d3830a
synapse = LFPy.Synapse(cell, **synapseParameters)
5d3830a
synapse.set_spike_times(np.array([1.]))
5d3830a
cell.set_pos(z=somapos[2])
5d3830a
cell.simulate(rec_imem=True, rec_vmem=True, rec_current_dipole_moment=True)
5d3830a
5d3830a
# Setting up recording positions
5d3830a
elec_z = np.array([radii[0],
5d3830a
                  (radii[0] + radii[1]) / 2,
5d3830a
                   radii[1],
5d3830a
                   radii[1] + 500])
5d3830a
5d3830a
elec_x = np.zeros(elec_z.shape)
5d3830a
elec_y = np.zeros(elec_x.shape)
5d3830a
eeg_coords = np.array([elec_x.flatten(), elec_y.flatten(), elec_z.flatten()]).T
5d3830a
5d3830a
MD_4s = LFPy.FourSphereVolumeConductor(radii, sigmas, eeg_coords)
5d3830a
phi = MD_4s.calc_potential_from_multi_dipoles(cell) * 1e6  # from mV to nV
5d3830a
5d3830a
# Plotting results
5d3830a
plt.close('all')
5d3830a
fig = plt.figure(figsize=[8, 10])
5d3830a
fig.subplots_adjust(left=0.02, hspace=0.5, right=0.98, top=0.95)
5d3830a
5d3830a
ax = fig.add_subplot(111, aspect=1, frameon=False, xlim=xlim, ylim=ylim,
5d3830a
                     xticks=[], yticks=[])
5d3830a
5d3830a
# Plotting cell
5d3830a
for sec in LFPy.cell.neuron.h.allsec():
5d3830a
    idx = cell.get_idx(sec.name())
5d3830a
    l_cell, = ax.plot(np.r_[cell.xstart[idx], cell.xend[idx][-1]],
5d3830a
            np.r_[cell.zstart[idx], cell.zend[idx][-1]],
5d3830a
            color='r', zorder=3, lw=np.sqrt(np.average(cell.diam[idx])))
5d3830a
5d3830a
l_syn, = ax.plot(cell.xmid[synapseParameters['idx']],
5d3830a
                 cell.zmid[synapseParameters['idx']],
5d3830a
                 '*', c='orange', zorder=5)
5d3830a
5d3830a
# Plotting the layers of the head model
5d3830a
max_angle = np.abs(np.rad2deg(np.arcsin(xlim[0] / ylim[0])))
5d3830a
plot_angle = np.linspace(-max_angle, max_angle, 100)
5d3830a
for b_idx in range(len(radii)):
5d3830a
    x_ = radii[b_idx] * np.sin(np.deg2rad(plot_angle))
5d3830a
    z_ = radii[b_idx] * np.cos(np.deg2rad(plot_angle))
5d3830a
    l_curved, = ax.plot(x_, z_, ':', c="gray")
5d3830a
5d3830a
ax.text(xlim[0], radii[0] - 70, "Brain", va="top", ha="left", color="k")
5d3830a
ax.text(xlim[0], radii[0] + 70, "CSF", va="top", ha="left", color="k")
5d3830a
ax.text(xlim[0], radii[1] + 70, "Skull", va="top", ha="left", color="k")
5d3830a
5d3830a
ax.plot([-700, -200], [radii[0]-300, radii[0]-300], 'k', lw=2)
5d3830a
ax.text(-550, radii[0]-290, "500 $\mu$m")
5d3830a
5d3830a
# Plotting the potential at different positions
5d3830a
y_norm = 200
5d3830a
x_norm = 500
5d3830a
elec_clr = lambda elec_idx: plt.cm.viridis(elec_idx / (len(elec_z) - 1))
5d3830a
for elec_idx in range(len(elec_z)):
5d3830a
    l_elec, = ax.plot(elec_x[elec_idx], elec_z[elec_idx],
5d3830a
                      'o', c=elec_clr(elec_idx), clip_on=False)
5d3830a
    y_ = phi[elec_idx, :]
5d3830a
    norm_const = np.max(np.abs(y_))
5d3830a
    y_ = y_ * y_norm / norm_const + elec_z[elec_idx]
5d3830a
    x_ = cell.tvec / cell.tvec[-1] * x_norm + elec_x[elec_idx]
5d3830a
    ax.plot(x_, y_, c=elec_clr(elec_idx), clip_on=False)
5d3830a
    ax.plot([x_[-1] + 200, x_[-1] + 200],
5d3830a
            [elec_z[elec_idx], elec_z[elec_idx] - y_norm], c='k')
5d3830a
    scale_text = "{:2.1f} nV".format(norm_const)
5d3830a
    ax.text(x_[-1] + 250, elec_z[elec_idx] - y_norm / 2, scale_text)
5d3830a
5d3830a
ax.plot([x_[0], x_[-1]],
5d3830a
        [elec_z[1] - y_norm*1.1, elec_z[1] - y_norm*1.1],
5d3830a
        c='k', clip_on=False, lw=2)
5d3830a
ax.text((x_[0] + x_[-1])/2, elec_z[1] - y_norm * 1.2,
5d3830a
        "{} ms".format(cell.tvec[-1]),
5d3830a
        va="top", ha="center", clip_on=False)
5d3830a
5d3830a
ax_inset = fig.add_axes([0.7, 0.05, 0.25, 0.15], title="Synaptic current",
5d3830a
                        ylabel="nA", xlabel="Time (ms)")
5d3830a
l_isyn, = ax_inset.plot(cell.tvec, synapse.i, c='orange')
5d3830a
5d3830a
ax.legend([l_cell, l_curved, l_syn, l_isyn, l_elec],
5d3830a
          ["Cell", "Four-sphere boundary", "Synapse",
5d3830a
           "Synaptic current", "Electrode"],
5d3830a
          ncol=1, loc=(0.01, -0.1), frameon=False)
5d3830a
5d3830a
plt.savefig(join('example_potential_through_head.pdf'))
5d3830a
plt.show()