Revision 0:f233164f4c86

View differences:

.gitignore
1
# ignore windows autosaves
2
*.asv
3

  
4
# ignore mac autosaves
5
*~
6

  
7
# ignore MSword
8
#*.doc
9
#*.docx
10
~*
11

  
12
# Mac OS dir file
13
*.DS_Store
14

  
15
# We probably should not redistribute 3rd party USB drivers
16
*/CedrusUSB/*
1
*.asv 		#ignore windows autosaves
2
*.*~ 		#ignore mac autosaves
3
.DS_Store 	#ignore some other Mac auto generated file
4
*.doc 		#ignore MSword
5
*.docx 		#ignore newer MSword
MAP/MAP1_14.m
3 3
    AN_spikesOrProbability, paramChanges)
4 4
% To test this function use test_MAP1_14 in this folder
5 5
%
6
% example:
7
% <navigate to 'MAP1_14\MAP'>
8
%  [inputSignal FS] = wavread('../wavFileStore/twister_44kHz');
9
%  MAP1_14(inputSignal, FS, -1, 'Normal', 'probability', [])
10
%
11 6
% All arguments are mandatory.
12 7
%
13
%  BFlist is a vector of BFs but can be '-1' to allow MAPparams to choose
14
%  MAPparamsName='Normal';          % source of model parameters
8
% BFlist is a list of BFs but can be '-1' to allow MAPparams to choose
9
%
10

  
11
%  MAPparamsName='Normal'; % source of model parameters
15 12
%  AN_spikesOrProbability='spikes'; % or 'probability'
16 13
%  paramChanges is a cell array of strings that can be used to make last
17 14
%   minute parameter changes, e.g., to simulate OHC loss
18
%  e.g.  paramChanges{1}= 'DRNLParams.a=0;'; % disable OHCs
19
%  e.g.  paramchanges={};                    % no changes
15
%   paramChanges{1}= 'DRNLParams.a=0;';
16

  
20 17
% The model parameters are established in the MAPparams<***> file
21 18
%  and stored as global
22 19

  
......
27 24
global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams
28 25

  
29 26
% All of the results of this function are stored as global
30
global  savedParamChanges savedBFlist saveAN_spikesOrProbability ...
31
    saveMAPparamsName savedInputSignal dt dtSpikes ...
32
    OMEextEarPressure TMoutput OMEoutput DRNLoutput...
33
    IHC_cilia_output IHCrestingCiliaCond IHCrestingV...
34
    IHCoutput ANprobRateOutput ANoutput savePavailable saveNavailable ...
35
    ANtauCas CNtauGk CNoutput ICoutput ICmembraneOutput ICfiberTypeRates...
36
    MOCattenuation ARattenuation 
37

  
27
global dt ANdt  savedBFlist saveAN_spikesOrProbability saveMAPparamsName...
28
    savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ...
29
    DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV...
30
    IHCoutput ANprobRateOutput ANoutput savePavailable tauCas  ...
31
    CNoutput  ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation
38 32

  
39 33
% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be
40 34
% needed by the user; so the following will suffice
41
%   global dtSpikes ICoutput ANprobRateOutput
35
%   global ANdt ICoutput ANprobRateOutput
42 36

  
43 37
% Note that sampleRate has not changed from the original function call and
44 38
%  ANprobRateOutput is sampled at this rate
45 39
% However ANoutput, CNoutput and IC output are stored as logical
46
%  'spike' matrices using a lower sample rate (see dtSpikes).
40
%  'spike' matrices using a lower sample rate (see ANdt).
47 41

  
48 42
% When AN_spikesOrProbability is set to probability,
49 43
%  no spike matrices are computed.
......
52 46

  
53 47
% Efferent control variables are ARattenuation and MOCattenuation
54 48
%  These are scalars between 1 (no attenuation) and 0.
55
%  They are represented with dt=1/sampleRate (not dtSpikes)
49
%  They are represented with dt=1/sampleRate (not ANdt)
56 50
%  They are computed using either AN probability rate output
57 51
%   or IC (spikes) output as approrpriate.
58 52
% AR is computed using across channel activity
59 53
% MOC is computed on a within-channel basis.
60 54

  
61
if nargin<1
62
    error(' MAP1_14 is not a script but a function that must be called')
63
end
64

  
65
if nargin<6
66
    paramChanges=[];
67
end
68
% Read parameters from MAPparams<***> file in 'parameterStore' folder
69
% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<>
70
%  It means that the calling program allows MAPparams to specify the list
71
cmd=['method=MAPparams' MAPparamsName ...
72
    '(BFlist, sampleRate, 0, paramChanges);'];
73
eval(cmd);
74
BFlist=DRNLParams.nonlinCFs;
75 55

  
76 56
% save as global for later plotting if required
77 57
savedBFlist=BFlist;
78 58
saveAN_spikesOrProbability=AN_spikesOrProbability;
79 59
saveMAPparamsName=MAPparamsName;
80
savedParamChanges=paramChanges;
60

  
61
% Read parameters from MAPparams<***> file in 'parameterStore' folder
62
cmd=['method=MAPparams' MAPparamsName ...
63
    '(BFlist, sampleRate, 0);'];
64
eval(cmd);
65

  
66
% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<>
67
%  if the calling program allows MAPparams to specify the list
68
BFlist=DRNLParams.nonlinCFs;
69

  
70
% now accept last mintue parameter changes required by the calling program
71
if nargin>5 && ~isempty(paramChanges)
72
    nChanges=length(paramChanges);
73
    for idx=1:nChanges
74
        eval(paramChanges{idx})
75
    end
76
end
81 77

  
82 78
dt=1/sampleRate;
83 79
duration=length(inputSignal)/sampleRate;
......
87 83
segmentTime=dt*(1:segmentLength); % used in debugging plots
88 84

  
89 85
% all spiking activity is computed using longer epochs
90
ANspeedUpFactor=ceil(sampleRate/AN_IHCsynapseParams.spikesTargetSampleRate);
91
% ANspeedUpFactor=AN_IHCsynapseParams.ANspeedUpFactor;  % e.g.5 times
86
ANspeedUpFactor=5;  % 5 times longer
92 87

  
93 88
% inputSignal must be  row vector
94 89
[r c]=size(inputSignal);
......
109 104
inputSignal=[inputSignal pad];
110 105
[ignore signalLength]=size(inputSignal);
111 106

  
112
% spiking activity is computed at longer sampling intervals (dtSpikes)
113
%  so it has a smaller number of epochs per segment(see 'ANspeeUpFactor' above)
107
% AN (spikes) is computed at a lower sample rate when spikes required
108
%  so it has a reduced segment length (see 'ANspeeUpFactor' above)
114 109
% AN CN and IC all use this sample interval
115
dtSpikes=dt*ANspeedUpFactor;
110
ANdt=dt*ANspeedUpFactor;
116 111
reducedSegmentLength=round(segmentLength/ANspeedUpFactor);
117 112
reducedSignalLength= round(signalLength/ANspeedUpFactor);
118 113

  
......
157 152
OME_TMdisplacementBndry=[];
158 153

  
159 154
% OME high pass (simulates poor low frequency stapes response)
160
OMEhighPassHighCutOff=OMEParams.OMEstapesHPcutoff;
155
OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff;
161 156
Nyquist=sampleRate/2;
162 157
[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high');
163 158
% figure(10), freqz(stapesDisp_b, stapesDisp_a)
......
170 165
% Acoustic reflex
171 166
efferentDelayPts=round(OMEParams.ARdelay/dt);
172 167
% smoothing filter
168
% Nyquist=(1/ANdt)/2;
169
% [ARfilt_b,ARfilt_a] = butter(1, (1/(2*pi*OMEParams.ARtau))/Nyquist, 'low');
173 170
a1=dt/OMEParams.ARtau-1; a0=1;
174 171
b0=1+ a1;
175 172
ARfilt_b=b0; ARfilt_a=[a0 a1];
......
195 192

  
196 193
MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor;
197 194
rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb;
198
MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb;
199
minMOCattenuation=10^(DRNLParams.minMOCattenuationdB/20);
195
MOCrateThreshold=DRNLParams.MOCrateThreshold;
200 196

  
201 197
% smoothing filter for MOC
198
% Nyquist=(1/ANdt)/2;
199
% [MOCfilt_b,MOCfilt_a] = ...
200
%     butter(1, (1/(2*pi*DRNLParams.MOCtau))/Nyquist, 'low');
201
% figure(10), freqz(stapesDisp_b, stapesDisp_a)
202 202
a1=dt/DRNLParams.MOCtau-1; a0=1;
203 203
b0=1+ a1;
204 204
MOCfilt_b=b0; MOCfilt_a=[a0 a1];
205

  
206
a1=dt/DRNLParams.MOCtauProb-1; a0=1;
207
b0=1+ a1;
208
MOCfiltProb_b=b0; MOCfiltProb_a=[a0 a1];
209

  
210

  
211 205
% figure(9), freqz(stapesDisp_b, stapesDisp_a)
212 206
MOCboundary=cell(nBFs,1);
213 207
MOCprobBoundary=cell(nBFs,1);
......
215 209
MOCattSegment=zeros(nBFs,reducedSegmentLength);
216 210
MOCattenuation=ones(nBFs,signalLength);
217 211

  
218
% if DRNLParams.a>0
219
%     DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ...
220
%     log10(DRNLParams.b/DRNLParams.a));
221
% else
222
%     DRNLcompressionThreshold=inf;
223
% end
224
% DRNLcompressionThreshold=DRNLParams.cTh;
212
if DRNLParams.a>0
213
    DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ...
214
    log10(DRNLParams.b/DRNLParams.a));
215
else
216
    DRNLcompressionThreshold=inf;
217
end
218

  
225 219
DRNLlinearOrder= DRNLParams.linOrder;
226 220
DRNLnonlinearOrder= DRNLParams.nonlinOrder;
227 221

  
228 222
DRNLa=DRNLParams.a;
229
% DRNLa2=DRNLParams.a2;
230
% DRNLb=DRNLParams.b;
223
DRNLb=DRNLParams.b;
231 224
DRNLc=DRNLParams.c;
232 225
linGAIN=DRNLParams.g;
233
ctBM=10e-9*10^(DRNLParams.ctBMdB/20);
234
CtS=ctBM/DRNLa;
235 226
%
236 227
% gammatone filter coefficients for linear pathway
237 228
bw=DRNLParams.linBWs';
......
293 284
b0=1+ a1;
294 285
% high pass (i.e. low pass reversed)
295 286
IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0;
296
% i.e. b= [1  dt/tc-1]  and a= dt/IHC_cilia_RPParams.tc
297 287
% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a)
298 288

  
299 289
IHCciliaBndry=cell(nBFs,1);
......
305 295
IHCs0= IHC_cilia_RPParams.s0;
306 296
IHCs1= IHC_cilia_RPParams.s1;
307 297
IHCGmax= IHC_cilia_RPParams.Gmax;
308
IHCGa= IHC_cilia_RPParams.Ga; % (leakage)
309

  
310
IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1)));
311
IHCrestingCiliaCond=IHCGu0;
298
IHCGu0= IHC_cilia_RPParams.Gu0; % (leakage)
299
IHCGa= IHCGmax./(1+exp(-(0-IHCu0)/IHCs0).*(1+exp(-(0-IHCu1)/IHCs1)));
300
IHCrestingCiliaCond=IHCGa+IHCGu0;
312 301

  
313 302
% Receptor potential
314 303
IHC_Cab= IHC_cilia_RPParams.Cab;
......
317 306
IHC_Ek= IHC_cilia_RPParams.Ek;
318 307
IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc;
319 308

  
320
IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk);
321

  
309
IHCrestingV= -0.06;
322 310
IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage
323 311
IHC_RP= zeros(nBFs,segmentLength);
324 312

  
......
333 321
% The number of channels is nBFs x nANfiberTypes
334 322
% Fiber types are specified in terms of tauCa
335 323
nANfiberTypes= length(IHCpreSynapseParams.tauCa);
336
ANtauCas= IHCpreSynapseParams.tauCa;
337
nANchannels= nANfiberTypes*nBFs;
338
synapticCa= zeros(nANchannels,segmentLength);
324
tauCas= IHCpreSynapseParams.tauCa;
325
nChannels= nANfiberTypes*nBFs;
326
synapticCa= zeros(nChannels,segmentLength);
339 327

  
340 328
% Calcium control (more calcium, greater release rate)
341 329
ECa=IHCpreSynapseParams.ECa;
342 330
gamma=IHCpreSynapseParams.gamma;
343 331
beta=IHCpreSynapseParams.beta;
344 332
tauM=IHCpreSynapseParams.tauM;
345
mICa=zeros(nANchannels,segmentLength);
333
mICa=zeros(nChannels,segmentLength);
346 334
GmaxCa=IHCpreSynapseParams.GmaxCa;
347 335
synapse_z= IHCpreSynapseParams.z;
348 336
synapse_power=IHCpreSynapseParams.power;
349 337

  
350 338
% tauCa vector is established across channels to allow vectorization
351
%  (one tauCa per channel). 
352
%  Do not confuse with ANtauCas vector (one per fiber type)
353
tauCa=repmat(ANtauCas, nBFs,1);
354
tauCa=reshape(tauCa, nANchannels, 1);
339
%  (one tauCa per channel). Do not confuse with tauCas (one pre fiber type)
340
tauCa=repmat(tauCas, nBFs,1);
341
tauCa=reshape(tauCa, nChannels, 1);
355 342

  
356
% presynapse startup values (vectors, length:nANchannels)
343
% presynapse startup values (vectors, length:nChannels)
357 344
% proportion (0 - 1) of Ca channels open at IHCrestingV
358 345
mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)...
359 346
    *ones(nBFs*nANfiberTypes,1);
......
371 358
% The results computed either for probabiities *or* for spikes (not both)
372 359
% Spikes are necessary if CN and IC are to be computed
373 360
nFibersPerChannel= AN_IHCsynapseParams.numFibers;
374
nANfibers= nANchannels*nFibersPerChannel;
375
AN_refractory_period= AN_IHCsynapseParams.refractory_period;
361
nANfibers= nChannels*nFibersPerChannel;
376 362

  
377 363
y=AN_IHCsynapseParams.y;
378 364
l=AN_IHCsynapseParams.l;
......
381 367
M=round(AN_IHCsynapseParams.M);
382 368

  
383 369
% probability            (NB initial 'P' on everything)
384
PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nANchannels,1);
385
PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nANchannels,1);
386
PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nANchannels,1);
387
PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nANchannels,1);
370
PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nChannels,1);
371
PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nChannels,1);
372
PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nChannels,1);
373
PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nChannels,1);
388 374
PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt;
389 375
PAN_M=round(AN_IHCsynapseParams.M);
390 376

  
......
393 379
Pavailable    = Pcleft*(l+r)./kt0;
394 380
Preprocess    = Pcleft*r/x; % canbe fractional
395 381

  
396
ANprobability=zeros(nANchannels,segmentLength);
397
ANprobRateOutput=zeros(nANchannels,signalLength);
398
lengthAbsRefractoryP= round(AN_refractory_period/dt);
399
cumANnotFireProb=ones(nANchannels,signalLength);
382
ANprobability=zeros(nChannels,segmentLength);
383
ANprobRateOutput=zeros(nChannels,signalLength);
400 384
% special variables for monitoring synaptic cleft (specialists only)
401
savePavailableSeg=zeros(nANchannels,segmentLength);
402
savePavailable=zeros(nANchannels,signalLength);
403
% only one stream of available transmitter will be saved
404
saveNavailableSeg=zeros(1,reducedSegmentLength);
405
saveNavailable=zeros(1,reducedSignalLength);
385
savePavailableSeg=zeros(nChannels,segmentLength);
386
savePavailable=zeros(nChannels,signalLength);
406 387

  
407 388
% spikes     % !  !  !    ! !        !   !  !
408
lengthAbsRefractory= round(AN_refractory_period/dtSpikes);
389
AN_refractory_period= AN_IHCsynapseParams.refractory_period;
390
lengthAbsRefractory= round(AN_refractory_period/ANdt);
409 391

  
410
AN_ydt= repmat(AN_IHCsynapseParams.y*dtSpikes, nANfibers,1);
411
AN_ldt= repmat(AN_IHCsynapseParams.l*dtSpikes, nANfibers,1);
412
AN_xdt= repmat(AN_IHCsynapseParams.x*dtSpikes, nANfibers,1);
413
AN_rdt= repmat(AN_IHCsynapseParams.r*dtSpikes, nANfibers,1);
392
AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1);
393
AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1);
394
AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1);
395
AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1);
414 396
AN_rdt_plus_ldt= AN_rdt + AN_ldt;
415 397
AN_M= round(AN_IHCsynapseParams.M);
416 398

  
......
432 414
%% CN (first brain stem nucleus - could be any subdivision of CN)
433 415
% Input to a CN neuorn is a random selection of AN fibers within a channel
434 416
%  The number of AN fibers used is ANfibersFanInToCN
417
ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron;
418
nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF;
435 419
% CNtauGk (Potassium time constant) determines the rate of firing of
436 420
%  the unit when driven hard by a DC input (not normally >350 sp/s)
437
% If there is more than one value, everything is replicated accordingly
421
CNtauGk=MacGregorMultiParams.tauGk;
422
ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers;
423
nCNneurons=nCNneuronsPerChannel*nChannels;
424
% nCNneuronsPerFiberType= nCNneurons/nANfiberTypes;
438 425

  
439
ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers;
440
ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron;
441

  
442
CNtauGk=MacGregorMultiParams.tauGk; % row vector of CN types (by tauGk)
443
nCNtauGk=length(CNtauGk);
444

  
445
% the total number of 'channels' is now greater
446
% 'channel' is defined as collections of units with the same parameters
447
%  i.e. same BF, same ANtau, same CNtauGk
448
nCNchannels=nANchannels*nCNtauGk;
449

  
450
nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF;
451
tauGk=repmat(CNtauGk, nCNneuronsPerChannel,1);
452
tauGk=reshape(tauGk,nCNneuronsPerChannel*nCNtauGk,1);
453

  
454
% Now the number of neurons has been increased
455
nCNneurons=nCNneuronsPerChannel*nCNchannels;
456 426
CNmembranePotential=zeros(nCNneurons,reducedSegmentLength);
457 427

  
458 428
% establish which ANfibers (by name) feed into which CN nuerons
459
CNinputfiberLists=zeros(nANchannels*nCNneuronsPerChannel, ANfibersFanInToCN);
429
CNinputfiberLists=zeros(nChannels*nCNneuronsPerChannel, ANfibersFanInToCN);
460 430
unitNo=1;
461
for ch=1:nANchannels
431
for ch=1:nChannels
462 432
    % Each channel contains a number of units =length(listOfFanInValues)
463 433
    for idx=1:nCNneuronsPerChannel
464
        for idx2=1:nCNtauGk
465
            fibersUsed=(ch-1)*ANavailableFibersPerChan + ...
466
                ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan);
467
            CNinputfiberLists(unitNo,:)=fibersUsed;
468
            unitNo=unitNo+1;
469
        end
434
        fibersUsed=(ch-1)*ANavailableFibersPerChan + ...
435
            ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan);
436
        CNinputfiberLists(unitNo,:)=fibersUsed;
437
        unitNo=unitNo+1;
470 438
    end
471 439
end
472 440

  
......
478 446
CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq;
479 447
CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike;
480 448
CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq);
481
t=dtSpikes:dtSpikes:5*CNspikeToCurrentTau;
482
CNalphaFunction= (1 / ...
483
    CNspikeToCurrentTau)*t.*exp(-t /CNspikeToCurrentTau);
484
CNalphaFunction=CNalphaFunction*CNcurrentPerSpike;
485

  
486
% figure(98), plot(t,CNalphaFunction), xlim([0 .020]), xlabel('time (s)'), ylabel('I')
449
t=ANdt:ANdt:5*CNspikeToCurrentTau;
450
CNalphaFunction=...
451
    (CNcurrentPerSpike/CNspikeToCurrentTau)*t.*exp(-t/CNspikeToCurrentTau);
452
% figure(98), plot(t,CNalphaFunction)
487 453
% working memory for implementing convolution
488

  
489 454
CNcurrentTemp=...
490 455
    zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1);
491 456
% trailing alphas are parts of humps carried forward to the next segment
......
508 473
CNtimeSinceLastSpike=zeros(nCNneurons,1);
509 474
% tauGk is the main distinction between neurons
510 475
%  in fact they are all the same in the standard model
511
tauGk=repmat(tauGk,nANchannels,1);
476
tauGk=repmat(CNtauGk,nChannels*nCNneuronsPerChannel,1);
512 477

  
478
CN_PSTH=zeros(nChannels,reducedSegmentLength);
513 479
CNoutput=false(nCNneurons,reducedSignalLength);
514 480

  
515 481

  
516 482
%% MacGregor (IC - second nucleus) --------
517
nICcells=nANchannels*nCNtauGk;  % one cell per channel
518
CN_PSTH=zeros(nICcells ,reducedSegmentLength);
483
nICcells=nChannels;  % one cell per channel
519 484

  
520
% ICspikeWidth=0.00015;   % this may need revisiting
521
% epochsPerSpike=round(ICspikeWidth/dtSpikes);
522
% if epochsPerSpike<1
523
%     error(['MacGregorMulti: sample rate too low to support ' ...
524
%         num2str(ICspikeWidth*1e6) '  microsec spikes']);
525
% end
485
ICspikeWidth=0.00015;   % this may need revisiting
486
epochsPerSpike=round(ICspikeWidth/ANdt);
487
if epochsPerSpike<1
488
    error(['MacGregorMulti: sample rate too low to support ' ...
489
        num2str(ICspikeWidth*1e6) '  microsec spikes']);
490
end
526 491

  
527 492
% short names
528 493
IC_tauM=MacGregorParams.tauM;
......
544 509
ICdendriteLPfreq= MacGregorParams.dendriteLPfreq;
545 510
ICcurrentPerSpike=MacGregorParams.currentPerSpike;
546 511
ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq);
547
t=dtSpikes:dtSpikes:3*ICspikeToCurrentTau;
512
t=ANdt:ANdt:3*ICspikeToCurrentTau;
548 513
IC_CNalphaFunction= (ICcurrentPerSpike / ...
549 514
    ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau);
550 515
% figure(98), plot(t,IC_CNalphaFunction)
......
555 520
ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction));
556 521

  
557 522
ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength);
558
ICoutput=false(nICcells,reducedSignalLength);
523
ICoutput=false(nChannels,reducedSignalLength);
559 524

  
560 525
ICmembranePotential=zeros(nICcells,reducedSegmentLength);
561 526
ICmembraneOutput=zeros(nICcells,signalLength);
......
571 536
    % shorter segments after speed up.
572 537
    shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1;
573 538

  
574
    inputPressureSegment=inputSignal...
539
    iputPressureSegment=inputSignal...
575 540
        (:,segmentStartPTR:segmentStartPTR+segmentLength-1);
576 541

  
577 542
    % segment debugging plots
578 543
    % figure(98)
579
    % plot(segmentTime,inputPressureSegment), title('signalSegment')
544
    % plot(segmentTime,iputPressureSegment), title('signalSegment')
580 545

  
581 546

  
582 547
    % OME ----------------------
583 548

  
584 549
    % OME Stage 1: external resonances. Add to inputSignal pressure wave
585
    y=inputPressureSegment;
550
    y=iputPressureSegment;
586 551
    for n=1:nOMEExtFilters
587 552
        % any number of resonances can be used
588 553
        [x  OMEExtFilterBndry{n}] = ...
589 554
            filter(ExtFilter_b{n},ExtFilter_a{n},...
590
            inputPressureSegment, OMEExtFilterBndry{n});
555
            iputPressureSegment, OMEExtFilterBndry{n});
591 556
        x= x* OMEgainScalars(n);
592 557
        % This is a parallel resonance so add it
593 558
        y=y+x;
594 559
    end
595
    inputPressureSegment=y;
596
    OMEextEarPressure(segmentStartPTR:segmentEndPTR)= inputPressureSegment;
560
    iputPressureSegment=y;
561
    OMEextEarPressure(segmentStartPTR:segmentEndPTR)= iputPressureSegment;
597 562
    
598 563
    % OME stage 2: convert input pressure (velocity) to
599 564
    %  tympanic membrane(TM) displacement using low pass filter
600 565
    [TMdisplacementSegment  OME_TMdisplacementBndry] = ...
601
        filter(TMdisp_b,TMdisp_a,inputPressureSegment, ...
566
        filter(TMdisp_b,TMdisp_a,iputPressureSegment, ...
602 567
        OME_TMdisplacementBndry);
603 568
    % and save it
604 569
    TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment;
......
633 598

  
634 599
        %            *linear* path
635 600
        linOutput = stapesDisplacement * linGAIN;  % linear gain
636
       
637 601
        for order = 1 : GTlinOrder
638 602
            [linOutput GTlinBdry{BFno,order}] = ...
639
                filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, ...
640
                GTlinBdry{BFno,order});
603
                filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry{BFno,order});
641 604
        end
642 605

  
643 606
        %           *nonLinear* path
......
648 611
        else    % no MOC available yet
649 612
            MOC=ones(1, segmentLength);
650 613
        end
651
        % apply MOC to nonlinear input function      
652
%         figure(88), plot(MOC)
653
        nonlinOutput=stapesDisplacement.* MOC;
654 614

  
655
        %       first gammatone filter (nonlin path)
615
        %       first gammatone filter
656 616
        for order = 1 : GTnonlinOrder
657 617
            [nonlinOutput GTnonlinBdry1{BFno,order}] = ...
658 618
                filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
659
                nonlinOutput, GTnonlinBdry1{BFno,order});
619
                stapesDisplacement, GTnonlinBdry1{BFno,order});
660 620
        end
661
        
662
        
663
        % Nick's compression algorithm
664
        abs_x= abs(nonlinOutput);
665
        signs= sign(nonlinOutput);
666
        belowThreshold= abs_x<CtS;
667
        nonlinOutput(belowThreshold)= DRNLa *nonlinOutput(belowThreshold);
668
        aboveThreshold=~belowThreshold;
669
        nonlinOutput(aboveThreshold)= signs(aboveThreshold) *ctBM .* ...
670
            exp(DRNLc *log( DRNLa*abs_x(aboveThreshold)/ctBM ));
671
                       
672
        
673
%         %    original   broken stick instantaneous compression
674
%         holdY=nonlinOutput;
675
%         abs_x = abs(nonlinOutput);
676
%         nonlinOutput=sign(nonlinOutput).*min(DRNLa*abs_x, DRNLb*abs_x.^DRNLc);
677
% 
678 621

  
679
%         %   new broken stick instantaneous compression
680
%         y= nonlinOutput.* DRNLa;  % linear section attenuation/gain.
681
%         % compress parts of the signal above the compression threshold
682
%         %         holdY=y;
683
%         abs_y = abs(y);
684
%         idx=find(abs_y>DRNLcompressionThreshold);
685
%         if ~isempty(idx)>0
686
%             %             y(idx)=sign(y(idx)).* (DRNLcompressionThreshold + ...
687
%             %                 (abs_y(idx)-DRNLcompressionThreshold).^DRNLc);
688
%             y(idx)=sign(y(idx)).* (DRNLcompressionThreshold + ...
689
%                 (abs_y(idx)-DRNLcompressionThreshold)*DRNLa2);
690
%         end
691
%         nonlinOutput=y;
622
        %       broken stick instantaneous compression
623
        % nonlinear gain is weakend by MOC before applied to BM response
624
        y= nonlinOutput.*(MOC* DRNLa);  % linear section.
625
        % compress those parts of the signal above the compression
626
        % threshold
627
        abs_x = abs(nonlinOutput);
628
        idx=find(abs_x>DRNLcompressionThreshold);
629
        if ~isempty(idx)>0
630
            y(idx)=sign(nonlinOutput(idx)).*...
631
                (DRNLb*abs_x(idx).^DRNLc);
632
        end
633
        nonlinOutput=y;
692 634

  
693

  
694
% if segmentStartPTR==10*segmentLength+1
695
%     figure(90)
696
%     plot(holdY,'b'), hold on
697
%     plot(nonlinOutput, 'r'), hold off
698
%     ylim([-1e-5 1e-5])
699
%     pause(1)
700
% end
701

  
702
%       second filter removes distortion products
635
        %       second filter removes distortion products
703 636
        for order = 1 : GTnonlinOrder
704 637
            [ nonlinOutput GTnonlinBdry2{BFno,order}] = ...
705
                filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
706
                nonlinOutput, GTnonlinBdry2{BFno,order});
638
                filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), nonlinOutput, GTnonlinBdry2{BFno,order});
707 639
        end
708 640

  
709 641
        %  combine the two paths to give the DRNL displacement
710 642
        DRNLresponse(BFno,:)=linOutput+nonlinOutput;
711
%         disp(num2str(max(linOutput)))
712 643
    end % BF
713 644

  
714 645
    % segment debugging plots
715 646
    % figure(98)
716 647
    %     if size(DRNLresponse,1)>3
717 648
    %         imagesc(DRNLresponse)  % matrix display
718
    %         title('DRNLresponse'); 
649
    %         title('DRNLresponse'); % single or double channel response
719 650
    %     else
720 651
    %         plot(segmentTime, DRNLresponse)
721 652
    %     end
......
741 672
        IHCciliaDisplacement;
742 673

  
743 674
    % compute apical conductance
744
    G=IHCGmax./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*...
675
    G=1./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*...
745 676
        (1+exp(-(IHCciliaDisplacement-IHCu1)/IHCs1)));
746
    Gu=G + IHCGa;
677
    Gu=IHCGmax*G;
678
    % add resting conductance to give apical conductance
679
    Gu= Gu+IHCGu0;
747 680

  
748 681
    % Compute receptor potential
749 682
    for idx=1:segmentLength
......
765 698

  
766 699
    %% synapse -----------------------------
767 700
    % Compute the vesicle release rate for each fiber type at each BF
768
    
769
    % replicate IHC_RP for each fiber type to obtain the driving voltage
701
    % replicate IHC_RP for each fiber type
770 702
    Vsynapse=repmat(IHC_RP, nANfiberTypes,1);
771 703

  
772 704
    % look-up table of target fraction channels open for a given IHC_RP
773 705
    mICaINF=    1./( 1 + exp(-gamma  * Vsynapse)  /beta);
774
    
775
    % fraction of channels open - apply time membrane constant
706
    % fraction of channel open - apply time constant
776 707
    for idx=1:segmentLength
777 708
        % mICaINF is the current 'target' value of mICa
778 709
        mICaCurrent=mICaCurrent+(mICaINF(:,idx)-mICaCurrent)*dt./tauM;
779 710
        mICa(:,idx)=mICaCurrent;
780 711
    end
781
    
782
    % calcium current
712

  
783 713
    ICa=   (GmaxCa* mICa.^3) .* (Vsynapse- ECa);
784
    % apply calcium channel time constant
714

  
785 715
    for idx=1:segmentLength
786 716
        CaCurrent=CaCurrent +  ICa(:,idx)*dt - CaCurrent*dt./tauCa;
787 717
        synapticCa(:,idx)=CaCurrent;
788 718
    end
789
    synapticCa=-synapticCa; % treat synapticCa as positive substance
719
    synapticCa=-synapticCa; % treat IHCpreSynapseParams as positive substance
790 720

  
791 721
    % NB vesicleReleaseRate is /s and is independent of dt
792 722
    vesicleReleaseRate = synapse_z * synapticCa.^synapse_power; % rate
......
799 729
    %     end
800 730

  
801 731

  
802
    %% AN -------------------------------
732
    %% AN
803 733
    switch AN_spikesOrProbability
804 734
        case 'probability'
735
            % No refractory effect is applied
805 736
            for t = 1:segmentLength;
806 737
                M_Pq=PAN_M-Pavailable;
807 738
                M_Pq(M_Pq<0)=0;
......
818 749
                Preprocess= Preprocess + reuptake - Preprocessed;
819 750
                Pavailable(Pavailable<0)=0;
820 751
                savePavailableSeg(:,t)=Pavailable;    % synapse tracking
821
                
822 752
            end
823

  
824 753
            % and save it as *rate*
825 754
            ANrate=ANprobability/dt;
826 755
            ANprobRateOutput(:, segmentStartPTR:...
......
828 757
            % monitor synapse contents (only sometimes used)
829 758
            savePavailable(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=...
830 759
                savePavailableSeg;
831
            
832
            %% Apply refractory effect
833
               % the probability of a spike's occurring in the preceding
834
               %  refractory window: t= (tnow-refractory period) :dt: tnow
835
               %    pFired= 1 - II(1-p(t)),
836
               % we need a running account of cumProb=II(1-p(t)) in order
837
               % not to have to recompute this for each value of t
838
               %   cumProb(t)= cumProb(t-1)*(1-p(t))/(1-p(t-refracPeriod))
839
               %   cumProb(0)=0
840
               %   pFired(t)= 1-cumProb(t)
841
               % This gives the fraction of firing events that must be 
842
               %  discounted because of a firing event in the refractory
843
               %  period
844
               %   p(t)= ANprobOutput(t) * pFired(t)
845
               % where ANprobOutput is the uncorrected firing probability
846
               %  based on vesicle release rate
847
               % NB this covers only the absoute refractory period
848
               % not the relative refractory period. To approximate this it
849
               % is necessary to extend the refractory period by 50%
850 760

  
851
                for t = segmentStartPTR:segmentEndPTR;
852
                    if t>1
853
                    ANprobRateOutput(:,t)= ANprobRateOutput(:,t)...
854
                        .* cumANnotFireProb(:,t-1);
855
                    end
856
                    % add recent and remove distant probabilities
857
                    refrac=round(lengthAbsRefractoryP * 1.5);
858
                    if t>refrac
859
                        cumANnotFireProb(:,t)= cumANnotFireProb(:,t-1)...
860
                            .*(1-ANprobRateOutput(:,t)*dt)...
861
                            ./(1-ANprobRateOutput(:,t-refrac)*dt);
862
                    end
863
                end
864
%                 figure(88), plot(cumANnotFireProb'), title('cumNotFire')
865
%                 figure(89), plot(ANprobRateOutput'), title('ANprobRateOutput')
761
            % Estimate efferent effects. ARattenuation (0 <> 1)
762
            %  acoustic reflex
763
            ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF
764
            % smooth
765
            [ARAttSeg, ARboundaryProb] = ...
766
                filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb);
767
            ARAttSeg=ARAttSeg-ARrateThreshold;
768
            ARAttSeg(ARAttSeg<0)=0;   % prevent negative strengths
769
            ARattenuation(segmentStartPTR:segmentEndPTR)=...
770
                (1-ARrateToAttenuationFactorProb.* ARAttSeg);
866 771

  
867
            %% Estimate acoustic reflex efferent effect:  0 < ARattenuation > 1
868
            [r c]=size(ANrate);
869
            if r>nBFs % Only if LSR fibers are computed
870
                ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF
871
                % smooth
872
                [ARAttSeg, ARboundaryProb] = ...
873
                    filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb);
874
                ARAttSeg=ARAttSeg-ARrateThreshold;
875
                ARAttSeg(ARAttSeg<0)=0;   % prevent negative strengths
876
                ARattenuation(segmentStartPTR:segmentEndPTR)=...
877
                    (1-ARrateToAttenuationFactorProb.* ARAttSeg);
878
            end
879
            %             plot(ARattenuation)
880

  
881
            % MOC attenuation based on within-channel HSR fiber activity
772
            % MOC attenuation
773
            % within-channel HSR response only
882 774
            HSRbegins=nBFs*(nANfiberTypes-1)+1;
883 775
            rates=ANrate(HSRbegins:end,:);
884
            if rateToAttenuationFactorProb<0
885
                % negative factor implies a fixed attenuation
886
                MOCattenuation(:,segmentStartPTR:segmentEndPTR)= ...
887
                    ones(size(rates))* -rateToAttenuationFactorProb;
888
            else
776
            for idx=1:nBFs
777
                [smoothedRates, MOCprobBoundary{idx}] = ...
778
                    filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ...
779
                    MOCprobBoundary{idx});
780
                smoothedRates=smoothedRates-MOCrateThreshold;
781
                smoothedRates(smoothedRates<0)=0;
782
                MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ...
783
                    (1- smoothedRates* rateToAttenuationFactorProb);
784
            end
785
            MOCattenuation(MOCattenuation<0)=0.001;
889 786

  
890
                for idx=1:nBFs
891
                    [smoothedRates, MOCprobBoundary{idx}] = ...
892
                        filter(MOCfiltProb_b, MOCfiltProb_a, rates(idx,:), ...
893
                        MOCprobBoundary{idx});
894
                    smoothedRates=smoothedRates-MOCrateThresholdProb;
895
                    smoothedRates=max(smoothedRates, 0);
896
                    
897
                    x=(1- smoothedRates* rateToAttenuationFactorProb);
898
                    MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= x;
899
                end
900
            end
901
            
902
            MOCattenuation(MOCattenuation<minMOCattenuation)= minMOCattenuation;
903
                
904
            % plot(MOCattenuation)            
905
            
787

  
906 788
        case 'spikes'
907 789
            ANtimeCount=0;
908 790
            % implement speed upt
909 791
            for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength;
910 792
                ANtimeCount=ANtimeCount+1;
911 793
                % convert release rate to probabilities
912
                releaseProb=vesicleReleaseRate(:,t)*dtSpikes;
794
                releaseProb=vesicleReleaseRate(:,t)*ANdt;
913 795
                % releaseProb is the release probability per channel
914 796
                %  but each channel has many synapses
915 797
                releaseProb=repmat(releaseProb',nFibersPerChannel,1);
916
                releaseProb=reshape(releaseProb, nFibersPerChannel*nANchannels,1);
798
                releaseProb=reshape(releaseProb, nFibersPerChannel*nChannels,1);
917 799

  
918 800
                % AN_available=round(AN_available); % vesicles must be integer, (?needed)
919 801
                M_q=AN_M- AN_available;     % number of missing vesicles
920 802
                M_q(M_q<0)= 0;              % cannot be less than 0
921 803

  
922
%                 probabilities= 1-(1-releaseProb).^AN_available; % slow
804
                % AN_N1 converts probability to discrete events
805
                %   it considers each event that might occur
806
                %   (how many vesicles might be released)
807
                %   and returns a count of how many were released
808

  
809
                % slow line
810
%                 probabilities= 1-(1-releaseProb).^AN_available;
923 811
                probabilities= 1-intpow((1-releaseProb), AN_available);
924 812
                ejected= probabilities> rand(length(AN_available),1);
925 813

  
926 814
                reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft;
927 815
                reuptake = AN_rdt.* AN_cleft;
928
                
929
%                 probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; % slow
816

  
817
                % slow line
818
%                 probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q;
930 819
                probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q);
931 820
                reprocessed= probabilities>rand(length(M_q),1);
932 821

  
933
%                 probabilities= 1-(1-AN_ydt).^M_q; %slow
822
                % slow line
823
%                 probabilities= 1-(1-AN_ydt).^M_q;
934 824
                 probabilities= 1-intpow((1-AN_ydt), M_q);
935 825

  
936 826
                replenish= probabilities>rand(length(M_q),1);
937 827

  
938 828
                AN_available = AN_available + replenish - ejected ...
939 829
                    + reprocessed;
940
                saveNavailableSeg(:,ANtimeCount)=AN_available(end,:); % only last channel
941

  
942 830
                AN_cleft = AN_cleft + ejected - reuptakeandlost;
943 831
                AN_reprocess = AN_reprocess + reuptake - reprocessed;
944 832

  
......
974 862

  
975 863
            % segment debugging
976 864
            % plotInstructions.figureNo=98;
977
            % plotInstructions.displaydt=dtSpikes;
865
            % plotInstructions.displaydt=ANdt;
978 866
            %  plotInstructions.numPlots=1;
979 867
            %  plotInstructions.subPlotNo=1;
980 868
            % UTIL_plotMatrix(ANspikes, plotInstructions);
981 869

  
982 870
            % and save it. NB, AN is now on 'speedUp' time
983 871
            ANoutput(:, reducedSegmentPTR: shorterSegmentEndPTR)=ANspikes;
984
            % monitor synapse contents (only sometimes used)
985
            saveNavailable(reducedSegmentPTR:reducedSegmentPTR+reducedSegmentLength-1)=...
986
                saveNavailableSeg;
987 872

  
988 873

  
989 874
            %% CN Macgregor first neucleus -------------------------------
990
            % input is from AN so dtSpikes is used throughout
875
            % input is from AN so ANdt is used throughout
991 876
            % Each CNneuron has a unique set of input fibers selected
992 877
            %  at random from the available AN fibers (CNinputfiberLists)
993 878

  
994 879
            % Create the dendritic current for that neuron
995 880
            % First get input spikes to this neuron
996 881
            synapseNo=1;
997
            for ch=1:nCNchannels
882
            for ch=1:nChannels
998 883
                for idx=1:nCNneuronsPerChannel
999 884
                    % determine candidate fibers for this unit
1000 885
                    fibersUsed=CNinputfiberLists(synapseNo,:);
1001
                    % ANpsth has a bin width of dtSpikes
886
                    % ANpsth has a bin width of dt
1002 887
                    %  (just a simple sum across fibers)
1003 888
                    AN_PSTH(synapseNo,:) = ...
1004 889
                        sum(ANspikes(fibersUsed,:), 1);
......
1011 896

  
1012 897
            for unitNo=1:nCNneurons
1013 898
                CNcurrentTemp(unitNo,:)= ...
1014
                    conv2(AN_PSTH(unitNo,:),CNalphaFunction);
899
                    conv(AN_PSTH(unitNo,:),CNalphaFunction);
1015 900
            end
1016
%             disp(['sum(AN_PSTH)= ' num2str(sum(AN_PSTH(1,:)))])
1017 901
            % add post-synaptic current  left over from previous segment
1018 902
            CNcurrentTemp(:,1:alphaCols)=...
1019 903
                CNcurrentTemp(:,1:alphaCols)+ CNtrailingAlphas;
1020 904

  
1021 905
            % take post-synaptic current for this segment
1022 906
            CNcurrentInput= CNcurrentTemp(:, 1:reducedSegmentLength);
1023
%                 disp(['mean(CNcurrentInput)= ' num2str(mean(CNcurrentInput(1,:)))])
1024 907

  
1025 908
            % trailingalphas are the ends of the alpha functions that
1026 909
            % spill over into the next segment
......
1030 913
            if CN_c>0
1031 914
                % variable threshold condition (slow)
1032 915
                for t=1:reducedSegmentLength
1033
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-dtSpikes;
916
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-dts;
1034 917
                    s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ;
1035 918
                    CNtimeSinceLastSpike(s)=0.0005;         % 0.5 ms for sodium spike
1036 919
                    dE =(-CN_E/CN_tauM + ...
1037
                        CNcurrentInput(:,t)/CN_cap+(...
1038
                        CN_Gk/CN_cap).*(CN_Ek-CN_E))*dtSpikes;
1039
                    dGk=-CN_Gk*dtSpikes./tauGk + CN_b*s;
1040
                    dTh=-(CN_Th-CN_Th0)*dtSpikes/CN_tauTh + CN_c*s;
920
                        CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt;
921
                    dGk=-CN_Gk*dt./tauGk + CN_b*s;
922
                    dTh=-(CN_Th-CN_Th0)*dt/CN_tauTh + CN_c*s;
1041 923
                    CN_E=CN_E+dE;
1042 924
                    CN_Gk=CN_Gk+dGk;
1043 925
                    CN_Th=CN_Th+dTh;
......
1045 927
                end
1046 928
            else
1047 929
                % static threshold (faster)
1048
                E=zeros(1,reducedSegmentLength);
1049
                Gk=zeros(1,reducedSegmentLength);
1050
                ss=zeros(1,reducedSegmentLength);
1051 930
                for t=1:reducedSegmentLength
1052
                    % time of previous spike moves back in time
1053
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-dtSpikes;
1054
                    % action potential if E>threshold
1055
                    %  allow time for s to reset between events
1056
                    s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ;  
1057
                    ss(t)=s(1);
1058
                    CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike
931
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-dt;
932
                    s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ;  % =1 if both conditions met
933
                    CNtimeSinceLastSpike(s)=0.0005;          % 0.5 ms for sodium spike
1059 934
                    dE = (-CN_E/CN_tauM + ...
1060
                        CNcurrentInput(:,t)/CN_cap +...
1061
                        (CN_Gk/CN_cap).*(CN_Ek-CN_E))*dtSpikes;
1062
                    dGk=-CN_Gk*dtSpikes./tauGk +CN_b*s;
935
                        CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt;
936
                    dGk=-CN_Gk*dt./tauGk +CN_b*s;
1063 937
                    CN_E=CN_E+dE;
1064 938
                    CN_Gk=CN_Gk+dGk;
1065
                    E(t)=CN_E(1);
1066
                    Gk(t)=CN_Gk(1);
1067 939
                    % add spike to CN_E and add resting potential (-60 mV)
1068
                    CNmembranePotential(:,t)=CN_E +s.*(CN_Eb-CN_E)+CN_Er;
940
                    CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er;
1069 941
                end
1070 942
            end
1071
%             disp(['CN_E= ' num2str(sum(CN_E(1,:)))])
1072
%             disp(['CN_Gk= ' num2str(sum(CN_Gk(1,:)))])
1073
%             disp(['CNmembranePotential= ' num2str(sum(CNmembranePotential(1,:)))])
1074
%             plot(CNmembranePotential(1,:))
1075

  
1076 943

  
1077 944
            % extract spikes.  A spike is a substantial upswing in voltage
1078
            CN_spikes=CNmembranePotential> -0.02;
1079
%             disp(['CNspikesbefore= ' num2str(sum(sum(CN_spikes)))])
945
            CN_spikes=CNmembranePotential> -0.01;
1080 946

  
1081 947
            % now remove any spike that is immediately followed by a spike
1082 948
            % NB 'find' works on columns (whence the transposing)
1083
            % for each spike put a zero in the next epoch
1084 949
            CN_spikes=CN_spikes';
1085 950
            idx=find(CN_spikes);
1086 951
            idx=idx(1:end-1);
1087 952
            CN_spikes(idx+1)=0;
1088 953
            CN_spikes=CN_spikes';
1089
%             disp(['CNspikes= ' num2str(sum(sum(CN_spikes)))])
1090 954

  
1091 955
            % segment debugging
1092 956
            % plotInstructions.figureNo=98;
1093
            % plotInstructions.displaydt=dtSpikes;
957
            % plotInstructions.displaydt=ANdt;
1094 958
            %  plotInstructions.numPlots=1;
1095 959
            %  plotInstructions.subPlotNo=1;
1096 960
            % UTIL_plotMatrix(CN_spikes, plotInstructions);
......
1103 967
            %% IC ----------------------------------------------
1104 968
                %  MacGregor or some other second order neurons
1105 969

  
1106
                % combine CN neurons in same channel (BF x AN tau x CNtau) 
1107
                %  i.e. same BF, same tauCa, same CNtau
970
                % combine CN neurons in same channel, i.e. same BF & same tauCa
1108 971
                %  to generate inputs to single IC unit
1109 972
                channelNo=0;
1110
                for idx=1:nCNneuronsPerChannel: ...
1111
                        nCNneurons-nCNneuronsPerChannel+1;
973
                for idx=1:nCNneuronsPerChannel:nCNneurons-nCNneuronsPerChannel+1;
1112 974
                    channelNo=channelNo+1;
1113 975
                    CN_PSTH(channelNo,:)=...
1114 976
                        sum(CN_spikes(idx:idx+nCNneuronsPerChannel-1,:));
......
1117 979
                [alphaRows alphaCols]=size(ICtrailingAlphas);
1118 980
                for ICneuronNo=1:nICcells
1119 981
                    ICcurrentTemp(ICneuronNo,:)= ...
1120
                        conv2(CN_PSTH(ICneuronNo,:),  IC_CNalphaFunction);
982
                        conv(CN_PSTH(ICneuronNo,:),  IC_CNalphaFunction);
1121 983
                end
1122 984

  
1123 985
                % add the unused current from the previous convolution
......
1128 990
                ICtrailingAlphas=ICcurrentTemp(:, reducedSegmentLength+1:end);
1129 991

  
1130 992
                if IC_c==0
1131
                    % faster computation when threshold is stable (c==0)
993
                    % faster computation when threshold is stable (C==0)
1132 994
                    for t=1:reducedSegmentLength
1133 995
                        s=IC_E>IC_Th0;
1134 996
                        dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +...
1135
                            (IC_Gk/IC_cap).*(IC_Ek-IC_E))*dtSpikes;
1136
                        dGk=-IC_Gk*dtSpikes/IC_tauGk +IC_b*s;
997
                            (IC_Gk/IC_cap).*(IC_Ek-IC_E))*dt;
998
                        dGk=-IC_Gk*dt/IC_tauGk +IC_b*s;
1137 999
                        IC_E=IC_E+dE;
1138 1000
                        IC_Gk=IC_Gk+dGk;
1139 1001
                        ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er;
......
1143 1005
                    for t=1:reducedSegmentLength
1144 1006
                        dE = (-IC_E/IC_tauM + ...
1145 1007
                            inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)...
1146
                            .*(IC_Ek-IC_E))*dtSpikes;
1008
                            .*(IC_Ek-IC_E))*dt;
1147 1009
                        IC_E=IC_E+dE;
1148 1010
                        s=IC_E>IC_Th;
1149 1011
                        ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er;
1150
                        dGk=-IC_Gk*dtSpikes/IC_tauGk +IC_b*s;
1012
                        dGk=-IC_Gk*dt/IC_tauGk +IC_b*s;
1151 1013
                        IC_Gk=IC_Gk+dGk;
1152 1014

  
1153 1015
                        % After a spike, the threshold is raised
1154 1016
                        % otherwise it settles to its baseline
1155
                        dTh=-(IC_Th-Th0)*dtSpikes/IC_tauTh +s*IC_c;
1017
                        dTh=-(IC_Th-Th0)*dt/IC_tauTh +s*IC_c;
1156 1018
                        IC_Th=IC_Th+dTh;
1157 1019
                    end
1158 1020
                end
1159 1021

  
1160 1022
                ICspikes=ICmembranePotential> -0.01;
1161
                %figure(2),plot(ICmembranePotential(2,:))
1162 1023
                % now remove any spike that is immediately followed by a spike
1163 1024
                % NB 'find' works on columns (whence the transposing)
1164 1025
                ICspikes=ICspikes';
......
1172 1033
                lastCell=nCellsPerTau;
1173 1034
                for tauCount=1:nANfiberTypes
1174 1035
                    % separate rates according to fiber types
1175
                    % currently only the last segment is saved
1176 1036
                    ICfiberTypeRates(tauCount, ...
1177 1037
                        reducedSegmentPTR:shorterSegmentEndPTR)=...
1178 1038
                        sum(ICspikes(firstCell:lastCell, :))...
1179
                        /(nCellsPerTau*dtSpikes);
1039
                        /(nCellsPerTau*ANdt);
1180 1040
                    firstCell=firstCell+nCellsPerTau;
1181 1041
                    lastCell=lastCell+nCellsPerTau;
1182 1042
                end
1183
                
1184
                ICoutput(:,reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes;
1185
                % figure(3),plot(ICoutput(2,:))
1186
                
1187
                % store membrane output on original dt scale
1188
                % do this for single channel models only 
1189
                % and only for the HSR-driven IC cells
1190
                if round(nICcells/length(ANtauCas))==1  % single channel
1191
                    % select HSR driven cells
1192
                    x= ICmembranePotential(length(ANtauCas),:);
1193
                    % restore original dt
1194
                    x= repmat(x, ANspeedUpFactor,1);
1043
                ICoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes;
1044

  
1045
                if nBFs==1  % single channel
1046
                    x= repmat(ICmembranePotential(1,:), ANspeedUpFactor,1);
1195 1047
                    x= reshape(x,1,segmentLength);
1196 1048
                    if nANfiberTypes>1  % save HSR and LSR
1197
                        y=repmat(ICmembranePotential(end,:),...
1198
                            ANspeedUpFactor,1);
1049
                        y= repmat(ICmembranePotential(end,:), ANspeedUpFactor,1);
1199 1050
                        y= reshape(y,1,segmentLength);
1200 1051
                        x=[x; y];
1201 1052
                    end
1202 1053
                    ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x;
1203 1054
                end
1204
                % figure(4),plot(ICmembraneOutput(2,:))
1205 1055

  
1206 1056
                % estimate efferent effects.
1207
                % AR is based on LSR units. LSR channels are 1:nBF
1208
                if nANfiberTypes>1  % use only if model is multi-fiber
1209
                    ARAttSeg=mean(ICspikes(1:nBFs,:),1)/dtSpikes;
1057
                % ARis based on LSR units. LSR channels are 1:nBF
1058
                if nANfiberTypes>1  % AR is multi-channel only
1059
                    ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt;
1210 1060
                    [ARAttSeg, ARboundary] = ...
1211 1061
                        filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary);
1212
%                    ARAttSeg(ARAttSeg<0)=0;   % prevent negative strengths
1213
                    % scale up to dt from dtSpikes
1214
                    x= repmat(ARAttSeg, ANspeedUpFactor,1);
1215
                    x= reshape(x,1,segmentLength);
1062
                    ARAttSeg=ARAttSeg-ARrateThreshold;
1063
                    ARAttSeg(ARAttSeg<0)=0;   % prevent negative strengths
1064
                    % scale up to dt from ANdt
1065
                    x=    repmat(ARAttSeg, ANspeedUpFactor,1);
1066
                    x=reshape(x,1,segmentLength);
1216 1067
                    ARattenuation(segmentStartPTR:segmentEndPTR)=...
1217 1068
                        (1-ARrateToAttenuationFactor* x);
1218
                    % max 60 dB attenuation
1219
                    ARattenuation(ARattenuation<0)=0.01;
1069
                    ARattenuation(ARattenuation<0)=0.001;
1220 1070
                else
1221
                    % single fiber type; disable AR because no LSR fibers
1071
                    % single channel model; disable AR
1222 1072
                    ARattenuation(segmentStartPTR:segmentEndPTR)=...
1223 1073
                        ones(1,segmentLength);
1224 1074
                end
1225 1075

  
1226 1076
                % MOC attenuation using HSR response only
1227
                %  separate MOC effect for each BF
1228
                %  there is only one unit per channel
1077
                % Separate MOC effect for each BF
1229 1078
                HSRbegins=nBFs*(nANfiberTypes-1)+1;
1230
                rates=ICspikes(HSRbegins:end,:)/dtSpikes;
1231
                % figure(4),plot(rates(1,:))
1232

  
1079
                rates=ICspikes(HSRbegins:end,:)/ANdt;
1233 1080
                for idx=1:nBFs
1234 1081
                    [smoothedRates, MOCboundary{idx}] = ...
1235 1082
                        filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ...
1236 1083
                        MOCboundary{idx});
1237
                    % spont 'rates' is zero for IC
1238 1084
                    MOCattSegment(idx,:)=smoothedRates;
1239
                    % expand timescale back to model dt from dtSpikes
1085
                    % expand timescale back to model dt from ANdt
1240 1086
                    x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1);
1241 1087
                    x= reshape(x,1,segmentLength);
1242 1088
                    MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ...
1243 1089
                        (1- MOCrateToAttenuationFactor*  x);
1244
                    % figure(4),plot(x)
1245 1090
                end
1246
                % max attenuation is 30 dB
1247
                MOCattenuation(MOCattenuation<minMOCattenuation)=...
1248
                    minMOCattenuation;
1249
                % figure(4),plot(MOCattenuation)
1250
                
1091
                MOCattenuation(MOCattenuation<0)=0.04;
1251 1092
                % segment debugging
1252 1093
                % plotInstructions.figureNo=98;
1253
                % plotInstructions.displaydt=dtSpikes;
1094
                % plotInstructions.displaydt=ANdt;
1254 1095
                %  plotInstructions.numPlots=1;
1255 1096
                %  plotInstructions.subPlotNo=1;
1256 1097
                % UTIL_plotMatrix(ICspikes, plotInstructions);
......
1259 1100
    segmentStartPTR=segmentStartPTR+segmentLength;
1260 1101
    reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength;
1261 1102

  
1103

  
1262 1104
end  % segment
1263 1105

  
1264
path(restorePath)
1106
path(restorePath)
MAP/filteredSACF.m
1
function [LP_SACF, BFlist, SACF, ACFboundaryValue] = ...
2
    filteredSACF(inputSignalMatrix, dt, BFlist, params)
3
% UTIL_filteredSACF computes within-channel, running autocorrelations (ACFs)
4
%  and finds the running sum across channels (SACF).
5
%  The SACF is smoothed to give the 'p function' (LP_SACF).
6
%  (Balaguer-Ballestera, E. Denham, S.L. and Meddis, R. (2008))
7
%
1
function [P, BFlist, sacf, boundaryValue] = ...
2
    filteredSACF(inputSignalMatrix, method, params)
3
% UTIL_filteredSACF computes within-channel, running autocorrelations (acfs)
4
%  and finds the sum across channels (sacf).
5
%  The SACF is smoothed to give the 'p function' (P).
8 6
%
9 7
% INPUT
10 8
%  	inputSignalMatrix: a matrix (channel x time) of AN activity
11
%  	dt:		the signal sampling interval in seconds
12
%   BFlist: channel BFs
9
%  	method.dt:			the signal sampling interval in seconds
10
%   method.segmentNo:
11
%   method.nonlinCF
12
%   
13
% params: 	a list of parmeters to guide the computation:
14
%   filteredSACFParams.lags: an array of lags to be computed (seconds)
15
%   filteredSACFParams.acfTau: time constant (sec) of the running acf calculations
16
%     if acfTau>1 it is assumed that Wiegrebe'sacf method
17
%   	for calculating tau is to be used (see below)
18
%   filteredSACFParams.Lambda: time constant  for smoothing thsacf to make P
19
%   filteredSACFParams.lagsProcedure identifies a strategy for omitting some lags.
20
%    Options are: 'useAllLags', 'omitShortLags', or 'useBernsteinLagWeights'
21
%   filteredSACFParams.usePressnitzer applies lower weights longer lags
22
%   parafilteredSACFParamsms.plotACFs (=1) creates movie of acf matrix (optional)
13 23
%
14
% params: 	a list of parmeters to guide the computation:
15
%   params.lags: an array of lags to be computed (seconds)
16
%   params.acfTau: time constant (sec) of the running ACF
17
%     if acfTau>1 it is assumed that Wiegrebe'SACF method
18
%   	for calculating tau is to be used (see below)
19
%   params.Lambda: smoothing factor for the SACF
20
%   params.lagsProcedure: strategies for omitting some lags.
21
%    (Options: 'useAllLags' or 'omitShortLags')
22
%   params.usePressnitzer applies lower weights longer lags
23
%   params.plotACFs (=1) creates movie of ACF matrix (optional)
24 24
%
25 25
% OUTPUT
26
%  	LP_SACF:	LP_SACF function 	(time x lags), a low pass filtered version of SACF.
27
%  method: updated version of input 'method' (to include lags used)
28
%   SACF:  	(time x lags)
29
%
30
% Notes:
31
% ACFboundaryValue refers to segmented evaluation and is currently not
32
%  supported. However the code may be useful later when this function
33
%  is incorporated into MAP1_14.
26
%  	P:	P function 	(time x lags), a low pass filtered version of sacf.
27
%  method: updated version of input method (to include lags used)
28
%   sacf:  	(time x lags)
34 29

  
35 30
%%
36
global savedInputSignal
31
boundaryValue=[];
32
[nChannels inputLength]= size(inputSignalMatrix);
33
% list of BFs must be repeated is many fiber types used
34
BFlist=method.nonlinCF;
35
nfibertypes=nChannels/length(BFlist);
36
BFlist=repmat(BFlist',2,1)';
37 37

  
38
ACFboundaryValue=[];
38
dt=method.dt;
39
% adjust sample rate, if required
40
if isfield(params,'dt')
41
    [inputSignalMatrix dt]=UTIL_adjustDT(params.dt, method.dt, inputSignalMatrix);
42
    method.dt=dt;
43
end
39 44

  
40
[nChannels inputLength]= size(inputSignalMatrix);
41

  
42
% create ACF movie
45
% create acf movie
43 46
if isfield(params, 'plotACFs') && params.plotACFs==1
44 47
    plotACF=1;
45
    signalTime=dt:dt:dt*length(savedInputSignal);
46 48
else
47 49
    plotACF=0;  % default
48 50
end
49
params.plotACFsInterval=round(params.plotACFsInterval/dt);
50 51

  
51 52
if isfield(params,'lags')
52 53
    lags=params.lags;
......
63 64
else
64 65
    lagsProcedure='useAllLags';  % default
65 66
end
66

  
67
% disp(['lag procedure= ''' lagsProcedure ''''])
67 68
lagWeights=ones(nChannels,nLags);
68 69
switch lagsProcedure
69 70
    case 'useAllLags'
70
        % no action required lagWeights set above
71
       % no action required lagWeights set above
71 72
    case 'omitShortLags'
72 73
        % remove lags that are short relative to CF
73 74
        allLags=repmat(lags,nChannels,1);
......
75 76
        criterionForOmittingLags=1./(params.criterionForOmittingLags*allCFs);
76 77
        idx= allLags < criterionForOmittingLags;	% ignore these lags
77 78
        lagWeights(idx)=0;
79
    case 'useBernsteinLagWeights'
80
        lagWeights=BernsteinLags(BFlist, lags)';
78 81
    otherwise
79
        error ('ACF: params.lagProcedure not recognised')
82
        error ('acf: params.lagProcedure not recognised')
80 83
end
81 84

  
82 85

  
83
% Establish matrix of lag time constants
86
% Establish matrix of lag time constants 
84 87
%   these are all the same if tau<1
85 88
% if acfTau>1, it is assumed that we are using the Wiegrebe method
86 89
%   and a different decay factor is applied to each lag
......
89 92
if acfTau<1          % all taus are the same
90 93
    acfTaus=repmat(acfTau, 1, nLags);
91 94
    acfDecayFactors=ones(size(lags)).*exp(-dt/acfTau);
92
else                  % use Wiegrebe method: tau= 2*lag (for example)
95
else                      % use Wiegrebe method: tau= 2*lag (for example)
93 96
    WiegrebeFactor=acfTau;
94 97
    acfTaus=WiegrebeFactor*lags;
95 98
    idx= acfTaus<0.0025; acfTaus(idx)=0.0025;
......
98 101
% make acfDecayFactors into a (channels x lags) matrix for speedy computation
99 102
acfDecayFactors=repmat(acfDecayFactors,nChannels, 1);
100 103

  
101
% LP_SACF function lowpass filter decay (only one value needed)
104
% P function lowpass filter decay (only one value needed)
102 105
pDecayFactor=exp(-dt/params.lambda);
103 106

  
104 107
% ACF
......
109 112
end
110 113

  
111 114

  
112
LP_SACF=zeros(nLags,inputLength+1);   % LP_SACF must match segment length +1
113
SACF=zeros(nLags,inputLength);
114
method=[];  % legacy programming
115
P=zeros(nLags,inputLength+1);   % P must match segment length +1
116
sacf=zeros(nLags,inputLength);
115 117
if   ~isfield(method,'segmentNumber') || method.segmentNumber==1
116
    ACF=zeros(nChannels,nLags);
118
    acf=zeros(nChannels,nLags);
117 119
    % create a runup buffer of signal
118 120
    buffer= zeros(nChannels, max(lagPointers));
119 121
else
120
    % ACFboundaryValue picks up from a previous calculation
121
    ACF=params.ACFboundaryValue{1};
122
    % NB first value is last value of previous segment
123
    LP_SACF(: , 1)=params.ACFboundaryValue{2};
124
    buffer=params.ACFboundaryValue{3};
122
    % boundaryValue picks up from a previous calculation
123
    acf=params.boundaryValue{1};
124
    P(: , 1)=params.boundaryValue{2}; % NB first value is last value of previous segment
125
    buffer=params.boundaryValue{3};
125 126
end
126 127
inputSignalMatrix=[buffer inputSignalMatrix];
127 128
[nChannels inputLength]= size(inputSignalMatrix);
128 129

  
129 130
timeCounter=0; biggestSACF=0;
130 131
for timePointer= max(lagPointers)+1:inputLength
131
    % ACF is a continuously changing channels x lags matrix
132
    % acf is a continuously changing channels x lags matrix
132 133
    %   Only the current value is stored
133
    % SACF is the vertical sum of ACFs; all values are kept and returned
134
    % LP_SACF is the smoothed version of SACF:all values are kept and returned
134
    % sacf is the vertical summary of acf ( a vector) and all values are kept and returned
135
    % P is the smoothed version of sacf and all values are kept and returned
135 136
    % lagWeights emphasise some BF/lag combinations and ignore others
136 137
    % NB time now begins at the longest lag.
137
    % E.g. if max(lags) is .04 then this is when the ACf will begin (?).
138

  
138
    % E.g. if max(lags) is .04 then this is when the ACf will begin.
139
    %            AN                                       AN delayed                             weights               filtering
140
    
139 141
    % This is the ACF calculation
140 142
    timeCounter=timeCounter+1;
141
    ACF= (repmat(inputSignalMatrix(:, timePointer), 1, nLags) .* ...
142
        inputSignalMatrix(:, timePointer-lagPointers)).*...
143
        lagWeights *dt + ACF.* acfDecayFactors;
144
    x=(mean(ACF,1)./acfTaus)';
145
    SACF(:,timeCounter)=x;
143
    acf= (repmat(inputSignalMatrix(:, timePointer), 1, nLags) .* inputSignalMatrix(:, timePointer-lagPointers)).*lagWeights *dt + acf.* acfDecayFactors;
144
    x=(mean(acf,1)./acfTaus)';
145
%     disp(num2str(x'))
146
    sacf(:,timeCounter)=x;
147
    P(:,timeCounter+1)=sacf(:,timeCounter)*(1-pDecayFactor)+P(:,timeCounter)*pDecayFactor;
146 148
    
147
    % smoothed version of SACF
148
    LP_SACF(:,timeCounter+1)=SACF(:,timeCounter)* (1-pDecayFactor) + ...
149
        LP_SACF(:,timeCounter)* pDecayFactor;
150

  
151
    % plot ACF at intervals if requested to do so
152
    if plotACF && ~mod(timePointer,params.plotACFsInterval) && ...
153
            timePointer*dt>3*max(lags)
154
        figure(89), clf
155
        %           plot ACFs one per channel
156
        subplot(2,1,1)
157
        UTIL_cascadePlot(ACF, lags)
158
        title(['running ACF  at ' num2str(dt*timePointer,'%5.3f') ' s'])
159
        ylabel('channel BF'), xlabel('period (lag, ms)')
160
        set(gca,'ytickLabel',[])
161

  
162
        %           plot SACF
163
        subplot(4,1,3), cla
164
        plotSACF=SACF(:,timeCounter)-min(SACF(:,timeCounter));
165
        plot(lags*1000, plotSACF, 'k')
166
        biggestSACF=max(biggestSACF, max(plotSACF));
167
        if biggestSACF>0, ylim([0 biggestSACF]), else ylim([0 1]), end
168
        ylabel('SACF'), set(gca,'ytickLabel',[])
169
%         xlim([min(lags*1000) max(lags*1000)])
170

  
171
        %           plot signal
172
        subplot(4,1,4)
173
        plot(signalTime, savedInputSignal, 'k'), hold on
174
        xlim([0 max(signalTime)])
175
        a= ylim;
176
        %       mark cursor on chart to indicate progress
149
    % plot at intervals of 200 points
150
    if plotACF && ~mod(timePointer,params.plotACFsInterval)
151
        %       mark cursor on chart to signal progress
152
        % this assumes that the user has already plotted
153
        % the signal in subplot(2,1,1) of figure (13)
154
        figure(13)
155
        hold on
156
        subplot(4,1,1)
177 157
        time=timePointer*dt;
178
        plot([time time], [a(1) a(1)+(a(2)-a(1))/4], 'r', 'linewidth', 5)
158
        a =ylim;
159
        plot([time time], [a(1) a(1)+(a(2)-a(1))/4]) % current signal point marker
160
        
161
        %         plot ACFs one per channel
162
        subplot(2,1,2), cla
163
        cascadePlot(acf, lags, BFlist)
164
        xlim([min(lags) max(lags)])
165
        %         set(gca,'xscale','log')
166
        title(num2str(method.dt*timePointer))
167
        ylabel('BF'), xlabel('period (lag)')
168
        
169
        %         plot SACF
170
        subplot(4,1,2), hold off
171
        plot(lags,sacf(:,timeCounter)-min(sacf(:,timeCounter)))
172
        biggestSACF=max(biggestSACF, max(sacf(:,timeCounter)));
173
        if biggestSACF>0, ylim([0 biggestSACF]), end
174
        %         set(gca,'xscale','log')
175
        title('SACF')
179 176
        pause(params.plotMoviePauses)
180 177
    end
181 178
end
182
LP_SACF=LP_SACF(:,1:end-1);  % correction for speed up above
179
P=P(:,1:end-1);  % correction for speed up above
183 180

  
184 181
% Pressnitzer weights
185 182
if ~isfield(params, 'usePressnitzer'),     params.usePressnitzer=0; end
186 183
if params.usePressnitzer
187
    [a nTimePoints]=size(LP_SACF);
184
    [a nTimePoints]=size(P);
188 185
    % higher pitches get higher weights
189 186
    %     PressnitzerWeights=repmat(min(lags)./lags,nTimePoints,1);
190 187
    % weaker weighting
191 188
    PressnitzerWeights=repmat((min(lags)./lags).^0.5, nTimePoints,1);
192
    LP_SACF=LP_SACF.*PressnitzerWeights';
193
    SACF=SACF.*PressnitzerWeights';
189
    P=P.*PressnitzerWeights';
190
    sacf=sacf.*PressnitzerWeights';
194 191
end
195 192

  
196 193
% wrap up
197
% BoundaryValue is legacy programming used in segmented model (keep)
198
ACFboundaryValue{1}=ACF(:,end-nLags+1:end);
199
ACFboundaryValue{2}=LP_SACF(:,end);
194
method.acfLags=lags;
195
method.filteredSACFdt=dt;
196

  
197
boundaryValue{1}=acf(:,end-nLags+1:end);
198
boundaryValue{2}=P(:,end);
200 199
% save signal buffer for next segment
201
ACFboundaryValue{3} = inputSignalMatrix(:, end-max(lagPointers)+1 : end);
200
boundaryValue{3} = inputSignalMatrix(:, end-max(lagPointers)+1 : end);
201

  
202
method.displaydt=method.filteredSACFdt;
203

  
204
% if ~isfield(params, 'plotUnflteredSACF'), params.plotUnflteredSACF=0; end
205
% if method.plotGraphs
206
%     method.plotUnflteredSACF=params.plotUnflteredSACF;
207
%     if ~method.plotUnflteredSACF
208
%         method=filteredSACFPlot(P,method);
209
%     else
210
%         method=filteredSACFPlot(SACF,method);
211
%     end
212
% end
213

  
214

  
215
% ------------------------------------------------  plotting ACFs
216
function cascadePlot(toPlot, lags, BFs)
217
% % useful code
218
[nChannels nLags]=size(toPlot);
219

  
220
% cunning code to represent channels as parallel lines
221
[nRows nCols]=size(toPlot);
222
if nChannels>1
223
    % max(toPlot) defines the spacing between lines
224
    a=max(max(toPlot))*(0:nRows-1)';
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff