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 p=params.int;
|
tomwalters@0
|
12
|
tomwalters@0
|
13
|
tomwalters@0
|
14 % the 'zero' eta determines the spontaneous activity
|
tomwalters@0
|
15 % p1_null=50;
|
tomwalters@0
|
16
|
tomwalters@0
|
17 % % other parameters
|
tomwalters@0
|
18 if isfield(params,'latency')
|
tomwalters@0
|
19 latency=params.latency;
|
tomwalters@0
|
20 else
|
tomwalters@0
|
21 latency=4;
|
tomwalters@0
|
22 end
|
tomwalters@0
|
23 if isfield(params,'first_spike_boost')
|
tomwalters@0
|
24 first_spike_boost=params.first_spike_boost;
|
tomwalters@0
|
25 else
|
tomwalters@0
|
26 first_spike_boost=2;
|
tomwalters@0
|
27 end
|
tomwalters@0
|
28 if isfield(params,'threshold')
|
tomwalters@0
|
29 threshold=params.threshold;
|
tomwalters@0
|
30 else
|
tomwalters@0
|
31 threshold=0; % in dB
|
tomwalters@0
|
32 end
|
tomwalters@0
|
33 if isfield(params,'dynamic_range')
|
tomwalters@0
|
34 dynamic_range=params.dynamic_range;
|
tomwalters@0
|
35 else
|
tomwalters@0
|
36 dynamic_range=20; % in dB
|
tomwalters@0
|
37 end
|
tomwalters@0
|
38 % if isfield(params,'start_boost_beta_length')
|
tomwalters@0
|
39 % start_boost_beta_length=params.start_boost_beta_length;
|
tomwalters@0
|
40 % else
|
tomwalters@0
|
41 % start_boost_beta_length=15;
|
tomwalters@0
|
42 % end
|
tomwalters@0
|
43 % if isfield(params,'start_boost_beta_val')
|
tomwalters@0
|
44 % start_boost_beta_val=params.start_boost_beta_val;
|
tomwalters@0
|
45 % else
|
tomwalters@0
|
46 % start_boost_beta_val=2;
|
tomwalters@0
|
47 % end
|
tomwalters@0
|
48 % if isfield(params,'jitter')
|
tomwalters@0
|
49 % jitter_time=params.jitter;
|
tomwalters@0
|
50 % else
|
tomwalters@0
|
51 % jitter_time=0.2;
|
tomwalters@0
|
52 % end
|
tomwalters@0
|
53
|
tomwalters@0
|
54
|
tomwalters@0
|
55 % calcualates an artificail spiketrain with so many sweeps
|
tomwalters@0
|
56 % the important parameter are mu (the location) and beta (the scale) of the
|
tomwalters@0
|
57 % distribution
|
tomwalters@0
|
58
|
tomwalters@0
|
59 % changing some parameters so that the result looks good
|
tomwalters@0
|
60 %jitter to reduce some effect that the odd (or even?) multiples
|
tomwalters@0
|
61 %of the sr have significant and repeatable higher nr intervals
|
tomwalters@0
|
62 %then the others. Cant work out why. solution: let the interval
|
tomwalters@0
|
63 %jitter around the peak a bit
|
tomwalters@0
|
64
|
tomwalters@0
|
65 % calculate the x values of the distribution
|
tomwalters@0
|
66 % take a length of the distribution up to the point where it it 99.9 %
|
tomwalters@0
|
67 % that saves a lot of time
|
tomwalters@0
|
68 % maxpoint=0.999;
|
tomwalters@0
|
69 % tlength=mu-beta*log(-log(maxpoint));
|
tomwalters@0
|
70
|
tomwalters@0
|
71 % set the random number generator to a new value
|
tomwalters@0
|
72 % rand('state', sum(100*clock));
|
tomwalters@0
|
73 % dont do that because the values are too close to each other and actually
|
tomwalters@0
|
74 % not random at all!
|
tomwalters@0
|
75
|
tomwalters@0
|
76 binwidth=1/getsr(sig)*1000;
|
tomwalters@0
|
77 sig_len=getlength(sig);
|
tomwalters@0
|
78 nr_steps=getnrpoints(sig);
|
tomwalters@0
|
79
|
tomwalters@0
|
80
|
tomwalters@0
|
81 % % x2=binwidth:binwidth:tlength;
|
tomwalters@0
|
82 %
|
tomwalters@0
|
83 % % spike_prob_function=hazard_function(x2,mu,beta); % for the full signal length
|
tomwalters@0
|
84 % % spike_prob_function2=hazard_function(x2,mu,beta/start_boost_beta_val); % for the first 20 ms
|
tomwalters@0
|
85 %
|
tomwalters@0
|
86 % test_sig=getvalues(sig);
|
tomwalters@0
|
87 % test_sig=test_sig+60; % shift it upwards
|
tomwalters@0
|
88 %
|
tomwalters@0
|
89 %
|
tomwalters@0
|
90 % for i=1:nr_sweeps
|
tomwalters@0
|
91 % spikes=[];
|
tomwalters@0
|
92 % last_spike=-1; % inital condition: how long ago was the last spike
|
tomwalters@0
|
93 % spikecounter=1; % spikecounter
|
tomwalters@0
|
94 % for j=1:nr_steps
|
tomwalters@0
|
95 % time_now=j*binwidth; % thats the global time counter
|
tomwalters@0
|
96 % difft=time_now-last_spike; % how long ago is the last spike?
|
tomwalters@0
|
97 % if difft<1, continue, end
|
tomwalters@0
|
98 %
|
tomwalters@0
|
99 % % % modify eta by the amplitude:
|
tomwalters@0
|
100 % % cur_amp=test_sig(j)-threshold; % in dB above threshold
|
tomwalters@0
|
101 % % if cur_amp>dynamic_range % in saturation
|
tomwalters@0
|
102 % % cur_eta=eta;
|
tomwalters@0
|
103 % % else
|
tomwalters@0
|
104 % % cur_eta=(eta-eta_null)/dynamic_range*cur_amp+eta_null;
|
tomwalters@0
|
105 % % % cur_eta=f2f(cur_amp,0,dynamic_range,eta_null,eta);
|
tomwalters@0
|
106 % % end
|
tomwalters@0
|
107 %
|
tomwalters@0
|
108 % % z = (log(difft) - p1) ./ p2;
|
tomwalters@0
|
109 % % spike_prob = exp(p3 - exp(p3)) ./ p2;
|
tomwalters@0
|
110 % spike_prob = gevpdf(log(difft),p3,p2,p1);
|
tomwalters@0
|
111 %
|
tomwalters@0
|
112 % % weibull function
|
tomwalters@0
|
113 % % spike_prob=(beta/cur_eta)*power(log(difft)/cur_eta,beta-1);
|
tomwalters@0
|
114 %
|
tomwalters@0
|
115 % % spike_prob=spike_prob*test_sig(j)+spont_rate; % % modulate the probability with the height of the signal
|
tomwalters@0
|
116 % % spike_prob=spike_prob/(1.2+binwidth/2); %correction factor
|
tomwalters@0
|
117 % if rand<spike_prob % if a random number is smaller, then ...
|
tomwalters@0
|
118 % % jitter=randfloat(-jitter_time,jitter_time);
|
tomwalters@0
|
119 % % last_spike=time_now+jitter; % yes, a spike has happend now!
|
tomwalters@0
|
120 % last_spike=time_now; % yes, a spike has happend now!
|
tomwalters@0
|
121 % spikes(spikecounter)=last_spike+latency; % save and add the latency
|
tomwalters@0
|
122 % spikecounter=spikecounter+1; %remember the spike, when it happens
|
tomwalters@0
|
123 % end
|
tomwalters@0
|
124 % end
|
tomwalters@0
|
125 % % end
|
tomwalters@0
|
126 % ret_spikes{i}=spikes;
|
tomwalters@0
|
127 % end
|
tomwalters@0
|
128
|
tomwalters@0
|
129 x2=getxvalues(sig).*1000;
|
tomwalters@0
|
130 x2=x2(x2>0);
|
tomwalters@0
|
131 x2=[x2; x2(end)+binwidth];
|
tomwalters@0
|
132 % figure(43)
|
tomwalters@0
|
133 % cla
|
tomwalters@0
|
134 % hold on
|
tomwalters@0
|
135 for i=10:-1:1
|
tomwalters@0
|
136 if isfield(p{i},'k') % otherwise no spikes
|
tomwalters@0
|
137 p1=p{i}.k;
|
tomwalters@0
|
138 p2=log(p{i}.x)*3.2;
|
tomwalters@0
|
139 p3=p{i}.y*1.5;
|
tomwalters@0
|
140 % plot3(p1,p2,p3,'o')
|
tomwalters@0
|
141 pdf=gevpdf(log(x2),p1,p2,p3);
|
tomwalters@0
|
142 cdf=gevcdf(log(x2),p1,p2,p3);
|
tomwalters@0
|
143 spike_prob_function{i}=ones(size(x2))*inf;
|
tomwalters@0
|
144 for j=1:length(x2)
|
tomwalters@0
|
145 if cdf(j)<1
|
tomwalters@0
|
146 spike_prob_function{i}(j)=pdf(j)/(1-cdf(j));
|
tomwalters@0
|
147 end
|
tomwalters@0
|
148 end
|
tomwalters@0
|
149 else
|
tomwalters@0
|
150 % otherwise take the "default" one
|
tomwalters@0
|
151 spike_prob_function{i}=spike_prob_function{10};
|
tomwalters@0
|
152 end
|
tomwalters@0
|
153 end
|
tomwalters@0
|
154
|
tomwalters@0
|
155 times=0:10:60;
|
tomwalters@0
|
156 times=[times 100 250];
|
tomwalters@0
|
157
|
tomwalters@0
|
158
|
tomwalters@0
|
159 % spike_prob_function2=gevpdf(x2,p3,p2/start_boost_beta_val,p1); % for the first 20 ms
|
tomwalters@0
|
160
|
tomwalters@0
|
161 jitter_time=0;
|
tomwalters@0
|
162 latency=0;
|
tomwalters@0
|
163
|
tomwalters@0
|
164 start_boost_beta_length=20;
|
tomwalters@0
|
165 test_sig=zeros(length(x2),1);
|
tomwalters@0
|
166 test_sig(1:55/binwidth)=1;
|
tomwalters@0
|
167 spont_rate=0;
|
tomwalters@0
|
168
|
tomwalters@0
|
169 for i=1:nr_sweeps
|
tomwalters@0
|
170 spikes=[];
|
tomwalters@0
|
171 last_spike=-1; % inital condition: how long ago was the last spike
|
tomwalters@0
|
172 spikecounter=1; % spikecounter
|
tomwalters@0
|
173 swapc=2;
|
tomwalters@0
|
174 next_swap=times(swapc);
|
tomwalters@0
|
175 c_function=spike_prob_function{swapc};
|
tomwalters@0
|
176
|
tomwalters@0
|
177 for j=1:nr_steps
|
tomwalters@0
|
178 time_now=j*binwidth; % thats the global time counter
|
tomwalters@0
|
179 if time_now>next_swap
|
tomwalters@0
|
180 swapc=swapc+1;
|
tomwalters@0
|
181 next_swap=times(swapc);
|
tomwalters@0
|
182 c_function=spike_prob_function{swapc};
|
tomwalters@0
|
183 end
|
tomwalters@0
|
184 % implementation of a simple solution for the first spike problem: if the spike is the first then assume a very high probability
|
tomwalters@0
|
185 if spikecounter==1 % yes, its the first
|
tomwalters@0
|
186 % if rand<binwidth*first_spike_boost % if a random number is smaller, then ...
|
tomwalters@0
|
187 % jitter=randfloat(-jitter_time,jitter_time);
|
tomwalters@0
|
188 % last_spike=time_now+jitter; % yes, a spike has happend now!
|
tomwalters@0
|
189 % spikes(spikecounter)=last_spike+latency; % save and add the latency
|
tomwalters@0
|
190 % spikecounter=spikecounter+1; %remember the spike, when it happens
|
tomwalters@0
|
191 % end
|
tomwalters@0
|
192
|
tomwalters@0
|
193 % follow the first spike prob
|
tomwalters@0
|
194 spike_prob=spike_prob_function{1}(j);
|
tomwalters@0
|
195 if rand<spike_prob% if a random number is smaller, then ...
|
tomwalters@0
|
196 jitter=randfloat(-jitter_time,jitter_time);
|
tomwalters@0
|
197 last_spike=time_now+jitter; % yes, a spike has happend now!
|
tomwalters@0
|
198 spikes(spikecounter)=last_spike+latency; % save and add the latency
|
tomwalters@0
|
199 spikecounter=spikecounter+1; %remember the spike, when it happens
|
tomwalters@0
|
200 end
|
tomwalters@0
|
201
|
tomwalters@0
|
202
|
tomwalters@0
|
203 else % its a follow up spike
|
tomwalters@0
|
204 difft=time_now-last_spike; % how long ago is the last spike?
|
tomwalters@0
|
205 sindx=round(difft/binwidth); sindx=max(1,sindx); sindx=min(350,sindx);
|
tomwalters@0
|
206
|
tomwalters@0
|
207 spike_prob=c_function(sindx);
|
tomwalters@0
|
208 %timefound=find(difft<times,1,'first');
|
tomwalters@0
|
209 %spike_prob=spike_prob_function{timefound}(sindx);
|
tomwalters@0
|
210
|
tomwalters@0
|
211 spike_prob=spike_prob*test_sig(j)+spont_rate; % % modulate the probability with the height of the signal
|
tomwalters@0
|
212 % spike_prob=spike_prob/(1.2+binwidth/2); %correction factor
|
tomwalters@0
|
213 if rand<spike_prob % if a random number is smaller, then ...
|
tomwalters@0
|
214 jitter=randfloat(-jitter_time,jitter_time);
|
tomwalters@0
|
215 last_spike=time_now+jitter; % yes, a spike has happend now!
|
tomwalters@0
|
216 % make sure that it is not too close to the last one (as a result of the jitter)
|
tomwalters@0
|
217 if last_spike<spikes(spikecounter-1)+0.1;
|
tomwalters@0
|
218 last_spike=time_now;
|
tomwalters@0
|
219 end
|
tomwalters@0
|
220 spikes(spikecounter)=last_spike+latency; % save and add the latency
|
tomwalters@0
|
221 spikecounter=spikecounter+1; %remember the spike, when it happens
|
tomwalters@0
|
222 end
|
tomwalters@0
|
223 end
|
tomwalters@0
|
224 end
|
tomwalters@0
|
225 ret_spikes{i}=spikes;
|
tomwalters@0
|
226 end
|
tomwalters@0
|
227
|