From 380f4cf0abba38ac6f7e4fe61126f4901a602230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kili=C3=A7=20Ilkan=20Fabrice?= Date: Thu, 7 Dec 2023 19:31:58 +0100 Subject: [PATCH 1/5] Update banner link for PyPI compatibility --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 427674fd..d09f9e45 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - + @@ -73,7 +73,7 @@ the values to the user. The core of the library is written in C++, and a Python wrapper is included. At the moment we provide a way to automatically compile and install the library -as a Python module. Instructions on how to compile the eFEL as a standalone C++ +as a Python module. Instructions on how to compile the eFEL as a standalone C++ library can be found [here](http://efel.readthedocs.io/en/latest/installation.html#installing-the-c-standalone-library). @@ -83,12 +83,12 @@ Citation When you use this eFEL software for your research, we ask you to cite the following publications (this includes poster presentations): ``` - @article{efel, - title={eFEL}, + @article{efel, + title={eFEL}, DOI={10.5281/zenodo.593869}, - url={https://doi.org/10.5281/zenodo.593869} - abstractNote={The Electrophys Feature Extraction Library (eFEL) allows neuroscientists to automatically extract features from time series data recorded from neurons (both in vitro and in silico). Examples are the action potential width and amplitude in voltage traces recorded during whole-cell patch clamp experiments. The user of the library provides a set of traces and selects the features to be calculated. The library will then extract the requested features and return the values to the user.}, - publisher={Zenodo}, + url={https://doi.org/10.5281/zenodo.593869} + abstractNote={The Electrophys Feature Extraction Library (eFEL) allows neuroscientists to automatically extract features from time series data recorded from neurons (both in vitro and in silico). Examples are the action potential width and amplitude in voltage traces recorded during whole-cell patch clamp experiments. The user of the library provides a set of traces and selects the features to be calculated. The library will then extract the requested features and return the values to the user.}, + publisher={Zenodo}, author={Ranjan, Rajnish and Van Geit, Werner and Moor, Ruben and @@ -97,8 +97,8 @@ When you use this eFEL software for your research, we ask you to cite the follow Damart, Tanguy and Jaquier, Aurélien and Tuncel, Anil}, - year={2023}, - month={Jul} + year={2023}, + month={Jul} } ``` @@ -235,15 +235,15 @@ Results are in mV. Full documentation ================== -The full documentation can be found [here](http://efel.readthedocs.io) +The full documentation can be found [here](http://efel.readthedocs.io) Funding ======= -This work has been partially funded by the European Union Seventh Framework Program (FP7/2007­2013) under grant agreement no. 604102 (HBP), -the European Union’s Horizon 2020 Framework Programme for Research and Innovation under the Specific Grant Agreement No. 720270, 785907 -(Human Brain Project SGA1/SGA2) and by the EBRAINS research infrastructure, funded from the European Union’s Horizon 2020 Framework -Programme for Research and Innovation under the Specific Grant Agreement No. 945539 (Human Brain Project SGA3). -This project/research was supported by funding to the Blue Brain Project, a research center of the École polytechnique fédérale de +This work has been partially funded by the European Union Seventh Framework Program (FP7/2007­2013) under grant agreement no. 604102 (HBP), +the European Union’s Horizon 2020 Framework Programme for Research and Innovation under the Specific Grant Agreement No. 720270, 785907 +(Human Brain Project SGA1/SGA2) and by the EBRAINS research infrastructure, funded from the European Union’s Horizon 2020 Framework +Programme for Research and Innovation under the Specific Grant Agreement No. 945539 (Human Brain Project SGA3). +This project/research was supported by funding to the Blue Brain Project, a research center of the École polytechnique fédérale de Lausanne (EPFL), from the Swiss government’s ETH Board of the Swiss Federal Institutes of Technology. Copyright (c) 2009-2022 Blue Brain Project/EPFL From bd42cf441a12ef5828660b18a46db621cd7ce829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kili=C3=A7=20Ilkan=20Fabrice?= Date: Fri, 8 Dec 2023 10:15:53 +0100 Subject: [PATCH 2/5] update copyright year --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d09f9e45..e2002832 100644 --- a/README.md +++ b/README.md @@ -246,5 +246,5 @@ Programme for Research and Innovation under the Specific Grant Agreement No. 945 This project/research was supported by funding to the Blue Brain Project, a research center of the École polytechnique fédérale de Lausanne (EPFL), from the Swiss government’s ETH Board of the Swiss Federal Institutes of Technology. -Copyright (c) 2009-2022 Blue Brain Project/EPFL +Copyright (c) 2009-2024 Blue Brain Project/EPFL From cd2adde70d69ff358991d29b8dd4f98a203a292d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kili=C3=A7=20Ilkan=20Fabrice?= Date: Fri, 8 Dec 2023 10:42:36 +0100 Subject: [PATCH 3/5] include README in setup.py as long description --- setup.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index b51ce34d..c32b1a37 100644 --- a/setup.py +++ b/setup.py @@ -73,6 +73,9 @@ extra_compile_args=coverage_flags + ['-std=c++17'], extra_link_args=coverage_flags) +with open("README.md", encoding="utf-8") as f: + README = f.read() + setup( name="efel", version=versioneer.get_version(), @@ -84,14 +87,8 @@ maintainer="Werner Van Geit", maintainer_email="werner.vangeit@epfl.ch", description="Electrophys Feature Extract Library (eFEL)", - long_description="The Electrophys Feature Extract Library (eFEL) allows " - "neuroscientists to automatically extract features from time series data " - "recorded from neurons (both in vitro and in silico). " - "Examples are the action potential width and amplitude in " - "voltage traces recorded during whole-cell patch clamp experiments. " - "The user of the library provides a set of traces and selects the " - "features to be calculated. The library will then extract the requested " - "features and return the values to the user.", + long_description=README, + long_description_content_type="text/markdown", license="LGPLv3", keywords=[ 'feature', From bd62343121e5a847da5239d4d98d52b88e98321f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kili=C3=A7=20Ilkan=20Fabrice?= Date: Fri, 8 Dec 2023 11:04:45 +0100 Subject: [PATCH 4/5] add alt text to banner img tag --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e2002832..c19bfc1f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - +eFEL banner
From 1d898c8e233d1f7afd9e2e2966b557d5787b20cf Mon Sep 17 00:00:00 2001 From: anilbey Date: Mon, 11 Dec 2023 16:16:13 +0100 Subject: [PATCH 5/5] simplify the loading of input files in the io module #minor (#335) * simplify the loading of ascii file in the io module * add annotations for earlier python versions * simplify load_neo_file's logic --- efel/io.py | 121 +++----------- setup.py | 3 +- tests/test_basic.py | 335 +++++++++++---------------------------- tests/test_io.py | 130 ++------------- tests/test_pyfeatures.py | 118 ++++---------- 5 files changed, 163 insertions(+), 544 deletions(-) diff --git a/efel/io.py b/efel/io.py index a99046a1..d5afe622 100644 --- a/efel/io.py +++ b/efel/io.py @@ -1,3 +1,4 @@ +from __future__ import annotations """IO handler for eFEL""" """ @@ -18,89 +19,22 @@ along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """ +from pathlib import Path +import neo +import numpy as np -import os -# pylint:disable=E0611, F0401 -import urllib.parse as up -import urllib.request as ur +def load_ascii_input( + file_path: Path | str, delimiter: str = " " +) -> tuple[np.ndarray, np.ndarray]: + """Loads electrophysiology data from an ASCII file. -# pylint:enable=E0611,F0401 - -import mimetypes - - -def windows_compatible(func): - """Decorator allowing to use urlparse with windows.""" - - def inner(fragment_url): - """Change windows path part to url.""" - # if system is windows - if os.name == "nt": - fragment_url.replace("\\", "/") - - parsed_url = func(fragment_url) - - return parsed_url - - return inner - - -def load_fragment(fragment_url, mime_type=None): - """Load fragment - - Load a fragment (e.g. time series data) from a given URL + Returns: A tuple containing two numpy arrays, one for time and one for voltage. """ - parsed_url = windows_compatible(up.urlparse)(fragment_url) - - scheme = parsed_url.scheme - server_loc = parsed_url.netloc - path = parsed_url.path - fragment_string = parsed_url.fragment - - # reform path for windows files - if scheme == "file" and os.name == "nt": - path = ur.url2pathname(r"\\" + server_loc + path) - - if mime_type is None: - mimetypes.init() - mime_type, _ = mimetypes.guess_type(path) - if mime_type is None: - raise TypeError( - 'load_fragment: impossible to guess MIME type from url, ' - 'please specify the type manually as argument: %s' % path) - - if scheme == 'file' and os.name == 'nt': - file_handle = open(path, 'r') - elif scheme == 'file': - file_handle = open(os.path.join(server_loc, path), 'r') - - if 'text/' in mime_type: - import numpy - - if fragment_string == '': - cols = None - else: - import re - - match = re.match("col=([0-9]+)", fragment_string) - if match is None or len(match.groups()) != 1: - raise TypeError( - "load_fragment: don't understand url fragment %s" % - fragment_string) - else: - cols = int(match.groups()[0]) - 1 - - # Unfortunately we need this if statement - # Setting usecols to None throws an error in the loadtxt call - if cols is not None: - fragment_content = numpy.loadtxt(file_handle, usecols=[cols]) - else: - fragment_content = numpy.loadtxt(file_handle) - - return fragment_content - else: - raise TypeError('load_fragment: unknown mime type %s' % mime_type) + file_path = Path(file_path) + data = np.loadtxt(file_path, delimiter=delimiter) + time, voltage = data[:, 0], data[:, 1] + return time, voltage def extract_stim_times_from_neo_data(blocks, stim_start, stim_end): @@ -242,9 +176,6 @@ def load_neo_file(file_name, stim_start=None, stim_end=None, **kwargs): returned object : [Segments_1, Segments_2, ..., Segments_n] Segments_1 = [Traces_1, Traces_2, ..., Traces_n] """ - - import neo - reader = neo.io.get_io(file_name) blocks = reader.read(**kwargs) @@ -252,27 +183,23 @@ def load_neo_file(file_name, stim_start=None, stim_end=None, **kwargs): blocks, stim_start, stim_end) if stim_start is None or stim_end is None: raise ValueError( - 'No stim_start or stim_end has been found inside epochs or events.' - ' You can directly specify their value as argument "stim_start"' - ' and "stim_end"') + 'No stim_start or stim_end found in epochs or events. ' + 'Please specify "stim_start" and "stim_end" arguments.') - # this part of the code transforms the data format. + # Convert data for eFEL efel_blocks = [] for bl in blocks: efel_segments = [] for seg in bl.segments: traces = [] - count_traces = 0 - analogsignals = seg.analogsignals - - for sig in analogsignals: - traces.append({}) - traces[count_traces]['T'] = sig.times.rescale('ms').magnitude - traces[count_traces]['V'] = sig.rescale('mV').magnitude - traces[count_traces]['stim_start'] = [stim_start] - traces[count_traces]['stim_end'] = [stim_end] - count_traces += 1 - + for sig in seg.analogsignals: + trace = { + 'T': sig.times.rescale('ms').magnitude, + 'V': sig.rescale('mV').magnitude, + 'stim_start': [stim_start], + 'stim_end': [stim_end] + } + traces.append(trace) efel_segments.append(traces) efel_blocks.append(efel_segments) diff --git a/setup.py b/setup.py index c32b1a37..4cba88e9 100644 --- a/setup.py +++ b/setup.py @@ -80,8 +80,7 @@ name="efel", version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), - install_requires=['numpy>=1.6'], - extras_require={'neo': ['neo[neomatlabio]>=0.5.1']}, + install_requires=['numpy>=1.6', 'neo>=0.5.2'], packages=['efel', 'efel.pyfeatures', 'efel.units'], author="BlueBrain Project, EPFL", maintainer="Werner Van Geit", diff --git a/tests/test_basic.py b/tests/test_basic.py index 6c7e303c..cfc78988 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -31,91 +31,44 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ -import os +from pathlib import Path import numpy import pytest -_multiprocess_can_split_ = True +from efel.io import load_ascii_input -testdata_dir = os.path.join( - os.path.dirname( - os.path.abspath(__file__)), - 'testdata') - -meanfrequency1_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'mean_frequency_1.txt') - -ahptest1_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'ahptest_1.txt') - -tau20_0_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'tau20.0.csv') - -spikeoutsidestim_url = 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'spike_outside_stim.txt') - -sagtrace1_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'sagtrace_1.txt') - -zeroISIlog1_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'zero_ISI_log_slope_skip' - '95824004.abf.csv') - -derivwindow1_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'derivwindow.txt') - -dendriticAP_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'dendritic_AP.txt') - -burst1_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'init_burst1.txt') - -burst2_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'init_burst2.txt') - -burst3_url = 'file://%s' % os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'init_burst3.txt') - -spiking_from_beginning_to_end_url = 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'spiking_from_beginning_to_end.txt') +testdata_dir = Path(__file__).parent / 'testdata' +meanfrequency1_url = testdata_dir / 'basic' / 'mean_frequency_1.txt' +ahptest1_url = testdata_dir / 'basic' / 'ahptest_1.txt' +tau20_0_url = testdata_dir / 'basic' / 'tau20.0.csv' +spikeoutsidestim_url = testdata_dir / 'basic' / 'spike_outside_stim.txt' +sagtrace1_url = testdata_dir / 'basic' / 'sagtrace_1.txt' +zeroISIlog1_url = testdata_dir / 'basic' / 'zero_ISI_log_slope_skip95824004.abf.csv' +derivwindow1_url = testdata_dir / 'basic' / 'derivwindow.txt' +dendriticAP_url = testdata_dir / 'basic' / 'dendritic_AP.txt' +burst1_url = testdata_dir / 'basic' / 'init_burst1.txt' +burst2_url = testdata_dir / 'basic' / 'init_burst2.txt' +burst3_url = testdata_dir / 'basic' / 'init_burst3.txt' +spiking_from_beginning_to_end_url = ( + testdata_dir + / 'basic' + / 'spiking_from_beginning_to_end.txt' +) def load_data(data_name, interp=False, interp_dt=0.1): """Load data file""" - - import efel - trace = {} - if data_name == 'mean_frequency1': stim_start = 500.0 stim_end = 900.0 - - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) elif data_name == 'tau20.0': stim_start = 100.0 stim_end = 1000.0 - - time = efel.io.load_fragment('%s#col=1' % tau20_0_url) - voltage = efel.io.load_fragment('%s#col=2' % tau20_0_url) - + time, voltage = load_ascii_input(tau20_0_url) trace['decay_start_after_stim'] = [1.0] trace['decay_end_after_stim'] = [10.0] else: @@ -128,21 +81,16 @@ def load_data(data_name, interp=False, interp_dt=0.1): if interp: time, voltage = interpolate(time, voltage, interp_dt) - return trace, time, voltage, stim_start, stim_end def test_import(): - """basic: Test importing of eFEL""" - - # pylint: disable=W0611 - import efel # NOQA - # pylint: enable=W0611 + """basic: Test importing of eFEL.""" + import efel def test_version(): - """basic: Test if version number exists""" - + """basic: Test if version number exists.""" import efel efel.reset() @@ -150,8 +98,7 @@ def test_version(): def test_setDependencyFileLocation_wrongpath(): - """basic: Test if setDependencyFileLocation fails if path doesn't exist""" - + """basic: Test if setDependencyFileLocation fails if path doesn't exist.""" import efel efel.reset() pytest.raises( @@ -160,19 +107,17 @@ def test_setDependencyFileLocation_wrongpath(): def test_setDependencyFileLocation(): - """basic: Test if setDependencyFileLocation works""" + """basic: Test if setDependencyFileLocation works.""" import efel efel.reset() - dep_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), - 'DependencyV5_LibV5peakindices.txt') + dep_file = str(Path(__file__).parent / 'DependencyV5_LibV5peakindices.txt') efel.setDependencyFileLocation(dep_file) result = efel.getDependencyFileLocation() assert result == dep_file def test_nonexisting_feature(): - """basic: Test nonexisting feature""" - + """basic: Test nonexisting feature.""" import efel efel.reset() @@ -190,8 +135,7 @@ def test_nonexisting_feature(): def test_failing_double_feature(): - """basic: Test failing double feature""" - + """basic: Test failing double feature.""" import efel efel.reset() @@ -308,9 +252,7 @@ def test_multiprocessing_traces(): stim_start = 31.2 stim_end = 431.2 - - time1 = efel.io.load_fragment('%s#col=1' % zeroISIlog1_url) - voltage1 = efel.io.load_fragment('%s#col=2' % zeroISIlog1_url) + time1, voltage1 = load_ascii_input(zeroISIlog1_url) trace1 = {} @@ -321,10 +263,7 @@ def test_multiprocessing_traces(): feature_name = 'peak_time' - test_data_path = os.path.join( - testdata_dir, - 'basic', - 'AP_begin_indices_95810005.abf.csv') + test_data_path = testdata_dir / 'basic' / 'AP_begin_indices_95810005.abf.csv' data2 = numpy.loadtxt(test_data_path) voltage2 = data2 @@ -365,16 +304,13 @@ def test_multiprocessing_traces(): def test_consecutive_traces(): - """basic: Test if features from two different traces give other results""" - + """basic: Test if features from two different traces give other results.""" import efel efel.reset() stim_start = 31.2 stim_end = 431.2 - - time1 = efel.io.load_fragment('%s#col=1' % zeroISIlog1_url) - voltage1 = efel.io.load_fragment('%s#col=2' % zeroISIlog1_url) + time1, voltage1 = load_ascii_input(zeroISIlog1_url) trace1 = {} @@ -390,10 +326,7 @@ def test_consecutive_traces(): [trace1], [feature_name], raise_warnings=False) - test_data_path = os.path.join( - testdata_dir, - 'basic', - 'AP_begin_indices_95810005.abf.csv') + test_data_path = testdata_dir / 'basic' / 'AP_begin_indices_95810005.abf.csv' data2 = numpy.loadtxt(test_data_path) voltage2 = data2 @@ -424,10 +357,7 @@ def test_stimstart_stimend(): stim_start = 500.0 stim_end = 900.0 - - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) - + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -470,10 +400,7 @@ def test_setDerivativeThreshold(): stim_start = 500.0 stim_end = 900.0 - - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) - + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -538,8 +465,7 @@ def test_zero_ISI_log_slope_skip(): stim_start = 31.2 stim_end = 431.2 - time = efel.io.load_fragment('%s#col=1' % zeroISIlog1_url) - voltage = efel.io.load_fragment('%s#col=2' % zeroISIlog1_url) + time, voltage = load_ascii_input(zeroISIlog1_url) trace = {} trace['T'] = time @@ -557,16 +483,14 @@ def test_zero_ISI_log_slope_skip(): def test_peak_indices(): - """basic: Test peak_indices""" - + """basic: Test peak_indices.""" import efel efel.reset() stim_start = 650.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -595,8 +519,7 @@ def test_min_AHP_indices(): stim_start = 650.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -628,8 +551,7 @@ def test_min_AHP_indices_strict(): stim_start = 700.0 stim_end = 2700.0 - time = efel.io.load_fragment('%s#col=1' % ahptest1_url) - voltage = efel.io.load_fragment('%s#col=2' % ahptest1_url) + time, voltage = load_ascii_input(ahptest1_url) trace = {} @@ -657,10 +579,7 @@ def test_min_AHP_indices_single_peak(): import efel - trace_file = os.path.join( - testdata_dir, - 'basic', - 'min_AHP_values_single_peak.txt') + trace_file = testdata_dir / 'basic' / 'min_AHP_values_single_peak.txt' trace_values = numpy.loadtxt(trace_file) trace = {} @@ -689,8 +608,7 @@ def test_strict_stiminterval(): stim_start = 600.0 stim_end = 750.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -723,8 +641,7 @@ def test_ISI_log_slope(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -758,8 +675,7 @@ def test_ISI_values_noIgnore(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -798,8 +714,7 @@ def test_ISI_semilog_slope(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} trace['T'] = time @@ -828,17 +743,13 @@ def test_ISI_semilog_slope(): def test_AP_begin_indices1(): """basic: Test AP_begin_indices 1""" - import efel efel.reset() stim_start = 31.2 stim_end = 431.2 - test_data_path = os.path.join( - testdata_dir, - 'basic', - 'AP_begin_indices_95810005.abf.csv') + test_data_path = testdata_dir / 'basic' / 'AP_begin_indices_95810005.abf.csv' voltage = numpy.loadtxt(test_data_path) time = numpy.arange(len(voltage)) * 0.1 @@ -884,10 +795,7 @@ def test_AP_end_indices(): stim_start = 31.2 stim_end = 431.2 - test_data_path = os.path.join( - testdata_dir, - 'basic', - 'AP_begin_indices_95810005.abf.csv') + test_data_path = testdata_dir / 'basic' / 'AP_begin_indices_95810005.abf.csv' voltage = numpy.loadtxt(test_data_path) time = numpy.arange(len(voltage)) * 0.1 @@ -975,10 +883,7 @@ def test_ap_amplitude_outside_stim(): stim_start = 700.0 stim_end = 2700.0 - test_data_path = os.path.join( - testdata_dir, - 'basic', - 'spike_outside_stim.txt') + test_data_path = testdata_dir / 'basic' / 'spike_outside_stim.txt' data = numpy.loadtxt(test_data_path) time = data[:, 0] @@ -1016,8 +921,7 @@ def test_ap_amplitude_from_voltagebase1(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1097,13 +1001,10 @@ def test_voltagebase_median(): def test_currentbase(): """basic: Test currentbase""" - import efel efel.reset() - data = numpy.loadtxt(os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'current.txt')) + data = numpy.loadtxt(testdata_dir / 'basic' / 'current.txt') current = data[:, 1] time = data[:, 0] stim_start = 2.0 @@ -1125,14 +1026,11 @@ def test_currentbase(): def test_currentbase_median(): """basic: Test currentbase with median""" - import efel efel.reset() efel.setStrSetting("current_base_mode", "median") - data = numpy.loadtxt(os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'current.txt')) + data = numpy.loadtxt(testdata_dir / 'basic' / 'current.txt') current = data[:, 1] time = data[:, 0] stim_start = 2.0 @@ -1160,8 +1058,7 @@ def test_getDistance1(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1188,8 +1085,7 @@ def test_getDistance_error_dist(): stim_start = 400.0 stim_end = 500.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1269,8 +1165,7 @@ def test_APlast_amp(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1300,8 +1195,7 @@ def test_APlast_width(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1323,17 +1217,14 @@ def test_APlast_width(): def test_derivwindow1(): - """basic: Test DerivativeWindow""" - + """basic: Test DerivativeWindow.""" import efel efel.reset() stim_start = 100.0 stim_end = 1000.0 - time = efel.io.load_fragment('%s#col=1' % derivwindow1_url) - voltage = efel.io.load_fragment('%s#col=2' % derivwindow1_url) - + time, voltage = load_ascii_input(derivwindow1_url) trace = {} trace['T'] = time @@ -1382,8 +1273,7 @@ def test_spikecount1(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1405,17 +1295,14 @@ def test_spikecount1(): def test_spikecount_stimint1(): - """basic: Test Spikecount_stimint 1""" - + """basic: Test Spikecount_stimint 1.""" import efel efel.reset() stim_start = 700.0 stim_end = 2700.0 - time = efel.io.load_fragment('%s#col=1' % spikeoutsidestim_url) - voltage = efel.io.load_fragment('%s#col=2' % spikeoutsidestim_url) - + time, voltage = load_ascii_input(spikeoutsidestim_url) trace = {} trace['T'] = time @@ -1455,8 +1342,7 @@ def test_ohmic_inputresistance(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1491,8 +1377,7 @@ def test_sag_amplitude(): stim_start = 800.0 stim_end = 3800.0 - time = efel.io.load_fragment('%s#col=1' % sagtrace1_url) - voltage = efel.io.load_fragment('%s#col=2' % sagtrace1_url) + time, voltage = load_ascii_input(sagtrace1_url) trace = {} @@ -1529,8 +1414,7 @@ def test_sag_amplitude_pos_deflect(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1559,8 +1443,7 @@ def test_sag_ratio1(): stim_start = 800.0 stim_end = 3800.0 - time = efel.io.load_fragment('%s#col=1' % sagtrace1_url) - voltage = efel.io.load_fragment('%s#col=2' % sagtrace1_url) + time, voltage = load_ascii_input(sagtrace1_url) trace = {} @@ -1630,8 +1513,7 @@ def test_sag_ratio2(): stim_start = 800.0 stim_end = 3800.0 - time = efel.io.load_fragment('%s#col=1' % sagtrace1_url) - voltage = efel.io.load_fragment('%s#col=2' % sagtrace1_url) + time, voltage = load_ascii_input(sagtrace1_url) trace = {} @@ -1671,8 +1553,7 @@ def test_ohmic_input_resistance_vb_ssse(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1738,8 +1619,7 @@ def test_min_voltage_between_spikes1(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -1774,12 +1654,11 @@ def test_min_voltage_between_spikes1(): def test_getFeatureNames(): """basic: Test getting all feature names""" - import efel efel.reset() import json - test_data_path = os.path.join(testdata_dir, '..', 'featurenames.json') + test_data_path = testdata_dir.parent / 'featurenames.json' with open(test_data_path, 'r') as featurenames_json: expected_featurenames = json.load(featurenames_json) assert set(efel.getFeatureNames()) == set(expected_featurenames) @@ -1787,7 +1666,6 @@ def test_getFeatureNames(): def test_getFeatureNameExists(): """basic: Test FeatureNameExists""" - import efel efel.reset() assert efel.FeatureNameExists('voltage_base') @@ -2014,8 +1892,7 @@ def test_sag_time_constant(): stim_start = 800.0 stim_end = 3800.0 - time = efel.io.load_fragment('%s#col=1' % sagtrace1_url) - voltage = efel.io.load_fragment('%s#col=2' % sagtrace1_url) + time, voltage = load_ascii_input(sagtrace1_url) time, voltage = interpolate(time, voltage, interp_dt) trace = {} @@ -2059,8 +1936,7 @@ def test_getmeanfeaturevalues(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -2091,8 +1967,7 @@ def test_mean_AP_amplitude(): stim_start = 500.0 stim_end = 900.0 - time = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) - voltage = efel.io.load_fragment('%s#col=2' % meanfrequency1_url) + time, voltage = load_ascii_input(meanfrequency1_url) trace = {} @@ -2342,8 +2217,7 @@ def test_min_between_peaks_indices(): stim_start = 200.0 stim_end = 1200.0 - time = efel.io.load_fragment('%s#col=1' % dendriticAP_url) - voltage = efel.io.load_fragment('%s#col=2' % dendriticAP_url) + time, voltage = load_ascii_input(dendriticAP_url) trace = {} trace['T'] = time @@ -2373,8 +2247,7 @@ def test_min_between_peaks_values(): stim_start = 200.0 stim_end = 1200.0 - time = efel.io.load_fragment('%s#col=1' % dendriticAP_url) - voltage = efel.io.load_fragment('%s#col=2' % dendriticAP_url) + time, voltage = load_ascii_input(dendriticAP_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -2409,8 +2282,7 @@ def test_AP_width_between_threshold(): stim_start = 200.0 stim_end = 1200.0 - time = efel.io.load_fragment('%s#col=1' % dendriticAP_url) - voltage = efel.io.load_fragment('%s#col=2' % dendriticAP_url) + time, voltage = load_ascii_input(dendriticAP_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -2454,8 +2326,7 @@ def test_AP_width_between_threshold_strict(): stim_start = 200.0 stim_end = 1200.0 - time = efel.io.load_fragment('%s#col=1' % dendriticAP_url) - voltage = efel.io.load_fragment('%s#col=2' % dendriticAP_url) + time, voltage = load_ascii_input(dendriticAP_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -2516,8 +2387,7 @@ def test_burst_mean_freq(): import efel efel.reset() - time = efel.io.load_fragment('%s#col=1' % url) - voltage = efel.io.load_fragment('%s#col=2' % url) + time, voltage = load_ascii_input(url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -2561,10 +2431,8 @@ def test_segfault_in_AP_begin_width(): stim_end = 140.0 trace = {} - trace['T'] = efel.io.load_fragment( - '%s#col=1' % spiking_from_beginning_to_end_url) - trace['V'] = efel.io.load_fragment( - '%s#col=2' % spiking_from_beginning_to_end_url) + trace['T'], trace['V'] = load_ascii_input( + spiking_from_beginning_to_end_url) trace['stim_start'] = [stim_start] trace['stim_end'] = [stim_end] @@ -2603,8 +2471,7 @@ def test_interburst_voltage(): import efel efel.reset() - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -2730,8 +2597,7 @@ def test_time_constant(): stim_start = 800.0 stim_end = 3800.0 - time = efel.io.load_fragment('%s#col=1' % sagtrace1_url) - voltage = efel.io.load_fragment('%s#col=2' % sagtrace1_url) + time, voltage = load_ascii_input(sagtrace1_url) trace = {} trace['T'] = time @@ -2975,8 +2841,7 @@ def test_steady_state_hyper(): stim_start = 800.0 stim_end = 3800.0 - time = efel.io.load_fragment('%s#col=1' % sagtrace1_url) - voltage = efel.io.load_fragment('%s#col=2' % sagtrace1_url) + time, voltage = load_ascii_input(sagtrace1_url) trace = {} @@ -3221,8 +3086,7 @@ def test_burst_indices(): efel.reset() efel.setIntSetting('ignore_first_ISI', 0) - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -3258,8 +3122,7 @@ def test_strict_burst_mean_freq(): efel.reset() efel.setIntSetting('ignore_first_ISI', 0) - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -3306,8 +3169,7 @@ def test_strict_burst_number(): efel.reset() efel.setIntSetting('ignore_first_ISI', 0) - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -3355,8 +3217,7 @@ def test_strict_interburst_voltage(): efel.reset() efel.setIntSetting('ignore_first_ISI', 0) - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -3396,8 +3257,7 @@ def test_AP_width_spike_before_stim_start(): stim_start = 700.0 stim_end = 2700.0 - time = efel.io.load_fragment('%s#col=1' % spikeoutsidestim_url) - voltage = efel.io.load_fragment('%s#col=2' % spikeoutsidestim_url) + time, voltage = load_ascii_input(spikeoutsidestim_url) trace = {} @@ -3460,8 +3320,7 @@ def test_ADP_peak_amplitude(): stim_start = 250.0 stim_end = 1600.0 - time = efel.io.load_fragment('%s#col=1' % burst2_url) - voltage = efel.io.load_fragment('%s#col=2' % burst2_url) + time, voltage = load_ascii_input(burst2_url) _, interp_voltage = interpolate(time, voltage, 0.1) @@ -3541,8 +3400,7 @@ def test_interburst_min_values(): import efel efel.reset() - time = efel.io.load_fragment('%s#col=1' % url) - voltage = efel.io.load_fragment('%s#col=2' % url) + time, voltage = load_ascii_input(url) _, interp_voltage = interpolate(time, voltage, 0.1) @@ -3596,8 +3454,7 @@ def test_time_to_interburst_min(): import efel efel.reset() - time = efel.io.load_fragment('%s#col=1' % url) - voltage = efel.io.load_fragment('%s#col=2' % url) + time, voltage = load_ascii_input(url) interp_time, interp_voltage = interpolate(time, voltage, 0.1) @@ -3685,8 +3542,7 @@ def test_postburst_min_values(): # use this to have all spikes in burst for burst3_url case efel.setDoubleSetting('strict_burst_factor', 4.0) - time = efel.io.load_fragment('%s#col=1' % url) - voltage = efel.io.load_fragment('%s#col=2' % url) + time, voltage = load_ascii_input(url) interp_time, interp_voltage = interpolate(time, voltage, 0.1) @@ -3742,8 +3598,7 @@ def test_spikes_per_burst_diff(): import efel efel.reset() - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -3768,8 +3623,7 @@ def test_spikes_in_burst1_burst2_diff(): import efel efel.reset() - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} @@ -3796,8 +3650,7 @@ def test_spikes_in_burst1_burstlast_diff(): import efel efel.reset() - time = efel.io.load_fragment('%s#col=1' % burst1_url) - voltage = efel.io.load_fragment('%s#col=2' % burst1_url) + time, voltage = load_ascii_input(burst1_url) time, voltage = interpolate(time, voltage, 0.1) trace = {} diff --git a/tests/test_io.py b/tests/test_io.py index 073b36d2..47b8cd76 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -1,129 +1,31 @@ """Test eFEL io module""" -# pylint: disable=F0401 - import os +from pathlib import Path +import numpy as np import pytest -testdata_dir = os.path.join( - os.path.dirname( - os.path.abspath(__file__)), - 'testdata') - -neo_test_files_dir = os.path.join( - os.path.dirname( - os.path.abspath(__file__)), - 'neo_test_files') - -meanfrequency1_filename = os.path.join(testdata_dir, - 'basic', - 'mean_frequency_1.txt') -meanfrequency1_url = 'file://%s' % meanfrequency1_filename - - -def test_import(): - """io: Testing import""" - - # pylint: disable=W0611 - import efel.io # NOQA - # pylint: enable=W0611 - - -def test_import_without_urlparse(): - """io: Testing import without urlparse""" - - # The only purpose of this test is to get the code coverage to 100% :-) - - import sys - del sys.modules['efel.io'] - - python_version = sys.version_info[0] - - if python_version < 3: - import __builtin__ - else: - import builtins as __builtin__ - realimport = __builtin__.__import__ - - def myimport(name, *args): # global_s, local, fromlist, level): - """Override import""" - if name == 'urlparse': - raise ImportError - return realimport(name, *args) # global_s, local, fromlist, level) - __builtin__.__import__ = myimport - - try: - import urllib.parse # NOQA - urllibparse_import_fails = False - except ImportError: - urllibparse_import_fails = True - - if urllibparse_import_fails: - pytest.raises(ImportError, __builtin__.__import__, 'efel.io') - else: - import efel.io # NOQA - - __builtin__.__import__ = realimport - - -def test_load_fragment_column_txt1(): - """io: Test loading of one column from txt file""" - - import efel - import numpy - - time_io = efel.io.load_fragment('%s#col=1' % meanfrequency1_url) +from efel.io import load_ascii_input - time_numpy = numpy.loadtxt(meanfrequency1_filename, usecols=[0]) - numpy.testing.assert_array_equal(time_io, time_numpy) +testdata_dir = Path(__file__).parent / 'testdata' +neo_test_files_dir = Path(__file__).parent / 'neo_test_files' +meanfrequency1_filename = testdata_dir / 'basic' / 'mean_frequency_1.txt' +meanfrequency1_url = str(meanfrequency1_filename) -def test_load_fragment_strange_mimetype(): - """io: Test loading file with unresolvable mime type""" - - import efel - - pytest.raises( - TypeError, - efel.io.load_fragment, 'file://strange.mimetype') - - -def test_load_fragment_wrong_fragment_format(): - """io: Test loading file wrong fragment format""" - - import efel - - pytest.raises( - TypeError, - efel.io.load_fragment, - '%s#co=1' % - meanfrequency1_url) - - -def test_load_fragment_wrong_mimetype(): - """io: Test loading fragment wrong mime type""" - - import efel - - pytest.raises( - TypeError, - efel.io.load_fragment, - '%s#col=1' % meanfrequency1_url, mime_type='application/json') - - -def test_load_fragment_allcolumns(): - """io: Test loading fragment without specifying columns""" - - import efel - import numpy - - time_io = efel.io.load_fragment('%s' % meanfrequency1_url) +def test_load_ascii_input(): + """Test loading of data from an ASCII file and splitting into time and voltage.""" + time, voltage = load_ascii_input(meanfrequency1_url) - time_numpy = numpy.loadtxt(meanfrequency1_filename) + # Load data using numpy for comparison + expected_data = np.loadtxt(meanfrequency1_url, delimiter=' ') + expected_time, expected_voltage = expected_data[:, 0], expected_data[:, 1] - numpy.testing.assert_array_equal(time_io, time_numpy) + # Assert that the arrays are equal + np.testing.assert_array_equal(time, expected_time) + np.testing.assert_array_equal(voltage, expected_voltage) def test_load_neo_file_stim_time_arg(): diff --git a/tests/test_pyfeatures.py b/tests/test_pyfeatures.py index df451837..006ba2dd 100644 --- a/tests/test_pyfeatures.py +++ b/tests/test_pyfeatures.py @@ -29,113 +29,60 @@ """ -import os +from pathlib import Path import numpy import efel +from efel.io import load_ascii_input -testdata_dir = os.path.join( - os.path.dirname( - os.path.abspath(__file__)), - 'testdata') +testdata_dir = Path(__file__).parent / 'testdata' traces_data = { 'mean_frequency1': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'mean_frequency_1.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'basic' / 'mean_frequency_1.txt', 'stim_start': 500, 'stim_end': 900}, 'init_burst1': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'init_burst1.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'basic' / 'init_burst1.txt', 'stim_start': 250, 'stim_end': 1600}, 'init_burst2': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'init_burst2.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'basic' / 'init_burst2.txt', 'stim_start': 250, 'stim_end': 1600}, 'init_burst3': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'init_burst3.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'basic' / 'init_burst3.txt', 'stim_start': 250, 'stim_end': 1600}, 'init_burst_sahp_error': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'initburst_sahp_error.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'basic' / 'initburst_sahp_error.txt', 'stim_start': 800, 'stim_end': 1600}, 'depol_block_subthresh': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'allfeatures', - 'testdb2data.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'allfeatures' / 'testdb2data.txt', 'stim_start': 419.995, 'stim_end': 1419.995}, 'depol_block_subthresh_hyperpol': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'allfeatures', - 'testdb1data.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'allfeatures' / 'testdb1data.txt', 'stim_start': 419.995, 'stim_end': 1419.995}, 'depol_block_spiking': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'allfeatures', - 'testdb3data.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'allfeatures' / 'testdb3data.txt', 'stim_start': 419.995, 'stim_end': 1419.995}, 'depol_block_db': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'allfeatures', - 'testdbdata.txt'), - 't_col': 1, - 'v_col': 2, + 'url': testdata_dir / 'allfeatures' / 'testdbdata.txt', 'stim_start': 419.995, 'stim_end': 1419.995}, 'current': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'current.txt'), + 'url': testdata_dir / 'basic' / 'current.txt', 't_col': 1, 'i_col': 2, 'v_col': 3, 'stim_start': 700.0, 'stim_end': 2700.0}, 'impedance': { - 'url': 'file://%s' % os.path.join( - os.path.abspath(testdata_dir), - 'basic', - 'impedance.txt'), + 'url': testdata_dir / 'basic' / 'impedance.txt', 't_col': 1, 'v_col': 2, 'i_col': 3, @@ -146,35 +93,35 @@ def _load_trace(trace_name): """Load trace with a certain name""" - trace_data = traces_data[trace_name] url = trace_data['url'] trace = { - 'T': efel.io.load_fragment( - '%s#col=%d' % - (url, trace_data['t_col'])), - 'V': efel.io.load_fragment( - '%s#col=%d' % - (url, trace_data['v_col'])), 'stim_start': [trace_data['stim_start']], 'stim_end': [trace_data['stim_end']], } - if trace_name == "current": - trace['T'] = trace['T'] * 1000.0 # s -> ms - if 'i_col' in trace_data: - trace['I'] = efel.io.load_fragment('%s#col=%d' % - (url, trace_data['i_col'])) + data = numpy.loadtxt(url) + if trace_data['i_col'] == 3: # I is the last + trace['T'] = data[:, 0] + trace['V'] = data[:, 1] + trace['I'] = data[:, 2] + else: # V is the last + trace['T'] = data[:, 0] + trace['V'] = data[:, 2] + trace['I'] = data[:, 1] + if trace_name == "current": + trace['T'] = trace['T'] * 1000.0 # s -> ms + else: + trace['T'], trace['V'] = load_ascii_input(url) return trace def _test_expected_value(feature_name, expected_values): """Test expected values for feature""" - for trace_name, expected_value in expected_values.items(): trace = _load_trace(trace_name) @@ -191,7 +138,6 @@ def _test_expected_value(feature_name, expected_values): def test_initburst_sahp(): """pyfeatures: Test initburst_sahp feature""" - feature_name = 'initburst_sahp' expected_values = { 'mean_frequency1': None, 'init_burst1': [-69.19999695], @@ -203,7 +149,6 @@ def test_initburst_sahp(): def test_initburst_sahp_argmin_error(): """pyfeatures: Test initburst_sahp argmin error""" - feature_name = 'initburst_sahp' expected_values = { 'init_burst_sahp_error': None} @@ -213,7 +158,6 @@ def test_initburst_sahp_argmin_error(): def test_initburst_sahp_vb(): """pyfeatures: Test initburst_sahp_vb feature""" - feature_name = 'initburst_sahp_vb' expected_values = { 'mean_frequency1': None, 'init_burst1': [13.80537756], @@ -225,7 +169,6 @@ def test_initburst_sahp_vb(): def test_initburst_sahp_ssse(): """pyfeatures: Test initburst_sahp_ssse feature""" - feature_name = 'initburst_sahp_ssse' expected_values = { 'mean_frequency1': None, 'init_burst1': [-11.33152931], @@ -328,7 +271,6 @@ def test_pydistance(): def test_pydistance_featurefail(): """pyfeatures: Test failure of feature in getdistance""" - mf1_trace = _load_trace('mean_frequency1') feature_name = 'initburst_sahp' @@ -346,7 +288,6 @@ def test_pydistance_featurefail(): def test_interpolate_current(): """pyfeatures: Test interpolation of current""" - def interpolate(time, voltage, new_dt): """Interpolate voltage to new dt""" @@ -355,9 +296,7 @@ def interpolate(time, voltage, new_dt): return interp_time, interp_voltage - data = numpy.loadtxt(os.path.join(os.path.abspath(testdata_dir), - 'basic', - 'current.txt')) + data = numpy.loadtxt(testdata_dir / 'basic' / 'current.txt') time = data[:, 0] * 1000.0 # -> ms current = data[:, 1] voltage = data[:, 2] @@ -380,7 +319,6 @@ def interpolate(time, voltage, new_dt): def test_impedance(): """pyfeatures: Test impedance feature""" - feature_name = "impedance" expected_values = {feature_name: 4.615384615384615}