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