in_vivo_1/torus/code/multisensory_stimuli.py

121 lines
4.8 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import args
import numpy as np
import matplotlib.pyplot as plt
from IPython import embed
class MultichannelStimulus(object):
def __init__(self, namespace):
assert(namespace is not None)
assert(isinstance(namespace, argparse.Namespace))
self._constrast_stimulus = None
self._zap_stimulus = None
self._phase_stimulus = None
self._eod_ampl = namespace.amplitude
self._eod_freq = namespace.frequency
self._df = namespace.beatfrequency
self._dcf = namespace.dcfrequency
self._outfile = namespace.outfile
self._dt = namespace.stepsize
self._maxfreq = namespace.maxfreq
self._zap_duration = 10.0
self._contrast_sweep_duration = 5.0
self._phase_sweep_duration = 5.0
self.create_contrast_stim()
self.create_phase_stim()
self.create_zap_stim()
def create_contrast_stim(self):
t = np.arange(0, self._contrast_sweep_duration, self._dt)
sweep_up = np.linspace(0., 1.0, len(t))
am = np.sin((self._eod_freq + self._df) * 2 * np.pi * t)
dc = np.sin(2*np.pi*self._dcf*t)
am_sweep = am * sweep_up
dc_sweep = dc * sweep_up
self._contrast_stimulus = np.hstack((am_sweep, dc_sweep, am + dc_sweep, dc + am_sweep))
header = {" ": "Contrast sweeps for ampullary and tuberous pathways",
"sd": 1.0,
"deltat": "%.5f s" % self._dt,
"eodf": self._eod_freq,
"df": self._df,
"dcf": self._dcf,
"T": "%.3f s" % (4 * self._contrast_sweep_duration)}
self.save_stim(np.arange(len(self._contrast_stimulus)) * self._dt, self._contrast_stimulus, header,
"contrast_sweep")
def create_phase_stim(self):
t = np.arange(0, self._phase_sweep_duration, self._dt)
phase_sweep = np.linspace(0., 2*np.pi, len(t))
am = np.sin((self._eod_freq + self._df) * 2 * np.pi * t)
dc = np.sin(2*np.pi*self._df*t + phase_sweep)
self._phase_stimulus = am + dc
header = {" ": "Phase sweep stimulating ampullary and tuberous pathways",
"sd": 1.0,
"deltat": "%.5f s" % self._dt,
"eodf": self._eod_freq,
"df": self._df,
"T": "%.3f s" % (self._phase_sweep_duration)}
self.save_stim(t, self._phase_stimulus, header, "phase_sweep")
def create_zap_stim(self):
t = np.arange(0, self._zap_duration, self._dt)
m = self._maxfreq/self._zap_duration
dc = np.sin(2*np.pi*m*t*t)
am = np.sin(2*np.pi*(m*t + self._eod_freq)*t)
self._zap_stimulus = np.hstack((dc, am, dc+am))
header = {" ": "Zap stimulus for ampullary and tuberous pathways",
"sd": 1.0,
"deltat": "%.5f s" % self._dt,
"eodf": self._eod_freq,
"maxf": self._maxfreq,
"T": "%.3f s" % (3*self._zap_duration)}
self.save_stim(np.arange(len(self._zap_stimulus))*self._dt, self._zap_stimulus, header, "zap")
def save_stim(self, time, stimulus, header, suffix):
assert(isinstance(header, dict))
with open('_'.join((self._outfile, suffix)) + '.dat', "w") as f:
for h in header.items():
if len(h[0].strip()) == 0:
f.write("# %s\n" % (h[1]))
else:
f.write("# %s = %s\n" % (h[0], h[1]))
f.write("\n")
f.write("#Key\n")
f.write("# t \t x \n")
f.write("# s \t 1 \n")
for t, s in zip(time, stimulus):
f.write("%.5f\t %.7f\n" % (t, s))
f.write("\n")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=args.description)
parser.add_argument('-f', '--frequency', metavar="f", type=float, default='100',
help='The fish\'s EOD frequency')
parser.add_argument('-a', '--amplitude', metavar='a', type=float,
help='The fish\'s EOD amplitude in mV/cm')
parser.add_argument('-bf', '--beatfrequency', default=20, metavar='b', type=float,
help=args.beat_help)
parser.add_argument('-dc', '--dcfrequency', default=20, metavar='dcfreq', type=float,
help=args.dc_help)
parser.add_argument('-dt', '--stepsize', type=float, default=1./20000,
help=args.dt_help)
parser.add_argument('-mf', '--maxfreq', type=float, default=100.,
help=args.maxfreq_help)
parser.add_argument('outfile prefix', help="name of the output file may include the path")
args = parser.parse_args()
stim = MultichannelStimulus(args)