bleeck@3
|
1 % This external file is included as part of the 'aim-mat' distribution package
|
bleeck@3
|
2 % (c) 2011, University of Southampton
|
bleeck@3
|
3 % Maintained by Stefan Bleeck (bleeck@gmail.com)
|
bleeck@3
|
4 % download of current version is on the soundsoftware site:
|
bleeck@3
|
5 % http://code.soundsoftware.ac.uk/projects/aimmat
|
bleeck@3
|
6 % documentation and everything is on http://www.acousticscale.org
|
tomwalters@0
|
7 function ret_spikes=sim_spikes(sig,nr_sweeps,params)
|
tomwalters@0
|
8 % simulates the response to a signal
|
tomwalters@0
|
9
|
tomwalters@0
|
10 % parameters of the recovery function
|
tomwalters@0
|
11 mu=params.mu;
|
tomwalters@0
|
12 beta=params.beta;
|
tomwalters@0
|
13
|
tomwalters@0
|
14 % other parameters
|
tomwalters@0
|
15 if isfield(params,'spont_rate')
|
tomwalters@0
|
16 spont_rate=params.spont_rate;
|
tomwalters@0
|
17 else
|
tomwalters@0
|
18 spont_rate=0;
|
tomwalters@0
|
19 end
|
tomwalters@0
|
20 if isfield(params,'latency')
|
tomwalters@0
|
21 latency=params.latency;
|
tomwalters@0
|
22 else
|
tomwalters@0
|
23 latency=4;
|
tomwalters@0
|
24 end
|
tomwalters@0
|
25 % if isfield(params,'first_spike_boost')
|
tomwalters@0
|
26 % first_spike_boost=params.first_spike_boost;
|
tomwalters@0
|
27 % else
|
tomwalters@0
|
28 % first_spike_boost=2;
|
tomwalters@0
|
29 % end
|
tomwalters@0
|
30 % if isfield(params,'start_boost_beta_length')
|
tomwalters@0
|
31 % start_boost_beta_length=params.start_boost_beta_length;
|
tomwalters@0
|
32 % else
|
tomwalters@0
|
33 % start_boost_beta_length=15;
|
tomwalters@0
|
34 % end
|
tomwalters@0
|
35 % if isfield(params,'start_boost_beta_val')
|
tomwalters@0
|
36 % start_boost_beta_val=params.start_boost_beta_val;
|
tomwalters@0
|
37 % else
|
tomwalters@0
|
38 % start_boost_beta_val=2;
|
tomwalters@0
|
39 % end
|
tomwalters@0
|
40 if isfield(params,'jitter')
|
tomwalters@0
|
41 jitter_time=params.jitter;
|
tomwalters@0
|
42 else
|
tomwalters@0
|
43 jitter_time=0.2;
|
tomwalters@0
|
44 end
|
tomwalters@0
|
45
|
tomwalters@0
|
46
|
tomwalters@0
|
47 % calcualates an artificail spiketrain with so many sweeps
|
tomwalters@0
|
48 % the important parameter are mu (the location) and beta (the scale) of the
|
tomwalters@0
|
49 % distribution
|
tomwalters@0
|
50
|
tomwalters@0
|
51 % changing some parameters so that the result looks good
|
tomwalters@0
|
52 %jitter to reduce some effect that the odd (or even?) multiples
|
tomwalters@0
|
53 %of the sr have significant and repeatable higher nr intervals
|
tomwalters@0
|
54 %then the others. Cant work out why. solution: let the interval
|
tomwalters@0
|
55 %jitter around the peak a bit
|
tomwalters@0
|
56
|
tomwalters@0
|
57 % calculate the x values of the distribution
|
tomwalters@0
|
58 % take a length of the distribution up to the point where it it 99.9 %
|
tomwalters@0
|
59 % that saves a lot of time
|
tomwalters@0
|
60 maxpoint=0.999;
|
tomwalters@0
|
61 tlength=mu-beta*log(-log(maxpoint));
|
tomwalters@0
|
62
|
tomwalters@0
|
63 % set the random number generator to a new value
|
tomwalters@0
|
64 % rand('state', sum(100*clock));
|
tomwalters@0
|
65 % dont do that because the values are too close to each other and actually
|
tomwalters@0
|
66 % not random at all!
|
tomwalters@0
|
67
|
tomwalters@0
|
68 binwidth=getsr(sig);
|
tomwalters@0
|
69 sig_len=getlength(sig);
|
tomwalters@0
|
70 nr_steps=sig_len/binwidth;
|
tomwalters@0
|
71 x2=binwidth:binwidth:tlength;
|
tomwalters@0
|
72
|
tomwalters@0
|
73 spike_prob_function=hazard_function(x2,mu,beta); % for the full signal length
|
tomwalters@0
|
74 spike_prob_function2=hazard_function(x2,mu,beta/start_boost_beta_val); % for the first 20 ms
|
tomwalters@0
|
75
|
tomwalters@0
|
76
|
tomwalters@0
|
77 % build a "test signal" out of zeros and ones
|
tomwalters@0
|
78 test_sig=zeros(nr_steps,1);
|
tomwalters@0
|
79 test_sig(1:50/sig_sr)=1; % the first 50 ms are ones
|
tomwalters@0
|
80 % build a ramp...
|
tomwalters@0
|
81 test_sig(1:2/sig_sr)=linspace(0,1,length(5/sig_sr));
|
tomwalters@0
|
82
|
tomwalters@0
|
83
|
tomwalters@0
|
84 for i=1:nr_sweeps
|
tomwalters@0
|
85 spikes=[];
|
tomwalters@0
|
86 last_spike=-1; % inital condition: how long ago was the last spike
|
tomwalters@0
|
87 spikecounter=1; % spikecounter
|
tomwalters@0
|
88 for j=1:nr_steps
|
tomwalters@0
|
89 time_now=j*binwidth; % thats the global time counter
|
tomwalters@0
|
90 % implementation of a simple solution for the first spike problem: if the spike is the first then assume a very high probability
|
tomwalters@0
|
91 if spikecounter==1 % yes, its the first
|
tomwalters@0
|
92 if rand<binwidth*first_spike_boost % if a random number is smaller, then ...
|
tomwalters@0
|
93 jitter=randfloat(-jitter_time,jitter_time);
|
tomwalters@0
|
94 last_spike=time_now+jitter; % yes, a spike has happend now!
|
tomwalters@0
|
95 spikes(spikecounter)=last_spike+latency; % save and add the latency
|
tomwalters@0
|
96 spikecounter=spikecounter+1; %remember the spike, when it happens
|
tomwalters@0
|
97 end
|
tomwalters@0
|
98 else % its a follow up spike
|
tomwalters@0
|
99 difft=time_now-last_spike; % how long ago is the last spike?
|
tomwalters@0
|
100 sindx=ceil(difft/binwidth); sindx=max(1,sindx); sindx=min(length(spike_prob_function),sindx);
|
tomwalters@0
|
101 if time_now<start_boost_beta_length
|
tomwalters@0
|
102 spike_prob=spike_prob_function2(sindx);
|
tomwalters@0
|
103 else
|
tomwalters@0
|
104 spike_prob=spike_prob_function(sindx);
|
tomwalters@0
|
105 end
|
tomwalters@0
|
106 spike_prob=spike_prob*test_sig(j)+spont_rate; % % modulate the probability with the height of the signal
|
tomwalters@0
|
107 spike_prob=spike_prob/(1.2+binwidth/2); %correction factor
|
tomwalters@0
|
108 if rand<spike_prob % if a random number is smaller, then ...
|
tomwalters@0
|
109 jitter=randfloat(-jitter_time,jitter_time);
|
tomwalters@0
|
110 last_spike=time_now+jitter; % yes, a spike has happend now!
|
tomwalters@0
|
111 % make sure that it is not too close to the last one (as a result of the jitter)
|
tomwalters@0
|
112 if last_spike<spikes(spikecounter-1)+0.1;
|
tomwalters@0
|
113 last_spike=time_now;
|
tomwalters@0
|
114 end
|
tomwalters@0
|
115 spikes(spikecounter)=last_spike+latency; % save and add the latency
|
tomwalters@0
|
116 spikecounter=spikecounter+1; %remember the spike, when it happens
|
tomwalters@0
|
117 end
|
tomwalters@0
|
118 end
|
tomwalters@0
|
119 end
|
tomwalters@0
|
120 ret_spikes{i}=spikes;
|
tomwalters@0
|
121 end
|