bluecellulab 2.6.43__tar.gz → 2.6.45__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.43 → bluecellulab-2.6.45}/PKG-INFO +1 -1
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/injector.py +36 -5
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/circuit_access/sonata_circuit_access.py +2 -1
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit_simulation.py +29 -3
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/stimulus/circuit_stimulus_definitions.py +37 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/stimulus/factory.py +67 -1
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/stimulus/stimulus.py +103 -5
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab.egg-info/PKG-INFO +1 -1
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.compile_mod.sh +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.gitattributes +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.github/dependabot.yml +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.github/workflows/release.yml +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.github/workflows/test.yml +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.gitignore +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.gitlab-ci.yml +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.readthedocs.yml +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/.zenodo.json +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/AUTHORS.txt +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/CHANGELOG.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/CITATION.cff +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/CONTRIBUTING.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/LICENSE +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/MANIFEST.in +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/Makefile +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/README.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/analysis/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/analysis/analysis.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/analysis/inject_sequence.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/analysis/plotting.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/ballstick/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/ballstick/emodel.hoc +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/ballstick/morphology.asc +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/cell_dict.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/core.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/plotting.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/random.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/recording.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/section_distance.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/serialized_sections.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/sonata_proxy.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/stimuli_generator.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/cell/template.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/circuit_access/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/circuit_access/bluepy_circuit_access.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/circuit_access/definition.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/config/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/config/bluepy_simulation_config.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/config/definition.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/config/sections.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/config/sonata_simulation_config.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/format.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/iotools.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/node_id.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/simulation_access.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/synapse_properties.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/validate.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/connection.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/dendrogram.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/exceptions.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/graph.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/hoc/Cell.hoc +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/hoc/RNGSettings.hoc +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/hoc/TDistFunc.hoc +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/hoc/TStim.hoc +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/hoc/fileUtils.hoc +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/importer.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/neuron_interpreter.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/plotwindow.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/psection.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/psegment.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/rngsettings.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/simulation/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/simulation/neuron_globals.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/simulation/parallel.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/simulation/simulation.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/stimulus/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/synapse/__init__.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/synapse/synapse_factory.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/synapse/synapse_types.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/tools.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/type_aliases.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/utils.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/verbosity.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab.egg-info/SOURCES.txt +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab.egg-info/dependency_links.txt +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab.egg-info/requires.txt +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab.egg-info/top_level.txt +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/Makefile +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/images/voltage-readme.png +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/make.bat +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/requirements_docs.txt +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/_static/.gitkeep +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/api.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/changelog.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/compiling-mechanisms.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/conf.py +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/contributing.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/index.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/list_of_stim.rst +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/docs/source/logo/BlueCelluLabBanner.jpg +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/pyproject.toml +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/setup.cfg +0 -0
- {bluecellulab-2.6.43 → bluecellulab-2.6.45}/tox.ini +0 -0
|
@@ -30,6 +30,8 @@ from bluecellulab.exceptions import BluecellulabError
|
|
|
30
30
|
from bluecellulab.rngsettings import RNGSettings
|
|
31
31
|
from bluecellulab.stimulus.circuit_stimulus_definitions import (
|
|
32
32
|
ClampMode,
|
|
33
|
+
Linear,
|
|
34
|
+
RelativeLinear,
|
|
33
35
|
Hyperpolarizing,
|
|
34
36
|
Noise,
|
|
35
37
|
OrnsteinUhlenbeck,
|
|
@@ -259,12 +261,32 @@ class InjectableMixin:
|
|
|
259
261
|
self.persistent.append(tstim) # type: ignore
|
|
260
262
|
return tstim
|
|
261
263
|
|
|
262
|
-
def
|
|
264
|
+
def add_replay_linear(self, stimulus: Linear):
|
|
265
|
+
"""Add a linear stimulus."""
|
|
266
|
+
|
|
267
|
+
return self.add_ramp(
|
|
268
|
+
stimulus.delay,
|
|
269
|
+
stimulus.delay + stimulus.duration,
|
|
270
|
+
stimulus.amp_start,
|
|
271
|
+
stimulus.amp_end
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def add_replay_relativelinear(self, stimulus: RelativeLinear):
|
|
263
275
|
"""Add a relative linear stimulus."""
|
|
264
|
-
tstim = neuron.h.TStim(0.5, sec=self.soma)
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
276
|
+
tstim = neuron.h.TStim(0.5, sec=self.soma) # type: ignore
|
|
277
|
+
amp_start = stimulus.percent_start / 100.0 * self.threshold # type: ignore
|
|
278
|
+
amp_end = stimulus.percent_end / 100.0 * self.threshold # type: ignore
|
|
279
|
+
|
|
280
|
+
tstim.ramp(
|
|
281
|
+
0.0,
|
|
282
|
+
stimulus.delay, # Time when the ramp starts
|
|
283
|
+
amp_start, # Initial amplitude (amp_start)
|
|
284
|
+
amp_end, # Final amplitude (amp_end)
|
|
285
|
+
stimulus.duration, # Duration of the ramp
|
|
286
|
+
0.0,
|
|
287
|
+
0.0
|
|
288
|
+
)
|
|
289
|
+
self.persistent.append(tstim) # type: ignore
|
|
268
290
|
|
|
269
291
|
return tstim
|
|
270
292
|
|
|
@@ -493,3 +515,12 @@ class InjectableMixin:
|
|
|
493
515
|
syn.e = e
|
|
494
516
|
self.persistent.append(syn) # type: ignore
|
|
495
517
|
return syn
|
|
518
|
+
|
|
519
|
+
def add_sinusoidal(self, stimulus) -> TStim:
|
|
520
|
+
"""Inject sinusoidal stimulus for replay."""
|
|
521
|
+
return self.add_sin_current(
|
|
522
|
+
stimulus.amp_start,
|
|
523
|
+
stimulus.delay,
|
|
524
|
+
stimulus.duration,
|
|
525
|
+
stimulus.frequency,
|
|
526
|
+
)
|
|
@@ -152,8 +152,9 @@ class SonataCircuitAccess:
|
|
|
152
152
|
|
|
153
153
|
# make multiindex
|
|
154
154
|
synapses = synapses.reset_index(drop=True)
|
|
155
|
+
synapse_ids = list(synapses.index)
|
|
155
156
|
synapses.index = pd.MultiIndex.from_tuples(
|
|
156
|
-
|
|
157
|
+
[(edge_population_name, syn_id) for syn_id in synapse_ids],
|
|
157
158
|
names=["edge_name", "synapse_id"],
|
|
158
159
|
)
|
|
159
160
|
|
|
@@ -139,6 +139,8 @@ class CircuitSimulation:
|
|
|
139
139
|
pre_spike_trains: None | dict[tuple[str, int], Iterable] | dict[int, Iterable] = None,
|
|
140
140
|
add_shotnoise_stimuli: bool = False,
|
|
141
141
|
add_ornstein_uhlenbeck_stimuli: bool = False,
|
|
142
|
+
add_sinusoidal_stimuli: bool = False,
|
|
143
|
+
add_linear_stimuli: bool = False,
|
|
142
144
|
):
|
|
143
145
|
"""Instantiate a list of cells.
|
|
144
146
|
|
|
@@ -209,6 +211,16 @@ class CircuitSimulation:
|
|
|
209
211
|
of the simulation config,
|
|
210
212
|
Setting add_stimuli=True,
|
|
211
213
|
will automatically set this option to True.
|
|
214
|
+
add_sinusoidal_stimuli : Process the 'sinusoidal' stimuli
|
|
215
|
+
blocks of the simulation config.
|
|
216
|
+
Setting add_stimuli=True,
|
|
217
|
+
will automatically set this option to
|
|
218
|
+
True.
|
|
219
|
+
add_linear_stimuli : Process the 'linear' stimuli
|
|
220
|
+
blocks of the simulation config.
|
|
221
|
+
Setting add_stimuli=True,
|
|
222
|
+
will automatically set this option to
|
|
223
|
+
True.
|
|
212
224
|
"""
|
|
213
225
|
if not isinstance(cells, Iterable) or isinstance(cells, tuple):
|
|
214
226
|
cells = [cells]
|
|
@@ -265,22 +277,28 @@ class CircuitSimulation:
|
|
|
265
277
|
add_hyperpolarizing_stimuli = True
|
|
266
278
|
add_relativelinear_stimuli = True
|
|
267
279
|
add_pulse_stimuli = True
|
|
280
|
+
add_sinusoidal_stimuli = True
|
|
268
281
|
add_shotnoise_stimuli = True
|
|
269
282
|
add_ornstein_uhlenbeck_stimuli = True
|
|
283
|
+
add_linear_stimuli = True
|
|
270
284
|
|
|
271
285
|
if add_noise_stimuli or \
|
|
272
286
|
add_hyperpolarizing_stimuli or \
|
|
273
287
|
add_pulse_stimuli or \
|
|
274
288
|
add_relativelinear_stimuli or \
|
|
275
289
|
add_shotnoise_stimuli or \
|
|
276
|
-
add_ornstein_uhlenbeck_stimuli
|
|
290
|
+
add_ornstein_uhlenbeck_stimuli or \
|
|
291
|
+
add_sinusoidal_stimuli or \
|
|
292
|
+
add_linear_stimuli:
|
|
277
293
|
self._add_stimuli(
|
|
278
294
|
add_noise_stimuli=add_noise_stimuli,
|
|
279
295
|
add_hyperpolarizing_stimuli=add_hyperpolarizing_stimuli,
|
|
280
296
|
add_relativelinear_stimuli=add_relativelinear_stimuli,
|
|
281
297
|
add_pulse_stimuli=add_pulse_stimuli,
|
|
282
298
|
add_shotnoise_stimuli=add_shotnoise_stimuli,
|
|
283
|
-
add_ornstein_uhlenbeck_stimuli=add_ornstein_uhlenbeck_stimuli
|
|
299
|
+
add_ornstein_uhlenbeck_stimuli=add_ornstein_uhlenbeck_stimuli,
|
|
300
|
+
add_sinusoidal_stimuli=add_sinusoidal_stimuli,
|
|
301
|
+
add_linear_stimuli=add_linear_stimuli
|
|
284
302
|
)
|
|
285
303
|
|
|
286
304
|
def _add_stimuli(self, add_noise_stimuli=False,
|
|
@@ -288,7 +306,9 @@ class CircuitSimulation:
|
|
|
288
306
|
add_relativelinear_stimuli=False,
|
|
289
307
|
add_pulse_stimuli=False,
|
|
290
308
|
add_shotnoise_stimuli=False,
|
|
291
|
-
add_ornstein_uhlenbeck_stimuli=False
|
|
309
|
+
add_ornstein_uhlenbeck_stimuli=False,
|
|
310
|
+
add_sinusoidal_stimuli=False,
|
|
311
|
+
add_linear_stimuli=False
|
|
292
312
|
):
|
|
293
313
|
"""Instantiate all the stimuli."""
|
|
294
314
|
stimuli_entries = self.circuit_access.config.get_all_stimuli_entries()
|
|
@@ -316,6 +336,9 @@ class CircuitSimulation:
|
|
|
316
336
|
elif isinstance(stimulus, circuit_stimulus_definitions.Pulse):
|
|
317
337
|
if add_pulse_stimuli:
|
|
318
338
|
self.cells[cell_id].add_pulse(stimulus)
|
|
339
|
+
elif isinstance(stimulus, circuit_stimulus_definitions.Linear):
|
|
340
|
+
if add_linear_stimuli:
|
|
341
|
+
self.cells[cell_id].add_replay_linear(stimulus)
|
|
319
342
|
elif isinstance(stimulus, circuit_stimulus_definitions.RelativeLinear):
|
|
320
343
|
if add_relativelinear_stimuli:
|
|
321
344
|
self.cells[cell_id].add_replay_relativelinear(stimulus)
|
|
@@ -339,6 +362,9 @@ class CircuitSimulation:
|
|
|
339
362
|
self.cells[cell_id].add_relative_ornstein_uhlenbeck(
|
|
340
363
|
self.cells[cell_id].soma, 0.5, stimulus,
|
|
341
364
|
stim_count=ornstein_uhlenbeck_stim_count)
|
|
365
|
+
elif isinstance(stimulus, circuit_stimulus_definitions.Sinusoidal):
|
|
366
|
+
if add_sinusoidal_stimuli:
|
|
367
|
+
self.cells[cell_id].add_sinusoidal(stimulus)
|
|
342
368
|
elif isinstance(stimulus, circuit_stimulus_definitions.SynapseReplay): # sonata only
|
|
343
369
|
if self.circuit_access.target_contains_cell(
|
|
344
370
|
stimulus.target, cell_id
|
{bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/stimulus/circuit_stimulus_definitions.py
RENAMED
|
@@ -42,12 +42,14 @@ class Pattern(Enum):
|
|
|
42
42
|
NOISE = "noise"
|
|
43
43
|
HYPERPOLARIZING = "hyperpolarizing"
|
|
44
44
|
PULSE = "pulse"
|
|
45
|
+
LINEAR = "linear"
|
|
45
46
|
RELATIVE_LINEAR = "relative_linear"
|
|
46
47
|
SYNAPSE_REPLAY = "synapse_replay"
|
|
47
48
|
SHOT_NOISE = "shot_noise"
|
|
48
49
|
RELATIVE_SHOT_NOISE = "relative_shot_noise"
|
|
49
50
|
ORNSTEIN_UHLENBECK = "ornstein_uhlenbeck"
|
|
50
51
|
RELATIVE_ORNSTEIN_UHLENBECK = "relative_ornstein_uhlenbeck"
|
|
52
|
+
SINUSOIDAL = "sinusoidal"
|
|
51
53
|
|
|
52
54
|
@classmethod
|
|
53
55
|
def from_blueconfig(cls, pattern: str) -> Pattern:
|
|
@@ -80,6 +82,8 @@ class Pattern(Enum):
|
|
|
80
82
|
return Pattern.HYPERPOLARIZING
|
|
81
83
|
elif pattern == "pulse":
|
|
82
84
|
return Pattern.PULSE
|
|
85
|
+
elif pattern == "linear":
|
|
86
|
+
return Pattern.LINEAR
|
|
83
87
|
elif pattern == "relative_linear":
|
|
84
88
|
return Pattern.RELATIVE_LINEAR
|
|
85
89
|
elif pattern == "synapse_replay":
|
|
@@ -92,6 +96,8 @@ class Pattern(Enum):
|
|
|
92
96
|
return Pattern.ORNSTEIN_UHLENBECK
|
|
93
97
|
elif pattern == "relative_ornstein_uhlenbeck":
|
|
94
98
|
return Pattern.RELATIVE_ORNSTEIN_UHLENBECK
|
|
99
|
+
elif pattern == "sinusoidal":
|
|
100
|
+
return Pattern.SINUSOIDAL
|
|
95
101
|
else:
|
|
96
102
|
raise ValueError(f"Unknown pattern {pattern}")
|
|
97
103
|
|
|
@@ -141,6 +147,7 @@ class Stimulus:
|
|
|
141
147
|
delay=stimulus_entry["Delay"],
|
|
142
148
|
duration=stimulus_entry["Duration"],
|
|
143
149
|
percent_start=stimulus_entry["PercentStart"],
|
|
150
|
+
percent_end=stimulus_entry["PercentEnd"],
|
|
144
151
|
)
|
|
145
152
|
elif pattern == Pattern.SYNAPSE_REPLAY:
|
|
146
153
|
warnings.warn("Ignoring syanpse replay stimulus as it is not supported")
|
|
@@ -230,12 +237,21 @@ class Stimulus:
|
|
|
230
237
|
width=stimulus_entry["width"],
|
|
231
238
|
frequency=stimulus_entry["frequency"],
|
|
232
239
|
)
|
|
240
|
+
elif pattern == Pattern.LINEAR:
|
|
241
|
+
return Linear(
|
|
242
|
+
target=stimulus_entry["node_set"],
|
|
243
|
+
delay=stimulus_entry["delay"],
|
|
244
|
+
duration=stimulus_entry["duration"],
|
|
245
|
+
amp_start=stimulus_entry["amp_start"],
|
|
246
|
+
amp_end=stimulus_entry["amp_end"],
|
|
247
|
+
)
|
|
233
248
|
elif pattern == Pattern.RELATIVE_LINEAR:
|
|
234
249
|
return RelativeLinear(
|
|
235
250
|
target=stimulus_entry["node_set"],
|
|
236
251
|
delay=stimulus_entry["delay"],
|
|
237
252
|
duration=stimulus_entry["duration"],
|
|
238
253
|
percent_start=stimulus_entry["percent_start"],
|
|
254
|
+
percent_end=stimulus_entry["percent_end"],
|
|
239
255
|
)
|
|
240
256
|
elif pattern == Pattern.SYNAPSE_REPLAY:
|
|
241
257
|
return SynapseReplay(
|
|
@@ -300,6 +316,14 @@ class Stimulus:
|
|
|
300
316
|
mode=ClampMode(stimulus_entry.get("input_type", "current_clamp").lower()),
|
|
301
317
|
reversal=stimulus_entry.get("reversal", 0.0)
|
|
302
318
|
)
|
|
319
|
+
elif pattern == Pattern.SINUSOIDAL:
|
|
320
|
+
return Sinusoidal(
|
|
321
|
+
target=stimulus_entry["node_set"],
|
|
322
|
+
delay=stimulus_entry["delay"],
|
|
323
|
+
duration=stimulus_entry["duration"],
|
|
324
|
+
amp_start=stimulus_entry["amp_start"],
|
|
325
|
+
frequency=stimulus_entry["frequency"],
|
|
326
|
+
)
|
|
303
327
|
else:
|
|
304
328
|
raise ValueError(f"Unknown pattern {pattern}")
|
|
305
329
|
|
|
@@ -322,9 +346,16 @@ class Pulse(Stimulus):
|
|
|
322
346
|
frequency: float
|
|
323
347
|
|
|
324
348
|
|
|
349
|
+
@dataclass(frozen=True, config=dict(extra="forbid"))
|
|
350
|
+
class Linear(Stimulus):
|
|
351
|
+
amp_start: float
|
|
352
|
+
amp_end: float
|
|
353
|
+
|
|
354
|
+
|
|
325
355
|
@dataclass(frozen=True, config=dict(extra="forbid"))
|
|
326
356
|
class RelativeLinear(Stimulus):
|
|
327
357
|
percent_start: float
|
|
358
|
+
percent_end: float
|
|
328
359
|
|
|
329
360
|
|
|
330
361
|
@dataclass(frozen=True, config=dict(extra="forbid"))
|
|
@@ -416,3 +447,9 @@ class RelativeOrnsteinUhlenbeck(Stimulus):
|
|
|
416
447
|
seed: Optional[int] = None
|
|
417
448
|
mode: ClampMode = ClampMode.CURRENT
|
|
418
449
|
reversal: float = 0.0
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
@dataclass(frozen=True, config=dict(extra="forbid"))
|
|
453
|
+
class Sinusoidal(Stimulus):
|
|
454
|
+
amp_start: float
|
|
455
|
+
frequency: float
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
from typing import Optional
|
|
18
18
|
import logging
|
|
19
|
-
from bluecellulab.stimulus.stimulus import DelayedZap, Empty, Ramp, Slope, Step, StepNoise, Stimulus, OrnsteinUhlenbeck, ShotNoise
|
|
19
|
+
from bluecellulab.stimulus.stimulus import DelayedZap, Empty, Ramp, Slope, Step, StepNoise, Stimulus, OrnsteinUhlenbeck, ShotNoise, Sinusoidal
|
|
20
20
|
from bluecellulab.stimulus.circuit_stimulus_definitions import Stimulus as CircuitStimulus
|
|
21
21
|
|
|
22
22
|
logger = logging.getLogger(__name__)
|
|
@@ -376,6 +376,72 @@ class StimulusFactory:
|
|
|
376
376
|
|
|
377
377
|
raise TypeError("You have to give either threshold_current or amplitude")
|
|
378
378
|
|
|
379
|
+
def sinusoidal(
|
|
380
|
+
self,
|
|
381
|
+
pre_delay: float,
|
|
382
|
+
post_delay: float,
|
|
383
|
+
duration: float,
|
|
384
|
+
frequency: float,
|
|
385
|
+
amplitude: Optional[float] = None,
|
|
386
|
+
amplitude_percent: Optional[float] = None,
|
|
387
|
+
threshold_current: Optional[float] = None,
|
|
388
|
+
dt: float = 0.025,
|
|
389
|
+
) -> Stimulus:
|
|
390
|
+
"""Creates a Sinusoidal stimulus (factory-compatible).
|
|
391
|
+
|
|
392
|
+
Args:
|
|
393
|
+
pre_delay: Delay before the sinusoidal stimulus starts (ms).
|
|
394
|
+
post_delay: Delay after the stimulus ends (ms).
|
|
395
|
+
duration: Duration of the stimulus (ms).
|
|
396
|
+
frequency: Frequency of oscillation (Hz).
|
|
397
|
+
amplitude: Absolute amplitude (nA). Used if provided.
|
|
398
|
+
amplitude_percent: Amplitude as a percentage of threshold current.
|
|
399
|
+
threshold_current: Reference threshold current for percentage-based calculation.
|
|
400
|
+
dt: Time step of the stimulus (ms).
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
A `Stimulus` object (Sinusoidal) that can be plotted and injected.
|
|
404
|
+
|
|
405
|
+
Notes:
|
|
406
|
+
- If `amplitude` is provided, `amplitude_percent` is ignored.
|
|
407
|
+
- If `threshold_current` is not provided, threshold-based parameters cannot be used.
|
|
408
|
+
"""
|
|
409
|
+
is_amplitude_based = amplitude is not None
|
|
410
|
+
is_threshold_based = (
|
|
411
|
+
threshold_current is not None
|
|
412
|
+
and threshold_current != 0
|
|
413
|
+
and amplitude_percent is not None
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
if is_amplitude_based:
|
|
417
|
+
if is_threshold_based:
|
|
418
|
+
logger.info(
|
|
419
|
+
"amplitude, threshold_current, and amplitude_percent are all set in Sinusoidal."
|
|
420
|
+
" Using absolute amplitude and ignoring threshold-based parameters."
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
return Sinusoidal.amplitude_based(
|
|
424
|
+
dt=dt,
|
|
425
|
+
pre_delay=pre_delay,
|
|
426
|
+
post_delay=post_delay,
|
|
427
|
+
duration=duration,
|
|
428
|
+
frequency=frequency,
|
|
429
|
+
amplitude=amplitude, # type: ignore[arg-type]
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
if is_threshold_based:
|
|
433
|
+
return Sinusoidal.threshold_based(
|
|
434
|
+
dt=dt,
|
|
435
|
+
pre_delay=pre_delay,
|
|
436
|
+
post_delay=post_delay,
|
|
437
|
+
duration=duration,
|
|
438
|
+
frequency=frequency,
|
|
439
|
+
amplitude_percent=amplitude_percent, # type: ignore[arg-type]
|
|
440
|
+
threshold_current=threshold_current, # type: ignore[arg-type]
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
raise TypeError("You have to provide either `amplitude` or `threshold_current` with `amplitude_percent`.")
|
|
444
|
+
|
|
379
445
|
def ornstein_uhlenbeck(
|
|
380
446
|
self,
|
|
381
447
|
pre_delay: float,
|
|
@@ -18,6 +18,7 @@ from abc import ABC, abstractmethod
|
|
|
18
18
|
from typing import Optional
|
|
19
19
|
import logging
|
|
20
20
|
import matplotlib.pyplot as plt
|
|
21
|
+
import neuron
|
|
21
22
|
import numpy as np
|
|
22
23
|
from bluecellulab.cell.stimuli_generator import get_relative_shotnoise_params
|
|
23
24
|
from bluecellulab.exceptions import BluecellulabError
|
|
@@ -57,7 +58,6 @@ class Stimulus(ABC):
|
|
|
57
58
|
ax.plot(self.time, self.current, **kwargs)
|
|
58
59
|
ax.set_xlabel("Time (ms)")
|
|
59
60
|
ax.set_ylabel("Current (nA)")
|
|
60
|
-
ax.set_title(self.__class__.__name__)
|
|
61
61
|
return ax
|
|
62
62
|
|
|
63
63
|
def __add__(self, other: Stimulus) -> CombinedStimulus:
|
|
@@ -203,7 +203,6 @@ class OUProcess(Stimulus):
|
|
|
203
203
|
"""Generates an Ornstein-Uhlenbeck noise signal."""
|
|
204
204
|
from bluecellulab.cell.stimuli_generator import gen_ornstein_uhlenbeck
|
|
205
205
|
from bluecellulab.rngsettings import RNGSettings
|
|
206
|
-
import neuron
|
|
207
206
|
|
|
208
207
|
rng_settings = RNGSettings.get_instance()
|
|
209
208
|
rng = neuron.h.Random()
|
|
@@ -251,7 +250,6 @@ class ShotNoiseProcess(Stimulus):
|
|
|
251
250
|
"""Generates the shot noise time and current vectors."""
|
|
252
251
|
from bluecellulab.cell.stimuli_generator import gen_shotnoise_signal
|
|
253
252
|
from bluecellulab.rngsettings import RNGSettings
|
|
254
|
-
import neuron
|
|
255
253
|
|
|
256
254
|
rng_settings = RNGSettings.get_instance()
|
|
257
255
|
rng = neuron.h.Random()
|
|
@@ -310,12 +308,11 @@ class StepNoiseProcess(Stimulus):
|
|
|
310
308
|
def _generate_step_noise(self):
|
|
311
309
|
"""Generates the step noise time and current vectors using NEURON’s
|
|
312
310
|
random generator."""
|
|
313
|
-
from neuron import h
|
|
314
311
|
from bluecellulab.rngsettings import RNGSettings
|
|
315
312
|
|
|
316
313
|
# Get NEURON RNG settings
|
|
317
314
|
rng_settings = RNGSettings.get_instance()
|
|
318
|
-
rng = h.Random()
|
|
315
|
+
rng = neuron.h.Random()
|
|
319
316
|
|
|
320
317
|
if rng_settings.mode == "Random123":
|
|
321
318
|
seed1, seed2, seed3 = 2997, 19216, self.seed if self.seed else 123
|
|
@@ -341,6 +338,37 @@ class StepNoiseProcess(Stimulus):
|
|
|
341
338
|
return np.array(time_values), np.array(current_values)
|
|
342
339
|
|
|
343
340
|
|
|
341
|
+
class SinusoidalWave(Stimulus):
|
|
342
|
+
"""Generates a sinusoidal current wave."""
|
|
343
|
+
|
|
344
|
+
def __init__(self, dt: float, duration: float, amplitude: float, frequency: float):
|
|
345
|
+
super().__init__(dt)
|
|
346
|
+
self.duration = duration
|
|
347
|
+
self.amplitude = amplitude
|
|
348
|
+
self.frequency = frequency
|
|
349
|
+
|
|
350
|
+
self._time, self._current = self._generate_sinusoidal_signal()
|
|
351
|
+
|
|
352
|
+
@property
|
|
353
|
+
def time(self) -> np.ndarray:
|
|
354
|
+
return self._time
|
|
355
|
+
|
|
356
|
+
@property
|
|
357
|
+
def current(self) -> np.ndarray:
|
|
358
|
+
return self._current
|
|
359
|
+
|
|
360
|
+
def _generate_sinusoidal_signal(self):
|
|
361
|
+
"""Generate the sinusoidal waveform."""
|
|
362
|
+
tvec = neuron.h.Vector()
|
|
363
|
+
tvec.indgen(0.0, self.duration, self.dt) # Time points using NEURON
|
|
364
|
+
|
|
365
|
+
stim = neuron.h.Vector(len(tvec))
|
|
366
|
+
stim.sin(self.frequency, 0.0, self.dt) # Generate sinusoidal wave using NEURON
|
|
367
|
+
stim.mul(self.amplitude) # Scale by amplitude
|
|
368
|
+
|
|
369
|
+
return np.array(tvec.to_python()), np.array(stim.to_python())
|
|
370
|
+
|
|
371
|
+
|
|
344
372
|
class Step(Stimulus):
|
|
345
373
|
|
|
346
374
|
def __init__(self):
|
|
@@ -780,3 +808,73 @@ class StepNoise(Stimulus):
|
|
|
780
808
|
sigma=sigma,
|
|
781
809
|
seed=seed,
|
|
782
810
|
)
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
class Sinusoidal(Stimulus):
|
|
814
|
+
"""Factory-compatible Sinusoidal Stimulus."""
|
|
815
|
+
|
|
816
|
+
def __init__(self):
|
|
817
|
+
"""Prevents direct instantiation."""
|
|
818
|
+
raise NotImplementedError(
|
|
819
|
+
"This class cannot be instantiated directly. "
|
|
820
|
+
"Please use 'amplitude_based' or 'threshold_based' methods."
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
@classmethod
|
|
824
|
+
def amplitude_based(
|
|
825
|
+
cls,
|
|
826
|
+
dt: float,
|
|
827
|
+
pre_delay: float,
|
|
828
|
+
duration: float,
|
|
829
|
+
post_delay: float,
|
|
830
|
+
amplitude: float,
|
|
831
|
+
frequency: float,
|
|
832
|
+
) -> CombinedStimulus:
|
|
833
|
+
"""Creates a sinusoidal stimulus with a specified amplitude.
|
|
834
|
+
|
|
835
|
+
Args:
|
|
836
|
+
dt: Time step of the stimulus.
|
|
837
|
+
pre_delay: Delay before the sinusoidal wave starts.
|
|
838
|
+
duration: Duration of the sinusoidal signal.
|
|
839
|
+
post_delay: Delay after the wave ends.
|
|
840
|
+
amplitude: Amplitude of the sinusoidal wave.
|
|
841
|
+
frequency: Frequency of the wave in Hz.
|
|
842
|
+
"""
|
|
843
|
+
return (
|
|
844
|
+
Empty(dt, duration=pre_delay)
|
|
845
|
+
+ SinusoidalWave(dt, duration, amplitude, frequency)
|
|
846
|
+
+ Empty(dt, duration=post_delay)
|
|
847
|
+
)
|
|
848
|
+
|
|
849
|
+
@classmethod
|
|
850
|
+
def threshold_based(
|
|
851
|
+
cls,
|
|
852
|
+
dt: float,
|
|
853
|
+
pre_delay: float,
|
|
854
|
+
duration: float,
|
|
855
|
+
post_delay: float,
|
|
856
|
+
frequency: float,
|
|
857
|
+
threshold_current: float,
|
|
858
|
+
amplitude_percent: float,
|
|
859
|
+
) -> CombinedStimulus:
|
|
860
|
+
"""Creates a sinusoidal stimulus relative to the threshold current.
|
|
861
|
+
|
|
862
|
+
Args:
|
|
863
|
+
dt: Time step of the stimulus.
|
|
864
|
+
pre_delay: Delay before the sinusoidal wave starts.
|
|
865
|
+
duration: Duration of the sinusoidal signal.
|
|
866
|
+
post_delay: Delay after the wave ends.
|
|
867
|
+
frequency: Frequency of the wave in Hz.
|
|
868
|
+
threshold_current: Baseline threshold current.
|
|
869
|
+
amplitude_percent: Amplitude as a percentage of the threshold current.
|
|
870
|
+
"""
|
|
871
|
+
amplitude = (amplitude_percent / 100) * threshold_current
|
|
872
|
+
|
|
873
|
+
return cls.amplitude_based(
|
|
874
|
+
dt,
|
|
875
|
+
pre_delay=pre_delay,
|
|
876
|
+
duration=duration,
|
|
877
|
+
post_delay=post_delay,
|
|
878
|
+
amplitude=amplitude,
|
|
879
|
+
frequency=frequency,
|
|
880
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/circuit_access/definition.py
RENAMED
|
File without changes
|
|
File without changes
|
{bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/config/bluepy_simulation_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bluecellulab-2.6.43 → bluecellulab-2.6.45}/bluecellulab/circuit/config/sonata_simulation_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|