From e12fbd2ce890e3bf009c2f025146cd4c0b05fde1 Mon Sep 17 00:00:00 2001 From: Espen Hagen Date: Fri, 13 Jan 2017 20:42:52 +0100 Subject: [PATCH] fixed implementation of linesource method (#5) * fixed implementation of linesource method, assert that the number of x,y,z-coordinate values for electrodes are identical * prep new bugfix release 1.1.3 --- LFPy/__init__.py | 2 +- LFPy/lfpcalc.py | 22 +++++++++------------- LFPy/lfpcalc.pyx | 11 +++++------ LFPy/pointprocess.py | 27 ++++++++++++++------------- LFPy/recextelectrode.py | 11 ++++++++--- documentation/sources/conf.py | 2 +- setup.py | 2 +- 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/LFPy/__init__.py b/LFPy/__init__.py index 3878bd7d..5725b1f2 100644 --- a/LFPy/__init__.py +++ b/LFPy/__init__.py @@ -29,7 +29,7 @@ * inputgenerators - functions for synaptic input time generation ''' -__version__ = "1.1.2" +__version__ = "1.1.3" from .pointprocess import Synapse, PointProcess, StimIntElectrode from .recextelectrode import RecExtElectrode, RecExtElectrodeSetup diff --git a/LFPy/lfpcalc.py b/LFPy/lfpcalc.py index b9c80b2b..22c2fea0 100644 --- a/LFPy/lfpcalc.py +++ b/LFPy/lfpcalc.py @@ -13,7 +13,7 @@ import numpy as np -def calc_lfp_choose(cell, x=0, y=0, z=0, sigma=0.3, +def calc_lfp_choose(cell, x=0., y=0., z=0., sigma=0.3, r_limit=None, timestep=None, t_indices=None, method='linesource'): ''' @@ -46,7 +46,7 @@ def calc_lfp_choose(cell, x=0, y=0, z=0, sigma=0.3, r_limit=r_limit, timestep=timestep, t_indices=t_indices) -def calc_lfp_linesource(cell, x=0, y=0, z=0, sigma=0.3, +def calc_lfp_linesource(cell, x=0., y=0., z=0., sigma=0.3, r_limit=None, timestep=None, t_indices=None): '''Calculate electric field potential using the line-source method, all @@ -102,9 +102,9 @@ def calc_lfp_linesource(cell, x=0, y=0, z=0, sigma=0.3, #case i, h < 0, l < 0 [i] = np.where(hnegi & lnegi) - #case ii, h < 0, l > 0 + #case ii, h < 0, l >= 0 [ii] = np.where(hnegi & lposi) - #case iii, h > 0, l > 0 + #case iii, h >= 0, l >= 0 [iii] = np.where(hposi & lposi) Ememi = _Ememi_calc(i, currmem, sigma, deltaS, l, r2, h) @@ -116,7 +116,7 @@ def calc_lfp_linesource(cell, x=0, y=0, z=0, sigma=0.3, return Emem.transpose() -def calc_lfp_som_as_point(cell, x=0, y=0, z=0, sigma=0.3, +def calc_lfp_som_as_point(cell, x=0., y=0., z=0., sigma=0.3, r_limit=None, timestep=None, t_indices=None): '''Calculate electric field potential using the line-source method, @@ -180,7 +180,7 @@ def calc_lfp_som_as_point(cell, x=0, y=0, z=0, sigma=0.3, % (r_soma, s_limit))) r_soma = s_limit - # Check that no segment is close the electrode than r_limit + # Check that no segment is closer to the electrode than r_limit if np.sum(np.nonzero( r2 < r_limit*r_limit )) > 0: for idx in np.nonzero( r2[1:] < r_limit[1:] * r_limit[1:] )[0]+1: if (h[idx] < r_limit[idx]) and \ @@ -202,9 +202,9 @@ def calc_lfp_som_as_point(cell, x=0, y=0, z=0, sigma=0.3, #Line sources #case i, h < 0, l < 0 i = np.where(hnegi & lnegi) - #case ii, h < 0, l > 0 + #case ii, h < 0, l >= 0 ii = np.where(hnegi & lposi) - #case iii, h > 0, l > 0 + #case iii, h >= 0, l >= 0 iii = np.where(hposi & lposi) Ememi = _Ememi_calc(i, currmem, sigma, deltaS, l, r2, h) @@ -281,12 +281,8 @@ def _h_calc(xstart, xend, ystart, yend, zstart, zend, deltaS, x, y, z): '''Subroutine used by calc_lfp_*()''' aa = np.array([x - xend, y - yend, z-zend]) bb = np.array([xend - xstart, yend - ystart, zend - zstart]) - try: - cc = np.dot(aa.T, bb).diagonal().copy() - except: - raise ValueError + cc = np.dot(aa.T, bb).diagonal() hh = cc / deltaS - hh[0] = 0 return hh def _r2_calc(xend, yend, zend, x, y, z, h): diff --git a/LFPy/lfpcalc.pyx b/LFPy/lfpcalc.pyx index e61ae0e9..b00f6eda 100644 --- a/LFPy/lfpcalc.pyx +++ b/LFPy/lfpcalc.pyx @@ -127,9 +127,9 @@ cpdef np.ndarray[DTYPE_t, ndim=1, negative_indices=False] calc_lfp_linesource( #case i, h < 0, l < 0 [i] = np.where(hnegi & lnegi) - #case ii, h < 0, l > 0 + #case ii, h < 0, l >= 0 [ii] = np.where(hnegi & lposi) - #case iii, h > 0, l > 0 + #case iii, h >= 0, l >= 0 [iii] = np.where(hposi & lposi) @@ -238,9 +238,9 @@ cpdef np.ndarray[DTYPE_t, ndim=1] calc_lfp_som_as_point(cell, #Line sources #case i, h < 0, l < 0 [i] = np.where(hnegi & lnegi) - #case ii, h < 0, l > 0 + #case ii, h < 0, l >= 0 [ii] = np.where(hnegi & lposi) - #case iii, h > 0, l > 0 + #case iii, h >= 0, l >= 0 [iii] = np.where(hposi & lposi) Ememi = _Ememi_calc(i, currmem, sigma, deltaS, l, r2, h) @@ -407,9 +407,8 @@ cdef np.ndarray[DTYPE_t, ndim=1, negative_indices=False] _h_calc( aa = np.array([x - xend, y - yend, z-zend]) aaT = aa.T bb = np.array([xend - xstart, yend - ystart, zend - zstart]) - cc = np.dot(aaT, bb).diagonal().copy() + cc = np.dot(aaT, bb).diagonal() hh = cc / deltaS - hh[0] = 0 return hh diff --git a/LFPy/pointprocess.py b/LFPy/pointprocess.py index 02951eee..0d0803aa 100644 --- a/LFPy/pointprocess.py +++ b/LFPy/pointprocess.py @@ -121,19 +121,20 @@ def set_spike_times_w_netstim(self, noise=1., start=0., number=1E3, Generate a train of pre-synaptic stimulus times by setting up the neuron NetStim object associated with this synapse - Arguments - --------- - noise : float in [0, 1] - Fractional randomness, from deterministic to intervals that drawn - from negexp distribution (Poisson spiketimes). - start : float - ms, (most likely) start time of first spike - number : int - (average) number of spikes - interval : float - ms, (mean) time between spikes - seed : float - random seed value + kwargs: + :: + + noise : float in [0, 1] + Fractional randomness, from deterministic to intervals that drawn + from negexp distribution (Poisson spiketimes). + start : float + ms, (most likely) start time of first spike + number : int + (average) number of spikes + interval : float + ms, (mean) time between spikes + seed : float + random seed value ''' self.cell.netstimlist[-1].noise = noise self.cell.netstimlist[-1].start = start diff --git a/LFPy/recextelectrode.py b/LFPy/recextelectrode.py index 20ffb383..ca29f433 100644 --- a/LFPy/recextelectrode.py +++ b/LFPy/recextelectrode.py @@ -69,18 +69,23 @@ def __init__(self, cell=None, sigma=0.3, '''Initialize class RecExtElectrodeSetup''' self.cell = cell self.sigma = sigma - if type(x) == float or type(x) == int: + if type(x) is float or type(x) is int: self.x = np.array([x]) else: self.x = np.array(x).flatten() - if type(y) == float or type(y) == int: + if type(y) is float or type(y) is int: self.y = np.array([y]) else: self.y = np.array(y).flatten() - if type(z) == float or type(z) == int: + if type(z) is float or type(z) is int: self.z = np.array([z]) else: self.z = np.array(z).flatten() + try: + assert((self.x.size==self.y.size) and (self.x.size==self.z.size)) + except AssertionError as ae: + raise ae, "The number of elements in [x, y, z] must be identical" + self.color = color self.marker = marker if N is not None: diff --git a/documentation/sources/conf.py b/documentation/sources/conf.py index 832f828a..a18abd99 100644 --- a/documentation/sources/conf.py +++ b/documentation/sources/conf.py @@ -50,7 +50,7 @@ # The short X.Y version. version = '1.1' # The full version, including alpha/beta/rc tags. -release = '1.1.2' +release = '1.1.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index 339a5fab..d00adbd5 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ setup( name = "LFPy", - version = "1.1.2", + version = "1.1.3", maintainer = "Espen Hagen", maintainer_email = 'e.hagen@fz-juelich.de', packages = ['LFPy'],