bluecellulab 2.6.40__py3-none-any.whl → 2.6.41__py3-none-any.whl
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/analysis/analysis.py +130 -16
- bluecellulab/analysis/inject_sequence.py +69 -16
- bluecellulab/analysis/plotting.py +39 -7
- bluecellulab/cell/core.py +64 -9
- bluecellulab/tools.py +105 -13
- {bluecellulab-2.6.40.dist-info → bluecellulab-2.6.41.dist-info}/METADATA +1 -1
- {bluecellulab-2.6.40.dist-info → bluecellulab-2.6.41.dist-info}/RECORD +11 -11
- {bluecellulab-2.6.40.dist-info → bluecellulab-2.6.41.dist-info}/AUTHORS.txt +0 -0
- {bluecellulab-2.6.40.dist-info → bluecellulab-2.6.41.dist-info}/LICENSE +0 -0
- {bluecellulab-2.6.40.dist-info → bluecellulab-2.6.41.dist-info}/WHEEL +0 -0
- {bluecellulab-2.6.40.dist-info → bluecellulab-2.6.41.dist-info}/top_level.txt +0 -0
|
@@ -8,26 +8,56 @@ import numpy as np
|
|
|
8
8
|
from bluecellulab.stimulus import StimulusFactory
|
|
9
9
|
from bluecellulab.tools import calculate_rheobase
|
|
10
10
|
from bluecellulab.analysis.inject_sequence import run_stimulus
|
|
11
|
-
from bluecellulab.analysis.plotting import plot_iv_curve
|
|
11
|
+
from bluecellulab.analysis.plotting import plot_iv_curve, plot_fi_curve
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def compute_plot_iv_curve(cell,
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
def compute_plot_iv_curve(cell,
|
|
15
|
+
injecting_section="soma[0]",
|
|
16
|
+
injecting_segment=0.5,
|
|
17
|
+
recording_section="soma[0]",
|
|
18
|
+
recording_segment=0.5,
|
|
19
|
+
stim_start=100.0,
|
|
20
|
+
duration=500.0,
|
|
21
|
+
post_delay=100.0,
|
|
22
|
+
threshold_voltage=-30,
|
|
23
|
+
nb_bins=11):
|
|
24
|
+
"""Compute and plot the Current-Voltage (I-V) curve for a given cell by
|
|
25
|
+
injecting a range of currents.
|
|
26
|
+
|
|
27
|
+
This function evaluates the relationship between the injected current amplitude and the resulting
|
|
28
|
+
steady-state membrane potential of a neuronal cell model. Currents are injected at a specified section
|
|
29
|
+
and segment, and the steady-state voltage at the recording location is used to construct the I-V curve.
|
|
17
30
|
|
|
18
31
|
Args:
|
|
19
|
-
cell (bluecellulab.cell.Cell): The initialized cell model.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
cell (bluecellulab.cell.Cell): The initialized BlueCelluLab cell model.
|
|
33
|
+
injecting_section (str, optional): The name of the section where the stimulus is injected.
|
|
34
|
+
Default is "soma[0]".
|
|
35
|
+
injecting_segment (float, optional): The position along the injecting section (0.0 to 1.0)
|
|
36
|
+
where the stimulus is applied. Default is 0.5.
|
|
37
|
+
recording_section (str, optional): The name of the section where the voltage is recorded.
|
|
38
|
+
Default is "soma[0]".
|
|
39
|
+
recording_segment (float, optional): The position along the recording section (0.0 to 1.0)
|
|
40
|
+
where the voltage is recorded. Default is 0.5.
|
|
41
|
+
stim_start (float, optional): The start time of the current injection (in ms). Default is 100.0 ms.
|
|
42
|
+
duration (float, optional): The duration of the current injection (in ms). Default is 500.0 ms.
|
|
43
|
+
post_delay (float, optional): The delay after the stimulation ends before the simulation stops
|
|
44
|
+
(in ms). Default is 100.0 ms.
|
|
45
|
+
threshold_voltage (float, optional): The voltage threshold (in mV) for detecting a steady-state
|
|
46
|
+
response. Default is -30 mV.
|
|
47
|
+
nb_bins (int, optional): The number of discrete current levels between 0 and the maximum current.
|
|
48
|
+
Default is 11.
|
|
24
49
|
|
|
25
50
|
Returns:
|
|
26
51
|
tuple: A tuple containing:
|
|
27
|
-
- list_amp (np.ndarray): The
|
|
28
|
-
- steady_states (np.ndarray): The corresponding steady-state voltages (mV)
|
|
52
|
+
- list_amp (np.ndarray): The injected current amplitudes (nA).
|
|
53
|
+
- steady_states (np.ndarray): The corresponding steady-state voltages (mV) recorded at the
|
|
54
|
+
specified location.
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
ValueError: If the cell object is invalid, the specified sections/segments are not found, or if
|
|
58
|
+
the simulation results are inconsistent.
|
|
29
59
|
"""
|
|
30
|
-
rheobase = calculate_rheobase(cell)
|
|
60
|
+
rheobase = calculate_rheobase(cell=cell, section=injecting_section, segx=injecting_segment)
|
|
31
61
|
|
|
32
62
|
list_amp = np.linspace(rheobase - 2, rheobase - 0.1, nb_bins) # [nA]
|
|
33
63
|
|
|
@@ -35,10 +65,15 @@ def compute_plot_iv_curve(cell, stim_start=100.0, duration=500.0, post_delay=100
|
|
|
35
65
|
times = []
|
|
36
66
|
voltages = []
|
|
37
67
|
# inject step current and record voltage response
|
|
68
|
+
stim_factory = StimulusFactory(dt=0.1)
|
|
38
69
|
for amp in list_amp:
|
|
39
|
-
stim_factory = StimulusFactory(dt=0.1)
|
|
40
70
|
step_stimulus = stim_factory.step(pre_delay=stim_start, duration=duration, post_delay=post_delay, amplitude=amp)
|
|
41
|
-
recording = run_stimulus(cell.template_params,
|
|
71
|
+
recording = run_stimulus(cell.template_params,
|
|
72
|
+
step_stimulus,
|
|
73
|
+
section=injecting_section,
|
|
74
|
+
segment=injecting_segment,
|
|
75
|
+
recording_section=recording_section,
|
|
76
|
+
recording_segment=recording_segment)
|
|
42
77
|
steps.append(step_stimulus)
|
|
43
78
|
times.append(recording.time)
|
|
44
79
|
voltages.append(recording.voltage)
|
|
@@ -57,7 +92,86 @@ def compute_plot_iv_curve(cell, stim_start=100.0, duration=500.0, post_delay=100
|
|
|
57
92
|
steady_state = features_results[0]['steady_state_voltage_stimend']
|
|
58
93
|
steady_states.append(steady_state)
|
|
59
94
|
|
|
60
|
-
|
|
61
|
-
|
|
95
|
+
plot_iv_curve(list_amp,
|
|
96
|
+
steady_states,
|
|
97
|
+
injecting_section=injecting_section,
|
|
98
|
+
injecting_segment=injecting_segment,
|
|
99
|
+
recording_section=recording_section,
|
|
100
|
+
recording_segment=recording_segment)
|
|
62
101
|
|
|
63
102
|
return np.array(list_amp), np.array(steady_states)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def compute_plot_fi_curve(cell,
|
|
106
|
+
injecting_section="soma[0]",
|
|
107
|
+
injecting_segment=0.5,
|
|
108
|
+
recording_section="soma[0]",
|
|
109
|
+
recording_segment=0.5,
|
|
110
|
+
stim_start=100.0,
|
|
111
|
+
duration=500.0,
|
|
112
|
+
post_delay=100.0,
|
|
113
|
+
max_current=0.8,
|
|
114
|
+
nb_bins=11):
|
|
115
|
+
"""Compute and plot the Frequency-Current (F-I) curve for a given cell by
|
|
116
|
+
injecting a range of currents.
|
|
117
|
+
|
|
118
|
+
This function evaluates the relationship between injected current amplitude and the firing rate
|
|
119
|
+
of a neuronal cell model. Currents are injected at a specified section and segment, and the number
|
|
120
|
+
of spikes recorded in the specified recording location is used to construct the F-I curve.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
cell (bluecellulab.cell.Cell): The initialized BlueCelluLab cell model.
|
|
124
|
+
injecting_section (str, optional): The name of the section where the stimulus is injected.
|
|
125
|
+
Default is "soma[0]".
|
|
126
|
+
injecting_segment (float, optional): The position along the injecting section (0.0 to 1.0)
|
|
127
|
+
where the stimulus is applied. Default is 0.5.
|
|
128
|
+
recording_section (str, optional): The name of the section where spikes are recorded.
|
|
129
|
+
Default is "soma[0]".
|
|
130
|
+
recording_segment (float, optional): The position along the recording section (0.0 to 1.0)
|
|
131
|
+
where spikes are recorded. Default is 0.5.
|
|
132
|
+
stim_start (float, optional): The start time of the current injection (in ms). Default is 100.0 ms.
|
|
133
|
+
duration (float, optional): The duration of the current injection (in ms). Default is 500.0 ms.
|
|
134
|
+
post_delay (float, optional): The delay after the stimulation ends before the simulation stops
|
|
135
|
+
(in ms). Default is 100.0 ms.
|
|
136
|
+
max_current (float, optional): The maximum amplitude of the injected current (in nA).
|
|
137
|
+
Default is 0.8 nA.
|
|
138
|
+
nb_bins (int, optional): The number of discrete current levels between 0 and `max_current`.
|
|
139
|
+
Default is 11.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
tuple: A tuple containing:
|
|
143
|
+
- list_amp (np.ndarray): The injected current amplitudes (nA).
|
|
144
|
+
- spike_count (np.ndarray): The corresponding spike counts for each current amplitude.
|
|
145
|
+
|
|
146
|
+
Raises:
|
|
147
|
+
ValueError: If the cell object is invalid or the specified sections/segments are not found.
|
|
148
|
+
"""
|
|
149
|
+
rheobase = calculate_rheobase(cell=cell, section=injecting_section, segx=injecting_segment)
|
|
150
|
+
|
|
151
|
+
list_amp = np.linspace(rheobase, max_current, nb_bins) # [nA]
|
|
152
|
+
steps = []
|
|
153
|
+
spikes = []
|
|
154
|
+
# inject step current and record spike response
|
|
155
|
+
stim_factory = StimulusFactory(dt=0.1)
|
|
156
|
+
for amp in list_amp:
|
|
157
|
+
step_stimulus = stim_factory.step(pre_delay=stim_start, duration=duration, post_delay=post_delay, amplitude=amp)
|
|
158
|
+
recording = run_stimulus(cell.template_params,
|
|
159
|
+
step_stimulus,
|
|
160
|
+
section=injecting_section,
|
|
161
|
+
segment=injecting_segment,
|
|
162
|
+
recording_section=recording_section,
|
|
163
|
+
recording_segment=recording_segment,
|
|
164
|
+
enable_spike_detection=True)
|
|
165
|
+
steps.append(step_stimulus)
|
|
166
|
+
spikes.append(recording.spike)
|
|
167
|
+
|
|
168
|
+
spike_count = [len(spike) for spike in spikes]
|
|
169
|
+
|
|
170
|
+
plot_fi_curve(list_amp,
|
|
171
|
+
spike_count,
|
|
172
|
+
injecting_section=injecting_section,
|
|
173
|
+
injecting_segment=injecting_segment,
|
|
174
|
+
recording_section=recording_section,
|
|
175
|
+
recording_segment=recording_segment)
|
|
176
|
+
|
|
177
|
+
return np.array(list_amp), np.array(spike_count)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Module for injecting a sequence of protocols to the cell."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
from enum import Enum, auto
|
|
4
|
-
from typing import NamedTuple, Sequence, Dict
|
|
4
|
+
from typing import NamedTuple, Sequence, Dict, Optional
|
|
5
5
|
|
|
6
6
|
import neuron
|
|
7
7
|
import numpy as np
|
|
@@ -11,6 +11,7 @@ from bluecellulab.simulation.parallel import IsolatedProcess
|
|
|
11
11
|
from bluecellulab.simulation.simulation import Simulation
|
|
12
12
|
from bluecellulab.stimulus.circuit_stimulus_definitions import Hyperpolarizing
|
|
13
13
|
from bluecellulab.stimulus.factory import Stimulus, StimulusFactory
|
|
14
|
+
from bluecellulab.tools import validate_section_and_segment
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class StimulusName(Enum):
|
|
@@ -24,10 +25,12 @@ class StimulusName(Enum):
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class Recording(NamedTuple):
|
|
27
|
-
"""A tuple of the current, voltage and time recordings
|
|
28
|
+
"""A tuple of the current, voltage and time recordings with optional spike
|
|
29
|
+
recordings."""
|
|
28
30
|
current: np.ndarray
|
|
29
31
|
voltage: np.ndarray
|
|
30
32
|
time: np.ndarray
|
|
33
|
+
spike: np.ndarray | None
|
|
31
34
|
|
|
32
35
|
|
|
33
36
|
StimulusRecordings = Dict[str, Recording]
|
|
@@ -40,41 +43,91 @@ def run_stimulus(
|
|
|
40
43
|
segment: float,
|
|
41
44
|
cvode: bool = True,
|
|
42
45
|
add_hypamp: bool = True,
|
|
46
|
+
recording_section: str = "soma[0]",
|
|
47
|
+
recording_segment: float = 0.5,
|
|
48
|
+
enable_spike_detection: bool = False,
|
|
49
|
+
threshold_spike_detection: float = -30,
|
|
43
50
|
) -> Recording:
|
|
44
|
-
"""Creates a cell
|
|
51
|
+
"""Creates a cell from template parameters, applies a stimulus, and records
|
|
52
|
+
the response.
|
|
53
|
+
|
|
54
|
+
This function simulates the electrical activity of a neuronal cell model by injecting
|
|
55
|
+
a stimulus into a specified section and segment, recording the voltage response, and
|
|
56
|
+
optionally detecting spikes.
|
|
45
57
|
|
|
46
58
|
Args:
|
|
47
|
-
template_params:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
59
|
+
template_params (TemplateParams): Parameters required to create the cell from a
|
|
60
|
+
specified template, including morphology and mechanisms.
|
|
61
|
+
stimulus (Stimulus): The stimulus waveform to inject, defined by time and current arrays.
|
|
62
|
+
section (str): Name of the section of the cell where the stimulus is applied.
|
|
63
|
+
(e.g. soma[0])
|
|
64
|
+
segment (float): The normalized position (0.0 to 1.0) along the injecting
|
|
65
|
+
section where the stimulus is applied.
|
|
66
|
+
cvode (bool, optional): Whether to use variable time-step integration. Defaults to True.
|
|
67
|
+
add_hypamp (bool, optional): If True, adds a hyperpolarizing stimulus before applying
|
|
68
|
+
the main stimulus. Defaults to True.
|
|
69
|
+
recording_section (str): Name of the section of the cell where voltage is recorded.
|
|
70
|
+
recording_segment (float): The normalized position (0.0 to 1.0) along the recording
|
|
71
|
+
section where voltage is recorded.
|
|
72
|
+
enable_spike_detection (bool, optional): If True, enables spike detection at the
|
|
73
|
+
recording location. Defaults to False.
|
|
74
|
+
threshold_spike_detection (float, optional): The voltage threshold (mV) for spike detection.
|
|
75
|
+
Defaults to -30 mV.
|
|
52
76
|
|
|
53
77
|
Returns:
|
|
54
|
-
|
|
78
|
+
Recording: A `Recording` object containing the following:
|
|
79
|
+
- `current` (np.ndarray): The injected current waveform (nA).
|
|
80
|
+
- `voltage` (np.ndarray): The recorded membrane potential (mV) over time.
|
|
81
|
+
- `time` (np.ndarray): The simulation time points (ms).
|
|
82
|
+
- `spike` (np.ndarray or None): The detected spikes, if spike detection is enabled.
|
|
55
83
|
|
|
56
84
|
Raises:
|
|
57
|
-
ValueError: If the time and voltage arrays
|
|
85
|
+
ValueError: If the time, current, and voltage arrays do not have the same length,
|
|
86
|
+
or if the specified sections or segments are not found in the cell model.
|
|
58
87
|
"""
|
|
59
88
|
cell = Cell.from_template_parameters(template_params)
|
|
60
|
-
|
|
89
|
+
|
|
90
|
+
validate_section_and_segment(cell, section, segment)
|
|
91
|
+
validate_section_and_segment(cell, recording_section, recording_segment)
|
|
92
|
+
|
|
61
93
|
if add_hypamp:
|
|
62
94
|
hyp_stim = Hyperpolarizing(target="", delay=0.0, duration=stimulus.stimulus_time)
|
|
63
95
|
cell.add_replay_hypamp(hyp_stim)
|
|
64
|
-
|
|
96
|
+
|
|
97
|
+
cell.add_voltage_recording(cell.sections[recording_section], recording_segment)
|
|
98
|
+
|
|
99
|
+
# Set up spike detection if enabled
|
|
100
|
+
spikes: Optional[np.ndarray] = None
|
|
101
|
+
if enable_spike_detection:
|
|
102
|
+
recording_location = f"{recording_section}({str(recording_segment)})"
|
|
103
|
+
cell.start_recording_spikes(None, location=recording_location, threshold=threshold_spike_detection)
|
|
104
|
+
|
|
105
|
+
# Inject the stimulus and run the simulation
|
|
65
106
|
iclamp, _ = cell.inject_current_waveform(
|
|
66
|
-
stimulus.time, stimulus.current, section=
|
|
107
|
+
stimulus.time, stimulus.current, section=cell.sections[section], segx=segment
|
|
67
108
|
)
|
|
68
109
|
current_vector = neuron.h.Vector()
|
|
69
110
|
current_vector.record(iclamp._ref_i)
|
|
111
|
+
|
|
70
112
|
simulation = Simulation(cell)
|
|
71
113
|
simulation.run(stimulus.stimulus_time, cvode=cvode)
|
|
114
|
+
|
|
115
|
+
# Retrieve simulation results
|
|
72
116
|
current = np.array(current_vector.to_python())
|
|
73
|
-
voltage = cell.get_voltage_recording(
|
|
117
|
+
voltage = cell.get_voltage_recording(cell.sections[recording_section], recording_segment)
|
|
74
118
|
time = cell.get_time()
|
|
119
|
+
|
|
75
120
|
if len(time) != len(voltage) or len(time) != len(current):
|
|
76
|
-
raise ValueError("Time, current and voltage arrays are not the same length")
|
|
77
|
-
|
|
121
|
+
raise ValueError("Time, current, and voltage arrays are not the same length")
|
|
122
|
+
|
|
123
|
+
if enable_spike_detection:
|
|
124
|
+
results = cell.get_recorded_spikes(location=recording_location, threshold=threshold_spike_detection)
|
|
125
|
+
if results is not None:
|
|
126
|
+
spikes = np.array(results)
|
|
127
|
+
else:
|
|
128
|
+
spikes = None
|
|
129
|
+
|
|
130
|
+
return Recording(current=current, voltage=voltage, time=time, spike=spikes)
|
|
78
131
|
|
|
79
132
|
|
|
80
133
|
def apply_multiple_stimuli(
|
|
@@ -3,23 +3,55 @@
|
|
|
3
3
|
import matplotlib.pyplot as plt
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def plot_iv_curve(currents, voltages):
|
|
6
|
+
def plot_iv_curve(currents, voltages, injecting_section, injecting_segment, recording_section, recording_segment):
|
|
7
7
|
"""Plots the IV curve.
|
|
8
8
|
|
|
9
9
|
Args:
|
|
10
|
-
currents (
|
|
11
|
-
voltages (
|
|
10
|
+
currents (list): The injected current levels (nA).
|
|
11
|
+
voltages (list): The corresponding steady-state voltages (mV).
|
|
12
|
+
injecting_section (str): The section in the cell where the current was injected.
|
|
13
|
+
injecting_segment (float): The segment position (0.0 to 1.0) where the current was injected.
|
|
14
|
+
recording_section (str): The section in the cell where spikes were recorded.
|
|
15
|
+
recording_segment (float): The segment position (0.0 to 1.0) where spikes were recorded.
|
|
16
|
+
|
|
12
17
|
Raises:
|
|
13
18
|
ValueError: If the lengths of currents and voltages do not match.
|
|
14
19
|
"""
|
|
15
20
|
if len(currents) != len(voltages):
|
|
16
21
|
raise ValueError("currents and voltages must have the same length")
|
|
17
22
|
|
|
18
|
-
# Plotting
|
|
19
23
|
plt.figure(figsize=(10, 6))
|
|
20
|
-
plt.plot(
|
|
24
|
+
plt.plot(currents, voltages, marker='o', linestyle='-', color='b')
|
|
21
25
|
plt.title("I-V Curve")
|
|
22
|
-
plt.
|
|
23
|
-
plt.
|
|
26
|
+
plt.xlabel(f"Injected Current [nA] at {injecting_section}({injecting_segment:.2f})")
|
|
27
|
+
plt.ylabel(f"Steady state voltage [mV] at {recording_section}({recording_segment:.2f})")
|
|
28
|
+
plt.grid(True)
|
|
29
|
+
plt.tight_layout()
|
|
30
|
+
plt.show()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def plot_fi_curve(currents, spike_count, injecting_section, injecting_segment, recording_section, recording_segment):
|
|
34
|
+
"""Plots the F-I (Frequency-Current) curve.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
currents (list): The injected current levels (nA).
|
|
38
|
+
spike_count (list): The number of spikes recorded for each current level.
|
|
39
|
+
injecting_section (str): The section in the cell where the current was injected.
|
|
40
|
+
injecting_segment (float): The segment position (0.0 to 1.0) where the current was injected.
|
|
41
|
+
recording_section (str): The section in the cell where spikes were recorded.
|
|
42
|
+
recording_segment (float): The segment position (0.0 to 1.0) where spikes were recorded.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
ValueError: If the lengths of currents and spike counts do not match.
|
|
46
|
+
"""
|
|
47
|
+
if len(currents) != len(spike_count):
|
|
48
|
+
raise ValueError("currents and spike count must have the same length")
|
|
49
|
+
|
|
50
|
+
plt.figure(figsize=(10, 6))
|
|
51
|
+
plt.plot(currents, spike_count, marker='o')
|
|
52
|
+
plt.title("F-I Curve")
|
|
53
|
+
plt.xlabel(f"Injected Current [nA] at {injecting_section}({injecting_segment:.2f})")
|
|
54
|
+
plt.ylabel(f"Spike Count recorded at {recording_section}({recording_segment:.2f})")
|
|
55
|
+
plt.grid(True)
|
|
24
56
|
plt.tight_layout()
|
|
25
57
|
plt.show()
|
bluecellulab/cell/core.py
CHANGED
|
@@ -25,6 +25,7 @@ from typing_extensions import deprecated
|
|
|
25
25
|
import neuron
|
|
26
26
|
import numpy as np
|
|
27
27
|
import pandas as pd
|
|
28
|
+
import re
|
|
28
29
|
|
|
29
30
|
import bluecellulab
|
|
30
31
|
from bluecellulab.cell.recording import section_to_voltage_recording_str
|
|
@@ -376,7 +377,11 @@ class Cell(InjectableMixin, PlottableMixin):
|
|
|
376
377
|
|
|
377
378
|
def get_recording(self, var_name: str) -> np.ndarray:
|
|
378
379
|
"""Get recorded values."""
|
|
379
|
-
|
|
380
|
+
try:
|
|
381
|
+
res = np.array(self.recordings[var_name].to_python())
|
|
382
|
+
except KeyError as e:
|
|
383
|
+
raise ValueError(f"No recording for '{var_name}' was found.") from e
|
|
384
|
+
return res
|
|
380
385
|
|
|
381
386
|
def add_replay_synapse(self,
|
|
382
387
|
synapse_id: SynapseID,
|
|
@@ -432,19 +437,42 @@ class Cell(InjectableMixin, PlottableMixin):
|
|
|
432
437
|
def create_netcon_spikedetector(self, target: HocObjectType, location: str, threshold: float = -30.0) -> HocObjectType:
|
|
433
438
|
"""Add and return a spikedetector.
|
|
434
439
|
|
|
435
|
-
This
|
|
436
|
-
connects to target
|
|
440
|
+
This function creates a NetCon object that detects spikes at a specific
|
|
441
|
+
location in the current cell and connects to the provided target point process.
|
|
442
|
+
The location can be specified as a predefined site ('soma' or 'AIS') or as a
|
|
443
|
+
custom location in the format `section[index](position)`. Custom locations
|
|
444
|
+
allow fine-grained control of the spike detection site within the cell's sections.
|
|
437
445
|
|
|
438
446
|
Args:
|
|
439
|
-
target:
|
|
440
|
-
location:
|
|
441
|
-
|
|
447
|
+
target: A NEURON point process object (e.g., synapse) that the NetCon connects to.
|
|
448
|
+
location: The spike detection location. Acceptable formats include:
|
|
449
|
+
|
|
450
|
+
- `"soma"`: Detect spikes in the soma section at the distal end.
|
|
451
|
+
|
|
452
|
+
- `"AIS"`: Detect spikes in the axon initial segment at the midpoint.
|
|
442
453
|
|
|
443
|
-
|
|
454
|
+
- `"section[index](position)"`: Custom location specifying:
|
|
455
|
+
|
|
456
|
+
- `section`: The name of the section (e.g., 'soma', 'axon').
|
|
457
|
+
- `[index]` (optional): Segment index within a section array (e.g., 'soma[0]').
|
|
458
|
+
- `(position)` (optional): Normalized position along the section length (0 to 1).
|
|
459
|
+
Defaults to 0.5 if not provided.
|
|
460
|
+
|
|
461
|
+
threshold: The voltage threshold for spike detection (default: -30.0 mV).
|
|
462
|
+
|
|
463
|
+
Returns:
|
|
464
|
+
A NEURON `NetCon` object configured for spike detection at the specified location.
|
|
444
465
|
|
|
445
466
|
Raises:
|
|
446
|
-
ValueError: If
|
|
467
|
+
ValueError: If:
|
|
468
|
+
|
|
469
|
+
- The `location` is not 'soma', 'AIS', or a valid custom format.
|
|
470
|
+
|
|
471
|
+
- The specified section or segment index does not exist.
|
|
472
|
+
|
|
473
|
+
- The position is out of bounds (e.g., negative or greater than 1.0).
|
|
447
474
|
"""
|
|
475
|
+
|
|
448
476
|
if location == "soma":
|
|
449
477
|
sec = public_hoc_cell(self.cell).soma[0]
|
|
450
478
|
source = sec(1)._ref_v
|
|
@@ -452,7 +480,34 @@ class Cell(InjectableMixin, PlottableMixin):
|
|
|
452
480
|
sec = public_hoc_cell(self.cell).axon[1]
|
|
453
481
|
source = sec(0.5)._ref_v
|
|
454
482
|
else:
|
|
455
|
-
|
|
483
|
+
# Parse custom location (e.g., 'soma[0](0.3)')
|
|
484
|
+
pattern = r'^([a-zA-Z_]+)(?:\[(\d+)\])?(?:\((-?\d+\.\d+)\))?$'
|
|
485
|
+
match = re.search(pattern, location)
|
|
486
|
+
|
|
487
|
+
# Extract the value if a match is found
|
|
488
|
+
if match:
|
|
489
|
+
section_name = match.group(1)
|
|
490
|
+
segment_index = match.group(2)
|
|
491
|
+
pos = match.group(3)
|
|
492
|
+
if pos is None:
|
|
493
|
+
pos = 0.5
|
|
494
|
+
else:
|
|
495
|
+
pos = float(pos)
|
|
496
|
+
|
|
497
|
+
else:
|
|
498
|
+
raise ValueError(f"Invalid location format: {location}")
|
|
499
|
+
|
|
500
|
+
try:
|
|
501
|
+
# Handle section arrays (e.g., soma[0])
|
|
502
|
+
if segment_index is not None:
|
|
503
|
+
sec = getattr(public_hoc_cell(self.cell), section_name)[int(segment_index)]
|
|
504
|
+
else:
|
|
505
|
+
sec = getattr(public_hoc_cell(self.cell), section_name)
|
|
506
|
+
|
|
507
|
+
source = sec(pos)._ref_v
|
|
508
|
+
except (AttributeError, ValueError, IndexError) as e:
|
|
509
|
+
raise ValueError(f"Invalid spike detection location: {location}") from e
|
|
510
|
+
|
|
456
511
|
netcon = neuron.h.NetCon(source, target, sec=sec)
|
|
457
512
|
netcon.threshold = threshold
|
|
458
513
|
return netcon
|
bluecellulab/tools.py
CHANGED
|
@@ -28,6 +28,8 @@ from bluecellulab.circuit.circuit_access import EmodelProperties
|
|
|
28
28
|
from bluecellulab.exceptions import UnsteadyCellError
|
|
29
29
|
from bluecellulab.simulation.parallel import IsolatedProcess
|
|
30
30
|
from bluecellulab.utils import CaptureOutput
|
|
31
|
+
from bluecellulab.type_aliases import NeuronSection
|
|
32
|
+
|
|
31
33
|
|
|
32
34
|
logger = logging.getLogger(__name__)
|
|
33
35
|
|
|
@@ -38,10 +40,13 @@ def calculate_input_resistance(
|
|
|
38
40
|
template_format: str,
|
|
39
41
|
emodel_properties: EmodelProperties | None,
|
|
40
42
|
current_delta: float = 0.01,
|
|
43
|
+
section: str = "soma[0]",
|
|
44
|
+
segx: float = 0.5
|
|
41
45
|
) -> float:
|
|
42
46
|
"""Calculate the input resistance at rest of the cell."""
|
|
43
47
|
rest_voltage = calculate_SS_voltage(
|
|
44
|
-
template_path, morphology_path, template_format, emodel_properties, 0.0
|
|
48
|
+
template_path, morphology_path, template_format, emodel_properties, 0.0,
|
|
49
|
+
section=section, segx=segx
|
|
45
50
|
)
|
|
46
51
|
step_voltage = calculate_SS_voltage(
|
|
47
52
|
template_path,
|
|
@@ -49,6 +54,8 @@ def calculate_input_resistance(
|
|
|
49
54
|
template_format,
|
|
50
55
|
emodel_properties,
|
|
51
56
|
current_delta,
|
|
57
|
+
section=section,
|
|
58
|
+
segx=segx
|
|
52
59
|
)
|
|
53
60
|
|
|
54
61
|
voltage_delta = step_voltage - rest_voltage
|
|
@@ -64,6 +71,8 @@ def calculate_SS_voltage(
|
|
|
64
71
|
step_level: float,
|
|
65
72
|
check_for_spiking=False,
|
|
66
73
|
spike_threshold=-20.0,
|
|
74
|
+
section: str = "soma[0]",
|
|
75
|
+
segx: float = 0.5
|
|
67
76
|
) -> float:
|
|
68
77
|
"""Calculate the steady state voltage at a certain current step."""
|
|
69
78
|
with IsolatedProcess() as runner:
|
|
@@ -77,6 +86,8 @@ def calculate_SS_voltage(
|
|
|
77
86
|
step_level,
|
|
78
87
|
check_for_spiking,
|
|
79
88
|
spike_threshold,
|
|
89
|
+
section,
|
|
90
|
+
segx
|
|
80
91
|
],
|
|
81
92
|
)
|
|
82
93
|
return SS_voltage
|
|
@@ -90,6 +101,8 @@ def calculate_SS_voltage_subprocess(
|
|
|
90
101
|
step_level: float,
|
|
91
102
|
check_for_spiking: bool,
|
|
92
103
|
spike_threshold: float,
|
|
104
|
+
section: str = "soma[0]",
|
|
105
|
+
segx: float = 0.5
|
|
93
106
|
) -> float:
|
|
94
107
|
"""Subprocess wrapper of calculate_SS_voltage.
|
|
95
108
|
|
|
@@ -104,11 +117,15 @@ def calculate_SS_voltage_subprocess(
|
|
|
104
117
|
template_format=template_format,
|
|
105
118
|
emodel_properties=emodel_properties,
|
|
106
119
|
)
|
|
107
|
-
|
|
120
|
+
|
|
121
|
+
sec = get_section(cell, section)
|
|
122
|
+
neuron_section = sec
|
|
123
|
+
cell.add_voltage_recording(cell.sections[section], segx)
|
|
124
|
+
cell.add_ramp(500, 5000, step_level, step_level, section=neuron_section, segx=segx)
|
|
108
125
|
simulation = bluecellulab.Simulation()
|
|
109
126
|
simulation.run(1000, cvode=template_accepts_cvode(template_path))
|
|
110
127
|
time = cell.get_time()
|
|
111
|
-
voltage = cell.
|
|
128
|
+
voltage = cell.get_voltage_recording(section=neuron_section, segx=segx)
|
|
112
129
|
SS_voltage = np.mean(voltage[np.where((time < 1000) & (time > 800))])
|
|
113
130
|
cell.delete()
|
|
114
131
|
|
|
@@ -250,6 +267,8 @@ def detect_spike_step(
|
|
|
250
267
|
inj_start: float,
|
|
251
268
|
inj_stop: float,
|
|
252
269
|
step_level: float,
|
|
270
|
+
section: str = "soma[0]",
|
|
271
|
+
segx: float = 0.5
|
|
253
272
|
) -> bool:
|
|
254
273
|
"""Detect if there is a spike at a certain step level."""
|
|
255
274
|
with IsolatedProcess() as runner:
|
|
@@ -264,6 +283,8 @@ def detect_spike_step(
|
|
|
264
283
|
inj_start,
|
|
265
284
|
inj_stop,
|
|
266
285
|
step_level,
|
|
286
|
+
section,
|
|
287
|
+
segx
|
|
267
288
|
],
|
|
268
289
|
)
|
|
269
290
|
return spike_detected
|
|
@@ -277,7 +298,9 @@ def detect_spike_step_subprocess(
|
|
|
277
298
|
hyp_level: float,
|
|
278
299
|
inj_start: float,
|
|
279
300
|
inj_stop: float,
|
|
280
|
-
step_level: float
|
|
301
|
+
step_level: float,
|
|
302
|
+
section: str = "soma[0]",
|
|
303
|
+
segx: float = 0.5
|
|
281
304
|
) -> bool:
|
|
282
305
|
"""Detect if there is a spike at a certain step level."""
|
|
283
306
|
cell = bluecellulab.Cell(
|
|
@@ -285,13 +308,18 @@ def detect_spike_step_subprocess(
|
|
|
285
308
|
morphology_path=morphology_path,
|
|
286
309
|
template_format=template_format,
|
|
287
310
|
emodel_properties=emodel_properties)
|
|
288
|
-
|
|
289
|
-
|
|
311
|
+
|
|
312
|
+
sec = get_section(cell, section)
|
|
313
|
+
cell.add_voltage_recording(cell.sections[section], segx)
|
|
314
|
+
|
|
315
|
+
neuron_section = sec
|
|
316
|
+
cell.add_ramp(0, 5000, hyp_level, hyp_level, section=neuron_section, segx=segx)
|
|
317
|
+
cell.add_ramp(inj_start, inj_stop, step_level, step_level, section=neuron_section, segx=segx)
|
|
290
318
|
simulation = bluecellulab.Simulation()
|
|
291
319
|
simulation.run(int(inj_stop), cvode=template_accepts_cvode(template_path))
|
|
292
320
|
|
|
293
321
|
time = cell.get_time()
|
|
294
|
-
voltage = cell.
|
|
322
|
+
voltage = cell.get_voltage_recording(section=neuron_section, segx=segx)
|
|
295
323
|
voltage_step = voltage[np.where((time > inj_start) & (time < inj_stop))]
|
|
296
324
|
spike_detected = detect_spike(voltage_step)
|
|
297
325
|
|
|
@@ -319,6 +347,8 @@ def search_threshold_current(
|
|
|
319
347
|
min_current: float,
|
|
320
348
|
max_current: float,
|
|
321
349
|
current_precision: float = 0.01,
|
|
350
|
+
section: str = "soma[0]",
|
|
351
|
+
segx: float = 0.5
|
|
322
352
|
):
|
|
323
353
|
"""Search current necessary to reach threshold."""
|
|
324
354
|
if abs(max_current - min_current) < current_precision:
|
|
@@ -328,7 +358,8 @@ def search_threshold_current(
|
|
|
328
358
|
|
|
329
359
|
spike_detected = detect_spike_step(
|
|
330
360
|
template_name, morphology_path, template_format, emodel_properties,
|
|
331
|
-
hyp_level, inj_start, inj_stop, med_current
|
|
361
|
+
hyp_level, inj_start, inj_stop, med_current,
|
|
362
|
+
section=section, segx=segx
|
|
332
363
|
)
|
|
333
364
|
logger.info("Spike threshold detection at: %f nA" % med_current)
|
|
334
365
|
|
|
@@ -337,13 +368,15 @@ def search_threshold_current(
|
|
|
337
368
|
template_format, emodel_properties,
|
|
338
369
|
hyp_level, inj_start, inj_stop,
|
|
339
370
|
min_current, med_current,
|
|
340
|
-
current_precision
|
|
371
|
+
current_precision,
|
|
372
|
+
section=section, segx=segx)
|
|
341
373
|
else:
|
|
342
374
|
return search_threshold_current(template_name, morphology_path,
|
|
343
375
|
template_format, emodel_properties,
|
|
344
376
|
hyp_level, inj_start, inj_stop,
|
|
345
377
|
med_current, max_current,
|
|
346
|
-
current_precision
|
|
378
|
+
current_precision,
|
|
379
|
+
section=section, segx=segx)
|
|
347
380
|
|
|
348
381
|
|
|
349
382
|
def check_empty_topology() -> bool:
|
|
@@ -354,12 +387,17 @@ def check_empty_topology() -> bool:
|
|
|
354
387
|
return stdout == ['', '']
|
|
355
388
|
|
|
356
389
|
|
|
357
|
-
def calculate_max_thresh_current(cell: Cell,
|
|
390
|
+
def calculate_max_thresh_current(cell: Cell,
|
|
391
|
+
threshold_voltage: float = -30.0,
|
|
392
|
+
section: str = "soma[0]",
|
|
393
|
+
segx: float = 0.5) -> float:
|
|
358
394
|
"""Calculate the upper bound threshold current.
|
|
359
395
|
|
|
360
396
|
Args:
|
|
361
397
|
cell (bluecellulab.cell.Cell): The initialized cell model.
|
|
362
398
|
threshold_voltage (float, optional): Voltage threshold for spike detection. Default is -30.0 mV.
|
|
399
|
+
section (str, optional): The section where current is injected.
|
|
400
|
+
segx (float, optional): Fractional location within the section for current injection.
|
|
363
401
|
|
|
364
402
|
Returns:
|
|
365
403
|
float: The upper bound threshold current.
|
|
@@ -371,6 +409,8 @@ def calculate_max_thresh_current(cell: Cell, threshold_voltage: float = -30.0) -
|
|
|
371
409
|
template_format=cell.template_params.template_format,
|
|
372
410
|
emodel_properties=cell.template_params.emodel_properties,
|
|
373
411
|
step_level=0.0,
|
|
412
|
+
section=section,
|
|
413
|
+
segx=segx
|
|
374
414
|
)
|
|
375
415
|
|
|
376
416
|
# Calculate input resistance (rin)
|
|
@@ -379,6 +419,8 @@ def calculate_max_thresh_current(cell: Cell, threshold_voltage: float = -30.0) -
|
|
|
379
419
|
morphology_path=cell.template_params.morph_filepath,
|
|
380
420
|
template_format=cell.template_params.template_format,
|
|
381
421
|
emodel_properties=cell.template_params.emodel_properties,
|
|
422
|
+
section=section,
|
|
423
|
+
segx=segx
|
|
382
424
|
)
|
|
383
425
|
|
|
384
426
|
# Calculate upperbound threshold current
|
|
@@ -391,7 +433,9 @@ def calculate_max_thresh_current(cell: Cell, threshold_voltage: float = -30.0) -
|
|
|
391
433
|
def calculate_rheobase(cell: Cell,
|
|
392
434
|
threshold_voltage: float = -30.0,
|
|
393
435
|
threshold_search_stim_start: float = 300.0,
|
|
394
|
-
threshold_search_stim_stop: float = 1000.0
|
|
436
|
+
threshold_search_stim_stop: float = 1000.0,
|
|
437
|
+
section: str = "soma[0]",
|
|
438
|
+
segx: float = 0.5) -> float:
|
|
395
439
|
"""Calculate the rheobase by first computing the upper bound threshold
|
|
396
440
|
current.
|
|
397
441
|
|
|
@@ -400,6 +444,8 @@ def calculate_rheobase(cell: Cell,
|
|
|
400
444
|
threshold_voltage (float, optional): Voltage threshold for spike detection. Default is -30.0 mV.
|
|
401
445
|
threshold_search_stim_start (float, optional): Start time for threshold search stimulation (in ms). Default is 300.0 ms.
|
|
402
446
|
threshold_search_stim_stop (float, optional): Stop time for threshold search stimulation (in ms). Default is 1000.0 ms.
|
|
447
|
+
section (str, optional): The section where current is injected.
|
|
448
|
+
segx (float, optional): Fractional location within the section for current injection.
|
|
403
449
|
|
|
404
450
|
Returns:
|
|
405
451
|
float: The rheobase current.
|
|
@@ -408,7 +454,12 @@ def calculate_rheobase(cell: Cell,
|
|
|
408
454
|
raise ValueError("emodel_properties cannot be None")
|
|
409
455
|
|
|
410
456
|
# Calculate upper bound threshold current
|
|
411
|
-
upperbound_threshold_current = calculate_max_thresh_current(
|
|
457
|
+
upperbound_threshold_current = calculate_max_thresh_current(
|
|
458
|
+
cell,
|
|
459
|
+
threshold_voltage,
|
|
460
|
+
section,
|
|
461
|
+
segx
|
|
462
|
+
)
|
|
412
463
|
|
|
413
464
|
# Compute rheobase
|
|
414
465
|
rheobase = search_threshold_current(
|
|
@@ -422,6 +473,47 @@ def calculate_rheobase(cell: Cell,
|
|
|
422
473
|
min_current=cell.template_params.emodel_properties.holding_current,
|
|
423
474
|
max_current=upperbound_threshold_current,
|
|
424
475
|
current_precision=0.005,
|
|
476
|
+
section=section,
|
|
477
|
+
segx=segx
|
|
425
478
|
)
|
|
426
479
|
|
|
427
480
|
return rheobase
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def validate_section_and_segment(cell: Cell, section_name: str, segment_position: float):
|
|
484
|
+
"""Validate a single section and segment position.
|
|
485
|
+
|
|
486
|
+
Args:
|
|
487
|
+
cell: The cell model to validate against.
|
|
488
|
+
section_name: The name of the section to validate (e.g., 'soma', 'axon[1]').
|
|
489
|
+
segment_position: The position within the section (e.g., 0.5 for the middle).
|
|
490
|
+
|
|
491
|
+
Raises:
|
|
492
|
+
ValueError: If the section or position is invalid.
|
|
493
|
+
"""
|
|
494
|
+
# Validate the section
|
|
495
|
+
if section_name not in cell.sections:
|
|
496
|
+
raise ValueError(f"Section '{section_name}' not found in the cell model.")
|
|
497
|
+
|
|
498
|
+
# Validate the segment position
|
|
499
|
+
if not (0.0 <= segment_position <= 1.0):
|
|
500
|
+
raise ValueError(f"Segment position must be between 0.0 and 1.0, got {segment_position}.")
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
def get_section(cell: Cell, section_name: str) -> NeuronSection:
|
|
504
|
+
"""Retrieve a NEURON section from the cell by its name.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
cell (Cell): The cell object containing the sections.
|
|
508
|
+
section_name (str): The name of the section to retrieve.
|
|
509
|
+
|
|
510
|
+
Returns:
|
|
511
|
+
NeuronSection: The NEURON section corresponding to the provided name.
|
|
512
|
+
|
|
513
|
+
Raises:
|
|
514
|
+
ValueError: If the section with the specified name does not exist.
|
|
515
|
+
"""
|
|
516
|
+
try:
|
|
517
|
+
return cell.sections[section_name]
|
|
518
|
+
except KeyError:
|
|
519
|
+
raise ValueError(f"Section '{section_name}' not found in the cell.")
|
|
@@ -10,17 +10,17 @@ bluecellulab/plotwindow.py,sha256=ePU-EegZ1Sqk0SoYYiQ6k24ZO4s3Hgfpx10uePiJ5xM,27
|
|
|
10
10
|
bluecellulab/psection.py,sha256=FSOwRNuOTyB469BM-jPEf9l1J59FamXmzrQgBI6cnP4,6174
|
|
11
11
|
bluecellulab/psegment.py,sha256=PTgoGLqM4oFIdF_8QHFQCU59j-8TQmtq6PakiGUQhIo,3138
|
|
12
12
|
bluecellulab/rngsettings.py,sha256=2Ykb4Ylk3XTs58x1UIxjg8XJqjSpnCgKRZ8avXCDpxk,4237
|
|
13
|
-
bluecellulab/tools.py,sha256=
|
|
13
|
+
bluecellulab/tools.py,sha256=pljNpD7dXvnKlgKoyc3YdGH3uDvhukWPHH7ausROwVM,17604
|
|
14
14
|
bluecellulab/type_aliases.py,sha256=DvgjERv2Ztdw_sW63JrZTQGpJ0x5uMTFB5hcBHDb0WA,441
|
|
15
15
|
bluecellulab/utils.py,sha256=SbOOkzw1YGjCKV3qOw0zpabNEy7V9BRtgMLsQJiFRq4,1526
|
|
16
16
|
bluecellulab/verbosity.py,sha256=T0IgX7DrRo19faxrT4Xzb27gqxzoILQ8FzYKxvUeaPM,1342
|
|
17
17
|
bluecellulab/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
bluecellulab/analysis/analysis.py,sha256=
|
|
19
|
-
bluecellulab/analysis/inject_sequence.py,sha256=
|
|
20
|
-
bluecellulab/analysis/plotting.py,sha256
|
|
18
|
+
bluecellulab/analysis/analysis.py,sha256=ItRtUeXeIoYN6gkSZh-U5lBv-plClNZECU6y6YlaNCI,8615
|
|
19
|
+
bluecellulab/analysis/inject_sequence.py,sha256=KlqkQO6gvXAPVkjh7t95rr6Ic-v3N2u04M_WUWtcL1o,8994
|
|
20
|
+
bluecellulab/analysis/plotting.py,sha256=-ArjWHZsAlUoNSu_t0HQjQmFhGI1tCQtdAoICgwstFs,2588
|
|
21
21
|
bluecellulab/cell/__init__.py,sha256=Sbc0QOsJ8E7tSwf3q7fsXuE_SevBN6ZmoCVyyU5zfII,208
|
|
22
22
|
bluecellulab/cell/cell_dict.py,sha256=VE7pi-NsMVRSmo-PSdbiLYmolDOu0Gc6JxFBkuQpFdk,1346
|
|
23
|
-
bluecellulab/cell/core.py,sha256=
|
|
23
|
+
bluecellulab/cell/core.py,sha256=BualY0WOtC0arKmvKzQ3sQ0fhc2jrtd6wqSd9M-e25E,33797
|
|
24
24
|
bluecellulab/cell/injector.py,sha256=p4e36Bmubm7uYfK0gvdEUeff18SE_4lZcRszRfqccWs,18042
|
|
25
25
|
bluecellulab/cell/plotting.py,sha256=t2qDUabFtsBb-nJMkDh5UfsgW-wvQ2wfDwAVZ8-hWPo,4032
|
|
26
26
|
bluecellulab/cell/random.py,sha256=pemekc11geRBKD8Ghb82tvKOZLfFWkUz1IKLc_NWg-A,1773
|
|
@@ -64,9 +64,9 @@ bluecellulab/stimulus/factory.py,sha256=L85RN-lImkyCEM87Pp1X5rpGNIHLNSMwx1b9dZxO
|
|
|
64
64
|
bluecellulab/synapse/__init__.py,sha256=RW8XoAMXOvK7OG1nHl_q8jSEKLj9ZN4oWf2nY9HAwuk,192
|
|
65
65
|
bluecellulab/synapse/synapse_factory.py,sha256=NHwRMYMrnRVm_sHmyKTJ1bdoNmWZNU4UPOGu7FCi-PE,6987
|
|
66
66
|
bluecellulab/synapse/synapse_types.py,sha256=zs_yBvGTH4QrbQF3nEViidyq1WM_ZcTSFdjUxB3khW0,16871
|
|
67
|
-
bluecellulab-2.6.
|
|
68
|
-
bluecellulab-2.6.
|
|
69
|
-
bluecellulab-2.6.
|
|
70
|
-
bluecellulab-2.6.
|
|
71
|
-
bluecellulab-2.6.
|
|
72
|
-
bluecellulab-2.6.
|
|
67
|
+
bluecellulab-2.6.41.dist-info/AUTHORS.txt,sha256=EDs3H-2HXBojbma10psixk3C2rFiOCTIREi2ZAbXYNQ,179
|
|
68
|
+
bluecellulab-2.6.41.dist-info/LICENSE,sha256=dAMAR2Sud4Nead1wGFleKiwTZfkTNZbzmuGfcTKb3kg,11335
|
|
69
|
+
bluecellulab-2.6.41.dist-info/METADATA,sha256=8LgcqnSi_oOjFjuBet86o7KVyzqHVjkRodOfdAzw4iQ,8213
|
|
70
|
+
bluecellulab-2.6.41.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
71
|
+
bluecellulab-2.6.41.dist-info/top_level.txt,sha256=VSyEP8w9l3pXdRkyP_goeMwiNA8KWwitfAqUkveJkdQ,13
|
|
72
|
+
bluecellulab-2.6.41.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|