-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BBPBGLIB-1137] Account for nonzero total current when using SEClamp…
…; allow nonzero total current when simulating physical electrodes (#134) ## Context NEURON reports SEClamp currents at different time points than all other currents, thus giving inaccurate results in lfp calculations, in cases where the SEClamp represents synaptic inputs. This can be fixed by replacing the SEClamp with a new point process mechanism that is identical, except for producing a NONSPECIFIC_CURRENT instead of an ELECTRODE_CURRENT. However, in cases where SEClamp or IClamp are used to represent physical electrodes, rather than synaptic inputs, the currents should not be included in the LFP calcualtion ## Scope When a current_source or conductance_source is used, we check if the alternative mod file, which is expected to be named 'MembraneCurrentSource.mod' or 'ConductanceSource.mod' is available. If so, it is used, with nothing else changed, unless the key-value pair "represents_physical_electrode" is set to True in the Stimulus Config file. Otherwise the IClamp or SEClamp is used as before. ## Testing Scientific test added to ensure that new mechanisms produce identical membrane voltages to the old ones ## Review * [x] PR description is complete * [x] Coding style (imports, function length, New functions, classes or files) are good * [x] Unit/Scientific test added * [x] Updated Readme, in-code, developer documentation --------- Co-authored-by: Jorge Blanco Alonso <jorge.blancoalonso@epfl.ch> Co-authored-by: Jorge Blanco Alonso <41900536+jorblancoa@users.noreply.github.com>
- Loading branch information
1 parent
512dbb8
commit 1d2bf99
Showing
6 changed files
with
184 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import json | ||
import numpy | ||
import os | ||
import pytest | ||
from tempfile import NamedTemporaryFile | ||
|
||
|
||
@pytest.fixture | ||
def sonata_config_files(sonata_config, input_type): | ||
config_files = [] | ||
for represents_physical_electrode in [True, False]: | ||
# Create a deep copy of sonata_config for each configuration to avoid conflicts | ||
config_copy = json.loads(json.dumps(sonata_config)) | ||
|
||
stimulus_config = { | ||
"input_type": input_type, | ||
"delay": 5, | ||
"duration": 2100, | ||
"node_set": "l4pc", | ||
"represents_physical_electrode": represents_physical_electrode | ||
} | ||
|
||
if input_type == "current_clamp": | ||
stimulus_config.update({ | ||
"module": "noise", | ||
"mean": 0.05, | ||
"variance": 0.01 | ||
}) | ||
elif input_type == "conductance": | ||
stimulus_config.update({ | ||
"module": "ornstein_uhlenbeck", | ||
"mean": 0.05, | ||
"sigma": 0.01, | ||
"tau": 0.1 | ||
}) | ||
|
||
config_copy["inputs"] = {"Stimulus": stimulus_config} | ||
config_copy["reports"] = { | ||
"current": { | ||
"type": "summation", | ||
"cells": "l4pc", | ||
"variable_name": "i_membrane", | ||
"unit": "nA", | ||
"dt": 0.1, | ||
"start_time": 0.0, | ||
"end_time": 50.0 | ||
}, | ||
"voltage": { | ||
"type": "compartment", | ||
"cells": "l4pc", | ||
"variable_name": "v", | ||
"unit": "mV", | ||
"dt": 0.1, | ||
"start_time": 0.0, | ||
"end_time": 50.0 | ||
} | ||
} | ||
|
||
with NamedTemporaryFile("w", suffix='.json', delete=False) as config_file: | ||
json.dump(config_copy, config_file) | ||
config_files.append(config_file.name) | ||
|
||
yield tuple(config_files) | ||
|
||
# Cleanup | ||
for config_file in config_files: | ||
os.unlink(config_file) | ||
|
||
|
||
def _read_sonata_soma_report(report_name): | ||
import libsonata | ||
report = libsonata.SomaReportReader(report_name) | ||
pop_name = report.get_population_names()[0] | ||
ids = report[pop_name].get_node_ids() | ||
data = report[pop_name].get(node_ids=[ids[0]]) | ||
return numpy.array(data.data).flatten() | ||
|
||
|
||
def _run_simulation(config_file): | ||
import subprocess | ||
output_dir = "output_current_conductance" | ||
command = [ | ||
"neurodamus", | ||
config_file, | ||
f"--output-path={output_dir}" | ||
] | ||
config_dir = os.path.dirname(config_file) | ||
subprocess.run(command, cwd=config_dir, check=True) | ||
soma_report_path = os.path.join(config_dir, output_dir, "voltage.h5") | ||
return _read_sonata_soma_report(soma_report_path) | ||
|
||
|
||
@pytest.mark.parametrize("input_type", [ | ||
"current_clamp", | ||
"conductance", | ||
]) | ||
def test_current_conductance_injection(sonata_config_files): | ||
""" | ||
Test the consistency of voltage traces between original and new configurations | ||
(set by 'represents_physical_electrode': true/false) | ||
under different types of input (current clamp and conductance). | ||
""" | ||
import numpy.testing as npt | ||
config_file_original, config_file_new = sonata_config_files | ||
|
||
voltage_vec_original = _run_simulation(config_file_original) | ||
voltage_vec_new = _run_simulation(config_file_new) | ||
|
||
npt.assert_equal(voltage_vec_original, voltage_vec_new) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters