From 13799d5d152571a7c4662f384ec89ce99cae84b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <72930209+AurelienJaquier@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:48:38 +0200 Subject: [PATCH 1/3] new function for computing emodel properties --- bluecellulab/tools.py | 55 +++++++++++++++++++++++++++++++++++++++++++ tests/test_tools.py | 20 +++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/bluecellulab/tools.py b/bluecellulab/tools.py index 7ff20298..e1c89c15 100644 --- a/bluecellulab/tools.py +++ b/bluecellulab/tools.py @@ -553,3 +553,58 @@ def compute_memodel_properties( ) return {"holding_current": holding_current, "rheobase": rheobase, "rin": rin} + + +def compute_memodel_properties_v2( + template_path, + morphology_path, + template_format, + holding_voltage, + emodel_properties, + spike_threshold_voltage=-30, + v_init=-80.0, + celsius=34.0, +): + """Compute holding and threshold currents, resting membrane potential, and + input resistance.""" + # set initial voltage and temperature + set_neuron_globals(temperature=celsius, v_init=v_init) + + cell_kwargs = { + "template_path": template_path, + "morphology_path": morphology_path, + "template_format": template_format, + "emodel_properties": emodel_properties, + } + + with IsolatedProcess() as runner: + i_hold, _ = runner.apply( + holding_current_subprocess, [holding_voltage, False, cell_kwargs] + ) + + # update holding current in emodel properties because it is used in rheobase computation + emodel_properties.holding_current = i_hold + + rmp = calculate_SS_voltage( + template_path, morphology_path, template_format, emodel_properties, 0.0, + ) + + rin = calculate_input_resistance( + template_path=template_path, + morphology_path=morphology_path, + template_format=template_format, + emodel_properties=emodel_properties, + ) + + cell = Cell( + template_path=template_path, + morphology_path=morphology_path, + template_format=template_format, + emodel_properties=emodel_properties, + ) + rheobase = calculate_rheobase( + cell=cell, section="soma[0]", segx=0.5, threshold_voltage=spike_threshold_voltage + ) + cell.delete() + + return {"holding_current": i_hold, "resting_potential": rmp, "input_resistance": rin, "threshold_current": rheobase} diff --git a/tests/test_tools.py b/tests/test_tools.py index b5850c2d..06b48eff 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -25,7 +25,7 @@ from bluecellulab.circuit.circuit_access import EmodelProperties from bluecellulab.circuit.node_id import create_cell_id from bluecellulab.exceptions import UnsteadyCellError -from bluecellulab.tools import calculate_SS_voltage, calculate_SS_voltage_subprocess, calculate_input_resistance, detect_hyp_current, detect_spike, detect_spike_step, detect_spike_step_subprocess, holding_current, holding_current_subprocess, search_threshold_current, template_accepts_cvode, check_empty_topology, calculate_max_thresh_current, calculate_rheobase, validate_section_and_segment +from bluecellulab.tools import calculate_SS_voltage, calculate_SS_voltage_subprocess, calculate_input_resistance, detect_hyp_current, detect_spike, detect_spike_step, detect_spike_step_subprocess, holding_current, holding_current_subprocess, search_threshold_current, template_accepts_cvode, check_empty_topology, calculate_max_thresh_current, calculate_rheobase, validate_section_and_segment, compute_memodel_properties_v2 from bluecellulab.cell.section_tools import currents_vars, mechs_vars @@ -250,6 +250,24 @@ def test_detect_spike_step_subprocess(self): ) assert spike_occurred is True + def test_compute_memodel_properties_v2(self): + """Unit test compute_memodel_properties_v2.""" + resp_dict = compute_memodel_properties_v2( + template_path=self.template_name, + morphology_path=self.morphology_path, + template_format=self.template_format, + holding_voltage=-85.0, + emodel_properties=self.emodel_properties, + ) + import warnings + warnings.warn(resp_dict["resting_potential"]) + warnings.warn(resp_dict["input_resistance"]) + warnings.warn(resp_dict["threshold_current"]) + assert resp_dict["holding_current"] == pytest.approx(0.0003600167531203624) + assert resp_dict["resting_potential"] == pytest.approx(-85.13006257460853) + assert resp_dict["input_resistance"] == pytest.approx(334.1862365049614) + assert resp_dict["threshold_current"] == pytest.approx(0.03380088341395323) + @pytest.mark.v6 class TestOnSonataCircuit: From 707a82f80ddfe43d11764ebe8180002895ad4edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <72930209+AurelienJaquier@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:48:50 +0200 Subject: [PATCH 2/3] fix typos in example --- .../singlecell_H5_morph_H5_container.ipynb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/1-singlecell/singlecell_H5_morph_H5_container.ipynb b/examples/1-singlecell/singlecell_H5_morph_H5_container.ipynb index 7c7c1486..d82babed 100644 --- a/examples/1-singlecell/singlecell_H5_morph_H5_container.ipynb +++ b/examples/1-singlecell/singlecell_H5_morph_H5_container.ipynb @@ -13,9 +13,9 @@ "id": "6f011909", "metadata": {}, "source": [ - "This is an advanced example. Please refer to [singlecell.ipynb notebook](singlecell.ipynb) for a basic example.Morphology formats that can be run by BlueCelluLab are: [asc](https://morphio.readthedocs.io/en/latest/specification_neurolucida.html#id1), [swc](https://swc-specification.readthedocs.io/en/latest/swc.html), [H5](https://morphology-documentation.readthedocs.io/en/latest/h5v1.html#file-format) and [H5 container](https://morphology-documentation.readthedocs.io/en/latest/h5-containers.html).\n", + "This is an advanced example. Please refer to [singlecell.ipynb notebook](singlecell.ipynb) for a basic example. Morphology formats that can be run by BlueCelluLab are: [asc](https://morphio.readthedocs.io/en/latest/specification_neurolucida.html#id1), [swc](https://swc-specification.readthedocs.io/en/latest/swc.html), [H5](https://morphology-documentation.readthedocs.io/en/latest/h5v1.html#file-format) and [H5 container](https://morphology-documentation.readthedocs.io/en/latest/h5-containers.html).\n", "\n", - "You can read more about the morphology formats [here](https://morphio.readthedocs.io/en/latest/specification.html). This notebook demonstrates run single cell models using different morphology formats:\n", + "You can read more about the morphology formats [here](https://morphio.readthedocs.io/en/latest/specification.html). This notebook demonstrates single cell models simulations using different morphology formats:\n", "1. [H5](https://morphology-documentation.readthedocs.io/en/latest/h5v1.html#file-format) \n", "2. [H5 container](https://morphology-documentation.readthedocs.io/en/latest/h5-containers.html).\n", "\n", @@ -28,7 +28,7 @@ "id": "0fa091d5", "metadata": {}, "source": [ - "The morphologies of this rat Somatosensory cortex circuit are stored in H5 container format [Modeling and simulation of neocortical micro- and mesocircuitry (Part II, Physiology and experimentation)](https://doi.org/10.7554/eLife.99693.3). You can view the central subvolume of this nbS1 circuit (nbS1-O1) on your own [Virtual Labs](https://www.openbraininstitute.org/app/virtual-lab) of the [Open Brain Insititute](https://www.openbraininstitute.org/)(OBI)\n", + "The morphologies of this rat Somatosensory cortex circuit are stored in H5 container format [Modeling and simulation of neocortical micro- and mesocircuitry (Part II, Physiology and experimentation)](https://doi.org/10.7554/eLife.99693.3). You can view the central subvolume of this nbS1 circuit (nbS1-O1) on your own [Virtual Labs](https://www.openbraininstitute.org/app/virtual-lab) at the [Open Brain Insititute](https://www.openbraininstitute.org/)(OBI).\n", "This nbS1-O1 and nbS1 circuit use morphologies in H5 container morphology format. Once you login, you can view all the details, subcircuits and circuit analysis on the detailed circuit page." ] }, @@ -45,7 +45,7 @@ "id": "c1edea5b", "metadata": {}, "source": [ - "For this notebook, we will use a `cADpyr_L5TPC` single cell model used in the circuit with all the intrinsic and extrinsic synapses extracted from the Somatosensory cortex(SSCx) circuit publish in [Modeling and simulation of neocortical micro- and mesocircuitry (Part II, Physiology and experimentation](https://doi.org/10.7554/eLife.99693.3).We also call such single cells with all its synapses, a **Synaptome**. The synaptome is stored in the [SONATA](https://sonata-extension.readthedocs.io/en/latest/) format. You can also view the cell in the [Open Brain Institute's Virtual Labs](https://www.openbraininstitute.org/app/virtual-lab):" + "For this notebook, we will use a `cADpyr_L5TPC` single cell model with all the intrinsic and extrinsic synapses extracted from the Somatosensory cortex(SSCx) circuit publish in [Modeling and simulation of neocortical micro- and mesocircuitry (Part II, Physiology and experimentation](https://doi.org/10.7554/eLife.99693.3). Such single cells with all its synapses is called a **Synaptome**. The synaptome is stored in the [SONATA](https://sonata-extension.readthedocs.io/en/latest/) format. You can also view the cell in the [Open Brain Institute's Virtual Labs](https://www.openbraininstitute.org/app/virtual-lab):" ] }, { @@ -61,8 +61,8 @@ "id": "7ec26b93", "metadata": {}, "source": [ - "Locally, it is present in this folder: `BlueCelluLab/tests/examples/container_nbS1-O1__202247__cADpyr__L5_TPC_A`\n", - "The cell is stored in SONATA format with all the components including the H5 morphology. We also have the morphology in a H5 container containing a single morphology. SONATA circuit documentation: https://sonata-extension.readthedocs.io/en/latest/ " + "Locally, it is present in this folder: `BlueCelluLab/tests/examples/container_nbS1-O1__202247__cADpyr__L5_TPC_A`.\n", + "The cell is stored in SONATA format with all the components including the H5 morphology. We also have the morphology in a H5 container containing a single morphology. See SONATA circuit documentation for more details: https://sonata-extension.readthedocs.io/en/latest/ " ] }, { @@ -126,7 +126,7 @@ "id": "68c740b1", "metadata": {}, "source": [ - "We will use the threahold current and holding current properties of the cell to initialise it. These are present in the nodes.h5 file of the SOANTA format. Let's read the nodes.h5 file and extract the threshold current and holding current properties." + "We will use the threshold current and holding current properties of the cell to initialise it. These are present in the nodes.h5 file of the SOANTA format. Let's read the nodes.h5 file and extract the threshold current and holding current properties." ] }, { From f3576769c7e9a10a2d6586c1190e73aecbd0c02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <72930209+AurelienJaquier@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:50:14 +0200 Subject: [PATCH 3/3] remove debug statements --- tests/test_tools.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_tools.py b/tests/test_tools.py index 06b48eff..41d83ac0 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -259,10 +259,7 @@ def test_compute_memodel_properties_v2(self): holding_voltage=-85.0, emodel_properties=self.emodel_properties, ) - import warnings - warnings.warn(resp_dict["resting_potential"]) - warnings.warn(resp_dict["input_resistance"]) - warnings.warn(resp_dict["threshold_current"]) + assert resp_dict["holding_current"] == pytest.approx(0.0003600167531203624) assert resp_dict["resting_potential"] == pytest.approx(-85.13006257460853) assert resp_dict["input_resistance"] == pytest.approx(334.1862365049614)