You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.5 KiB
126 lines
4.5 KiB
2 years ago
|
__author__ = "pbmanis"
|
||
|
"""
|
||
|
ccstim
|
||
|
Generate current-clamp (or voltage-clamp) stimulus waveforms from a dictionary
|
||
|
used for vectory play modes in current clamp
|
||
|
(prior version was called 'makestim')
|
||
|
|
||
|
Can generate several types of pulses
|
||
|
|
||
|
"""
|
||
|
|
||
|
import numpy as np
|
||
|
|
||
|
|
||
|
def ccstim(stim, dt, pulsetype="square"):
|
||
|
"""
|
||
|
Create stimulus pulse waveforms of different types.
|
||
|
|
||
|
Parameters
|
||
|
----------
|
||
|
stim : dict
|
||
|
a dictionary with keys [required]
|
||
|
delay (delay to start of pulse train, msec [all]
|
||
|
duration: duration of pulses in train, msec [all]
|
||
|
Sfreq: stimulus train frequency (Hz) [timedSpikes]
|
||
|
PT: post-train test delay [all]
|
||
|
NP: number of pulses in the train [timedSpikes, exp]
|
||
|
amp: amplitude of the pulses in the train [all]
|
||
|
hypamp: amplitude of prehyperpolarizing pulse [hyp]
|
||
|
hypdur: duration of prehyperpolarizing pulse [hyp]
|
||
|
spikeTimes" times of spikes [timedSpikes]
|
||
|
|
||
|
dt : time (microseconds) [required]
|
||
|
step time, in microseconds. Required parameter
|
||
|
|
||
|
pulsetype : string (default: 'square')
|
||
|
Type of pulse to generate: one of square, hyp, timedspikes or exp
|
||
|
square produces a train of "square" (retangular) pulses levels 0 and ampitude
|
||
|
hyp is like square, but precedes the pulse train with a single prepulse
|
||
|
of hypamp and hypdur
|
||
|
timedspikes is like square, excpet the pulses are generated at times specified
|
||
|
in the spikeTimes key in the stim dictionary
|
||
|
exp: pulses with an exponential decay.
|
||
|
|
||
|
TO DO:
|
||
|
add pulsetypes, including sine wave, rectified sine wave, etc.
|
||
|
|
||
|
Returns
|
||
|
-------
|
||
|
list containing [waveform (numpy array),
|
||
|
maxtime(float),
|
||
|
timebase (numpy array)]
|
||
|
"""
|
||
|
|
||
|
assert dt is not None
|
||
|
assert "delay" in stim.keys()
|
||
|
delay = int(np.floor(stim["delay"] / dt))
|
||
|
if pulsetype in ["square", "hyp", "exp"]:
|
||
|
ipi = int(np.floor((1000.0 / stim["Sfreq"]) / dt))
|
||
|
pdur = int(np.floor(stim["duration"] / dt))
|
||
|
posttest = int(np.floor(stim["PT"] / dt))
|
||
|
if pulsetype not in ["timedSpikes"]:
|
||
|
NP = int(stim["NP"])
|
||
|
else:
|
||
|
NP = len(stim["spikeTimes"])
|
||
|
tstims = [0] * NP
|
||
|
if pulsetype == "hyp":
|
||
|
assert "hypamp" in stim.keys()
|
||
|
assert "hypdur" in stim.keys()
|
||
|
hypdur = int(np.floor(stim["hypdur"] / dt))
|
||
|
delay0 = delay # save original delay
|
||
|
|
||
|
if pulsetype in ["square", "hyp"]:
|
||
|
maxt = dt * (stim["delay"] + (ipi * (NP + 2)) + posttest + pdur * 2)
|
||
|
if pulsetype == "hyp":
|
||
|
maxt = maxt + dt * stim["hypdur"]
|
||
|
delay = delay + hypdur
|
||
|
w = np.zeros(int(np.floor(maxt / dt)))
|
||
|
for j in range(0, NP):
|
||
|
t = (delay + j * ipi) * dt
|
||
|
w[delay + ipi * j : delay + (ipi * j) + pdur] = stim["amp"]
|
||
|
tstims[j] = delay + ipi * j
|
||
|
if stim["PT"] > 0.0:
|
||
|
send = delay + ipi * j
|
||
|
for i in range(send + posttest, send + posttest + pdur):
|
||
|
w[i] = stim["amp"]
|
||
|
if pulsetype == "hyp": # fill in the prepulse now
|
||
|
for i in range(delay0, delay0 + hypdur):
|
||
|
w[i] = stim["hypamp"]
|
||
|
|
||
|
if pulsetype == "timedSpikes":
|
||
|
maxt = np.max(stim["spikeTimes"]) + stim["PT"] + stim["duration"] * 2
|
||
|
w = np.zeros(int(np.floor(maxt / dt)))
|
||
|
for j in range(len(stim["spikeTimes"])):
|
||
|
st = delay + int(np.floor(stim["spikeTimes"][j] / dt))
|
||
|
t = st * dt
|
||
|
w[st : st + pdur] = stim["amp"]
|
||
|
tstims[j] = st
|
||
|
|
||
|
if stim["PT"] > 0.0:
|
||
|
for i in range(st + posttest, st + posttest + pdur):
|
||
|
w[i] = stim["amp"]
|
||
|
|
||
|
if pulsetype == "exp":
|
||
|
maxt = dt * (stim["delay"] + (ipi * (NP + 2)) + posttest + pdur * 2)
|
||
|
w = np.zeros(int(np.floor(maxt / dt)))
|
||
|
|
||
|
for j in range(0, NP):
|
||
|
for i in range(0, len(w)):
|
||
|
if delay + ipi * j + i < len(w):
|
||
|
w[delay + ipi * j + i] = w[delay + ipi * j + i] + stim["amp"] * (
|
||
|
(1.0 - np.exp(-i / (pdur / 3.0)))
|
||
|
* np.exp(-(i - (pdur / 3.0)) / pdur)
|
||
|
)
|
||
|
tstims[j] = delay + ipi * j
|
||
|
if stim["PT"] > 0.0:
|
||
|
send = delay + ipi * j
|
||
|
for i in range(send + posttest, len(w)):
|
||
|
w[i] += (
|
||
|
stim["amp"]
|
||
|
* (1.0 - np.exp(-i / (pdur / 3.0)))
|
||
|
* np.exp(-(i - (pdur / 3.0)) / pdur)
|
||
|
)
|
||
|
|
||
|
return (w, maxt, tstims)
|