Skip to content

Commit

Permalink
Add a new test for sAHP extraction (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
AurelienJaquier authored Dec 7, 2023
1 parent d4edc58 commit f46caab
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ test_run
MouseCells/
.ipynb_checkpoints/
coverage.xml
MouseCells_sAHP/
tests/exp_data/X/
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"the eFel library. BluePyEfe outputs protocols and features files in a "
"format that can then be used by BluePyOpt for electrical model building "
"purposes.",
packages=setuptools.find_packages(),
packages=setuptools.find_packages(exclude=["tests"]),
python_requires=">=3.8",
include_package_data=True,
author="BlueBrain Project, EPFL",
Expand Down
Empty file added tests/__init__.py
Empty file.
125 changes: 125 additions & 0 deletions tests/test_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import bluepyefe.extract
import bluepyefe.tools
from tests.utils import download_sahp_datafiles


def get_config(absolute_amplitude=False):
Expand Down Expand Up @@ -74,6 +75,74 @@ def get_config(absolute_amplitude=False):

return files_metadata, bluepyefe.extract.convert_legacy_targets(targets)

def get_sahp_config(absolute_amplitude=False):
download_sahp_datafiles()

interesting_efeatures = {
"Spikecount": {},
"mean_frequency": {},
"ISI_CV": {},
"AP1_amp": {},
"AP_width": {},
}

files_metadata1 = []
for file in glob.glob("./tests/exp_data/X/X_sAHP_ch0_*.ibw"):
files_metadata1.append(
{
"i_file": file,
"v_file": file.replace("ch0", "ch1"),
"i_unit": "A",
"v_unit": "V",
"t_unit": "s",
"dt": 0.00025,
"ljp": 14,
"ton": 10,
"tmid": 260,
"tmid2": 360,
"toff": 1360,
}
)
files_metadata2 = []
for file in glob.glob("./tests/exp_data/X/X_IDthresh_ch0_*.ibw"):
files_metadata2.append(
{
"i_file": file,
"v_file": file.replace("ch0", "ch1"),
"i_unit": "A",
"v_unit": "V",
"t_unit": "s",
"dt": 0.00025,
"ljp": 14,
}
)

files_metadata = {
"MouseNeuron1": {"sAHP": files_metadata1, "IDthresh": files_metadata2},
}

if absolute_amplitude:
targets = {
"sAHP": {
"amplitudes": [0.315, 0.225, 0.5, 0.69, 0.41, 0.595],
"tolerances": [0.01],
"efeatures": interesting_efeatures,
"location": "soma",
}
}

else:
targets = {
"sAHP": {
"amplitudes": [285, 200, 450, 625, 370, 540],
"tolerances": [10.0],
"efeatures": interesting_efeatures,
"location": "soma",
}
}

return files_metadata, bluepyefe.extract.convert_legacy_targets(targets)


class ExtractorTest(unittest.TestCase):
def test_extract(self):
Expand Down Expand Up @@ -219,6 +288,62 @@ def test_extract_absolute(self):
protocols = json.load(fp)

self.assertEqual(len(features), len(protocols))

def test_extract_sahp(self):

files_metadata, targets = get_sahp_config()

cells = bluepyefe.extract.read_recordings(files_metadata=files_metadata)

cells = bluepyefe.extract.extract_efeatures_at_targets(
cells=cells, targets=targets
)

bluepyefe.extract.compute_rheobase(cells, protocols_rheobase=["IDthresh"])

self.assertEqual(len(cells), 1)
self.assertEqual(len(cells[0].recordings), 24)
self.assertLess(abs(cells[0].rheobase - 0.1103), 0.01)

# amplitude test for one recording
# sort the recordings because they can be in any order,
# and we want to select the same one each time we test
sahp_recs = [rec for rec in cells[0].recordings if rec.protocol_name == "sAHP"]
rec1 = sorted(sahp_recs, key=lambda x: x.amp2)[1]
self.assertLess(abs(rec1.amp - 0.0953), 0.01)
self.assertLess(abs(rec1.amp2 - 0.3153), 0.01)
self.assertLess(abs(rec1.amp_rel - 86.4), 0.1)
self.assertLess(abs(rec1.amp2_rel - 285.8), 0.1)


protocols = bluepyefe.extract.group_efeatures(
cells,
targets,
use_global_rheobase=True,
protocol_mode="mean"
)

_ = bluepyefe.extract.create_feature_protocol_files(
cells=cells, protocols=protocols, output_directory="MouseCells_sAHP"
)

for protocol in protocols:
if protocol.name == "sAHP" and protocol.amplitude == 625:
for target in protocol.feature_targets:
if target.efel_feature_name == "Spikecount":
self.assertEqual(target.mean, 6)
break

bluepyefe.extract.plot_all_recordings_efeatures(
cells, protocols, output_dir="MouseCells_sAHP/"
)

with open("MouseCells_sAHP/features.json") as fp:
features = json.load(fp)
with open("MouseCells_sAHP/protocols.json") as fp:
protocols = json.load(fp)

self.assertEqual(len(features), len(protocols))


if __name__ == "__main__":
Expand Down
28 changes: 28 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Utils"""

import urllib.request
import shutil
from pathlib import Path


def download_sahp_datafiles():
"""Download data files for sAHP and IDthresh traces"""
output_dir = "./tests/exp_data/X/"
gb_url = "https://raw.githubusercontent.com/BlueBrain/SSCxEModelExamples/main/feature_extraction/input-traces/C060109A1-SR-C1/"
sahp_pathname = "X_sAHP"
sahp_ch = ["ch0", "ch1"]
sahp_numbers = list(range(320, 326))
idthresh_pathname = "X_IDthresh"
idthresh_ch = ["ch0", "ch1"]
idthresh_numbers = list(range(349, 358)) + list(range(362, 371))

sahp_paths = [f"{sahp_pathname}_{ch}_{n}.ibw" for ch in sahp_ch for n in sahp_numbers]
idthresh_paths = [f"{idthresh_pathname}_{ch}_{n}.ibw" for ch in idthresh_ch for n in idthresh_numbers]
pathnames = sahp_paths + idthresh_paths

Path(output_dir).mkdir(exist_ok=True, parents=True)
for pathname in pathnames:
output_path = f"{output_dir}{pathname}"
if not Path(output_path).is_file():
with urllib.request.urlopen(f"{gb_url}{pathname}") as response, open(output_path, "wb") as out_file:
shutil.copyfileobj(response, out_file)

0 comments on commit f46caab

Please sign in to comment.