bluecellulab 2.6.47__tar.gz → 2.6.48__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bluecellulab might be problematic. Click here for more details.
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/PKG-INFO +1 -1
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/analysis/analysis.py +47 -11
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/analysis/inject_sequence.py +96 -24
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/analysis/plotting.py +47 -4
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/stimulus/factory.py +104 -74
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/tools.py +3 -4
- bluecellulab-2.6.48/bluecellulab/validation/validation.py +401 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab.egg-info/PKG-INFO +1 -1
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab.egg-info/SOURCES.txt +1 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.compile_mod.sh +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.gitattributes +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.github/dependabot.yml +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.github/workflows/release.yml +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.github/workflows/test.yml +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.gitignore +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.gitlab-ci.yml +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.readthedocs.yml +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/.zenodo.json +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/AUTHORS.txt +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/CHANGELOG.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/CITATION.cff +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/CONTRIBUTING.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/LICENSE +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/MANIFEST.in +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/Makefile +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/README.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/analysis/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/ballstick/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/ballstick/emodel.hoc +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/ballstick/morphology.asc +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/cell_dict.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/core.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/injector.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/plotting.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/random.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/recording.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/section_distance.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/serialized_sections.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/sonata_proxy.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/stimuli_generator.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/cell/template.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/circuit_access/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/circuit_access/bluepy_circuit_access.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/circuit_access/definition.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/circuit_access/sonata_circuit_access.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/config/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/config/bluepy_simulation_config.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/config/definition.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/config/sections.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/config/sonata_simulation_config.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/format.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/iotools.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/node_id.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/simulation_access.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/synapse_properties.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit/validate.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/circuit_simulation.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/connection.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/dendrogram.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/exceptions.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/graph.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/hoc/Cell.hoc +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/hoc/RNGSettings.hoc +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/hoc/TDistFunc.hoc +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/hoc/TStim.hoc +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/hoc/fileUtils.hoc +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/importer.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/neuron_interpreter.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/plotwindow.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/psection.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/psegment.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/rngsettings.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/simulation/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/simulation/neuron_globals.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/simulation/parallel.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/simulation/simulation.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/stimulus/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/stimulus/circuit_stimulus_definitions.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/stimulus/stimulus.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/synapse/__init__.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/synapse/synapse_factory.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/synapse/synapse_types.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/type_aliases.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/utils.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab/verbosity.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab.egg-info/dependency_links.txt +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab.egg-info/requires.txt +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/bluecellulab.egg-info/top_level.txt +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/Makefile +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/images/voltage-readme.png +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/make.bat +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/requirements_docs.txt +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/_static/.gitkeep +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/api.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/changelog.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/compiling-mechanisms.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/conf.py +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/contributing.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/index.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/list_of_stim.rst +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/docs/source/logo/BlueCelluLabBanner.jpg +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/pyproject.toml +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/setup.cfg +0 -0
- {bluecellulab-2.6.47 → bluecellulab-2.6.48}/tox.ini +0 -0
|
@@ -5,10 +5,10 @@ except ImportError:
|
|
|
5
5
|
efel = None
|
|
6
6
|
import numpy as np
|
|
7
7
|
|
|
8
|
-
from bluecellulab.stimulus import StimulusFactory
|
|
9
|
-
from bluecellulab.tools import calculate_rheobase
|
|
10
8
|
from bluecellulab.analysis.inject_sequence import run_stimulus
|
|
11
9
|
from bluecellulab.analysis.plotting import plot_iv_curve, plot_fi_curve
|
|
10
|
+
from bluecellulab.stimulus import StimulusFactory
|
|
11
|
+
from bluecellulab.tools import calculate_rheobase
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def compute_plot_iv_curve(cell,
|
|
@@ -19,8 +19,13 @@ def compute_plot_iv_curve(cell,
|
|
|
19
19
|
stim_start=100.0,
|
|
20
20
|
duration=500.0,
|
|
21
21
|
post_delay=100.0,
|
|
22
|
-
threshold_voltage=-
|
|
23
|
-
nb_bins=11
|
|
22
|
+
threshold_voltage=-20,
|
|
23
|
+
nb_bins=11,
|
|
24
|
+
rheobase=None,
|
|
25
|
+
show_figure=True,
|
|
26
|
+
save_figure=False,
|
|
27
|
+
output_dir="./",
|
|
28
|
+
output_fname="iv_curve.pdf"):
|
|
24
29
|
"""Compute and plot the Current-Voltage (I-V) curve for a given cell by
|
|
25
30
|
injecting a range of currents.
|
|
26
31
|
|
|
@@ -46,6 +51,12 @@ def compute_plot_iv_curve(cell,
|
|
|
46
51
|
response. Default is -30 mV.
|
|
47
52
|
nb_bins (int, optional): The number of discrete current levels between 0 and the maximum current.
|
|
48
53
|
Default is 11.
|
|
54
|
+
rheobase (float, optional): The rheobase current (in nA) for the cell. If not provided, it will
|
|
55
|
+
be calculated using the `calculate_rheobase` function.
|
|
56
|
+
show_figure (bool): Whether to display the figure. Default is True.
|
|
57
|
+
save_figure (bool): Whether to save the figure. Default is False.
|
|
58
|
+
output_dir (str): The directory to save the figure if save_figure is True. Default is "./".
|
|
59
|
+
output_fname (str): The filename to save the figure as if save_figure is True. Default is "iv_curve.png".
|
|
49
60
|
|
|
50
61
|
Returns:
|
|
51
62
|
tuple: A tuple containing:
|
|
@@ -57,7 +68,8 @@ def compute_plot_iv_curve(cell,
|
|
|
57
68
|
ValueError: If the cell object is invalid, the specified sections/segments are not found, or if
|
|
58
69
|
the simulation results are inconsistent.
|
|
59
70
|
"""
|
|
60
|
-
rheobase
|
|
71
|
+
if rheobase is None:
|
|
72
|
+
rheobase = calculate_rheobase(cell=cell, section=injecting_section, segx=injecting_segment)
|
|
61
73
|
|
|
62
74
|
list_amp = np.linspace(rheobase - 2, rheobase - 0.1, nb_bins) # [nA]
|
|
63
75
|
|
|
@@ -89,7 +101,7 @@ def compute_plot_iv_curve(cell,
|
|
|
89
101
|
'stim_end': [stim_start + duration]
|
|
90
102
|
}
|
|
91
103
|
features_results = efel.get_feature_values([trace], ['steady_state_voltage_stimend'])
|
|
92
|
-
steady_state = features_results[0]['steady_state_voltage_stimend']
|
|
104
|
+
steady_state = features_results[0]['steady_state_voltage_stimend'][0]
|
|
93
105
|
steady_states.append(steady_state)
|
|
94
106
|
|
|
95
107
|
plot_iv_curve(list_amp,
|
|
@@ -97,7 +109,11 @@ def compute_plot_iv_curve(cell,
|
|
|
97
109
|
injecting_section=injecting_section,
|
|
98
110
|
injecting_segment=injecting_segment,
|
|
99
111
|
recording_section=recording_section,
|
|
100
|
-
recording_segment=recording_segment
|
|
112
|
+
recording_segment=recording_segment,
|
|
113
|
+
show_figure=show_figure,
|
|
114
|
+
save_figure=save_figure,
|
|
115
|
+
output_dir=output_dir,
|
|
116
|
+
output_fname=output_fname)
|
|
101
117
|
|
|
102
118
|
return np.array(list_amp), np.array(steady_states)
|
|
103
119
|
|
|
@@ -111,7 +127,13 @@ def compute_plot_fi_curve(cell,
|
|
|
111
127
|
duration=500.0,
|
|
112
128
|
post_delay=100.0,
|
|
113
129
|
max_current=0.8,
|
|
114
|
-
|
|
130
|
+
threshold_voltage=-20,
|
|
131
|
+
nb_bins=11,
|
|
132
|
+
rheobase=None,
|
|
133
|
+
show_figure=True,
|
|
134
|
+
save_figure=False,
|
|
135
|
+
output_dir="./",
|
|
136
|
+
output_fname="fi_curve.pdf"):
|
|
115
137
|
"""Compute and plot the Frequency-Current (F-I) curve for a given cell by
|
|
116
138
|
injecting a range of currents.
|
|
117
139
|
|
|
@@ -135,8 +157,16 @@ def compute_plot_fi_curve(cell,
|
|
|
135
157
|
(in ms). Default is 100.0 ms.
|
|
136
158
|
max_current (float, optional): The maximum amplitude of the injected current (in nA).
|
|
137
159
|
Default is 0.8 nA.
|
|
160
|
+
threshold_voltage (float, optional): The voltage threshold (in mV) for detecting a steady-state
|
|
161
|
+
response. Default is -30 mV.
|
|
138
162
|
nb_bins (int, optional): The number of discrete current levels between 0 and `max_current`.
|
|
139
163
|
Default is 11.
|
|
164
|
+
rheobase (float, optional): The rheobase current (in nA) for the cell. If not provided, it will
|
|
165
|
+
be calculated using the `calculate_rheobase` function.
|
|
166
|
+
show_figure (bool): Whether to display the figure. Default is True.
|
|
167
|
+
save_figure (bool): Whether to save the figure. Default is False.
|
|
168
|
+
output_dir (str): The directory to save the figure if save_figure is True. Default is "./".
|
|
169
|
+
output_fname (str): The filename to save the figure as if save_figure is True. Default is "iv_curve.png".
|
|
140
170
|
|
|
141
171
|
Returns:
|
|
142
172
|
tuple: A tuple containing:
|
|
@@ -146,7 +176,8 @@ def compute_plot_fi_curve(cell,
|
|
|
146
176
|
Raises:
|
|
147
177
|
ValueError: If the cell object is invalid or the specified sections/segments are not found.
|
|
148
178
|
"""
|
|
149
|
-
rheobase
|
|
179
|
+
if rheobase is None:
|
|
180
|
+
rheobase = calculate_rheobase(cell=cell, section=injecting_section, segx=injecting_segment)
|
|
150
181
|
|
|
151
182
|
list_amp = np.linspace(rheobase, max_current, nb_bins) # [nA]
|
|
152
183
|
steps = []
|
|
@@ -161,7 +192,8 @@ def compute_plot_fi_curve(cell,
|
|
|
161
192
|
segment=injecting_segment,
|
|
162
193
|
recording_section=recording_section,
|
|
163
194
|
recording_segment=recording_segment,
|
|
164
|
-
enable_spike_detection=True
|
|
195
|
+
enable_spike_detection=True,
|
|
196
|
+
threshold_spike_detection=threshold_voltage)
|
|
165
197
|
steps.append(step_stimulus)
|
|
166
198
|
spikes.append(recording.spike)
|
|
167
199
|
|
|
@@ -172,6 +204,10 @@ def compute_plot_fi_curve(cell,
|
|
|
172
204
|
injecting_section=injecting_section,
|
|
173
205
|
injecting_segment=injecting_segment,
|
|
174
206
|
recording_section=recording_section,
|
|
175
|
-
recording_segment=recording_segment
|
|
207
|
+
recording_segment=recording_segment,
|
|
208
|
+
show_figure=show_figure,
|
|
209
|
+
save_figure=save_figure,
|
|
210
|
+
output_dir=output_dir,
|
|
211
|
+
output_fname=output_fname)
|
|
176
212
|
|
|
177
213
|
return np.array(list_amp), np.array(spike_count)
|
|
@@ -36,18 +36,17 @@ class Recording(NamedTuple):
|
|
|
36
36
|
StimulusRecordings = Dict[str, Recording]
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
def
|
|
39
|
+
def run_multirecordings_stimulus(
|
|
40
40
|
template_params: TemplateParams,
|
|
41
41
|
stimulus: Stimulus,
|
|
42
42
|
section: str,
|
|
43
43
|
segment: float,
|
|
44
44
|
cvode: bool = True,
|
|
45
45
|
add_hypamp: bool = True,
|
|
46
|
-
|
|
47
|
-
recording_segment: float = 0.5,
|
|
46
|
+
recording_locations: list[tuple[str, float]] = [("soma[0]", 0.5)],
|
|
48
47
|
enable_spike_detection: bool = False,
|
|
49
|
-
threshold_spike_detection: float = -
|
|
50
|
-
) -> Recording:
|
|
48
|
+
threshold_spike_detection: float = -20.0,
|
|
49
|
+
) -> list[Recording]:
|
|
51
50
|
"""Creates a cell from template parameters, applies a stimulus, and records
|
|
52
51
|
the response.
|
|
53
52
|
|
|
@@ -66,16 +65,17 @@ def run_stimulus(
|
|
|
66
65
|
cvode (bool, optional): Whether to use variable time-step integration. Defaults to True.
|
|
67
66
|
add_hypamp (bool, optional): If True, adds a hyperpolarizing stimulus before applying
|
|
68
67
|
the main stimulus. Defaults to True.
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
recording_location (list): List of tuples containing the name of the section of the cell
|
|
69
|
+
where voltage is recorded and the normalized position (0.0 to 1.0) along the recording
|
|
71
70
|
section where voltage is recorded.
|
|
71
|
+
(e.g. [("soma[0]", 0.5), ("dend[0]", 0.5)])
|
|
72
72
|
enable_spike_detection (bool, optional): If True, enables spike detection at the
|
|
73
73
|
recording location. Defaults to False.
|
|
74
74
|
threshold_spike_detection (float, optional): The voltage threshold (mV) for spike detection.
|
|
75
|
-
Defaults to -
|
|
75
|
+
Defaults to -20 mV.
|
|
76
76
|
|
|
77
77
|
Returns:
|
|
78
|
-
Recording:
|
|
78
|
+
list[Recording]: `Recording` objects containing the following:
|
|
79
79
|
- `current` (np.ndarray): The injected current waveform (nA).
|
|
80
80
|
- `voltage` (np.ndarray): The recorded membrane potential (mV) over time.
|
|
81
81
|
- `time` (np.ndarray): The simulation time points (ms).
|
|
@@ -88,19 +88,22 @@ def run_stimulus(
|
|
|
88
88
|
cell = Cell.from_template_parameters(template_params)
|
|
89
89
|
|
|
90
90
|
validate_section_and_segment(cell, section, segment)
|
|
91
|
-
|
|
91
|
+
for recording_section, recording_segment in recording_locations:
|
|
92
|
+
validate_section_and_segment(cell, recording_section, recording_segment)
|
|
92
93
|
|
|
93
94
|
if add_hypamp:
|
|
94
95
|
hyp_stim = Hyperpolarizing(target="", delay=0.0, duration=stimulus.stimulus_time)
|
|
95
96
|
cell.add_replay_hypamp(hyp_stim)
|
|
96
97
|
|
|
97
|
-
|
|
98
|
+
for recording_section, recording_segment in recording_locations:
|
|
99
|
+
cell.add_voltage_recording(cell.sections[recording_section], recording_segment)
|
|
98
100
|
|
|
99
101
|
# Set up spike detection if enabled
|
|
100
102
|
spikes: Optional[np.ndarray] = None
|
|
101
103
|
if enable_spike_detection:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
for recording_section, recording_segment in recording_locations:
|
|
105
|
+
recording_location = f"{recording_section}({str(recording_segment)})"
|
|
106
|
+
cell.start_recording_spikes(None, location=recording_location, threshold=threshold_spike_detection)
|
|
104
107
|
|
|
105
108
|
# Inject the stimulus and run the simulation
|
|
106
109
|
iclamp, _ = cell.inject_current_waveform(
|
|
@@ -113,21 +116,90 @@ def run_stimulus(
|
|
|
113
116
|
simulation.run(stimulus.stimulus_time, cvode=cvode)
|
|
114
117
|
|
|
115
118
|
# Retrieve simulation results
|
|
119
|
+
recordings = []
|
|
116
120
|
current = np.array(current_vector.to_python())
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
for recording_section, recording_segment in recording_locations:
|
|
122
|
+
recording_location = f"{recording_section}({str(recording_segment)})"
|
|
123
|
+
voltage = cell.get_voltage_recording(cell.sections[recording_section], recording_segment)
|
|
124
|
+
time = cell.get_time()
|
|
119
125
|
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
if len(time) != len(voltage) or len(time) != len(current):
|
|
127
|
+
raise ValueError("Time, current, and voltage arrays are not the same length")
|
|
122
128
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
if enable_spike_detection:
|
|
130
|
+
results = cell.get_recorded_spikes(location=recording_location, threshold=threshold_spike_detection)
|
|
131
|
+
if results is not None:
|
|
132
|
+
spikes = np.array(results)
|
|
133
|
+
else:
|
|
134
|
+
spikes = None
|
|
135
|
+
|
|
136
|
+
recordings.append(
|
|
137
|
+
Recording(current=current, voltage=voltage, time=time, spike=spikes)
|
|
138
|
+
)
|
|
129
139
|
|
|
130
|
-
return
|
|
140
|
+
return recordings
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def run_stimulus(
|
|
144
|
+
template_params: TemplateParams,
|
|
145
|
+
stimulus: Stimulus,
|
|
146
|
+
section: str,
|
|
147
|
+
segment: float,
|
|
148
|
+
cvode: bool = True,
|
|
149
|
+
add_hypamp: bool = True,
|
|
150
|
+
recording_section: str = "soma[0]",
|
|
151
|
+
recording_segment: float = 0.5,
|
|
152
|
+
enable_spike_detection: bool = False,
|
|
153
|
+
threshold_spike_detection: float = -20.0,
|
|
154
|
+
) -> Recording:
|
|
155
|
+
"""Creates a cell from template parameters, applies a stimulus, and records
|
|
156
|
+
the response.
|
|
157
|
+
|
|
158
|
+
This function simulates the electrical activity of a neuronal cell model by injecting
|
|
159
|
+
a stimulus into a specified section and segment, recording the voltage response, and
|
|
160
|
+
optionally detecting spikes.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
template_params (TemplateParams): Parameters required to create the cell from a
|
|
164
|
+
specified template, including morphology and mechanisms.
|
|
165
|
+
stimulus (Stimulus): The stimulus waveform to inject, defined by time and current arrays.
|
|
166
|
+
section (str): Name of the section of the cell where the stimulus is applied.
|
|
167
|
+
(e.g. soma[0])
|
|
168
|
+
segment (float): The normalized position (0.0 to 1.0) along the injecting
|
|
169
|
+
section where the stimulus is applied.
|
|
170
|
+
cvode (bool, optional): Whether to use variable time-step integration. Defaults to True.
|
|
171
|
+
add_hypamp (bool, optional): If True, adds a hyperpolarizing stimulus before applying
|
|
172
|
+
the main stimulus. Defaults to True.
|
|
173
|
+
recording_section (str): Name of the section of the cell where voltage is recorded.
|
|
174
|
+
recording_segment (float): The normalized position (0.0 to 1.0) along the recording
|
|
175
|
+
section where voltage is recorded.
|
|
176
|
+
enable_spike_detection (bool, optional): If True, enables spike detection at the
|
|
177
|
+
recording location. Defaults to False.
|
|
178
|
+
threshold_spike_detection (float, optional): The voltage threshold (mV) for spike detection.
|
|
179
|
+
Defaults to -20 mV.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
Recording: A `Recording` object containing the following:
|
|
183
|
+
- `current` (np.ndarray): The injected current waveform (nA).
|
|
184
|
+
- `voltage` (np.ndarray): The recorded membrane potential (mV) over time.
|
|
185
|
+
- `time` (np.ndarray): The simulation time points (ms).
|
|
186
|
+
- `spike` (np.ndarray or None): The detected spikes, if spike detection is enabled.
|
|
187
|
+
|
|
188
|
+
Raises:
|
|
189
|
+
ValueError: If the time, current, and voltage arrays do not have the same length,
|
|
190
|
+
or if the specified sections or segments are not found in the cell model.
|
|
191
|
+
"""
|
|
192
|
+
return run_multirecordings_stimulus(
|
|
193
|
+
template_params=template_params,
|
|
194
|
+
stimulus=stimulus,
|
|
195
|
+
section=section,
|
|
196
|
+
segment=segment,
|
|
197
|
+
cvode=cvode,
|
|
198
|
+
add_hypamp=add_hypamp,
|
|
199
|
+
recording_locations=[(recording_section, recording_segment)],
|
|
200
|
+
enable_spike_detection=enable_spike_detection,
|
|
201
|
+
threshold_spike_detection=threshold_spike_detection,
|
|
202
|
+
)[0]
|
|
131
203
|
|
|
132
204
|
|
|
133
205
|
def apply_multiple_stimuli(
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
"""Module for plotting analysis results of cell simulations."""
|
|
2
2
|
|
|
3
3
|
import matplotlib.pyplot as plt
|
|
4
|
+
import pathlib
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def plot_iv_curve(
|
|
7
|
+
def plot_iv_curve(
|
|
8
|
+
currents,
|
|
9
|
+
voltages,
|
|
10
|
+
injecting_section,
|
|
11
|
+
injecting_segment,
|
|
12
|
+
recording_section,
|
|
13
|
+
recording_segment,
|
|
14
|
+
show_figure=True,
|
|
15
|
+
save_figure=False,
|
|
16
|
+
output_dir="./",
|
|
17
|
+
output_fname="iv_curve.pdf",
|
|
18
|
+
):
|
|
7
19
|
"""Plots the IV curve.
|
|
8
20
|
|
|
9
21
|
Args:
|
|
@@ -13,6 +25,10 @@ def plot_iv_curve(currents, voltages, injecting_section, injecting_segment, reco
|
|
|
13
25
|
injecting_segment (float): The segment position (0.0 to 1.0) where the current was injected.
|
|
14
26
|
recording_section (str): The section in the cell where spikes were recorded.
|
|
15
27
|
recording_segment (float): The segment position (0.0 to 1.0) where spikes were recorded.
|
|
28
|
+
show_figure (bool): Whether to display the figure. Default is True.
|
|
29
|
+
save_figure (bool): Whether to save the figure. Default is False.
|
|
30
|
+
output_dir (str): The directory to save the figure if save_figure is True. Default is "./".
|
|
31
|
+
output_fname (str): The filename to save the figure as if save_figure is True. Default is "iv_curve.pdf".
|
|
16
32
|
|
|
17
33
|
Raises:
|
|
18
34
|
ValueError: If the lengths of currents and voltages do not match.
|
|
@@ -27,10 +43,27 @@ def plot_iv_curve(currents, voltages, injecting_section, injecting_segment, reco
|
|
|
27
43
|
plt.ylabel(f"Steady state voltage [mV] at {recording_section}({recording_segment:.2f})")
|
|
28
44
|
plt.grid(True)
|
|
29
45
|
plt.tight_layout()
|
|
30
|
-
|
|
46
|
+
if show_figure:
|
|
47
|
+
plt.show()
|
|
31
48
|
|
|
49
|
+
if save_figure:
|
|
50
|
+
pathlib.Path(output_dir).mkdir(parents=True, exist_ok=True)
|
|
51
|
+
plt.savefig(pathlib.Path(output_dir) / output_fname, format='pdf')
|
|
52
|
+
plt.close()
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
|
|
55
|
+
def plot_fi_curve(
|
|
56
|
+
currents,
|
|
57
|
+
spike_count,
|
|
58
|
+
injecting_section,
|
|
59
|
+
injecting_segment,
|
|
60
|
+
recording_section,
|
|
61
|
+
recording_segment,
|
|
62
|
+
show_figure=True,
|
|
63
|
+
save_figure=False,
|
|
64
|
+
output_dir="./",
|
|
65
|
+
output_fname="fi_curve.pdf",
|
|
66
|
+
):
|
|
34
67
|
"""Plots the F-I (Frequency-Current) curve.
|
|
35
68
|
|
|
36
69
|
Args:
|
|
@@ -40,6 +73,10 @@ def plot_fi_curve(currents, spike_count, injecting_section, injecting_segment, r
|
|
|
40
73
|
injecting_segment (float): The segment position (0.0 to 1.0) where the current was injected.
|
|
41
74
|
recording_section (str): The section in the cell where spikes were recorded.
|
|
42
75
|
recording_segment (float): The segment position (0.0 to 1.0) where spikes were recorded.
|
|
76
|
+
show_figure (bool): Whether to display the figure. Default is True.
|
|
77
|
+
save_figure (bool): Whether to save the figure. Default is False.
|
|
78
|
+
output_dir (str): The directory to save the figure if save_figure is True. Default is "./".
|
|
79
|
+
output_fname (str): The filename to save the figure as if save_figure is True. Default is "fi_curve.pdf".
|
|
43
80
|
|
|
44
81
|
Raises:
|
|
45
82
|
ValueError: If the lengths of currents and spike counts do not match.
|
|
@@ -54,4 +91,10 @@ def plot_fi_curve(currents, spike_count, injecting_section, injecting_segment, r
|
|
|
54
91
|
plt.ylabel(f"Spike Count recorded at {recording_section}({recording_segment:.2f})")
|
|
55
92
|
plt.grid(True)
|
|
56
93
|
plt.tight_layout()
|
|
57
|
-
|
|
94
|
+
if show_figure:
|
|
95
|
+
plt.show()
|
|
96
|
+
|
|
97
|
+
if save_figure:
|
|
98
|
+
pathlib.Path(output_dir).mkdir(parents=True, exist_ok=True)
|
|
99
|
+
plt.savefig(pathlib.Path(output_dir) / output_fname, format='pdf')
|
|
100
|
+
plt.close()
|