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.
117 lines
3.5 KiB
117 lines
3.5 KiB
2 years ago
|
"""
|
||
|
Test using sound stimulation to generate SGC spike trains.
|
||
|
|
||
|
This script uses an_model.get_spiketrain(), which internally calls MATLAB to
|
||
|
generate spike trains and caches the output. A higher-level approach is to use
|
||
|
DummySGC, which will automatically feed the spike train into a synapse for
|
||
|
input to downstream neurons (see test_sgc_input.py). Lower-level access to the
|
||
|
auditory nerve model is demonstrated in test_an_model.py.
|
||
|
|
||
|
This script also can measure the time required to generate the spike trains, or
|
||
|
to retrieve them from the cache. In addition, it can access a second interface
|
||
|
to the Zilany et al. mode that is in pure python ("cochlea") for comparison.
|
||
|
In general the speed to compute the spike trains for the same sets of stimuli
|
||
|
is faster with the pure Python interface than with the Matlab interface, and
|
||
|
fastest for retrieval of pre-computed trains. Note that changing the value
|
||
|
of "seed" will force a recomputation of the spike trains.
|
||
|
"""
|
||
|
import numpy as np
|
||
|
import pyqtgraph as pg
|
||
|
from cnmodel import an_model
|
||
|
from cnmodel.util import sound
|
||
|
import cochlea
|
||
|
|
||
|
import time
|
||
|
|
||
|
seed = 34986
|
||
|
|
||
|
|
||
|
def time_usage(func):
|
||
|
def wrapper(*args, **kwargs):
|
||
|
beg_ts = time.time()
|
||
|
res = func(*args, **kwargs)
|
||
|
end_ts = time.time()
|
||
|
print(("** Elapsed time: %f" % (end_ts - beg_ts)))
|
||
|
return res
|
||
|
|
||
|
return wrapper
|
||
|
|
||
|
|
||
|
def set_dbspl(signal, dbspl):
|
||
|
"""Scale the level of `signal` to the given dB_SPL."""
|
||
|
p0 = 20e-6
|
||
|
rms = np.sqrt(np.sum(signal ** 2) / signal.size)
|
||
|
scaled = signal * 10 ** (dbspl / 20.0) * p0 / rms
|
||
|
return scaled
|
||
|
|
||
|
|
||
|
@time_usage
|
||
|
def sound_stim(seed, useMatlab=True):
|
||
|
cf = 1.5e3
|
||
|
levels = list(range(-10, 101, 10))
|
||
|
|
||
|
result = {}
|
||
|
if useMatlab:
|
||
|
simulator = "matlab"
|
||
|
else:
|
||
|
simulator = "cochlea"
|
||
|
for sr in 1, 2, 3:
|
||
|
spikes = []
|
||
|
for level in levels:
|
||
|
stim = sound.TonePip(
|
||
|
rate=100e3,
|
||
|
duration=0.5,
|
||
|
f0=cf,
|
||
|
dbspl=level,
|
||
|
pip_duration=0.5,
|
||
|
pip_start=[0],
|
||
|
ramp_duration=2.5e-3,
|
||
|
)
|
||
|
if simulator == "cochlea":
|
||
|
stim._sound = set_dbspl(stim.sound, level) # adjust scaling here
|
||
|
spikes.append(
|
||
|
an_model.get_spiketrain(
|
||
|
cf=cf, sr=sr, seed=seed, stim=stim, simulator=simulator
|
||
|
)
|
||
|
)
|
||
|
seed += 1
|
||
|
result[sr] = {"levels": levels, "spikes": spikes}
|
||
|
return result
|
||
|
|
||
|
|
||
|
import sys
|
||
|
|
||
|
|
||
|
def runtest():
|
||
|
usematlab = True
|
||
|
if len(sys.argv) > 0:
|
||
|
if len(sys.argv) == 1:
|
||
|
print(
|
||
|
'Call requires argument, must be either "matlab" or "cochlea"; default is "matlab"'
|
||
|
)
|
||
|
exit()
|
||
|
flag = sys.argv[1]
|
||
|
if flag not in ["matlab", "cochlea"]:
|
||
|
print('Flag must be either "matlab" or "cochlea"; default is "matlab"')
|
||
|
exit()
|
||
|
if flag == "cochlea":
|
||
|
usematlab = False
|
||
|
if usematlab:
|
||
|
print("Running with matlab simulator")
|
||
|
else:
|
||
|
print("Running with MR cochlea simulator")
|
||
|
|
||
|
result = sound_stim(seed, useMatlab=usematlab)
|
||
|
|
||
|
win = pg.GraphicsWindow()
|
||
|
p1 = win.addPlot(title="Rate-level function")
|
||
|
for i, x in enumerate(result.keys()):
|
||
|
p1.plot(result[x]["levels"], [s.size for s in result[x]["spikes"]], pen=(x, 6))
|
||
|
return win
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
win = runtest()
|
||
|
if sys.flags.interactive == 0:
|
||
|
pg.QtGui.QApplication.exec_()
|