# -*- coding: utf-8 -*-
"""Copyright (C) 2012 Computational Neuroscience Group, NMBU.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
"""
from __future__ import division
import sys
import os
import posixpath
import unittest
import numpy as np
import LFPy
import neuron
from .common import *
# for nosetests to run load the SinSyn sinusoid synapse currrent mechanism
if "win32" in sys.platform:
pth = os.path.join(LFPy.__path__[0], 'test', 'nrnmech.dll')
pth = pth.replace(os.sep, posixpath.sep)
if not pth in neuron.nrn_dll_loaded:
neuron.h.nrn_load_dll(pth)
neuron.nrn_dll_loaded.append(pth)
else:
neuron.load_mechanisms(os.path.join(LFPy.__path__[0], 'test'))
class testRecExtElectrode(unittest.TestCase):
"""
test class LFPy.RecExtElectrode
"""
def test_method_pointsource(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulation(method='pointsource')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_linesource(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulation(method='linesource')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_soma_as_point(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulation(method='soma_as_point')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_pointsource_dotprodcoeffs(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulationDotprodcoeffs(method='pointsource')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_linesource_dotprodcoeffs(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulationDotprodcoeffs(method='linesource')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_soma_as_point_dotprodcoeffs(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulationDotprodcoeffs(method='soma_as_point')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_pointsource_contact_average_r10n100(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulationAveragingElectrode(
contactRadius=10, contactNPoints=100, method='soma_as_point')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_linesource_contact_average_r10n100(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulationAveragingElectrode(
contactRadius=10, contactNPoints=100, method='linesource')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_method_soma_as_point_contact_average_r10n100(self):
#create LFPs using LFPy-model
LFP_LFPy = stickSimulationAveragingElectrode(
contactRadius=10, contactNPoints=100, method='soma_as_point')
#create LFPs using the analytical approach
time = np.linspace(0, 100, 100*2**6+1)
R = np.ones(11)*100
Z = np.linspace(1000, 0, 11)
LFP_analytic = np.empty((R.size, time.size))
for i in range(R.size):
LFP_analytic[i, ] = analytical_LFP(time, electrodeR=R[i],
electrodeZ=Z[i])
np.testing.assert_allclose(LFP_analytic, LFP_LFPy, rtol=0,
atol=abs(LFP_analytic).max() / 10.)
def test_sigma_inputs(self):
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'stick.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : 0,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 1000,
}
stick = LFPy.Cell(**stickParams)
electrodeParams = {
'sigma' : [0.3, 0.3, 0.3, 0.3],
'x' : np.ones(11) * 100.,
'y' : np.zeros(11),
'z' : np.linspace(1000, 0, 11),
}
np.testing.assert_raises(ValueError, LFPy.RecExtElectrode, **electrodeParams)
def test_bad_cell_position_in_slice(self):
electrodeParams = {
'sigma_T' : 0.3,
'sigma_S' : 1.5,
'sigma_G' : 0.0,
'h': 200,
'x' : np.linspace(0, 1000, 11),
'y' : np.zeros(11),
'z' : np.zeros(11),
'method': "pointsource",
}
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'stick.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : -10,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 1000,
}
stick = LFPy.Cell(**stickParams)
stick.set_rotation(y=np.pi/2)
stick.simulate(rec_imem=True)
stick.set_pos(z=-100)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
np.testing.assert_raises(RuntimeError, MEA.calc_lfp)
stick.set_pos(z=300)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
np.testing.assert_raises(RuntimeError, MEA.calc_lfp)
def test_sqeeze_cell_and_bad_position(self):
electrodeParams = {
'sigma_T' : 0.3,
'sigma_S' : 1.5,
'sigma_G' : 0.0,
'h': 200,
'x' : np.linspace(0, 1000, 11),
'y' : np.zeros(11),
'z' : np.zeros(11),
'method': "pointsource",
'squeeze_cell_factor': None,
}
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'ball_and_sticks.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : -10,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 1000,
}
stick = LFPy.Cell(**stickParams)
stick.set_rotation(y=np.pi/2)
stick.simulate(rec_imem=True)
stick.set_pos(z=1)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
np.testing.assert_raises(RuntimeError, MEA.test_cell_extent)
stick.set_pos(z=199)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
np.testing.assert_raises(RuntimeError, MEA.test_cell_extent)
electrodeParams = {
'sigma_T' : 0.3,
'sigma_S' : 1.5,
'sigma_G' : 0.0,
'h': 200,
'x' : np.linspace(0, 1000, 11),
'y' : np.zeros(11),
'z' : np.zeros(11),
'method': "pointsource",
'squeeze_cell_factor': 0.1,
}
stick.set_pos(z=-1)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
np.testing.assert_raises(RuntimeError, MEA.test_cell_extent)
stick.set_pos(z=201)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
np.testing.assert_raises(RuntimeError, MEA.test_cell_extent)
def test_return_comp_outside_slice(self):
electrodeParams = {
'sigma_T' : 0.3,
'sigma_S' : 1.5,
'sigma_G' : 0.0,
'h': 200,
'x' : np.linspace(0, 1000, 11),
'y' : np.zeros(11),
'z' : np.zeros(11),
'method': "pointsource",
'squeeze_cell_factor': None,
}
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'ball_and_sticks.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : -10,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 1000,
}
stick = LFPy.Cell(**stickParams)
stick.set_rotation(y=np.pi/2)
stick.set_pos(z=100)
stick.simulate(rec_imem=True)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
np.testing.assert_raises(RuntimeError, MEA._return_comp_outside_slice)
true_bad_comp = np.array([2, 3, 6])
stick.zstart[true_bad_comp] = 1000
bad_comp, reason = MEA._return_comp_outside_slice()
np.testing.assert_equal(reason, "zstart above")
np.testing.assert_equal(true_bad_comp, bad_comp)
stick.zstart[true_bad_comp] = 100
stick.zstart[true_bad_comp] = -1000
bad_comp, reason = MEA._return_comp_outside_slice()
np.testing.assert_equal(reason, "zstart below")
np.testing.assert_equal(true_bad_comp, bad_comp)
stick.zstart[true_bad_comp] = 100
stick.zend[true_bad_comp] = 1000
bad_comp, reason = MEA._return_comp_outside_slice()
np.testing.assert_equal(reason, "zend above")
np.testing.assert_equal(true_bad_comp, bad_comp)
stick.zend[true_bad_comp] = 100
stick.zend[true_bad_comp] = -1000
bad_comp, reason = MEA._return_comp_outside_slice()
np.testing.assert_equal(reason, "zend below")
np.testing.assert_equal(true_bad_comp, bad_comp)
stick.zend[true_bad_comp] = 100
def test_position_shifted_slice(self):
electrodeParams = {
'sigma_T' : 0.3,
'sigma_S' : 1.5,
'sigma_G' : 0.0,
'h': 200,
'z_shift': -200,
'x' : np.linspace(0, 1000, 11),
'y' : np.zeros(11),
'z' : np.zeros(11) - 100,
'method': "pointsource",
'squeeze_cell_factor': None,
}
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'ball_and_sticks.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : -10,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 100,
}
stick = LFPy.Cell(**stickParams)
stick.set_rotation(y=np.pi/2)
stick.set_pos(z=-100)
MEA = LFPy.RecMEAElectrode(stick, **electrodeParams)
MEA.test_cell_extent()
def test_slice_shift_invariance_pointsource(self):
h = 200
z_shift_1 = 0
z_shift_2 = -352
electrodeParams_1 = {
'sigma_T' : 0.3,
'sigma_S' : 1.5,
'sigma_G' : 0.0,
'h': h,
'z_shift': z_shift_1,
'x' : np.linspace(0, 1000, 11),
'y' : np.zeros(11),
'z' : np.zeros(11) + z_shift_1,
'squeeze_cell_factor': None,
}
electrodeParams_2 = {
'sigma_T' : 0.3,
'sigma_S' : 1.5,
'sigma_G' : 0.0,
'h': h,
'z_shift': z_shift_2,
'x' : np.linspace(0, 1000, 11),
'y' : np.zeros(11),
'z' : np.zeros(11) + z_shift_2,
'squeeze_cell_factor': None,
}
stimParams = {
'pptype' : 'SinSyn',
'delay' : -100.,
'dur' : 1000.,
'pkamp' : 1.,
'freq' : 100.,
'phase' : -np.pi/2,
'bias' : 0.,
'record_current' : True
}
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'ball_and_sticks.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : -10,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 100,
}
stick = LFPy.Cell(**stickParams)
stick.set_rotation(y=np.pi/2)
synapse = LFPy.StimIntElectrode(stick, stick.get_closest_idx(0, 0, 0),
**stimParams)
stick.simulate(rec_imem=True)
methods = ["pointsource", "linesource", "soma_as_point"]
for method in methods:
electrodeParams_1["method"] = method
electrodeParams_2["method"] = method
stick.set_pos(z=z_shift_1 + h/2)
MEA_shift_1 = LFPy.RecMEAElectrode(stick, **electrodeParams_1)
MEA_shift_1.calc_lfp()
stick.set_pos(z=z_shift_2 + h/2)
MEA_shift_2 = LFPy.RecMEAElectrode(stick, **electrodeParams_2)
MEA_shift_2.calc_lfp()
np.testing.assert_allclose(MEA_shift_1.LFP,
MEA_shift_2.LFP, rtol=1E-7)
def test_isotropic_version_of_anisotropic_methods(self):
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'stick.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : 0,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 1000,
}
stimParams = {
'pptype' : 'SinSyn',
'delay' : -100.,
'dur' : 1000.,
'pkamp' : 1.,
'freq' : 100.,
'phase' : -np.pi/2,
'bias' : 0.,
'record_current' : True
}
isotropic_electrodeParams = {
'sigma' : 0.3,
'x' : np.ones(11) * 100.,
'y' : np.zeros(11),
'z' : np.linspace(1000, 0, 11),
}
anisotropic_electrodeParams = isotropic_electrodeParams.copy()
anisotropic_electrodeParams["sigma"] = [isotropic_electrodeParams["sigma"]] * 3
methods = ["pointsource", "linesource", "soma_as_point"]
for method in methods:
isotropic_electrodeParams["method"] = method
anisotropic_electrodeParams["method"] = method
isotropic_electrode = LFPy.RecExtElectrode(**isotropic_electrodeParams)
anisotropic_electrode = LFPy.RecExtElectrode(**anisotropic_electrodeParams)
stick = LFPy.Cell(**stickParams)
stick.set_pos(z=-stick.zstart[0])
synapse = LFPy.StimIntElectrode(stick, stick.get_closest_idx(0, 0, 1000),
**stimParams)
stick.simulate([isotropic_electrode, anisotropic_electrode],
rec_imem=True, rec_vmem=True)
np.testing.assert_allclose(isotropic_electrode.LFP,
anisotropic_electrode.LFP, rtol=1E-7)
def test_compare_anisotropic_lfp_methods(self):
stickParams = {
'morphology' : os.path.join(LFPy.__path__[0], 'test', 'stick.hoc'),
'passive_parameters' : {'g_pas' : 1./30000, 'e_pas' : -65},
'passive': True,
'tstart' : 0,
'tstop' : 20,
'dt' : 2**-4,
'nsegs_method' : 'lambda_f',
'lambda_f' : 1000,
}
stimParams = {
'pptype' : 'SinSyn',
'delay' : -100.,
'dur' : 1000.,
'pkamp' : 1.,
'freq' : 100.,
'phase' : -np.pi/2,
'bias' : 0.,
'record_current' : True
}
electrodeParams = {
'sigma' : [0.3, 0.3, 0.45],
'x' : np.array([0, 1000]),
'y' : np.zeros(2),
'z' : np.zeros(2),
}
ps_electrodeParams = electrodeParams.copy()
ls_electrodeParams = electrodeParams.copy()
sap_electrodeParams = electrodeParams.copy()
ps_electrodeParams["method"] = "pointsource"
ls_electrodeParams["method"] = "linesource"
sap_electrodeParams["method"] = "soma_as_point"
electrode_ps = LFPy.RecExtElectrode(**ps_electrodeParams)
electrode_ls = LFPy.RecExtElectrode(**ls_electrodeParams)
electrode_sap = LFPy.RecExtElectrode(**sap_electrodeParams)
stick = LFPy.Cell(**stickParams)
stick.set_pos(z=-stick.zstart[0])
synapse = LFPy.StimIntElectrode(stick, stick.get_closest_idx(0, 0, 1000),
**stimParams)
stick.simulate([electrode_ps, electrode_ls, electrode_sap],
rec_imem=True, rec_vmem=True)
# Test that distant electrode is independent of choice of method
np.testing.assert_almost_equal(electrode_ps.LFP[1,:],
electrode_ls.LFP[1,:])
np.testing.assert_almost_equal(electrode_ps.LFP[1,:],
electrode_sap.LFP[1,:])
# Hack to test that LFP close to stick is dependent on choice of method
np.testing.assert_raises(AssertionError, np.testing.assert_array_equal,
electrode_ps.LFP[0,:], electrode_ls.LFP[0,:])
np.testing.assert_raises(AssertionError, np.testing.assert_array_equal,
electrode_ps.LFP[0,:], electrode_sap.LFP[0,:])