bluecellulab 2.5.0__py3-none-any.whl → 2.6.37__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/__init__.py +3 -3
- bluecellulab/analysis/inject_sequence.py +47 -12
- bluecellulab/cell/cell_dict.py +1 -1
- bluecellulab/cell/core.py +34 -30
- bluecellulab/cell/injector.py +2 -4
- bluecellulab/cell/plotting.py +2 -1
- bluecellulab/cell/random.py +1 -1
- bluecellulab/cell/section_distance.py +1 -1
- bluecellulab/cell/serialized_sections.py +4 -6
- bluecellulab/cell/sonata_proxy.py +1 -1
- bluecellulab/cell/stimuli_generator.py +26 -8
- bluecellulab/cell/template.py +4 -3
- bluecellulab/circuit/circuit_access/bluepy_circuit_access.py +12 -20
- bluecellulab/circuit/circuit_access/definition.py +1 -1
- bluecellulab/circuit/circuit_access/sonata_circuit_access.py +5 -4
- bluecellulab/circuit/config/bluepy_simulation_config.py +1 -1
- bluecellulab/circuit/config/definition.py +1 -1
- bluecellulab/circuit/config/sections.py +1 -1
- bluecellulab/circuit/config/sonata_simulation_config.py +1 -1
- bluecellulab/circuit/format.py +1 -1
- bluecellulab/circuit/iotools.py +2 -2
- bluecellulab/circuit/node_id.py +1 -1
- bluecellulab/circuit/simulation_access.py +11 -8
- bluecellulab/circuit/synapse_properties.py +25 -9
- bluecellulab/circuit/validate.py +1 -1
- bluecellulab/{ssim.py → circuit_simulation.py} +33 -26
- bluecellulab/connection.py +1 -1
- bluecellulab/dendrogram.py +1 -1
- bluecellulab/exceptions.py +1 -1
- bluecellulab/graph.py +1 -1
- bluecellulab/importer.py +1 -1
- bluecellulab/neuron_interpreter.py +1 -1
- bluecellulab/plotwindow.py +1 -1
- bluecellulab/psection.py +11 -16
- bluecellulab/psegment.py +4 -4
- bluecellulab/rngsettings.py +2 -2
- bluecellulab/simulation/neuron_globals.py +14 -1
- bluecellulab/simulation/parallel.py +40 -0
- bluecellulab/simulation/simulation.py +25 -21
- bluecellulab/stimulus/circuit_stimulus_definitions.py +11 -6
- bluecellulab/stimulus/factory.py +537 -102
- bluecellulab/synapse/synapse_factory.py +8 -4
- bluecellulab/synapse/synapse_types.py +1 -1
- bluecellulab/tools.py +14 -11
- bluecellulab/utils.py +20 -22
- {bluecellulab-2.5.0.dist-info → bluecellulab-2.6.37.dist-info}/LICENSE +0 -7
- {bluecellulab-2.5.0.dist-info → bluecellulab-2.6.37.dist-info}/METADATA +42 -25
- bluecellulab-2.6.37.dist-info/RECORD +70 -0
- {bluecellulab-2.5.0.dist-info → bluecellulab-2.6.37.dist-info}/WHEEL +1 -1
- bluecellulab-2.5.0.dist-info/RECORD +0 -69
- {bluecellulab-2.5.0.dist-info → bluecellulab-2.6.37.dist-info}/AUTHORS.txt +0 -0
- {bluecellulab-2.5.0.dist-info → bluecellulab-2.6.37.dist-info}/top_level.txt +0 -0
bluecellulab/stimulus/factory.py
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import Optional
|
|
4
|
+
import logging
|
|
3
5
|
import matplotlib.pyplot as plt
|
|
4
6
|
import numpy as np
|
|
5
7
|
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
6
10
|
|
|
7
11
|
class Stimulus(ABC):
|
|
8
12
|
def __init__(self, dt: float) -> None:
|
|
@@ -39,38 +43,38 @@ class Stimulus(ABC):
|
|
|
39
43
|
ax.set_title(self.__class__.__name__)
|
|
40
44
|
return ax
|
|
41
45
|
|
|
42
|
-
def plot_during_simulation(self, duration: float, ax=None, **kwargs):
|
|
43
|
-
if ax is None:
|
|
44
|
-
ax = plt.gca()
|
|
45
|
-
# Create an array for the entire duration
|
|
46
|
-
full_time = np.arange(0, duration, self.dt)
|
|
47
|
-
full_current = np.zeros_like(full_time)
|
|
48
|
-
|
|
49
|
-
# Replace the corresponding values with self.time and self.current
|
|
50
|
-
indices = (self.time / self.dt).astype(int)
|
|
51
|
-
full_current[indices] = self.current
|
|
52
|
-
|
|
53
|
-
ax.plot(full_time, full_current, **kwargs)
|
|
54
|
-
ax.set_xlabel("Time (ms)")
|
|
55
|
-
ax.set_ylabel("Current (nA)")
|
|
56
|
-
ax.set_title(self.__class__.__name__)
|
|
57
|
-
ax.set_xlim(0, duration)
|
|
58
|
-
return ax
|
|
59
|
-
|
|
60
46
|
def __add__(self, other: Stimulus) -> CombinedStimulus:
|
|
61
47
|
"""Override + operator to concatenate Stimulus objects."""
|
|
62
48
|
if self.dt != other.dt:
|
|
63
|
-
raise ValueError(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
raise ValueError(
|
|
50
|
+
"Stimulus objects must have the same dt to be concatenated"
|
|
51
|
+
)
|
|
52
|
+
if len(self.time) == 0:
|
|
53
|
+
return CombinedStimulus(other.dt, other.time, other.current)
|
|
54
|
+
elif len(other.time) == 0:
|
|
55
|
+
return CombinedStimulus(self.dt, self.time, self.current)
|
|
56
|
+
else:
|
|
57
|
+
# shift other time
|
|
58
|
+
other_time = other.time + self.time[-1] + self.dt
|
|
59
|
+
combined_time = np.concatenate([self.time, other_time])
|
|
60
|
+
# Concatenate the current arrays
|
|
61
|
+
combined_current = np.concatenate([self.current, other.current])
|
|
62
|
+
return CombinedStimulus(self.dt, combined_time, combined_current)
|
|
63
|
+
|
|
64
|
+
def __eq__(self, other: object) -> bool:
|
|
65
|
+
if not isinstance(other, Stimulus):
|
|
66
|
+
return NotImplemented
|
|
67
|
+
else:
|
|
68
|
+
return (
|
|
69
|
+
np.allclose(self.time, other.time)
|
|
70
|
+
and np.allclose(self.current, other.current)
|
|
71
|
+
and self.dt == other.dt
|
|
72
|
+
)
|
|
70
73
|
|
|
71
74
|
|
|
72
75
|
class CombinedStimulus(Stimulus):
|
|
73
76
|
"""Represents the Stimulus created by combining multiple stimuli."""
|
|
77
|
+
|
|
74
78
|
def __init__(self, dt: float, time: np.ndarray, current: np.ndarray) -> None:
|
|
75
79
|
super().__init__(dt)
|
|
76
80
|
self._time = time
|
|
@@ -85,11 +89,12 @@ class CombinedStimulus(Stimulus):
|
|
|
85
89
|
return self._current
|
|
86
90
|
|
|
87
91
|
|
|
88
|
-
class
|
|
92
|
+
class Empty(Stimulus):
|
|
89
93
|
"""Represents empty stimulus (all zeros) that has no impact on the cell.
|
|
90
94
|
|
|
91
95
|
This is required by some Stimuli that expect the cell to rest.
|
|
92
96
|
"""
|
|
97
|
+
|
|
93
98
|
def __init__(self, dt: float, duration: float) -> None:
|
|
94
99
|
super().__init__(dt)
|
|
95
100
|
self.duration = duration
|
|
@@ -103,152 +108,582 @@ class EmptyStimulus(Stimulus):
|
|
|
103
108
|
return np.zeros_like(self.time)
|
|
104
109
|
|
|
105
110
|
|
|
106
|
-
class
|
|
107
|
-
def __init__(self, dt: float,
|
|
111
|
+
class Flat(Stimulus):
|
|
112
|
+
def __init__(self, dt: float, duration: float, amplitude: float) -> None:
|
|
108
113
|
super().__init__(dt)
|
|
109
|
-
self.
|
|
110
|
-
self.end = end
|
|
114
|
+
self.duration = duration
|
|
111
115
|
self.amplitude = amplitude
|
|
112
116
|
|
|
113
|
-
@classmethod
|
|
114
|
-
def threshold_based(
|
|
115
|
-
cls,
|
|
116
|
-
dt: float,
|
|
117
|
-
threshold_current: float,
|
|
118
|
-
threshold_percentage: float,
|
|
119
|
-
start: float,
|
|
120
|
-
end: float,
|
|
121
|
-
post_wait: float,
|
|
122
|
-
) -> CombinedStimulus:
|
|
123
|
-
amplitude = threshold_current * threshold_percentage / 100
|
|
124
|
-
res = cls(dt, start, end, amplitude) + EmptyStimulus(dt, duration=post_wait)
|
|
125
|
-
return res
|
|
126
|
-
|
|
127
117
|
@property
|
|
128
118
|
def time(self) -> np.ndarray:
|
|
129
|
-
return np.arange(
|
|
119
|
+
return np.arange(0.0, self.duration, self.dt)
|
|
130
120
|
|
|
131
121
|
@property
|
|
132
122
|
def current(self) -> np.ndarray:
|
|
133
123
|
return np.full_like(self.time, self.amplitude)
|
|
134
124
|
|
|
135
125
|
|
|
136
|
-
class
|
|
126
|
+
class Slope(Stimulus):
|
|
137
127
|
def __init__(
|
|
138
|
-
self,
|
|
139
|
-
dt: float,
|
|
140
|
-
start: float,
|
|
141
|
-
end: float,
|
|
142
|
-
amplitude_start: float,
|
|
143
|
-
amplitude_end: float,
|
|
128
|
+
self, dt: float, duration: float, amplitude_start: float, amplitude_end: float
|
|
144
129
|
) -> None:
|
|
145
130
|
super().__init__(dt)
|
|
146
|
-
self.
|
|
147
|
-
self.end = end
|
|
131
|
+
self.duration = duration
|
|
148
132
|
self.amplitude_start = amplitude_start
|
|
149
133
|
self.amplitude_end = amplitude_end
|
|
150
134
|
|
|
151
135
|
@property
|
|
152
136
|
def time(self) -> np.ndarray:
|
|
153
|
-
return np.arange(
|
|
137
|
+
return np.arange(0.0, self.duration, self.dt)
|
|
154
138
|
|
|
155
139
|
@property
|
|
156
140
|
def current(self) -> np.ndarray:
|
|
157
141
|
return np.linspace(self.amplitude_start, self.amplitude_end, len(self.time))
|
|
158
142
|
|
|
159
143
|
|
|
144
|
+
class Zap(Stimulus):
|
|
145
|
+
def __init__(self, dt: float, duration: float, amplitude: float) -> None:
|
|
146
|
+
super().__init__(dt)
|
|
147
|
+
self.duration = duration
|
|
148
|
+
self.amplitude = amplitude
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def time(self) -> np.ndarray:
|
|
152
|
+
return np.arange(0.0, self.duration, self.dt)
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def current(self) -> np.ndarray:
|
|
156
|
+
return self.amplitude * np.sin(
|
|
157
|
+
2.0 * np.pi * (1.0 + (1.0 / (5.15 - (self.time - 0.1)))) * (self.time - 0.1)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class Step(Stimulus):
|
|
162
|
+
|
|
163
|
+
def __init__(self):
|
|
164
|
+
raise NotImplementedError(
|
|
165
|
+
"This class cannot be instantiated directly. "
|
|
166
|
+
"Please use the class methods 'amplitude_based' "
|
|
167
|
+
"or 'threshold_based' to create objects."
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
@classmethod
|
|
171
|
+
def amplitude_based(
|
|
172
|
+
cls,
|
|
173
|
+
dt: float,
|
|
174
|
+
pre_delay: float,
|
|
175
|
+
duration: float,
|
|
176
|
+
post_delay: float,
|
|
177
|
+
amplitude: float,
|
|
178
|
+
) -> CombinedStimulus:
|
|
179
|
+
"""Create a Step stimulus from given time events and amplitude.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
dt: The time step of the stimulus.
|
|
183
|
+
pre_delay: The delay before the start of the step.
|
|
184
|
+
duration: The duration of the step.
|
|
185
|
+
post_delay: The time to wait after the end of the step.
|
|
186
|
+
amplitude: The amplitude of the step.
|
|
187
|
+
"""
|
|
188
|
+
return (
|
|
189
|
+
Empty(dt, duration=pre_delay)
|
|
190
|
+
+ Flat(dt, duration=duration, amplitude=amplitude)
|
|
191
|
+
+ Empty(dt, duration=post_delay)
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
@classmethod
|
|
195
|
+
def threshold_based(
|
|
196
|
+
cls,
|
|
197
|
+
dt: float,
|
|
198
|
+
pre_delay: float,
|
|
199
|
+
duration: float,
|
|
200
|
+
post_delay: float,
|
|
201
|
+
threshold_current: float,
|
|
202
|
+
threshold_percentage: float,
|
|
203
|
+
) -> CombinedStimulus:
|
|
204
|
+
"""Creates a Step stimulus with respect to the threshold current.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
|
|
208
|
+
dt: The time step of the stimulus.
|
|
209
|
+
pre_delay: The delay before the start of the step.
|
|
210
|
+
duration: The duration of the step.
|
|
211
|
+
post_delay: The time to wait after the end of the step.
|
|
212
|
+
threshold_current: The threshold current of the Cell.
|
|
213
|
+
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
214
|
+
"""
|
|
215
|
+
amplitude = threshold_current * threshold_percentage / 100
|
|
216
|
+
res = cls.amplitude_based(
|
|
217
|
+
dt,
|
|
218
|
+
pre_delay=pre_delay,
|
|
219
|
+
duration=duration,
|
|
220
|
+
post_delay=post_delay,
|
|
221
|
+
amplitude=amplitude,
|
|
222
|
+
)
|
|
223
|
+
return res
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class Ramp(Stimulus):
|
|
227
|
+
|
|
228
|
+
def __init__(self):
|
|
229
|
+
raise NotImplementedError(
|
|
230
|
+
"This class cannot be instantiated directly. "
|
|
231
|
+
"Please use the class methods 'amplitude_based' "
|
|
232
|
+
"or 'threshold_based' to create objects."
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
@classmethod
|
|
236
|
+
def amplitude_based(
|
|
237
|
+
cls,
|
|
238
|
+
dt: float,
|
|
239
|
+
pre_delay: float,
|
|
240
|
+
duration: float,
|
|
241
|
+
post_delay: float,
|
|
242
|
+
amplitude: float,
|
|
243
|
+
) -> CombinedStimulus:
|
|
244
|
+
"""Create a Ramp stimulus from given time events and amplitudes.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
dt: The time step of the stimulus.
|
|
248
|
+
pre_delay: The delay before the start of the ramp.
|
|
249
|
+
duration: The duration of the ramp.
|
|
250
|
+
post_delay: The time to wait after the end of the ramp.
|
|
251
|
+
amplitude: The final amplitude of the ramp.
|
|
252
|
+
"""
|
|
253
|
+
return (
|
|
254
|
+
Empty(dt, duration=pre_delay)
|
|
255
|
+
+ Slope(
|
|
256
|
+
dt,
|
|
257
|
+
duration=duration,
|
|
258
|
+
amplitude_start=0.0,
|
|
259
|
+
amplitude_end=amplitude,
|
|
260
|
+
)
|
|
261
|
+
+ Empty(dt, duration=post_delay)
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
@classmethod
|
|
265
|
+
def threshold_based(
|
|
266
|
+
cls,
|
|
267
|
+
dt: float,
|
|
268
|
+
pre_delay: float,
|
|
269
|
+
duration: float,
|
|
270
|
+
post_delay: float,
|
|
271
|
+
threshold_current: float,
|
|
272
|
+
threshold_percentage: float,
|
|
273
|
+
) -> CombinedStimulus:
|
|
274
|
+
"""Creates a Ramp stimulus with respect to the threshold current.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
|
|
278
|
+
dt: The time step of the stimulus.
|
|
279
|
+
pre_delay: The delay before the start of the ramp.
|
|
280
|
+
duration: The duration of the ramp.
|
|
281
|
+
post_delay: The time to wait after the end of the ramp.
|
|
282
|
+
threshold_current: The threshold current of the Cell.
|
|
283
|
+
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
284
|
+
"""
|
|
285
|
+
amplitude = threshold_current * threshold_percentage / 100
|
|
286
|
+
res = cls.amplitude_based(
|
|
287
|
+
dt,
|
|
288
|
+
pre_delay=pre_delay,
|
|
289
|
+
duration=duration,
|
|
290
|
+
post_delay=post_delay,
|
|
291
|
+
amplitude=amplitude,
|
|
292
|
+
)
|
|
293
|
+
return res
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class DelayedZap(Stimulus):
|
|
297
|
+
|
|
298
|
+
def __init__(self):
|
|
299
|
+
raise NotImplementedError(
|
|
300
|
+
"This class cannot be instantiated directly. "
|
|
301
|
+
"Please use the class methods 'amplitude_based' "
|
|
302
|
+
"or 'threshold_based' to create objects."
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
@classmethod
|
|
306
|
+
def amplitude_based(
|
|
307
|
+
cls,
|
|
308
|
+
dt: float,
|
|
309
|
+
pre_delay: float,
|
|
310
|
+
duration: float,
|
|
311
|
+
post_delay: float,
|
|
312
|
+
amplitude: float,
|
|
313
|
+
) -> CombinedStimulus:
|
|
314
|
+
"""Create a DelayedZap stimulus from given time events and amplitude.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
dt: The time step of the stimulus.
|
|
318
|
+
pre_delay: The delay before the start of the step.
|
|
319
|
+
duration: The duration of the step.
|
|
320
|
+
post_delay: The time to wait after the end of the step.
|
|
321
|
+
amplitude: The amplitude of the step.
|
|
322
|
+
"""
|
|
323
|
+
return (
|
|
324
|
+
Empty(dt, duration=pre_delay)
|
|
325
|
+
+ Zap(dt, duration=duration, amplitude=amplitude)
|
|
326
|
+
+ Empty(dt, duration=post_delay)
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
@classmethod
|
|
330
|
+
def threshold_based(
|
|
331
|
+
cls,
|
|
332
|
+
dt: float,
|
|
333
|
+
pre_delay: float,
|
|
334
|
+
duration: float,
|
|
335
|
+
post_delay: float,
|
|
336
|
+
threshold_current: float,
|
|
337
|
+
threshold_percentage: float,
|
|
338
|
+
) -> CombinedStimulus:
|
|
339
|
+
"""Creates a SineSpec stimulus with respect to the threshold current.
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
|
|
343
|
+
dt: The time step of the stimulus.
|
|
344
|
+
pre_delay: The delay before the start of the step.
|
|
345
|
+
duration: The duration of the step.
|
|
346
|
+
post_delay: The time to wait after the end of the step.
|
|
347
|
+
threshold_current: The threshold current of the Cell.
|
|
348
|
+
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
349
|
+
"""
|
|
350
|
+
amplitude = threshold_current * threshold_percentage / 100
|
|
351
|
+
res = cls.amplitude_based(
|
|
352
|
+
dt,
|
|
353
|
+
pre_delay=pre_delay,
|
|
354
|
+
duration=duration,
|
|
355
|
+
post_delay=post_delay,
|
|
356
|
+
amplitude=amplitude,
|
|
357
|
+
)
|
|
358
|
+
return res
|
|
359
|
+
|
|
360
|
+
|
|
160
361
|
class StimulusFactory:
|
|
161
362
|
def __init__(self, dt: float):
|
|
162
363
|
self.dt = dt
|
|
163
364
|
|
|
164
|
-
def step(
|
|
165
|
-
|
|
365
|
+
def step(
|
|
366
|
+
self, pre_delay: float, duration: float, post_delay: float, amplitude: float
|
|
367
|
+
) -> Stimulus:
|
|
368
|
+
return Step.amplitude_based(
|
|
369
|
+
self.dt,
|
|
370
|
+
pre_delay=pre_delay,
|
|
371
|
+
duration=duration,
|
|
372
|
+
post_delay=post_delay,
|
|
373
|
+
amplitude=amplitude,
|
|
374
|
+
)
|
|
166
375
|
|
|
167
376
|
def ramp(
|
|
168
|
-
self,
|
|
377
|
+
self, pre_delay: float, duration: float, post_delay: float, amplitude: float
|
|
169
378
|
) -> Stimulus:
|
|
170
|
-
return Ramp(
|
|
379
|
+
return Ramp.amplitude_based(
|
|
380
|
+
self.dt,
|
|
381
|
+
pre_delay=pre_delay,
|
|
382
|
+
duration=duration,
|
|
383
|
+
post_delay=post_delay,
|
|
384
|
+
amplitude=amplitude,
|
|
385
|
+
)
|
|
171
386
|
|
|
172
387
|
def ap_waveform(
|
|
173
388
|
self,
|
|
174
|
-
threshold_current: float,
|
|
175
|
-
threshold_percentage: float = 220.0,
|
|
176
|
-
|
|
177
|
-
end: float = 300.0,
|
|
178
|
-
post_wait: float = 250.0,
|
|
389
|
+
threshold_current: Optional[float] = None,
|
|
390
|
+
threshold_percentage: Optional[float] = 220.0,
|
|
391
|
+
amplitude: Optional[float] = None,
|
|
179
392
|
) -> Stimulus:
|
|
180
393
|
"""Returns the APWaveform Stimulus object, a type of Step stimulus.
|
|
181
394
|
|
|
182
395
|
Args:
|
|
183
396
|
threshold_current: The threshold current of the Cell.
|
|
184
397
|
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
185
|
-
|
|
186
|
-
end: The end time of the step.
|
|
187
|
-
post_wait: The time to wait after the end of the step.
|
|
398
|
+
amplitude: Raw amplitude of input current.
|
|
188
399
|
"""
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
400
|
+
pre_delay = 250.0
|
|
401
|
+
duration = 50.0
|
|
402
|
+
post_delay = 250.0
|
|
403
|
+
|
|
404
|
+
if amplitude is not None:
|
|
405
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
406
|
+
logger.info(
|
|
407
|
+
"amplitude, threshold_current and threshold_percentage are all set in ap_waveform."
|
|
408
|
+
" Will only keep amplitude value."
|
|
409
|
+
)
|
|
410
|
+
return Step.amplitude_based(
|
|
411
|
+
self.dt,
|
|
412
|
+
pre_delay=pre_delay,
|
|
413
|
+
duration=duration,
|
|
414
|
+
post_delay=post_delay,
|
|
415
|
+
amplitude=amplitude,
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
419
|
+
return Step.threshold_based(
|
|
420
|
+
self.dt,
|
|
421
|
+
pre_delay=pre_delay,
|
|
422
|
+
duration=duration,
|
|
423
|
+
post_delay=post_delay,
|
|
424
|
+
threshold_current=threshold_current,
|
|
425
|
+
threshold_percentage=threshold_percentage,
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
raise TypeError("You have to give either threshold_current or amplitude")
|
|
192
429
|
|
|
193
430
|
def idrest(
|
|
194
431
|
self,
|
|
195
|
-
threshold_current: float,
|
|
196
|
-
threshold_percentage: float = 200.0,
|
|
197
|
-
|
|
198
|
-
end: float = 1600.0,
|
|
199
|
-
post_wait: float = 250.0,
|
|
432
|
+
threshold_current: Optional[float] = None,
|
|
433
|
+
threshold_percentage: Optional[float] = 200.0,
|
|
434
|
+
amplitude: Optional[float] = None,
|
|
200
435
|
) -> Stimulus:
|
|
201
436
|
"""Returns the IDRest Stimulus object, a type of Step stimulus.
|
|
202
437
|
|
|
203
438
|
Args:
|
|
204
439
|
threshold_current: The threshold current of the Cell.
|
|
205
440
|
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
206
|
-
|
|
207
|
-
end: The end time of the step.
|
|
208
|
-
post_wait: The time to wait after the end of the step.
|
|
441
|
+
amplitude: Raw amplitude of input current.
|
|
209
442
|
"""
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
443
|
+
pre_delay = 250.0
|
|
444
|
+
duration = 1350.0
|
|
445
|
+
post_delay = 250.0
|
|
446
|
+
|
|
447
|
+
if amplitude is not None:
|
|
448
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
449
|
+
logger.info(
|
|
450
|
+
"amplitude, threshold_current and threshold_percentage are all set in idrest."
|
|
451
|
+
" Will only keep amplitude value."
|
|
452
|
+
)
|
|
453
|
+
return Step.amplitude_based(
|
|
454
|
+
self.dt,
|
|
455
|
+
pre_delay=pre_delay,
|
|
456
|
+
duration=duration,
|
|
457
|
+
post_delay=post_delay,
|
|
458
|
+
amplitude=amplitude,
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
462
|
+
return Step.threshold_based(
|
|
463
|
+
self.dt,
|
|
464
|
+
pre_delay=pre_delay,
|
|
465
|
+
duration=duration,
|
|
466
|
+
post_delay=post_delay,
|
|
467
|
+
threshold_current=threshold_current,
|
|
468
|
+
threshold_percentage=threshold_percentage,
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
raise TypeError("You have to give either threshold_current or amplitude")
|
|
213
472
|
|
|
214
473
|
def iv(
|
|
215
474
|
self,
|
|
216
|
-
threshold_current: float,
|
|
217
|
-
threshold_percentage: float = -40.0,
|
|
218
|
-
|
|
219
|
-
end: float = 3250.0,
|
|
220
|
-
post_wait: float = 250.0,
|
|
475
|
+
threshold_current: Optional[float] = None,
|
|
476
|
+
threshold_percentage: Optional[float] = -40.0,
|
|
477
|
+
amplitude: Optional[float] = None,
|
|
221
478
|
) -> Stimulus:
|
|
222
479
|
"""Returns the IV Stimulus object, a type of Step stimulus.
|
|
223
480
|
|
|
224
481
|
Args:
|
|
225
482
|
threshold_current: The threshold current of the Cell.
|
|
226
483
|
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
227
|
-
|
|
228
|
-
end: The end time of the step.
|
|
229
|
-
post_wait: The time to wait after the end of the step.
|
|
484
|
+
amplitude: Raw amplitude of input current.
|
|
230
485
|
"""
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
486
|
+
pre_delay = 250.0
|
|
487
|
+
duration = 3000.0
|
|
488
|
+
post_delay = 250.0
|
|
489
|
+
|
|
490
|
+
if amplitude is not None:
|
|
491
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
492
|
+
logger.info(
|
|
493
|
+
"amplitude, threshold_current and threshold_percentage are all set in iv."
|
|
494
|
+
" Will only keep amplitude value."
|
|
495
|
+
)
|
|
496
|
+
return Step.amplitude_based(
|
|
497
|
+
self.dt,
|
|
498
|
+
pre_delay=pre_delay,
|
|
499
|
+
duration=duration,
|
|
500
|
+
post_delay=post_delay,
|
|
501
|
+
amplitude=amplitude,
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
505
|
+
return Step.threshold_based(
|
|
506
|
+
self.dt,
|
|
507
|
+
pre_delay=pre_delay,
|
|
508
|
+
duration=duration,
|
|
509
|
+
post_delay=post_delay,
|
|
510
|
+
threshold_current=threshold_current,
|
|
511
|
+
threshold_percentage=threshold_percentage,
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
raise TypeError("You have to give either threshold_current or amplitude")
|
|
234
515
|
|
|
235
516
|
def fire_pattern(
|
|
236
517
|
self,
|
|
237
|
-
threshold_current: float,
|
|
238
|
-
threshold_percentage: float = 200.0,
|
|
239
|
-
|
|
240
|
-
end: float = 3850.0,
|
|
241
|
-
post_wait: float = 250.0,
|
|
518
|
+
threshold_current: Optional[float] = None,
|
|
519
|
+
threshold_percentage: Optional[float] = 200.0,
|
|
520
|
+
amplitude: Optional[float] = None,
|
|
242
521
|
) -> Stimulus:
|
|
243
522
|
"""Returns the FirePattern Stimulus object, a type of Step stimulus.
|
|
244
523
|
|
|
245
524
|
Args:
|
|
246
525
|
threshold_current: The threshold current of the Cell.
|
|
247
526
|
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
527
|
+
amplitude: Raw amplitude of input current.
|
|
528
|
+
"""
|
|
529
|
+
pre_delay = 250.0
|
|
530
|
+
duration = 3600.0
|
|
531
|
+
post_delay = 250.0
|
|
532
|
+
|
|
533
|
+
if amplitude is not None:
|
|
534
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
535
|
+
logger.info(
|
|
536
|
+
"amplitude, threshold_current and threshold_percentage are all set in fire_pattern."
|
|
537
|
+
" Will only keep amplitude value."
|
|
538
|
+
)
|
|
539
|
+
return Step.amplitude_based(
|
|
540
|
+
self.dt,
|
|
541
|
+
pre_delay=pre_delay,
|
|
542
|
+
duration=duration,
|
|
543
|
+
post_delay=post_delay,
|
|
544
|
+
amplitude=amplitude,
|
|
545
|
+
)
|
|
546
|
+
|
|
547
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
548
|
+
return Step.threshold_based(
|
|
549
|
+
self.dt,
|
|
550
|
+
pre_delay=pre_delay,
|
|
551
|
+
duration=duration,
|
|
552
|
+
post_delay=post_delay,
|
|
553
|
+
threshold_current=threshold_current,
|
|
554
|
+
threshold_percentage=threshold_percentage,
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
raise TypeError("You have to give either threshold_current or amplitude")
|
|
558
|
+
|
|
559
|
+
def pos_cheops(
|
|
560
|
+
self,
|
|
561
|
+
threshold_current: Optional[float] = None,
|
|
562
|
+
threshold_percentage: Optional[float] = 300.0,
|
|
563
|
+
amplitude: Optional[float] = None,
|
|
564
|
+
) -> Stimulus:
|
|
565
|
+
"""A combination of pyramid shaped Ramp stimuli with a positive
|
|
566
|
+
amplitude.
|
|
567
|
+
|
|
568
|
+
Args:
|
|
569
|
+
threshold_current: The threshold current of the Cell.
|
|
570
|
+
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
571
|
+
amplitude: Raw amplitude of input current.
|
|
251
572
|
"""
|
|
252
|
-
|
|
253
|
-
|
|
573
|
+
delay = 250.0
|
|
574
|
+
ramp1_duration = 4000.0
|
|
575
|
+
ramp2_duration = 2000.0
|
|
576
|
+
ramp3_duration = 1333.0
|
|
577
|
+
inter_delay = 2000.0
|
|
578
|
+
post_delay = 250.0
|
|
579
|
+
|
|
580
|
+
if amplitude is None:
|
|
581
|
+
if threshold_current is None or threshold_current == 0 or threshold_percentage is None:
|
|
582
|
+
raise TypeError("You have to give either threshold_current or amplitude")
|
|
583
|
+
amplitude = threshold_current * threshold_percentage / 100
|
|
584
|
+
elif threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
585
|
+
logger.info(
|
|
586
|
+
"amplitude, threshold_current and threshold_percentage are all set in pos_cheops."
|
|
587
|
+
" Will only keep amplitude value."
|
|
588
|
+
)
|
|
589
|
+
result = (
|
|
590
|
+
Empty(self.dt, duration=delay)
|
|
591
|
+
+ Slope(self.dt, duration=ramp1_duration, amplitude_start=0.0, amplitude_end=amplitude)
|
|
592
|
+
+ Slope(self.dt, duration=ramp1_duration, amplitude_start=amplitude, amplitude_end=0.0)
|
|
593
|
+
+ Empty(self.dt, duration=inter_delay)
|
|
594
|
+
+ Slope(self.dt, duration=ramp2_duration, amplitude_start=0.0, amplitude_end=amplitude)
|
|
595
|
+
+ Slope(self.dt, duration=ramp2_duration, amplitude_start=amplitude, amplitude_end=0.0)
|
|
596
|
+
+ Empty(self.dt, duration=inter_delay)
|
|
597
|
+
+ Slope(self.dt, duration=ramp3_duration, amplitude_start=0.0, amplitude_end=amplitude)
|
|
598
|
+
+ Slope(self.dt, duration=ramp3_duration, amplitude_start=amplitude, amplitude_end=0.0)
|
|
599
|
+
+ Empty(self.dt, duration=post_delay)
|
|
254
600
|
)
|
|
601
|
+
return result
|
|
602
|
+
|
|
603
|
+
def neg_cheops(
|
|
604
|
+
self,
|
|
605
|
+
threshold_current: Optional[float] = None,
|
|
606
|
+
threshold_percentage: Optional[float] = 300.0,
|
|
607
|
+
amplitude: Optional[float] = None,
|
|
608
|
+
) -> Stimulus:
|
|
609
|
+
"""A combination of pyramid shaped Ramp stimuli with a negative
|
|
610
|
+
amplitude.
|
|
611
|
+
|
|
612
|
+
Args:
|
|
613
|
+
threshold_current: The threshold current of the Cell.
|
|
614
|
+
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
615
|
+
amplitude: Raw amplitude of input current.
|
|
616
|
+
"""
|
|
617
|
+
delay = 1750.0
|
|
618
|
+
ramp1_duration = 3333.0
|
|
619
|
+
ramp2_duration = 1666.0
|
|
620
|
+
ramp3_duration = 1111.0
|
|
621
|
+
inter_delay = 2000.0
|
|
622
|
+
post_delay = 250.0
|
|
623
|
+
|
|
624
|
+
if amplitude is None:
|
|
625
|
+
if threshold_current is None or threshold_current == 0 or threshold_percentage is None:
|
|
626
|
+
raise TypeError("You have to give either threshold_current or amplitude")
|
|
627
|
+
amplitude = - threshold_current * threshold_percentage / 100
|
|
628
|
+
elif threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
629
|
+
logger.info(
|
|
630
|
+
"amplitude, threshold_current and threshold_percentage are all set in neg_cheops."
|
|
631
|
+
" Will only keep amplitude value."
|
|
632
|
+
)
|
|
633
|
+
result = (
|
|
634
|
+
Empty(self.dt, duration=delay)
|
|
635
|
+
+ Slope(self.dt, duration=ramp1_duration, amplitude_start=0.0, amplitude_end=amplitude)
|
|
636
|
+
+ Slope(self.dt, duration=ramp1_duration, amplitude_start=amplitude, amplitude_end=0.0)
|
|
637
|
+
+ Empty(self.dt, duration=inter_delay)
|
|
638
|
+
+ Slope(self.dt, duration=ramp2_duration, amplitude_start=0.0, amplitude_end=amplitude)
|
|
639
|
+
+ Slope(self.dt, duration=ramp2_duration, amplitude_start=amplitude, amplitude_end=0.0)
|
|
640
|
+
+ Empty(self.dt, duration=inter_delay)
|
|
641
|
+
+ Slope(self.dt, duration=ramp3_duration, amplitude_start=0.0, amplitude_end=amplitude)
|
|
642
|
+
+ Slope(self.dt, duration=ramp3_duration, amplitude_start=amplitude, amplitude_end=0.0)
|
|
643
|
+
+ Empty(self.dt, duration=post_delay)
|
|
644
|
+
)
|
|
645
|
+
return result
|
|
646
|
+
|
|
647
|
+
def sinespec(
|
|
648
|
+
self,
|
|
649
|
+
threshold_current: Optional[float] = None,
|
|
650
|
+
threshold_percentage: Optional[float] = 60.0,
|
|
651
|
+
amplitude: Optional[float] = None,
|
|
652
|
+
pre_delay: float = 0,
|
|
653
|
+
) -> Stimulus:
|
|
654
|
+
"""Returns the SineSpec Stimulus object, a type of Zap stimulus.
|
|
655
|
+
|
|
656
|
+
Args:
|
|
657
|
+
threshold_current: The threshold current of the Cell.
|
|
658
|
+
threshold_percentage: Percentage of desired threshold_current amplification.
|
|
659
|
+
amplitude: Raw amplitude of input current.
|
|
660
|
+
pre_delay: delay before the start of the stimulus
|
|
661
|
+
"""
|
|
662
|
+
duration = 5000.0
|
|
663
|
+
post_delay = 0
|
|
664
|
+
|
|
665
|
+
if amplitude is not None:
|
|
666
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
667
|
+
logger.info(
|
|
668
|
+
"amplitude, threshold_current and threshold_percentage are all set in sinespec."
|
|
669
|
+
" Will only keep amplitude value."
|
|
670
|
+
)
|
|
671
|
+
return DelayedZap.amplitude_based(
|
|
672
|
+
self.dt,
|
|
673
|
+
pre_delay=pre_delay,
|
|
674
|
+
duration=duration,
|
|
675
|
+
post_delay=post_delay,
|
|
676
|
+
amplitude=amplitude,
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
if threshold_current is not None and threshold_current != 0 and threshold_percentage is not None:
|
|
680
|
+
return DelayedZap.threshold_based(
|
|
681
|
+
self.dt,
|
|
682
|
+
pre_delay=pre_delay,
|
|
683
|
+
duration=duration,
|
|
684
|
+
post_delay=post_delay,
|
|
685
|
+
threshold_current=threshold_current,
|
|
686
|
+
threshold_percentage=threshold_percentage,
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
raise TypeError("You have to give either threshold_current or amplitude")
|