diff --git a/bluepyopt/tests/test_ephys/test_create_acc.py b/bluepyopt/tests/test_ephys/test_create_acc.py index 649b0af5..a2b51ef4 100644 --- a/bluepyopt/tests/test_ephys/test_create_acc.py +++ b/bluepyopt/tests/test_ephys/test_create_acc.py @@ -2,46 +2,47 @@ # pylint: disable=W0212 +import json import os -import sys import pathlib import re -import json +import sys import tempfile -from bluepyopt.ephys.acc import arbor, ArbLabel -from bluepyopt.ephys.morphologies import ArbFileMorphology -from bluepyopt.ephys.parameterscalers import NrnSegmentSomaDistanceScaler - -from . import utils +import pytest from bluepyopt import ephys from bluepyopt.ephys import create_acc -from bluepyopt.ephys.create_acc import (Nrn2ArbParamAdapter, - Nrn2ArbMechGrouper, - ArbNmodlMechFormatter) +from bluepyopt.ephys.acc import ArbLabel, arbor +from bluepyopt.ephys.create_acc import ( + ArbNmodlMechFormatter, + Nrn2ArbMechGrouper, + Nrn2ArbParamAdapter, +) +from bluepyopt.ephys.morphologies import ArbFileMorphology +from bluepyopt.ephys.parameterscalers import NrnSegmentSomaDistanceScaler -import pytest +from . import utils DEFAULT_ARBOR_REGION_ORDER = [ - ('soma', 1), - ('axon', 2), - ('dend', 3), - ('apic', 4), - ('myelin', 5)] + ("soma", 1), + ("axon", 2), + ("dend", 3), + ("apic", 4), + ("myelin", 5), +] -testdata_dir = pathlib.Path(__file__).parent.joinpath( - 'testdata') +testdata_dir = pathlib.Path(__file__).parent.joinpath("testdata") @pytest.mark.unit def test_read_templates(): """Unit test for _read_templates function.""" - template_dir = testdata_dir / 'acc/templates' + template_dir = testdata_dir / "acc/templates" template_filename = "*_template.jinja2" templates = create_acc._read_templates(template_dir, template_filename) - assert templates.keys() == {'label_dict.acc', 'cell.json', 'decor.acc'} + assert templates.keys() == {"label_dict.acc", "cell.json", "decor.acc"} with pytest.raises(FileNotFoundError): create_acc._read_templates("DOES_NOT_EXIST", template_filename) @@ -52,13 +53,14 @@ def test_Nrn2ArbParamAdapter_param_name(): """Test Neuron to Arbor parameter mapping.""" # Identity mech_param_name = "gSKv3_1bar_SKv3_1" - assert Nrn2ArbParamAdapter._param_name(mech_param_name) \ - == mech_param_name + assert Nrn2ArbParamAdapter._param_name(mech_param_name) == mech_param_name # Non-trivial transformation global_property_name = "v_init" - assert Nrn2ArbParamAdapter._param_name(global_property_name) \ + assert ( + Nrn2ArbParamAdapter._param_name(global_property_name) == "membrane-potential" + ) @pytest.mark.unit @@ -75,7 +77,8 @@ def test_Nrn2ArbParamAdapter_param_value(): # Non-trivial name and value/units transformation global_property = create_acc.Location(name="celsius", value=34) assert Nrn2ArbParamAdapter._param_value(global_property) == ( - "307.14999999999998") + "307.14999999999998" + ) @pytest.mark.unit @@ -85,38 +88,39 @@ def test_Nrn2ArbParamAdapter_format(): mech_param = create_acc.Location(name="gSKv3_1bar_SKv3_1", value="1.025") mech = "SKv3_1" arb_mech_param = create_acc.Location(name="gSKv3_1bar", value="1.025") - assert ( - Nrn2ArbParamAdapter.format( - mech_param, mechs=[mech]) - == (mech, arb_mech_param) + assert Nrn2ArbParamAdapter.format(mech_param, mechs=[mech]) == ( + mech, + arb_mech_param, ) # Non-unique mapping to mechanisms with pytest.raises(create_acc.CreateAccException): - Nrn2ArbParamAdapter.format( - mech_param, mechs=["SKv3_1", "1"]) + Nrn2ArbParamAdapter.format(mech_param, mechs=["SKv3_1", "1"]) # Global property with non-trivial transformation global_property = create_acc.Location(name="celsius", value="0") mech = None arb_global_property = create_acc.Location( - name="temperature-kelvin", value="273.14999999999998") + name="temperature-kelvin", value="273.14999999999998" + ) # Non-trivial name and value/units transformation - assert Nrn2ArbParamAdapter.format(global_property, []) == \ - (mech, arb_global_property) + assert Nrn2ArbParamAdapter.format(global_property, []) == ( + mech, + arb_global_property, + ) # Inhomogeneuos mechanism parameter apical_region = ArbLabel("region", "apic", "(tag 4)") param_scaler = NrnSegmentSomaDistanceScaler( - name='soma-distance-scaler', - distribution='(-0.8696 + 2.087*math.exp(({distance})*0.0031))*{value}' + name="soma-distance-scaler", + distribution="(-0.8696 + 2.087*math.exp(({distance})*0.0031))*{value}", ) iexpr_param = create_acc.RangeExpr( location=apical_region, name="gkbar_hh", value="0.025", - value_scaler=param_scaler + value_scaler=param_scaler, ) mech = "hh" arb_iexpr_param = create_acc.RangeExpr( @@ -125,50 +129,56 @@ def test_Nrn2ArbParamAdapter_format(): value="0.025", value_scaler=param_scaler, ) - assert ( - Nrn2ArbParamAdapter.format( - iexpr_param, mechs=[mech]) - == (mech, arb_iexpr_param) + assert Nrn2ArbParamAdapter.format(iexpr_param, mechs=[mech]) == ( + mech, + arb_iexpr_param, ) # Point process mechanism parameter loc = ephys.locations.ArbLocsetLocation( - name='somacenter', - locset='(location 0 0.5)') + name="somacenter", locset="(location 0 0.5)" + ) mech = ephys.mechanisms.NrnMODPointProcessMechanism( - name='expsyn', - suffix='ExpSyn', - locations=[loc]) + name="expsyn", suffix="ExpSyn", locations=[loc] + ) mech_loc = ephys.locations.NrnPointProcessLocation( - 'expsyn_loc', - pprocess_mech=mech) + "expsyn_loc", pprocess_mech=mech + ) point_expr_param = create_acc.PointExpr( - name="tau", value="10", point_loc=[mech_loc]) + name="tau", value="10", point_loc=[mech_loc] + ) arb_point_expr_param = create_acc.PointExpr( - name="tau", value="10", point_loc=[mech_loc]) - assert ( - Nrn2ArbParamAdapter.format( - point_expr_param, mechs=[mech]) - == (mech, arb_point_expr_param) + name="tau", value="10", point_loc=[mech_loc] + ) + assert Nrn2ArbParamAdapter.format(point_expr_param, mechs=[mech]) == ( + mech, + arb_point_expr_param, ) @pytest.mark.unit def test_Nrn2ArbMechGrouper_format_params_and_group_by_mech(): """Test grouping of parameters by mechanism.""" - params = [create_acc.Location(name="gSKv3_1bar_SKv3_1", value="1.025"), - create_acc.Location(name="ena", value="-30")] + params = [ + create_acc.Location(name="gSKv3_1bar_SKv3_1", value="1.025"), + create_acc.Location(name="ena", value="-30"), + ] mechs = ["SKv3_1"] - local_mechs = Nrn2ArbMechGrouper.\ - _format_params_and_group_by_mech(params, mechs) - assert local_mechs == \ - {None: [create_acc.Location(name="ion-reversal-potential \"na\"", - value="-30")], - "SKv3_1": [create_acc.Location(name="gSKv3_1bar", value="1.025")]} + local_mechs = Nrn2ArbMechGrouper._format_params_and_group_by_mech( + params, mechs + ) + assert local_mechs == { + None: [ + create_acc.Location( + name='ion-reversal-potential "na"', value="-30" + ) + ], + "SKv3_1": [create_acc.Location(name="gSKv3_1bar", value="1.025")], + } @pytest.mark.unit @@ -177,10 +187,13 @@ def test_Nrn2ArbMechGrouper_process_global(): params = {"ki": 3, "v_init": -65} global_mechs = Nrn2ArbMechGrouper.process_global(params) assert global_mechs == { - None: [create_acc.Location(name="ion-internal-concentration \"k\"", - value="3"), - create_acc.Location(name="membrane-potential", - value="-65")]} + None: [ + create_acc.Location( + name='ion-internal-concentration "k"', value="3" + ), + create_acc.Location(name="membrane-potential", value="-65"), + ] + } @pytest.mark.unit @@ -188,22 +201,23 @@ def test_Nrn2ArbMechGrouper_is_global_property(): """Test adapting local parameters from Neuron to Arbor.""" all_regions = ArbLabel("region", "all_regions", "(all)") param = create_acc.Location(name="axial-resistivity", value="1") - assert Nrn2ArbMechGrouper._is_global_property( - all_regions, param) is True + assert Nrn2ArbMechGrouper._is_global_property(all_regions, param) is True soma_region = ArbLabel("region", "soma", "(tag 1)") - assert Nrn2ArbMechGrouper._is_global_property( - soma_region, param) is False + assert Nrn2ArbMechGrouper._is_global_property(soma_region, param) is False @pytest.mark.unit def test_separate_global_properties(): """Test separating global properties from label-specific mechs.""" all_regions = ArbLabel("region", "all_regions", "(all)") - mechs = {None: [create_acc.Location(name="axial-resistivity", value="1")], - "SKv3_1": [create_acc.Location(name="gSKv3_1bar", value="1.025")]} - local_mechs, global_properties = \ + mechs = { + None: [create_acc.Location(name="axial-resistivity", value="1")], + "SKv3_1": [create_acc.Location(name="gSKv3_1bar", value="1.025")], + } + local_mechs, global_properties = ( Nrn2ArbMechGrouper._separate_global_properties(all_regions, mechs) + ) assert local_mechs == {None: [], "SKv3_1": mechs["SKv3_1"]} assert global_properties == {None: mechs[None]} @@ -214,23 +228,28 @@ def test_Nrn2ArbMechGrouper_process_local(): all_regions = ArbLabel("region", "all_regions", "(all)") soma_region = ArbLabel("region", "soma", "(tag 1)") params = [ - (all_regions, - [create_acc.Location(name="cm", value="100")]), - (soma_region, - [create_acc.Location(name="v_init", value="-65"), - create_acc.Location(name="gSKv3_1bar_SKv3_1", value="1.025")]) + (all_regions, [create_acc.Location(name="cm", value="100")]), + ( + soma_region, + [ + create_acc.Location(name="v_init", value="-65"), + create_acc.Location(name="gSKv3_1bar_SKv3_1", value="1.025"), + ], + ), ] channels = {all_regions: [], soma_region: ["SKv3_1"]} - local_mechs, global_properties = \ - Nrn2ArbMechGrouper.process_local(params, channels) + local_mechs, global_properties = Nrn2ArbMechGrouper.process_local( + params, channels + ) assert local_mechs.keys() == {all_regions, soma_region} assert local_mechs[all_regions] == {None: []} assert local_mechs[soma_region] == { None: [create_acc.Location(name="membrane-potential", value="-65")], - "SKv3_1": [create_acc.Location(name="gSKv3_1bar", value="1.025")] + "SKv3_1": [create_acc.Location(name="gSKv3_1bar", value="1.025")], } assert global_properties == { - None: [create_acc.Location(name="membrane-capacitance", value="1")]} + None: [create_acc.Location(name="membrane-capacitance", value="1")] + } @pytest.mark.unit @@ -239,8 +258,8 @@ def test_ArbNmodlMechFormatter_load_mech_catalogue_meta(): nmodl_formatter = ArbNmodlMechFormatter(None) assert isinstance(nmodl_formatter.cats, dict) - assert nmodl_formatter.cats.keys() == {'BBP', 'default', 'allen'} - assert "Ca_HVA" in nmodl_formatter.cats['BBP'] + assert nmodl_formatter.cats.keys() == {"BBP", "default", "allen"} + assert "Ca_HVA" in nmodl_formatter.cats["BBP"] @pytest.mark.unit @@ -261,7 +280,7 @@ def test_ArbNmodlMechFormatter_translate_density(): value="0.029999999999999999", scale=( "(add (scalar -0.62109375) (mul (scalar 0.546875) " - "(log (add (mul (distance (region \"soma\"))" + '(log (add (mul (distance (region "soma"))' " (scalar 0.421875) ) (scalar 1.25) ) ) ) )" ), ), @@ -273,7 +292,7 @@ def test_ArbNmodlMechFormatter_translate_density(): value="0.029999999999999999", scale=( "(add (scalar -0.62109375) (mul (scalar 0.546875) " - "(log (add (mul (distance (region \"soma\"))" + '(log (add (mul (distance (region "soma"))' " (scalar 0.421875) ) (scalar 1.25) ) ) ) )" ), ), @@ -281,8 +300,7 @@ def test_ArbNmodlMechFormatter_translate_density(): } nmodl_formatter = ArbNmodlMechFormatter(None) translated_mechs = nmodl_formatter.translate_density(mechs) - assert translated_mechs.keys() == {"default::hh", - "default::pas/e=0.25"} + assert translated_mechs.keys() == {"default::hh", "default::pas/e=0.25"} assert translated_mechs["default::hh"] == mechs["hh"] assert translated_mechs["default::pas/e=0.25"] == mechs["pas"][1:] @@ -291,21 +309,21 @@ def test_ArbNmodlMechFormatter_translate_density(): def test_arb_populate_label_dict(): """Unit test for _populate_label_dict.""" local_mechs = {ArbLabel("region", "all", "(all)"): {}} - local_scaled_mechs = { - ArbLabel("region", "first_branch", "(branch 0)"): {}} + local_scaled_mechs = {ArbLabel("region", "first_branch", "(branch 0)"): {}} pprocess_mechs = {} - label_dict = create_acc._arb_populate_label_dict(local_mechs, - local_scaled_mechs, - pprocess_mechs) + label_dict = create_acc._arb_populate_label_dict( + local_mechs, local_scaled_mechs, pprocess_mechs + ) assert label_dict.keys() == {"all", "first_branch"} with pytest.raises(create_acc.CreateAccException): other_pprocess_mechs = { - ArbLabel("region", "first_branch", "(branch 1)"): {}} - create_acc._arb_populate_label_dict(local_mechs, - local_scaled_mechs, - other_pprocess_mechs) + ArbLabel("region", "first_branch", "(branch 1)"): {} + } + create_acc._arb_populate_label_dict( + local_mechs, local_scaled_mechs, other_pprocess_mechs + ) @pytest.mark.unit @@ -314,11 +332,16 @@ def test_create_acc(): mech = utils.make_mech() parameters = utils.make_parameters() - acc = create_acc.create_acc([mech, ], parameters, - morphology='CCell.swc', - template_name='CCell') + acc = create_acc.create_acc( + [ + mech, + ], + parameters, + morphology="CCell.swc", + template_name="CCell", + ) - ref_dir = testdata_dir / 'acc/CCell' + ref_dir = testdata_dir / "acc/CCell" cell_json = "CCell.json" decor_acc = "CCell_decor.acc" label_dict_acc = "CCell_label_dict.acc" @@ -326,22 +349,22 @@ def test_create_acc(): # Testing keys assert cell_json in acc cell_json_dict = json.loads(acc[cell_json]) - assert 'cell_model_name' in cell_json_dict - assert 'produced_by' in cell_json_dict - assert 'morphology' in cell_json_dict - assert 'label_dict' in cell_json_dict - assert 'decor' in cell_json_dict + assert "cell_model_name" in cell_json_dict + assert "produced_by" in cell_json_dict + assert "morphology" in cell_json_dict + assert "label_dict" in cell_json_dict + assert "decor" in cell_json_dict # Testing values with open(ref_dir / cell_json) as f: ref_cell_json = json.load(f) for k in ref_cell_json: - if k != 'produced_by': + if k != "produced_by": assert ref_cell_json[k] == cell_json_dict[k] # Testing building blocks assert decor_acc in acc - assert acc[decor_acc].startswith('(arbor-component') - assert '(decor' in acc[decor_acc] + assert acc[decor_acc].startswith("(arbor-component") + assert "(decor" in acc[decor_acc] # Testing values with open(ref_dir / decor_acc) as f: ref_decor = f.read() @@ -349,19 +372,20 @@ def test_create_acc(): # Testing building blocks assert label_dict_acc in acc - assert acc[label_dict_acc].startswith('(arbor-component') - assert '(label-dict' in acc[label_dict_acc] - matches = re.findall(r'\(region-def "(?P\w+)" \(tag (?P\d+)\)\)', - acc[label_dict_acc]) + assert acc[label_dict_acc].startswith("(arbor-component") + assert "(label-dict" in acc[label_dict_acc] + matches = re.findall( + r'\(region-def "(?P\w+)" \(tag (?P\d+)\)\)', + acc[label_dict_acc], + ) for pos, loc_tag in enumerate(DEFAULT_ARBOR_REGION_ORDER): assert matches[pos][0] == loc_tag[0] assert matches[pos][1] == str(loc_tag[1]) # Testing values - ref_labels = arbor.load_component( - ref_dir / label_dict_acc).component + ref_labels = arbor.load_component(ref_dir / label_dict_acc).component with tempfile.TemporaryDirectory() as test_dir: test_labels_filename = pathlib.Path(test_dir).joinpath(label_dict_acc) - with open(test_labels_filename, 'w') as f: + with open(test_labels_filename, "w") as f: f.write(acc[label_dict_acc]) test_labels = arbor.load_component(test_labels_filename).component assert dict(ref_labels.items()) == dict(test_labels.items()) @@ -375,41 +399,46 @@ def test_create_acc_filename(): custom_param_val = str(__file__) acc = create_acc.create_acc( - [mech, ], - parameters, morphology='CCell.asc', - template_name='CCell', - template_filename='acc/templates/*_template.jinja2', + [ + mech, + ], + parameters, + morphology="CCell.asc", + template_name="CCell", + template_filename="acc/templates/*_template.jinja2", template_dir=testdata_dir, - custom_jinja_params={ - 'custom_param': custom_param_val}) + custom_jinja_params={"custom_param": custom_param_val}, + ) cell_json = "CCell_cell.json" decor_acc = "CCell_decor.acc" label_dict_acc = "CCell_label_dict.acc" assert cell_json in acc cell_json_dict = json.loads(acc[cell_json]) - assert 'cell_model_name' in cell_json_dict - assert 'produced_by' in cell_json_dict - assert 'morphology' in cell_json_dict - assert 'label_dict' in cell_json_dict - assert 'decor' in cell_json_dict + assert "cell_model_name" in cell_json_dict + assert "produced_by" in cell_json_dict + assert "morphology" in cell_json_dict + assert "label_dict" in cell_json_dict + assert "decor" in cell_json_dict assert decor_acc in acc - assert acc[decor_acc].startswith('(arbor-component') - assert '(decor' in acc[decor_acc] + assert acc[decor_acc].startswith("(arbor-component") + assert "(decor" in acc[decor_acc] assert label_dict_acc in acc - assert acc[label_dict_acc].startswith('(arbor-component') - assert '(label-dict' in acc[label_dict_acc] - matches = re.findall(r'\(region-def "(?P\w+)" \(tag (?P\d+)\)\)', - acc[label_dict_acc]) + assert acc[label_dict_acc].startswith("(arbor-component") + assert "(label-dict" in acc[label_dict_acc] + matches = re.findall( + r'\(region-def "(?P\w+)" \(tag (?P\d+)\)\)', + acc[label_dict_acc], + ) for pos, loc_tag in enumerate(DEFAULT_ARBOR_REGION_ORDER): assert matches[pos][0] == loc_tag[0] assert matches[pos][1] == str(loc_tag[1]) assert '(meta-data (info "test-decor"))' in acc[decor_acc] assert '(meta-data (info "test-label-dict"))' in acc[label_dict_acc] - assert custom_param_val in cell_json_dict['produced_by'] + assert custom_param_val in cell_json_dict["produced_by"] @pytest.mark.unit @@ -426,60 +455,76 @@ def test_create_acc_replace_axon(): latest_seg, arbor.mpoint(prox_x, 0, 0, 0.5), arbor.mpoint(dist_x, 0, 0, 0.5), - ArbFileMorphology.tags['axon'] + ArbFileMorphology.tags["axon"], ) replace_axon = arbor.morphology(replace_axon_st) try: - acc = create_acc.create_acc([mech, ], parameters, - morphology_dir=testdata_dir, - morphology='simple.swc', - template_name='CCell', - replace_axon=replace_axon) + acc = create_acc.create_acc( + [ + mech, + ], + parameters, + morphology_dir=testdata_dir, + morphology="simple.swc", + template_name="CCell", + replace_axon=replace_axon, + ) except Exception as e: # fail with an older Arbor version assert isinstance(e, NotImplementedError) - assert len(e.args) == 1 and e.args[0] == \ - "Need a newer version of Arbor for axon replacement." + assert ( + len(e.args) == 1 + and e.args[0] + == "Need a newer version of Arbor for axon replacement." + ) return cell_json = "CCell.json" cell_json_dict = json.loads(acc[cell_json]) - assert 'replace_axon' in cell_json_dict['morphology'] + assert "replace_axon" in cell_json_dict["morphology"] - with open(testdata_dir / 'acc/CCell/simple_axon_replacement.acc') as f: + with open(testdata_dir / "acc/CCell/simple_axon_replacement.acc") as f: replace_axon_ref = f.read() - assert acc[cell_json_dict['morphology']['replace_axon']] == \ - replace_axon_ref + assert ( + acc[cell_json_dict["morphology"]["replace_axon"]] == replace_axon_ref + ) def make_cell(replace_axon): - morph_filename = testdata_dir / 'simple_ax2.swc' - morph = ephys.morphologies.NrnFileMorphology(morph_filename, - do_replace_axon=replace_axon) + morph_filename = testdata_dir / "simple_ax2.swc" + morph = ephys.morphologies.NrnFileMorphology( + morph_filename, do_replace_axon=replace_axon + ) somatic_loc = ephys.locations.NrnSeclistLocation( - 'somatic', seclist_name='somatic') - mechs = [ephys.mechanisms.NrnMODMechanism( - name='hh', suffix='hh', locations=[somatic_loc])] - gkbar_hh_scaler = '(-0.62109375 + 0.546875*math.log(' \ - '({distance})*0.421875 + 1.25))*{value}' + "somatic", seclist_name="somatic" + ) + mechs = [ + ephys.mechanisms.NrnMODMechanism( + name="hh", suffix="hh", locations=[somatic_loc] + ) + ] + gkbar_hh_scaler = ( + "(-0.62109375 + 0.546875*math.log(" + "({distance})*0.421875 + 1.25))*{value}" + ) params = [ ephys.parameters.NrnSectionParameter( - name='gnabar_hh', - param_name='gnabar_hh', - locations=[somatic_loc]), + name="gnabar_hh", param_name="gnabar_hh", locations=[somatic_loc] + ), ephys.parameters.NrnRangeParameter( - name='gkbar_hh', - param_name='gkbar_hh', + name="gkbar_hh", + param_name="gkbar_hh", value_scaler=ephys.parameterscalers.NrnSegmentSomaDistanceScaler( - distribution=gkbar_hh_scaler), - locations=[somatic_loc])] + distribution=gkbar_hh_scaler + ), + locations=[somatic_loc], + ), + ] return ephys.models.CellModel( - 'simple_ax2', - morph=morph, - mechs=mechs, - params=params) + "simple_ax2", morph=morph, mechs=mechs, params=params + ) def run_short_sim(cable_cell): @@ -487,9 +532,9 @@ def run_short_sim(cable_cell): arb_cell_model = arbor.single_cell_model(cable_cell) arb_cell_model.properties.catalogue = arbor.catalogue() arb_cell_model.properties.catalogue.extend( - arbor.default_catalogue(), "default::") - arb_cell_model.properties.catalogue.extend( - arbor.bbp_catalogue(), "BBP::") + arbor.default_catalogue(), "default::" + ) + arb_cell_model.properties.catalogue.extend(arbor.bbp_catalogue(), "BBP::") # Run a very short simulation to test mechanism instantiation arb_cell_model.run(tfinal=0.1) @@ -499,26 +544,29 @@ def run_short_sim(cable_cell): def test_cell_model_write_and_read_acc(): """ephys.create_acc: Test write_acc and read_acc w/o axon replacement""" cell = make_cell(replace_axon=False) - param_values = {'gnabar_hh': 0.1, - 'gkbar_hh': 0.03} + param_values = {"gnabar_hh": 0.1, "gkbar_hh": 0.03} with tempfile.TemporaryDirectory() as acc_dir: cell.write_acc(acc_dir, param_values) - cell_json, arb_morph, arb_decor, arb_labels = \ - create_acc.read_acc( - pathlib.Path(acc_dir).joinpath(cell.name + '.json')) - assert 'replace_axon' not in cell_json['morphology'] - - cable_cell = arbor.cable_cell(morphology=arb_morph, - decor=arb_decor, - labels=arb_labels) + cell_json, arb_morph, arb_decor, arb_labels = create_acc.read_acc( + pathlib.Path(acc_dir).joinpath(cell.name + ".json") + ) + assert "replace_axon" not in cell_json["morphology"] + + cable_cell = arbor.cable_cell( + morphology=arb_morph, decor=arb_decor, labels=arb_labels + ) assert isinstance(cable_cell, arbor.cable_cell) assert len(cable_cell.cables('"soma"')) == 1 assert len(cable_cell.cables('"axon"')) == 1 - assert len(arb_morph.branch_segments( - cable_cell.cables('"soma"')[0].branch)) == 5 - assert len(arb_morph.branch_segments( - cable_cell.cables('"axon"')[0].branch)) == 5 + assert ( + len(arb_morph.branch_segments(cable_cell.cables('"soma"')[0].branch)) + == 5 + ) + assert ( + len(arb_morph.branch_segments(cable_cell.cables('"axon"')[0].branch)) + == 5 + ) run_short_sim(cable_cell) @@ -527,40 +575,50 @@ def test_cell_model_write_and_read_acc(): def test_cell_model_write_and_read_acc_replace_axon(): """ephys.create_acc: Test write_acc and read_acc w/ axon replacement""" cell = make_cell(replace_axon=True) - param_values = {'gnabar_hh': 0.1, - 'gkbar_hh': 0.03} + param_values = {"gnabar_hh": 0.1, "gkbar_hh": 0.03} with tempfile.TemporaryDirectory() as acc_dir: try: nrn_sim = ephys.simulators.NrnSimulator() - cell.write_acc(acc_dir, param_values, - sim=nrn_sim) + cell.write_acc(acc_dir, param_values, sim=nrn_sim) except Exception as e: # fail with an older Arbor version assert isinstance(e, NotImplementedError) - assert len(e.args) == 1 and e.args[0] == \ - "Need a newer version of Arbor for axon replacement." + assert ( + len(e.args) == 1 + and e.args[0] + == "Need a newer version of Arbor for axon replacement." + ) return # Axon replacement implemented in installed Arbor version - cell_json, arb_morph, arb_decor, arb_labels = \ - create_acc.read_acc( - pathlib.Path(acc_dir).joinpath(cell.name + '.json')) - - assert 'replace_axon' in cell_json['morphology'] - cable_cell = arbor.cable_cell(morphology=arb_morph, - decor=arb_decor, - labels=arb_labels) + cell_json, arb_morph, arb_decor, arb_labels = create_acc.read_acc( + pathlib.Path(acc_dir).joinpath(cell.name + ".json") + ) + + assert "replace_axon" in cell_json["morphology"] + cable_cell = arbor.cable_cell( + morphology=arb_morph, decor=arb_decor, labels=arb_labels + ) assert isinstance(cable_cell, arbor.cable_cell) assert len(cable_cell.cables('"soma"')) == 1 assert len(cable_cell.cables('"axon"')) == 1 - assert len(arb_morph.branch_segments( - cable_cell.cables('"soma"')[0].branch)) == 6 - assert len(arb_morph.branch_segments( - cable_cell.cables('"axon"')[0].branch)) == 6 - assert cable_cell.cables('"soma"')[0].prox == 0. - assert abs(cable_cell.cables('"soma"')[0].dist - - cable_cell.cables('"axon"')[0].prox) < 1e-6 - assert cable_cell.cables('"axon"')[0].dist == 1. + assert ( + len(arb_morph.branch_segments(cable_cell.cables('"soma"')[0].branch)) + == 6 + ) + assert ( + len(arb_morph.branch_segments(cable_cell.cables('"axon"')[0].branch)) + == 6 + ) + assert cable_cell.cables('"soma"')[0].prox == 0.0 + assert ( + abs( + cable_cell.cables('"soma"')[0].dist + - cable_cell.cables('"axon"')[0].prox + ) + < 1e-6 + ) + assert cable_cell.cables('"axon"')[0].dist == 1.0 run_short_sim(cable_cell) @@ -569,37 +627,37 @@ def test_cell_model_write_and_read_acc_replace_axon(): def test_cell_model_create_acc_replace_axon_without_instantiate(): """ephys.create_acc: Test write_acc and read_acc w/ axon replacement""" cell = make_cell(replace_axon=True) - param_values = {'gnabar_hh': 0.1, - 'gkbar_hh': 0.03} - - with pytest.raises(ValueError, - match='Need an instance of NrnSimulator in sim' - ' to instantiate morphology in order to' - ' create JSON/ACC-description with' - ' axon replacement.'): + param_values = {"gnabar_hh": 0.1, "gkbar_hh": 0.03} + + with pytest.raises( + ValueError, + match="Need an instance of NrnSimulator in sim" + " to instantiate morphology in order to" + " create JSON/ACC-description with" + " axon replacement.", + ): cell.create_acc(param_values) def check_acc_dir(test_dir, ref_dir): assert os.listdir(ref_dir) == os.listdir(test_dir) - ref_dir_ver_suffix = '_py' + ''.join(sys.version.split('.')[:2]) + ref_dir_ver_suffix = "_py" + "".join(sys.version.split(".")[:2]) ref_dir_ver = ref_dir.parent / (ref_dir.name + ref_dir_ver_suffix) for file in os.listdir(ref_dir): - if (ref_dir_ver / file).exists(): ref_dir_file = ref_dir_ver else: ref_dir_file = ref_dir - if file.endswith('.json'): + if file.endswith(".json"): with open(os.path.join(test_dir, file)) as f: cell_json_dict = json.load(f) with open(ref_dir_file / file) as f: ref_cell_json = json.load(f) for k in ref_cell_json: - if k != 'produced_by': + if k != "produced_by": assert ref_cell_json[k] == cell_json_dict[k] else: with open(os.path.join(test_dir, file)) as f: @@ -611,17 +669,21 @@ def check_acc_dir(test_dir, ref_dir): @pytest.mark.unit def test_write_acc_simple(): - SIMPLECELL_PATH = str((pathlib.Path(__file__).parent / - '../../../examples/simplecell').resolve()) + SIMPLECELL_PATH = str( + ( + pathlib.Path(__file__).parent / "../../../examples/simplecell" + ).resolve() + ) sys.path.insert(0, SIMPLECELL_PATH) - ref_dir = (testdata_dir / 'acc/simplecell').resolve() + ref_dir = (testdata_dir / "acc/simplecell").resolve() old_cwd = os.getcwd() try: os.chdir(SIMPLECELL_PATH) import simplecell_model + param_values = { - 'gnabar_hh': 0.10299326453483033, - 'gkbar_hh': 0.027124836082684685 + "gnabar_hh": 0.10299326453483033, + "gkbar_hh": 0.027124836082684685, } cell = simplecell_model.create(do_replace_axon=True) @@ -629,16 +691,21 @@ def test_write_acc_simple(): cell.instantiate_morphology_3d(nrn_sim) with tempfile.TemporaryDirectory() as test_dir: - cell.write_acc(test_dir, - param_values, - # ext_catalogues=ext_catalogues, - create_mod_morph=True) + cell.write_acc( + test_dir, + param_values, + # ext_catalogues=ext_catalogues, + create_mod_morph=True, + ) check_acc_dir(test_dir, ref_dir) except Exception as e: # fail with an older Arbor version assert isinstance(e, NotImplementedError) - assert len(e.args) == 1 and e.args[0] == \ - "Need a newer version of Arbor for axon replacement." + assert ( + len(e.args) == 1 + and e.args[0] + == "Need a newer version of Arbor for axon replacement." + ) finally: cell.destroy(nrn_sim) os.chdir(old_cwd) @@ -647,34 +714,36 @@ def test_write_acc_simple(): @pytest.mark.unit def test_write_acc_l5pc(): - L5PC_PATH = str((pathlib.Path(__file__).parent / - '../../../examples/l5pc').resolve()) + L5PC_PATH = str( + (pathlib.Path(__file__).parent / "../../../examples/l5pc").resolve() + ) sys.path.insert(0, L5PC_PATH) - ref_dir = (testdata_dir / 'acc/l5pc').resolve() + ref_dir = (testdata_dir / "acc/l5pc").resolve() old_cwd = os.getcwd() try: import l5pc_model + param_values = { - 'gNaTs2_tbar_NaTs2_t.apical': 0.026145, - 'gSKv3_1bar_SKv3_1.apical': 0.004226, - 'gImbar_Im.apical': 0.000143, - 'gNaTa_tbar_NaTa_t.axonal': 3.137968, - 'gK_Tstbar_K_Tst.axonal': 0.089259, - 'gamma_CaDynamics_E2.axonal': 0.002910, - 'gNap_Et2bar_Nap_Et2.axonal': 0.006827, - 'gSK_E2bar_SK_E2.axonal': 0.007104, - 'gCa_HVAbar_Ca_HVA.axonal': 0.000990, - 'gK_Pstbar_K_Pst.axonal': 0.973538, - 'gSKv3_1bar_SKv3_1.axonal': 1.021945, - 'decay_CaDynamics_E2.axonal': 287.198731, - 'gCa_LVAstbar_Ca_LVAst.axonal': 0.008752, - 'gamma_CaDynamics_E2.somatic': 0.000609, - 'gSKv3_1bar_SKv3_1.somatic': 0.303472, - 'gSK_E2bar_SK_E2.somatic': 0.008407, - 'gCa_HVAbar_Ca_HVA.somatic': 0.000994, - 'gNaTs2_tbar_NaTs2_t.somatic': 0.983955, - 'decay_CaDynamics_E2.somatic': 210.485284, - 'gCa_LVAstbar_Ca_LVAst.somatic': 0.000333, + "gNaTs2_tbar_NaTs2_t.apical": 0.026145, + "gSKv3_1bar_SKv3_1.apical": 0.004226, + "gImbar_Im.apical": 0.000143, + "gNaTa_tbar_NaTa_t.axonal": 3.137968, + "gK_Tstbar_K_Tst.axonal": 0.089259, + "gamma_CaDynamics_E2.axonal": 0.002910, + "gNap_Et2bar_Nap_Et2.axonal": 0.006827, + "gSK_E2bar_SK_E2.axonal": 0.007104, + "gCa_HVAbar_Ca_HVA.axonal": 0.000990, + "gK_Pstbar_K_Pst.axonal": 0.973538, + "gSKv3_1bar_SKv3_1.axonal": 1.021945, + "decay_CaDynamics_E2.axonal": 287.198731, + "gCa_LVAstbar_Ca_LVAst.axonal": 0.008752, + "gamma_CaDynamics_E2.somatic": 0.000609, + "gSKv3_1bar_SKv3_1.somatic": 0.303472, + "gSK_E2bar_SK_E2.somatic": 0.008407, + "gCa_HVAbar_Ca_HVA.somatic": 0.000994, + "gNaTs2_tbar_NaTs2_t.somatic": 0.983955, + "decay_CaDynamics_E2.somatic": 210.485284, + "gCa_LVAstbar_Ca_LVAst.somatic": 0.000333, } cell = l5pc_model.create(do_replace_axon=True) @@ -682,16 +751,21 @@ def test_write_acc_l5pc(): cell.instantiate_morphology_3d(nrn_sim) with tempfile.TemporaryDirectory() as test_dir: - cell.write_acc(test_dir, - param_values, - # ext_catalogues=ext_catalogues, - create_mod_morph=True) + cell.write_acc( + test_dir, + param_values, + # ext_catalogues=ext_catalogues, + create_mod_morph=True, + ) check_acc_dir(test_dir, ref_dir) except Exception as e: # fail with an older Arbor version assert isinstance(e, NotImplementedError) - assert len(e.args) == 1 and e.args[0] == \ - "Need a newer version of Arbor for axon replacement." + assert ( + len(e.args) == 1 + and e.args[0] + == "Need a newer version of Arbor for axon replacement." + ) finally: cell.destroy(nrn_sim) os.chdir(old_cwd) @@ -700,22 +774,26 @@ def test_write_acc_l5pc(): @pytest.mark.unit def test_write_acc_expsyn(): - EXPSYN_PATH = str((pathlib.Path(__file__).parent / - '../../../examples/expsyn').resolve()) + EXPSYN_PATH = str( + (pathlib.Path(__file__).parent / "../../../examples/expsyn").resolve() + ) sys.path.insert(0, EXPSYN_PATH) - ref_dir = (testdata_dir / 'acc/expsyn').resolve() + ref_dir = (testdata_dir / "acc/expsyn").resolve() old_cwd = os.getcwd() try: import expsyn - param_values = {'expsyn_tau': 10.0} - cell = expsyn.create_model(sim='arb', do_replace_axon=False) + param_values = {"expsyn_tau": 10.0} + + cell = expsyn.create_model(sim="arb", do_replace_axon=False) with tempfile.TemporaryDirectory() as test_dir: - cell.write_acc(test_dir, - param_values, - # ext_catalogues=ext_catalogues, - create_mod_morph=True) + cell.write_acc( + test_dir, + param_values, + # ext_catalogues=ext_catalogues, + create_mod_morph=True, + ) check_acc_dir(test_dir, ref_dir) finally: diff --git a/bluepyopt/tests/test_ephys/test_locations.py b/bluepyopt/tests/test_ephys/test_locations.py index 28868742..cef6c78b 100644 --- a/bluepyopt/tests/test_ephys/test_locations.py +++ b/bluepyopt/tests/test_ephys/test_locations.py @@ -21,8 +21,8 @@ # pylint:disable=W0612, W0201 import json -import numpy as np +import numpy as np import pytest from bluepyopt import ephys @@ -33,27 +33,24 @@ def test_location_init(): """ephys.locations: test if Location works""" - loc = ephys.locations.Location('test') + loc = ephys.locations.Location("test") assert isinstance(loc, ephys.locations.Location) - assert loc.name == 'test' + assert loc.name == "test" @pytest.mark.unit class TestNrnSectionCompLocation(object): - """Test class for NrnSectionCompLocation""" - def setup(self): + def setup_method(self): """Setup""" self.loc = ephys.locations.NrnSectionCompLocation( - name='test', - sec_name='soma[0]', - comp_x=0.5) + name="test", sec_name="soma[0]", comp_x=0.5 + ) self.loc_dend = ephys.locations.NrnSectionCompLocation( - name='test', - sec_name='dend[1]', - comp_x=0.5) - assert self.loc.name == 'test' + name="test", sec_name="dend[1]", comp_x=0.5 + ) + assert self.loc.name == "test" self.sim = ephys.simulators.NrnSimulator() def test_instantiate(self): @@ -61,13 +58,14 @@ def test_instantiate(self): # Create a little test class with a soma and two dendritic sections class Cell(object): - """Cell class""" + pass + cell = Cell() soma = self.sim.neuron.h.Section() - dend1 = self.sim.neuron.h.Section(name='dend1') - dend2 = self.sim.neuron.h.Section(name='dend2') + dend1 = self.sim.neuron.h.Section(name="dend1") + dend2 = self.sim.neuron.h.Section(name="dend2") cell.soma = [soma] cell.dend = [dend1, dend2] @@ -81,22 +79,17 @@ class Cell(object): @pytest.mark.unit class TestNrnSeclistCompLocation(object): - """Test class for NrnSectionCompLocation""" - def setup(self): + def setup_method(self): """Setup""" self.loc = ephys.locations.NrnSeclistCompLocation( - name='test', - seclist_name='somatic', - sec_index=0, - comp_x=0.5) + name="test", seclist_name="somatic", sec_index=0, comp_x=0.5 + ) self.loc_dend = ephys.locations.NrnSeclistCompLocation( - name='test', - seclist_name='basal', - sec_index=1, - comp_x=0.5) - assert self.loc.name == 'test' + name="test", seclist_name="basal", sec_index=1, comp_x=0.5 + ) + assert self.loc.name == "test" self.sim = ephys.simulators.NrnSimulator() def test_instantiate(self): @@ -105,12 +98,13 @@ def test_instantiate(self): # Create a little test class with a soma and two dendritic sections class Cell(object): """Cell class""" + pass cell = Cell() soma = self.sim.neuron.h.Section() - dend1 = self.sim.neuron.h.Section(name='dend1') - dend2 = self.sim.neuron.h.Section(name='dend2') + dend1 = self.sim.neuron.h.Section(name="dend1") + dend2 = self.sim.neuron.h.Section(name="dend2") cell.somatic = self.sim.neuron.h.SectionList() cell.somatic.append(soma) @@ -130,20 +124,17 @@ class Cell(object): @pytest.mark.unit class TestNrnSeclistSecLocation(object): - """Test class for NrnSeclistSecLocation""" - def setup(self): + def setup_method(self): """Setup""" self.loc = ephys.locations.NrnSeclistSecLocation( - name='test', - seclist_name='somatic', - sec_index=0) + name="test", seclist_name="somatic", sec_index=0 + ) self.loc_dend = ephys.locations.NrnSeclistSecLocation( - name='test', - seclist_name='basal', - sec_index=1) - assert self.loc.name == 'test' + name="test", seclist_name="basal", sec_index=1 + ) + assert self.loc.name == "test" self.sim = ephys.simulators.NrnSimulator() def test_instantiate(self): @@ -152,12 +143,13 @@ def test_instantiate(self): # Create a little test class with a soma and two dendritic sections class Cell(object): """Cell class""" + pass cell = Cell() soma = self.sim.neuron.h.Section() - dend1 = self.sim.neuron.h.Section(name='dend1') - dend2 = self.sim.neuron.h.Section(name='dend2') + dend1 = self.sim.neuron.h.Section(name="dend1") + dend2 = self.sim.neuron.h.Section(name="dend2") cell.somatic = self.sim.neuron.h.SectionList() cell.somatic.append(soma) @@ -174,16 +166,14 @@ class Cell(object): @pytest.mark.unit class TestNrnSomaDistanceCompLocation(object): - """Test class for NrnSomaDistanceCompLocation""" - def setup(self): + def setup_method(self): """Setup""" self.loc = ephys.locations.NrnSomaDistanceCompLocation( - 'test', - 125, - 'testdend') - assert self.loc.name == 'test' + "test", 125, "testdend" + ) + assert self.loc.name == "test" self.sim = ephys.simulators.NrnSimulator() def test_instantiate(self): @@ -191,23 +181,26 @@ def test_instantiate(self): # Create a little test class with a soma and two dendritic sections class Cell(object): - """Cell class""" + pass + cell = Cell() soma = self.sim.neuron.h.Section() cell.soma = [soma] cell.testdend = self.sim.neuron.h.SectionList() - dend1 = self.sim.neuron.h.Section(name='dend1') - dend2 = self.sim.neuron.h.Section(name='dend2') + dend1 = self.sim.neuron.h.Section(name="dend1") + dend2 = self.sim.neuron.h.Section(name="dend2") cell.testdend.append(sec=dend1) cell.testdend.append(sec=dend2) - pytest.raises(ephys.locations.EPhysLocInstantiateException, - self.loc.instantiate, - sim=self.sim, - icell=cell) + pytest.raises( + ephys.locations.EPhysLocInstantiateException, + self.loc.instantiate, + sim=self.sim, + icell=cell, + ) dend1.connect(soma(0.5), 0.0) dend2.connect(dend1(1.0), 0.0) @@ -218,22 +211,17 @@ class Cell(object): @pytest.mark.unit class TestNrnSecSomaDistanceCompLocation(object): - """Test class for NrnSecSomaDistanceCompLocation""" - def setup(self): + def setup_method(self): """Setup""" self.loc = ephys.locations.NrnSecSomaDistanceCompLocation( - 'test', - 125, - 1, - 'testdend') + "test", 125, 1, "testdend" + ) self.loc_other = ephys.locations.NrnSecSomaDistanceCompLocation( - 'test', - 250, - 4, - 'testdend') - assert self.loc.name == 'test' + "test", 250, 4, "testdend" + ) + assert self.loc.name == "test" self.sim = ephys.simulators.NrnSimulator() def test_instantiate(self): @@ -241,18 +229,19 @@ def test_instantiate(self): # Create a little test class with a soma and two dendritic sections class Cell(object): - """Cell class""" + pass + cell = Cell() soma = self.sim.neuron.h.Section(name="soma[0]") cell.soma = [soma] cell.testdend = self.sim.neuron.h.SectionList() - dend1 = self.sim.neuron.h.Section(name='dend[0]') - dend2 = self.sim.neuron.h.Section(name='dend[1]') - dend3 = self.sim.neuron.h.Section(name='dend[2]') - dend4 = self.sim.neuron.h.Section(name='dend[3]') - dend5 = self.sim.neuron.h.Section(name='dend[4]') + dend1 = self.sim.neuron.h.Section(name="dend[0]") + dend2 = self.sim.neuron.h.Section(name="dend[1]") + dend3 = self.sim.neuron.h.Section(name="dend[2]") + dend4 = self.sim.neuron.h.Section(name="dend[3]") + dend5 = self.sim.neuron.h.Section(name="dend[4]") cell.testdend.append(sec=dend1) cell.testdend.append(sec=dend2) @@ -274,21 +263,18 @@ class Cell(object): @pytest.mark.unit class TestNrnTrunkSomaDistanceCompLocation(object): - """Test class for NrnTrunkSomaDistanceCompLocation""" - def setup(self): + def setup_method(self): """Setup""" self.loc = ephys.locations.NrnTrunkSomaDistanceCompLocation( - 'test', - soma_distance=150, - seclist_name='testdend') + "test", soma_distance=150, seclist_name="testdend" + ) self.loc_other = ephys.locations.NrnTrunkSomaDistanceCompLocation( - 'test', - soma_distance=350, - seclist_name='testdend') + "test", soma_distance=350, seclist_name="testdend" + ) - assert self.loc.name == 'test' + assert self.loc.name == "test" self.sim = ephys.simulators.NrnSimulator() def test_instantiate(self): @@ -296,18 +282,19 @@ def test_instantiate(self): # Create a little test class with a soma and two dendritic sections class Cell(object): - """Cell class""" + pass + cell = Cell() soma = self.sim.neuron.h.Section(name="soma[0]") cell.soma = [soma] cell.testdend = self.sim.neuron.h.SectionList() - dend1 = self.sim.neuron.h.Section(name='dend[0]') - dend2 = self.sim.neuron.h.Section(name='dend[1]') - dend3 = self.sim.neuron.h.Section(name='dend[2]') - dend4 = self.sim.neuron.h.Section(name='dend[3]') - dend5 = self.sim.neuron.h.Section(name='dend[4]') + dend1 = self.sim.neuron.h.Section(name="dend[0]") + dend2 = self.sim.neuron.h.Section(name="dend[1]") + dend3 = self.sim.neuron.h.Section(name="dend[2]") + dend4 = self.sim.neuron.h.Section(name="dend[3]") + dend5 = self.sim.neuron.h.Section(name="dend[4]") cell.testdend.append(sec=dend1) cell.testdend.append(sec=dend2) @@ -348,18 +335,22 @@ def test_serialize(): NrnSeclistCompLocation, NrnSeclistLocation, NrnSeclistSecLocation, - NrnSomaDistanceCompLocation) + NrnSomaDistanceCompLocation, + ) - seclist_name, sec_index, comp_x, soma_distance = 'somatic', 0, 0.5, 800 + seclist_name, sec_index, comp_x, soma_distance = "somatic", 0, 0.5, 800 locations = ( - NrnSeclistCompLocation('NrnSeclistCompLocation', - seclist_name, sec_index, comp_x), - NrnSeclistLocation( - 'NrnSeclistLocation', seclist_name), + NrnSeclistCompLocation( + "NrnSeclistCompLocation", seclist_name, sec_index, comp_x + ), + NrnSeclistLocation("NrnSeclistLocation", seclist_name), NrnSeclistSecLocation( - 'NrnSeclistSecLocation', seclist_name, sec_index), + "NrnSeclistSecLocation", seclist_name, sec_index + ), NrnSomaDistanceCompLocation( - 'NrnSomaDistanceCompLocation', soma_distance, seclist_name),) + "NrnSomaDistanceCompLocation", soma_distance, seclist_name + ), + ) for loc in locations: serialized = loc.to_dict()