Revision 38:c2204b18f4a2 userProgramsMathiasDietz

View differences:

userProgramsMathiasDietz/test_binaural.m
1
function test_binaural
2
% test_binaural is a first attempt to produce a binaural model
3
%  incorporating MSO and IC models.
4
% The monaural response is computed first for left and right stimuli
5
%  before using the CN response as input to the binaural MSO model
6
%  that, in turn, feeds a single cell IC model.
7
%
8
% The function has no arguments and everything is set up internally
9
%
10
% #1
11
% Identify the file (in 'MAPparamsName') containing the model parameters
12
%  the default is 'PL' which uses primary like neurons in the CN to
13
%  simulate spherical bushy cells
14
%
15
% #2
16
% Set AN_spikesOrProbability'). to 'spikes'
17
%
18
% #3
19
% Choose between a tone signal or file input (in 'signalType')
20
%
21
% #4
22
% Set the signal rms level (in leveldBSPL)
23
%
24
% #5
25
% Identify the channels in terms of their best frequencies in the vector
26
%  BFlist. This is currently a single-channel model, so only one BF needed
27
%
28
% #6
29
% Last minute changes to the parameters fetched earlier can be made using
30
%  the cell array of strings 'paramChanges'.
31
%  Each string must have the same format as the corresponding line in the
32
%  file identified in 'MAPparamsName'
33
% Currently this is used to specify that only HSR fibers are used and
34
%  for changing the current per AN spike at the CN dendrite
35
%
36
% #7
37
% specify the parameters of the MSO cells in the MSOParams structure
38
%
39
% #8
40
% specify the parameters of the IC cells in the ICMSOParams structure
41
%
42
% #9
43
% identify the plots required from MAP1_14 (i.e. before the bonaural model)
44
%
45
% #10
46
% Specify ITDs. The program cycles through different ITDs
47
%
48

  
49
global CNoutput dtSpikes
50
dbstop if error
51
restorePath=path;
52
addpath (['..' filesep 'MAP'],    ['..' filesep 'wavFileStore'], ...
53
    ['..' filesep 'utilities'])
54

  
55
%%  #1 monaural model parameter file name
56
MAPparamsName='PL';
57

  
58

  
59
%% #2 'spikes' are mandatory for this model
60
AN_spikesOrProbability='spikes';
61

  
62

  
63
%% #3 pure tone, harmonic sequence or speech file input
64
signalType= 'tones';
65
sampleRate= 50000;
66
duration=0.050;                 % seconds
67
rampDuration=.005;              % raised cosine ramp (seconds)
68
beginSilence=0.050;
69
endSilence=0.050;
70
toneFrequency= 750;            % or a pure tone (Hz)
71

  
72
%   or
73
% harmonic sequence (Hz)
74
% F0=210;
75
% toneFrequency= F0:F0:8000;
76

  
77
%   or
78
% signalType= 'file';
79
% fileName='twister_44kHz';
80

  
81
if strcmp(signalType, 'file')
82
    % needed for labeling plot
83
    showMapOptions.fileName=fileName;
84
else
85
    showMapOptions.fileName=[];
86
end
87

  
88
%% #4 rms level
89
leveldBSPL= 70;
90

  
91

  
92
%% #5 number of channels in the model
93
BFlist=toneFrequency;
94

  
95
%% #6 change model parameters
96

  
97
paramChanges={'IHCpreSynapseParams.tauCa=80e-6;',...
98
    'MacGregorMultiParams.currentPerSpike=0.800e-6;'};
99

  
100
% Parameter changes can be used to change one or more model parameters
101
%  *after* the MAPparams file has been read
102

  
103
%% #7 MSO parameters
104
MSOParams.nNeuronsPerBF=	10;   % N neurons per BF
105
MSOParams.type = 'primary-like cell';
106
MSOParams.fibersPerNeuron=4;   % N input fibers
107
MSOParams.dendriteLPfreq=2000;  % dendritic filter
108
MSOParams.currentPerSpike=0.11e-6; % (A) per spike
109
MSOParams.currentPerSpike=0.5e-6; % (A) per spike
110
MSOParams.Cap=4.55e-9;   % cell capacitance (Siemens)
111
MSOParams.tauM=5e-4;     % membrane time constant (s)
112
MSOParams.Ek=-0.01;      % K+ eq. potential (V)
113
MSOParams.dGkSpike=3.64e-5; % K+ cond.shift on spike,S
114
MSOParams.tauGk=	0.0012; % K+ conductance tau (s)
115
MSOParams.Th0=	0.01;   % equilibrium threshold (V)
116
MSOParams.c=	0.01;       % threshold shift on spike, (V)
117
MSOParams.tauTh=	0.015;  % variable threshold tau
118
MSOParams.Er=-0.06;      % resting potential (V)
119
MSOParams.Eb=0.06;       % spike height (V)
120
MSOParams.debugging=0;        % (special)
121
MSOParams.wideband=0;         % special for wideband units
122

  
123
%% #8 IC parameters
124
ICchopperParams.nNeuronsPerBF=	10;   % N neurons per BF
125
ICchopperParams.type = 'chopper cell';
126
ICchopperParams.fibersPerNeuron=10;  % N input fibers
127
ICchopperParams.dendriteLPfreq=50;   % dendritic filter
128
ICchopperParams.currentPerSpike=50e-9; % *per spike
129
ICchopperParams.currentPerSpike=100e-9; % *per spike
130
ICchopperParams.Cap=1.67e-8; % ??cell capacitance (Siemens)
131
ICchopperParams.tauM=0.002;  % membrane time constant (s)
132
ICchopperParams.Ek=-0.01;    % K+ eq. potential (V)
133
ICchopperParams.dGkSpike=1.33e-4; % K+ cond.shift on spike,S
134
ICchopperParams.tauGk=	0.0005;% K+ conductance tau (s)
135
ICchopperParams.Th0=	0.01; % equilibrium threshold (V)
136
ICchopperParams.c=	0;        % threshold shift on spike, (V)
137
ICchopperParams.tauTh=	0.02; % variable threshold tau
138
ICchopperParams.Er=-0.06;    % resting potential (V)
139
ICchopperParams.Eb=0.06;     % spike height (V)
140
ICchopperParams.PSTHbinWidth=	1e-4;
141

  
142
%% #9 delare 'showMap' options to control graphical output
143
% this applies to the monaural input model only
144
showMapOptions.printModelParameters=0;   % prints all parameters
145
showMapOptions.showModelOutput=1;   % plot all stages if monaural input
146

  
147
%% #10 ITDs
148
% the program cycles through a range of stimulus ITDs
149
ITDs=0e-6:100e-6:2000e-6;
150
% ITDs=0; % single shot
151

  
152
%% Now start computing!
153
figure(98), clf, set(gcf, 'name', 'binaural demo')
154
MSOcounts=zeros(1,length(ITDs));
155
ICcounts=zeros(1,length(ITDs));
156
ITDcount=0;
157
for ITD=ITDs
158
    ITDcount=ITDcount+1;
159
    delaySamples=round(ITD* sampleRate);
160
    %% Generate stimuli
161
    switch signalType
162
        case 'tones'
163
            % Create pure tone stimulus
164
            dt=1/sampleRate; % seconds
165
            time=dt: dt: duration;
166
            inputSignal=sum(sin(2*pi*toneFrequency'*time), 1);
167
            amp=10^(leveldBSPL/20)*28e-6;   % converts to Pascals (peak)
168
            inputSignal=amp*inputSignal;
169
            % apply ramps
170
            % catch rampTime error
171
            if rampDuration>0.5*duration, rampDuration=duration/2; end
172
            rampTime=dt:dt:rampDuration;
173
            ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ...
174
                ones(1,length(time)-length(rampTime))];
175
            inputSignal=inputSignal.*ramp;
176
            ramp=fliplr(ramp);
177
            inputSignal=inputSignal.*ramp;
178
            % add silence
179
            intialSilence= zeros(1,round(beginSilence/dt));
180
            finalSilence= zeros(1,round(endSilence/dt));
181
            inputSignal= [intialSilence inputSignal finalSilence];
182

  
183
        case 'file'
184
            %% file input simple or mixed
185
            [inputSignal sampleRate]=wavread(fileName);
186
            dt=1/sampleRate;
187
            inputSignal=inputSignal(:,1);
188
            targetRMS=20e-6*10^(leveldBSPL/20);
189
            rms=(mean(inputSignal.^2))^0.5;
190
            amp=targetRMS/rms;
191
            inputSignal=inputSignal*amp;
192
            intialSilence= zeros(1,round(0.1/dt));
193
            finalSilence= zeros(1,round(0.2/dt));
194
            inputSignal= [intialSilence inputSignal' finalSilence];
195
    end
196

  
197
    %% run the monaural model twice
198
    t=dt:dt:dt*length(inputSignal);
199
    for ear={'left','right'}
200
        figure(98), subplot(4,1,1), colour='b'; hold off
201
        switch ear{1}
202
            case 'right'
203
                inputSignal=circshift(inputSignal', delaySamples)';
204
                hold on
205
                colour='r';
206
        end
207
        plot(t, inputSignal, colour)
208
        title ('binaural inputs signals')
209
        ylabel('Pa'), xlabel('time')
210
        xlim([0 max(t)])
211

  
212
        % call to monaural model
213
        MAP1_14(inputSignal, sampleRate, BFlist, ...
214
            MAPparamsName, AN_spikesOrProbability, paramChanges);
215

  
216
        % the model run is now complete. Now display the results
217
        UTIL_showMAP(showMapOptions, paramChanges)
218

  
219
        % copy the CN inputspiking pattern to the binaural display
220
        figure(98)
221
        switch ear{1}
222
            case 'left'
223
                CNoutputLeft=CNoutput;
224
                subplot(4,2,3)
225
            case 'right'
226
                CNoutputRight=CNoutput;
227
                subplot(4,2,4)
228
        end
229
        plotInstructions=[];
230
        plotInstructions.axes=gca;
231
        plotInstructions.displaydt=dtSpikes;
232
        plotInstructions.title= ['CN spikes ' ear{1}];
233
        plotInstructions.rasterDotSize=2;
234
        if sum(sum(CNoutput))<100
235
            plotInstructions.rasterDotSize=3;
236
        end
237
        UTIL_plotMatrix(CNoutput, plotInstructions);
238

  
239
    end % left/ right ear
240

  
241
    %%  MSO
242
    % run MSO model using left and right CN spikes
243
    MSOspikes=MSO(CNoutputLeft,CNoutputRight, dtSpikes, MSOParams);
244
    
245
    sumspikes=sum(sum(MSOspikes));
246
    disp(['ITD/ MSO spikes count= ' num2str([ITD sumspikes])])
247
    MSOcounts(ITDcount)=sumspikes;
248
    figure(98), subplot(4,2, 8), cla, hold off, plot(ITDs*1e6, MSOcounts)
249

  
250
    %% IC chopper
251
    % run IC model using all MSO spikes as input to a single IC cell
252
    ICMSOspikes=ICchopper(MSOspikes, dtSpikes, ICchopperParams);
253
    
254
    sumspikes=sum(sum(ICMSOspikes));
255
    disp(['ITD/ ICMSO spikes count= ' num2str([ITD sumspikes])])
256
    ICcounts(ITDcount)=sumspikes;
257
    figure(98), subplot(4,2,8),hold on, plot(ITDs*1e6, ICcounts,'r')
258
    xlabel('ITD'), ylabel(' spike count')
259
    title('MSO (blue)/ IC (red) spike counts')
260
    legend({'MSO','IC'})
261

  
262
end % ITDs
263

  
264
path(restorePath)
265

  
266

  
267
function MSOspikes=MSO(CNoutputLeft,CNoutputRight, dtSpikes, MSOparams)
268
%%
269
[nMSOcells nEpochs]=size(CNoutputLeft);
270
inputCurrent=zeros(nMSOcells, nEpochs);
271
MSOmembranePotential=inputCurrent;
272

  
273
MSO_tauM=MSOparams.tauM;
274
MSO_tauGk=MSOparams.tauGk;
275
MSO_tauTh=MSOparams.tauTh;
276
MSO_cap=MSOparams.Cap;
277
MSO_c=MSOparams.c;
278
MSO_b=MSOparams.dGkSpike;
279
MSO_Th0=MSOparams.Th0;
280
MSO_Ek=MSOparams.Ek;
281
MSO_Eb= MSOparams.Eb;
282
MSO_Er=MSOparams.Er;
283

  
284
MSO_E=zeros(nMSOcells,1);
285
MSO_Gk=zeros(nMSOcells,1);
286
MSO_Th=MSO_Th0*ones(nMSOcells,1);
287

  
288
% Dendritic filtering, all spikes are replaced by CNalphaFunction functions
289
MSOdendriteLPfreq= MSOparams.dendriteLPfreq;
290
MSOcurrentPerSpike=MSOparams.currentPerSpike;
291
MSOspikeToCurrentTau=1/(2*pi*MSOdendriteLPfreq);
292
t=dtSpikes:dtSpikes:5*MSOspikeToCurrentTau;
293
MSO_CNalphaFunction= (MSOcurrentPerSpike / ...
294
    MSOspikeToCurrentTau)*t.*exp(-t / MSOspikeToCurrentTau);
295
% show alpha function
296
% figure(84), subplot(4,2,2), plot(t,MSO_CNalphaFunction)
297
% title(['LP cutoff ' num2str(MSOdendriteLPfreq)])
298

  
299
% convert CN spikes to post-dendritic current
300
CN_spikes=CNoutputLeft+CNoutputRight;
301
for i=1:nMSOcells
302
    x= conv2(CN_spikes(i,:),  MSO_CNalphaFunction);
303
    inputCurrent(i,:)=x(1:nEpochs);
304
end
305

  
306
if MSO_c==0
307
    % faster computation when threshold is stable (c==0)
308
    for t=1:nEpochs
309
        s=MSO_E>MSO_Th0;
310
        dE = (-MSO_E/MSO_tauM + inputCurrent(:,t)/MSO_cap +...
311
            (MSO_Gk/MSO_cap).*(MSO_Ek-MSO_E))*dtSpikes;
312
        dGk=-MSO_Gk*dtSpikes/MSO_tauGk +MSO_b*s;
313
        MSO_E=MSO_E+dE;
314
        MSO_Gk=MSO_Gk+dGk;
315
        MSOmembranePotential(:,t)=MSO_E+s.*(MSO_Eb-MSO_E)+MSO_Er;
316
    end
317
else
318
    %  threshold is changing (MSO_c>0; e.g. bushy cell)
319
    for t=1:nEpochs
320
        dE = (-MSO_E/MSO_tauM + ...
321
            inputCurrent(:,t)/MSO_cap + (MSO_Gk/MSO_cap)...
322
            .*(MSO_Ek-MSO_E))*dtSpikes;
323
        MSO_E=MSO_E+dE;
324
        s=MSO_E>MSO_Th;
325
        MSOmembranePotential(:,t)=MSO_E+s.*(MSO_Eb-MSO_E)+MSO_Er;
326
        dGk=-MSO_Gk*dtSpikes/MSO_tauGk +MSO_b*s;
327
        MSO_Gk=MSO_Gk+dGk;
328

  
329
        % After a spike, the threshold is raised
330
        % otherwise it settles to its baseline
331
        dTh=-(MSO_Th-MSO_Th0)*dtSpikes/MSO_tauTh +s*MSO_c;
332
        MSO_Th=MSO_Th+dTh;
333
    end
334
end
335

  
336
figure(98),subplot(4,1,3)
337
hold off, imagesc(MSOmembranePotential)
338
title ('MSO (V)')
339

  
340
MSOspikes=MSOmembranePotential> -0.01;
341
% Remove any spike that is immediately followed by a spike
342
%  NB 'find' works on columns (whence the transposing)
343
MSOspikes=MSOspikes';
344
idx=find(MSOspikes);
345
idx=idx(1:end-1);
346
MSOspikes(idx+1)=0;
347
MSOspikes=MSOspikes';
348

  
349

  
350
function ICMSOspikes=ICchopper(ICMSOspikes, dtSpikes, ICMSOParams)
351
%%
352
ICMSOspikes=sum(ICMSOspikes);
353
[nICMSOcells nEpochs]=size(ICMSOspikes);
354
inputCurrent=zeros(nICMSOcells, nEpochs);
355
ICMSOmembranePotential=inputCurrent;
356

  
357
ICMSO_tauM=ICMSOParams.tauM;
358
ICMSO_tauGk=ICMSOParams.tauGk;
359
ICMSO_tauTh=ICMSOParams.tauTh;
360
ICMSO_cap=ICMSOParams.Cap;
361
ICMSO_c=ICMSOParams.c;
362
ICMSO_b=ICMSOParams.dGkSpike;
363
ICMSO_Th0=ICMSOParams.Th0;
364
ICMSO_Ek=ICMSOParams.Ek;
365
ICMSO_Eb= ICMSOParams.Eb;
366
ICMSO_Er=ICMSOParams.Er;
367

  
368
ICMSO_E=zeros(nICMSOcells,1);
369
ICMSO_Gk=zeros(nICMSOcells,1);
370
ICMSO_Th=ICMSO_Th0*ones(nICMSOcells,1);
371

  
372
% Dendritic filtering, all spikes are replaced by CNalphaFunction functions
373
ICMSOdendriteLPfreq= ICMSOParams.dendriteLPfreq;
374
ICMSOcurrentPerSpike=ICMSOParams.currentPerSpike;
375
ICMSOspikeToCurrentTau=1/(2*pi*ICMSOdendriteLPfreq);
376
t=dtSpikes:dtSpikes:5*ICMSOspikeToCurrentTau;
377
ICMSOalphaFunction= (ICMSOcurrentPerSpike / ...
378
    ICMSOspikeToCurrentTau)*t.*exp(-t / ICMSOspikeToCurrentTau);
379
% show alpha function
380
% figure(84), subplot(4,2,5), plot(t,ICMSOalphaFunction)
381
% title(['IC MSO LP cutoff ' num2str(ICMSOdendriteLPfreq)])
382

  
383
% post-dendritic current
384
for i=1:nICMSOcells
385
    x= conv2(1*ICMSOspikes(i,:),  ICMSOalphaFunction);
386
    inputCurrent(i,:)=x(1:nEpochs);
387
end
388

  
389
if ICMSO_c==0
390
    % faster computation when threshold is stable (c==0)
391
    for t=1:nEpochs
392
        s=ICMSO_E>ICMSO_Th0;
393
        dE = (-ICMSO_E/ICMSO_tauM + inputCurrent(:,t)/ICMSO_cap +...
394
            (ICMSO_Gk/ICMSO_cap).*(ICMSO_Ek-ICMSO_E))*dtSpikes;
395
        dGk=-ICMSO_Gk*dtSpikes/ICMSO_tauGk +ICMSO_b*s;
396
        ICMSO_E=ICMSO_E+dE;
397
        ICMSO_Gk=ICMSO_Gk+dGk;
398
        ICMSOmembranePotential(:,t)=ICMSO_E+s.*(ICMSO_Eb-ICMSO_E)+ICMSO_Er;
399
    end
400
else
401
    %  threshold is changing (ICMSO_c>0; e.g. bushy cell)
402
    for t=1:nEpochs
403
        dE = (-ICMSO_E/ICMSO_tauM + ...
404
            inputCurrent(:,t)/ICMSO_cap + (ICMSO_Gk/ICMSO_cap)...
405
            .*(ICMSO_Ek-ICMSO_E))*dtSpikes;
406
        ICMSO_E=ICMSO_E+dE;
407
        s=ICMSO_E>ICMSO_Th;
408
        ICMSOmembranePotential(:,t)=ICMSO_E+s.*(ICMSO_Eb-ICMSO_E)+ICMSO_Er;
409
        dGk=-ICMSO_Gk*dtSpikes/ICMSO_tauGk +ICMSO_b*s;
410
        ICMSO_Gk=ICMSO_Gk+dGk;
411

  
412
        % After a spike, the threshold is raised
413
        % otherwise it settles to its baseline
414
        dTh=-(ICMSO_Th-ICMSO_Th0)*dtSpikes/ICMSO_tauTh +s*ICMSO_c;
415
        ICMSO_Th=ICMSO_Th+dTh;
416
    end
417
end
418

  
419
t=dtSpikes:dtSpikes:dtSpikes*length(ICMSOmembranePotential);
420
figure(98),subplot(4,2,7)
421
plot(t, ICMSOmembranePotential)
422
ylim([-0.07 0]), xlim([0 max(t)])
423
title('IC (V)')
424

  
425
ICMSOspikes=ICMSOmembranePotential> -0.01;
426
% now remove any spike that is immediately followed by a spike
427
% NB 'find' works on columns (whence the transposing)
428
ICMSOspikes=ICMSOspikes';
429
idx=find(ICMSOspikes);
430
idx=idx(1:end-1);
431
ICMSOspikes(idx+1)=0;
432
ICMSOspikes=ICMSOspikes';
433

  

Also available in: Unified diff