Revision 38:c2204b18f4a2

View differences:

MAP/MAP1_14.m
23 23
restorePath=path;
24 24
addpath (['..' filesep 'parameterStore'])
25 25

  
26
% clear global -regexp OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams
27
% clear global -regexp  AN_IHCsynapseParams MacGregorParams MacGregorMultiParams
28
% clear global -regexp dt ANdt  savedBFlist saveAN_spikesOrProbability saveMAPparamsName...
29
%     savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ...
30
%     DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV...
31
%     IHCoutput ANprobRateOutput ANoutput savePavailable ANtauCas  ...
32
%     CNtauGk CNoutput  ICoutput ICmembraneOutput ICfiberTypeRates ...
33
%     MOCattenuation
34

  
35 26
global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams
36 27
global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams
37 28

  
38 29
% All of the results of this function are stored as global
39
global dt ANdt  savedBFlist saveAN_spikesOrProbability saveMAPparamsName...
40
    savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ...
41
    DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV...
42
    IHCoutput ANprobRateOutput ANoutput savePavailable ANtauCas  ...
43
    CNtauGk CNoutput  ICoutput ICmembraneOutput ICfiberTypeRates ...
44
    MOCattenuation 
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 
45 37

  
46 38

  
47 39
% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be
48 40
% needed by the user; so the following will suffice
49
%   global ANdt ICoutput ANprobRateOutput
41
%   global dtSpikes ICoutput ANprobRateOutput
50 42

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

  
56 48
% When AN_spikesOrProbability is set to probability,
57 49
%  no spike matrices are computed.
......
60 52

  
61 53
% Efferent control variables are ARattenuation and MOCattenuation
62 54
%  These are scalars between 1 (no attenuation) and 0.
63
%  They are represented with dt=1/sampleRate (not ANdt)
55
%  They are represented with dt=1/sampleRate (not dtSpikes)
64 56
%  They are computed using either AN probability rate output
65 57
%   or IC (spikes) output as approrpriate.
66 58
% AR is computed using across channel activity
......
85 77
savedBFlist=BFlist;
86 78
saveAN_spikesOrProbability=AN_spikesOrProbability;
87 79
saveMAPparamsName=MAPparamsName;
80
savedParamChanges=paramChanges;
88 81

  
89 82
dt=1/sampleRate;
90 83
duration=length(inputSignal)/sampleRate;
......
94 87
segmentTime=dt*(1:segmentLength); % used in debugging plots
95 88

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

  
99 93
% inputSignal must be  row vector
100 94
[r c]=size(inputSignal);
......
115 109
inputSignal=[inputSignal pad];
116 110
[ignore signalLength]=size(inputSignal);
117 111

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

  
......
163 157
OME_TMdisplacementBndry=[];
164 158

  
165 159
% OME high pass (simulates poor low frequency stapes response)
166
OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff;
160
OMEhighPassHighCutOff=OMEParams.OMEstapesHPcutoff;
167 161
Nyquist=sampleRate/2;
168 162
[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high');
169 163
% figure(10), freqz(stapesDisp_b, stapesDisp_a)
......
236 230
% DRNLb=DRNLParams.b;
237 231
DRNLc=DRNLParams.c;
238 232
linGAIN=DRNLParams.g;
239
CtBM=10e-9*10^(DRNLParams.CtBMdB/20);
240
CtS=CtBM/DRNLa;
233
ctBM=10e-9*10^(DRNLParams.ctBMdB/20);
234
CtS=ctBM/DRNLa;
241 235
%
242 236
% gammatone filter coefficients for linear pathway
243 237
bw=DRNLParams.linBWs';
......
299 293
b0=1+ a1;
300 294
% high pass (i.e. low pass reversed)
301 295
IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0;
296
% i.e. b= [1  dt/tc-1]  and a= dt/IHC_cilia_RPParams.tc
302 297
% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a)
303 298

  
304 299
IHCciliaBndry=cell(nBFs,1);
......
405 400
% special variables for monitoring synaptic cleft (specialists only)
406 401
savePavailableSeg=zeros(nANchannels,segmentLength);
407 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);
408 406

  
409 407
% spikes     % !  !  !    ! !        !   !  !
410
lengthAbsRefractory= round(AN_refractory_period/ANdt);
408
lengthAbsRefractory= round(AN_refractory_period/dtSpikes);
411 409

  
412
AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1);
413
AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1);
414
AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1);
415
AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1);
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);
416 414
AN_rdt_plus_ldt= AN_rdt + AN_ldt;
417 415
AN_M= round(AN_IHCsynapseParams.M);
418 416

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

  
488
% figure(98), plot(t,CNalphaFunction)
486
% figure(98), plot(t,CNalphaFunction), xlim([0 .020]), xlabel('time (s)'), ylabel('I')
489 487
% working memory for implementing convolution
490 488

  
491 489
CNcurrentTemp=...
......
520 518
CN_PSTH=zeros(nICcells ,reducedSegmentLength);
521 519

  
522 520
% ICspikeWidth=0.00015;   % this may need revisiting
523
% epochsPerSpike=round(ICspikeWidth/ANdt);
521
% epochsPerSpike=round(ICspikeWidth/dtSpikes);
524 522
% if epochsPerSpike<1
525 523
%     error(['MacGregorMulti: sample rate too low to support ' ...
526 524
%         num2str(ICspikeWidth*1e6) '  microsec spikes']);
......
546 544
ICdendriteLPfreq= MacGregorParams.dendriteLPfreq;
547 545
ICcurrentPerSpike=MacGregorParams.currentPerSpike;
548 546
ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq);
549
t=ANdt:ANdt:3*ICspikeToCurrentTau;
547
t=dtSpikes:dtSpikes:3*ICspikeToCurrentTau;
550 548
IC_CNalphaFunction= (ICcurrentPerSpike / ...
551 549
    ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau);
552 550
% figure(98), plot(t,IC_CNalphaFunction)
......
661 659
                nonlinOutput, GTnonlinBdry1{BFno,order});
662 660
        end
663 661
        
662
        
664 663
        % Nick's compression algorithm
665
        abs_x = abs(nonlinOutput);
666
        y(abs_x<CtS)   = DRNLa * nonlinOutput(abs_x<CtS);
667
        y(abs_x>=CtS)  = sign(nonlinOutput(abs_x>=CtS)) * DRNLa * CtS .* ...
668
            exp(   DRNLc * log(  abs_x(abs_x>=CtS)/CtS  )   );
669
        nonlinOutput=y;
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
                       
670 672
        
671 673
%         %    original   broken stick instantaneous compression
672 674
%         holdY=nonlinOutput;
......
688 690
%         end
689 691
%         nonlinOutput=y;
690 692

  
691
        % % Boltzmann compression function
692
        % y=(nonlinOutput * DRNLa*100000);
693
        % holdY=y;
694
        % y=abs(y);
695
        % s=10; u=0.0;
696
        % x=1./(1+exp(-(y-u)/s))-0.5;
697
        % nonlinOutput=sign(nonlinOutput).*x/10000;
698 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
699 701

  
700
        % if segmentStartPTR==10*segmentLength+1
701
        %     figure(90)
702
        %     plot(holdY,'b'), hold on
703
        %     plot(nonlinOutput, 'r'), hold off
704
        %     ylim([-1e-5 1e-5])
705
        %     pause(1)
706
        % end
707

  
708
        %       second filter removes distortion products
702
%       second filter removes distortion products
709 703
        for order = 1 : GTnonlinOrder
710 704
            [ nonlinOutput GTnonlinBdry2{BFno,order}] = ...
711 705
                filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
......
839 833
               % the probability of a spike's occurring in the preceding
840 834
               %  refractory window: t= (tnow-refractory period) :dt: tnow
841 835
               %    pFired= 1 - II(1-p(t)),
842
               % we need a running account of cumProb=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
843 838
               %   cumProb(t)= cumProb(t-1)*(1-p(t))/(1-p(t-refracPeriod))
844 839
               %   cumProb(0)=0
845 840
               %   pFired(t)= 1-cumProb(t)
......
869 864
%                 figure(88), plot(cumANnotFireProb'), title('cumNotFire')
870 865
%                 figure(89), plot(ANprobRateOutput'), title('ANprobRateOutput')
871 866

  
872
            %% Estimate efferent effect:  0 < ARattenuation > 1
873
            %  acoustic reflex
867
            %% Estimate acoustic reflex efferent effect:  0 < ARattenuation > 1
874 868
            [r c]=size(ANrate);
875 869
            if r>nBFs % Only if LSR fibers are computed
876 870
                ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF
......
893 887
                    ones(size(rates))* -rateToAttenuationFactorProb;
894 888
            else
895 889

  
896
                % Nick's new code
897
%                 for idx=1:nBFs
898
%                     [smoothedRates, MOCprobBoundary{idx}] = ...
899
%                         filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ...
900
%                         MOCprobBoundary{idx});
901
% %                     smoothedRates=smoothedRates-MOCrateThresholdProb;
902
% %                     smoothedRates(smoothedRates<0)=0;
903
% %                     x =  (1- smoothedRates* rateToAttenuationFactorProb); %ORIGINAL 
904
%  
905
%                     %NEW !!!
906
%                     x = -20*log10(  max(smoothedRates/MOCrateThresholdProb,1)  )*rateToAttenuationFactorProb; %dB attenuation
907
%                     x = 10.^(x/20);
908
%                     x = max(x,10^(-35/20));    
909
% %                     %ALSO - filter at the end - this will stop rapid attack
910
% %                     %and slow decay
911
% %                     [x, MOCprobBoundary{idx}] = ...
912
% %                         filter(MOCfilt_b, MOCfilt_a, x, ...
913
% %                         MOCprobBoundary{idx});
914
%                     
915
%                                         
916
%                     MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ...
917
%                         x;                                                            
918
%                 end
919
                
920

  
921 890
                for idx=1:nBFs
922 891
                    [smoothedRates, MOCprobBoundary{idx}] = ...
923 892
                        filter(MOCfiltProb_b, MOCfiltProb_a, rates(idx,:), ...
......
940 909
            for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength;
941 910
                ANtimeCount=ANtimeCount+1;
942 911
                % convert release rate to probabilities
943
                releaseProb=vesicleReleaseRate(:,t)*ANdt;
912
                releaseProb=vesicleReleaseRate(:,t)*dtSpikes;
944 913
                % releaseProb is the release probability per channel
945 914
                %  but each channel has many synapses
946 915
                releaseProb=repmat(releaseProb',nFibersPerChannel,1);
......
968 937

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

  
971 942
                AN_cleft = AN_cleft + ejected - reuptakeandlost;
972 943
                AN_reprocess = AN_reprocess + reuptake - reprocessed;
973 944

  
......
1003 974

  
1004 975
            % segment debugging
1005 976
            % plotInstructions.figureNo=98;
1006
            % plotInstructions.displaydt=ANdt;
977
            % plotInstructions.displaydt=dtSpikes;
1007 978
            %  plotInstructions.numPlots=1;
1008 979
            %  plotInstructions.subPlotNo=1;
1009 980
            % UTIL_plotMatrix(ANspikes, plotInstructions);
1010 981

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

  
1014 988

  
1015 989
            %% CN Macgregor first neucleus -------------------------------
1016
            % input is from AN so ANdt is used throughout
990
            % input is from AN so dtSpikes is used throughout
1017 991
            % Each CNneuron has a unique set of input fibers selected
1018 992
            %  at random from the available AN fibers (CNinputfiberLists)
1019 993

  
......
1024 998
                for idx=1:nCNneuronsPerChannel
1025 999
                    % determine candidate fibers for this unit
1026 1000
                    fibersUsed=CNinputfiberLists(synapseNo,:);
1027
                    % ANpsth has a bin width of ANdt
1001
                    % ANpsth has a bin width of dtSpikes
1028 1002
                    %  (just a simple sum across fibers)
1029 1003
                    AN_PSTH(synapseNo,:) = ...
1030 1004
                        sum(ANspikes(fibersUsed,:), 1);
......
1056 1030
            if CN_c>0
1057 1031
                % variable threshold condition (slow)
1058 1032
                for t=1:reducedSegmentLength
1059
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt;
1033
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-dtSpikes;
1060 1034
                    s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ;
1061 1035
                    CNtimeSinceLastSpike(s)=0.0005;         % 0.5 ms for sodium spike
1062 1036
                    dE =(-CN_E/CN_tauM + ...
1063 1037
                        CNcurrentInput(:,t)/CN_cap+(...
1064
                        CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt;
1065
                    dGk=-CN_Gk*ANdt./tauGk + CN_b*s;
1066
                    dTh=-(CN_Th-CN_Th0)*ANdt/CN_tauTh + CN_c*s;
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;
1067 1041
                    CN_E=CN_E+dE;
1068 1042
                    CN_Gk=CN_Gk+dGk;
1069 1043
                    CN_Th=CN_Th+dTh;
......
1076 1050
                ss=zeros(1,reducedSegmentLength);
1077 1051
                for t=1:reducedSegmentLength
1078 1052
                    % time of previous spike moves back in time
1079
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt;
1053
                    CNtimeSinceLastSpike=CNtimeSinceLastSpike-dtSpikes;
1080 1054
                    % action potential if E>threshold
1081 1055
                    %  allow time for s to reset between events
1082 1056
                    s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ;  
......
1084 1058
                    CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike
1085 1059
                    dE = (-CN_E/CN_tauM + ...
1086 1060
                        CNcurrentInput(:,t)/CN_cap +...
1087
                        (CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt;
1088
                    dGk=-CN_Gk*ANdt./tauGk +CN_b*s;
1061
                        (CN_Gk/CN_cap).*(CN_Ek-CN_E))*dtSpikes;
1062
                    dGk=-CN_Gk*dtSpikes./tauGk +CN_b*s;
1089 1063
                    CN_E=CN_E+dE;
1090 1064
                    CN_Gk=CN_Gk+dGk;
1091 1065
                    E(t)=CN_E(1);
......
1116 1090

  
1117 1091
            % segment debugging
1118 1092
            % plotInstructions.figureNo=98;
1119
            % plotInstructions.displaydt=ANdt;
1093
            % plotInstructions.displaydt=dtSpikes;
1120 1094
            %  plotInstructions.numPlots=1;
1121 1095
            %  plotInstructions.subPlotNo=1;
1122 1096
            % UTIL_plotMatrix(CN_spikes, plotInstructions);
......
1158 1132
                    for t=1:reducedSegmentLength
1159 1133
                        s=IC_E>IC_Th0;
1160 1134
                        dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +...
1161
                            (IC_Gk/IC_cap).*(IC_Ek-IC_E))*ANdt;
1162
                        dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s;
1135
                            (IC_Gk/IC_cap).*(IC_Ek-IC_E))*dtSpikes;
1136
                        dGk=-IC_Gk*dtSpikes/IC_tauGk +IC_b*s;
1163 1137
                        IC_E=IC_E+dE;
1164 1138
                        IC_Gk=IC_Gk+dGk;
1165 1139
                        ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er;
......
1169 1143
                    for t=1:reducedSegmentLength
1170 1144
                        dE = (-IC_E/IC_tauM + ...
1171 1145
                            inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)...
1172
                            .*(IC_Ek-IC_E))*ANdt;
1146
                            .*(IC_Ek-IC_E))*dtSpikes;
1173 1147
                        IC_E=IC_E+dE;
1174 1148
                        s=IC_E>IC_Th;
1175 1149
                        ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er;
1176
                        dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s;
1150
                        dGk=-IC_Gk*dtSpikes/IC_tauGk +IC_b*s;
1177 1151
                        IC_Gk=IC_Gk+dGk;
1178 1152

  
1179 1153
                        % After a spike, the threshold is raised
1180 1154
                        % otherwise it settles to its baseline
1181
                        dTh=-(IC_Th-Th0)*ANdt/IC_tauTh +s*IC_c;
1155
                        dTh=-(IC_Th-Th0)*dtSpikes/IC_tauTh +s*IC_c;
1182 1156
                        IC_Th=IC_Th+dTh;
1183 1157
                    end
1184 1158
                end
......
1202 1176
                    ICfiberTypeRates(tauCount, ...
1203 1177
                        reducedSegmentPTR:shorterSegmentEndPTR)=...
1204 1178
                        sum(ICspikes(firstCell:lastCell, :))...
1205
                        /(nCellsPerTau*ANdt);
1179
                        /(nCellsPerTau*dtSpikes);
1206 1180
                    firstCell=firstCell+nCellsPerTau;
1207 1181
                    lastCell=lastCell+nCellsPerTau;
1208 1182
                end
......
1230 1204
                % figure(4),plot(ICmembraneOutput(2,:))
1231 1205

  
1232 1206
                % estimate efferent effects.
1233
                % ARis based on LSR units. LSR channels are 1:nBF
1207
                % AR is based on LSR units. LSR channels are 1:nBF
1234 1208
                if nANfiberTypes>1  % use only if model is multi-fiber
1235
                    ARAttSeg=mean(ICspikes(1:nBFs,:),1)/ANdt;
1209
                    ARAttSeg=mean(ICspikes(1:nBFs,:),1)/dtSpikes;
1236 1210
                    [ARAttSeg, ARboundary] = ...
1237 1211
                        filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary);
1238
%                     ARAttSeg(ARAttSeg<0)=0;   % prevent negative strengths
1239
                    % scale up to dt from ANdt
1212
%                    ARAttSeg(ARAttSeg<0)=0;   % prevent negative strengths
1213
                    % scale up to dt from dtSpikes
1240 1214
                    x= repmat(ARAttSeg, ANspeedUpFactor,1);
1241 1215
                    x= reshape(x,1,segmentLength);
1242 1216
                    ARattenuation(segmentStartPTR:segmentEndPTR)=...
1243 1217
                        (1-ARrateToAttenuationFactor* x);
1244 1218
                    % max 60 dB attenuation
1245
                    ARattenuation(ARattenuation<0)=0.001;
1219
                    ARattenuation(ARattenuation<0)=0.01;
1246 1220
                else
1247 1221
                    % single fiber type; disable AR because no LSR fibers
1248 1222
                    ARattenuation(segmentStartPTR:segmentEndPTR)=...
......
1253 1227
                %  separate MOC effect for each BF
1254 1228
                %  there is only one unit per channel
1255 1229
                HSRbegins=nBFs*(nANfiberTypes-1)+1;
1256
                rates=ICspikes(HSRbegins:end,:)/ANdt;
1230
                rates=ICspikes(HSRbegins:end,:)/dtSpikes;
1257 1231
                % figure(4),plot(rates(1,:))
1258 1232

  
1259 1233
                for idx=1:nBFs
......
1262 1236
                        MOCboundary{idx});
1263 1237
                    % spont 'rates' is zero for IC
1264 1238
                    MOCattSegment(idx,:)=smoothedRates;
1265
                    % expand timescale back to model dt from ANdt
1239
                    % expand timescale back to model dt from dtSpikes
1266 1240
                    x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1);
1267 1241
                    x= reshape(x,1,segmentLength);
1268 1242
                    MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ...
......
1276 1250
                
1277 1251
                % segment debugging
1278 1252
                % plotInstructions.figureNo=98;
1279
                % plotInstructions.displaydt=ANdt;
1253
                % plotInstructions.displaydt=dtSpikes;
1280 1254
                %  plotInstructions.numPlots=1;
1281 1255
                %  plotInstructions.subPlotNo=1;
1282 1256
                % UTIL_plotMatrix(ICspikes, plotInstructions);
MAP/MAPrunner.m
1
function MAPrunner(MAPparamsName, AN_spikesOrProbability, ...
2
    signalCharacteristics, paramChanges, showMapOptions)
3

  
4
dbstop if error
5
restorePath=path;
6
addpath (['..' filesep 'MAP'],    ['..' filesep 'wavFileStore'], ...
7
    ['..' filesep 'utilities'])
8

  
9

  
10
%% #3 pure tone, harmonic sequence or speech file input
11
signalType= signalCharacteristics.type;
12
sampleRate= signalCharacteristics.sampleRate;
13
duration=signalCharacteristics.duration;                 % seconds
14
rampDuration=signalCharacteristics.rampDuration;              % raised cosine ramp (seconds)
15
beginSilence=signalCharacteristics.beginSilence;               
16
endSilence=signalCharacteristics.endSilence;                  
17
toneFrequency= signalCharacteristics.toneFrequency;            % or a pure tone (Hz)
18
leveldBSPL=signalCharacteristics.leveldBSPL;
19

  
20
BFlist=-1;
21

  
22

  
23
%% Generate stimuli
24

  
25
switch signalType
26
    case 'tones'
27
        % Create pure tone stimulus
28
        dt=1/sampleRate; % seconds
29
        time=dt: dt: duration;
30
        inputSignal=sum(sin(2*pi*toneFrequency'*time), 1);
31
        amp=10^(leveldBSPL/20)*28e-6;   % converts to Pascals (peak)
32
        inputSignal=amp*inputSignal;
33
        % apply ramps
34
        % catch rampTime error
35
        if rampDuration>0.5*duration, rampDuration=duration/2; end
36
        rampTime=dt:dt:rampDuration;
37
        ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ...
38
            ones(1,length(time)-length(rampTime))];
39
        inputSignal=inputSignal.*ramp;
40
        ramp=fliplr(ramp);
41
        inputSignal=inputSignal.*ramp;
42
        % add silence
43
        intialSilence= zeros(1,round(beginSilence/dt));
44
        finalSilence= zeros(1,round(endSilence/dt));
45
        inputSignal= [intialSilence inputSignal finalSilence];
46

  
47
    case 'file'
48
        %% file input simple or mixed
49
        [inputSignal sampleRate]=wavread(fileName);
50
        dt=1/sampleRate;
51
        inputSignal=inputSignal(:,1);
52
        targetRMS=20e-6*10^(leveldBSPL/20);
53
        rms=(mean(inputSignal.^2))^0.5;
54
        amp=targetRMS/rms;
55
        inputSignal=inputSignal*amp;
56
        intialSilence= zeros(1,round(0.1/dt));
57
        finalSilence= zeros(1,round(0.2/dt));
58
        inputSignal= [intialSilence inputSignal' finalSilence];
59
end
60

  
61

  
62
%% run the model
63

  
64
MAP1_14(inputSignal, sampleRate, BFlist, ...
65
    MAPparamsName, AN_spikesOrProbability, paramChanges);
66

  
67
%% the model run is now complete. Now display the results
68
UTIL_showMAP(showMapOptions, paramChanges)
69

  
70
path(restorePath)
71

  
MAP/filteredSACF.m
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).
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
%
6 8
%
7 9
% INPUT
8 10
%  	inputSignalMatrix: a matrix (channel x time) of AN activity
9
%  	method.dt:			the signal sampling interval in seconds
10
%   method.segmentNo:
11
%   method.nonlinCF
12
%   
11
%  	dt:		the signal sampling interval in seconds
12
%   BFlist: channel BFs
13
%
13 14
% 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
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
17 18
%   	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)
23
%
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
%  	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)
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.
29 34

  
30 35
%%
31
boundaryValue=[];
36
global savedInputSignal
37

  
38
ACFboundaryValue=[];
39

  
32 40
[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 41

  
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
44

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

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

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

  
85 82

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

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

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

  
114 111

  
115
P=zeros(nLags,inputLength+1);   % P must match segment length +1
116
sacf=zeros(nLags,inputLength);
112
LP_SACF=zeros(nLags,inputLength+1);   % LP_SACF must match segment length +1
113
SACF=zeros(nLags,inputLength);
114
method=[];  % legacy programming
117 115
if   ~isfield(method,'segmentNumber') || method.segmentNumber==1
118
    acf=zeros(nChannels,nLags);
116
    ACF=zeros(nChannels,nLags);
119 117
    % create a runup buffer of signal
120 118
    buffer= zeros(nChannels, max(lagPointers));
121 119
else
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};
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};
126 125
end
127 126
inputSignalMatrix=[buffer inputSignalMatrix];
128 127
[nChannels inputLength]= size(inputSignalMatrix);
129 128

  
130 129
timeCounter=0; biggestSACF=0;
131 130
for timePointer= max(lagPointers)+1:inputLength
132
    % acf is a continuously changing channels x lags matrix
131
    % ACF is a continuously changing channels x lags matrix
133 132
    %   Only the current value is stored
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
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
136 135
    % lagWeights emphasise some BF/lag combinations and ignore others
137 136
    % NB time now begins at the longest lag.
138
    % E.g. if max(lags) is .04 then this is when the ACf will begin.
139
    %            AN                                       AN delayed                             weights               filtering
140
    
137
    % E.g. if max(lags) is .04 then this is when the ACf will begin (?).
138

  
141 139
    % This is the ACF calculation
142 140
    timeCounter=timeCounter+1;
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;
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;
148 146
    
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)
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
157 177
        time=timePointer*dt;
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')
178
        plot([time time], [a(1) a(1)+(a(2)-a(1))/4], 'r', 'linewidth', 5)
176 179
        pause(params.plotMoviePauses)
177 180
    end
178 181
end
179
P=P(:,1:end-1);  % correction for speed up above
182
LP_SACF=LP_SACF(:,1:end-1);  % correction for speed up above
180 183

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

  
193 196
% wrap up
194
method.acfLags=lags;
195
method.filteredSACFdt=dt;
196

  
197
boundaryValue{1}=acf(:,end-nLags+1:end);
198
boundaryValue{2}=P(:,end);
197
% BoundaryValue is legacy programming used in segmented model (keep)
198
ACFboundaryValue{1}=ACF(:,end-nLags+1:end);
199
ACFboundaryValue{2}=LP_SACF(:,end);
199 200
% save signal buffer for next segment
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)';
225
    % a is the height to be added to each channel
226
    peakGain=10;
227
    % peakGain emphasises the peak height
228
    x=peakGain*toPlot+repmat(a,1,nCols);
229
    x=nRows*x/max(max(x));
230
else
231
    x=toPlot;                            % used when only the stimulus is returned
232
end
233
plot(lags, x','k')
234
ylim([0 nRows])
235

  
201
ACFboundaryValue{3} = inputSignalMatrix(:, end-max(lagPointers)+1 : end);
MAP/old MAP files/MAP1_14AP.m
1

  
2
function  MAP1_14AP(inputSignal, sampleRate, BFlist, MAPparamsName, ...
3
    AN_spikesOrProbability, paramChanges)
4
% To test this function use test_MAP1_14 in this folder
5
%
6
% All arguments are mandatory.
7
%
8
%  BFlist is a vector of BFs but can be '-1' to allow MAPparams to choose
9
%  MAPparamsName='Normal';          % source of model parameters
10
%  AN_spikesOrProbability='spikes'; % or 'probability'
11
%  paramChanges is a cell array of strings that can be used to make last
12
%   minute parameter changes, e.g., to simulate OHC loss
13
%  e.g.  paramChanges{1}= 'DRNLParams.a=0;'; % disable OHCs
14
%  e.g.  paramchanges={};                    % no changes
15
% The model parameters are established in the MAPparams<***> file
16
%  and stored as global
17

  
18
restorePath=path;
19
addpath (['..' filesep 'parameterStore'])
20

  
21

  
22
CONVOLUTION_CHANGE_TEST = 0; %for debug
23

  
24

  
25
global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams
26
global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams
27

  
28
% All of the results of this function are stored as global
29
global dt ANdt  savedBFlist saveAN_spikesOrProbability saveMAPparamsName...
30
    savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ...
31
    DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV...
32
    IHCoutput ANprobRateOutput ANoutput savePavailable tauCas  ...
33
    CNoutput  ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation
34

  
35
% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be
36
% needed by the user; so the following will suffice
37
%   global ANdt ICoutput ANprobRateOutput
38

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

  
44
% When AN_spikesOrProbability is set to probability,
45
%  no spike matrices are computed.
46
% When AN_spikesOrProbability is set to 'spikes',
47
%  no probability output is computed
48

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

  
57
if nargin<1
58
    error(' MAP1_14 is not a script but a function that must be called')
59
end
60

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

  
72
% save as global for later plotting if required
73
savedBFlist=BFlist;
74
saveAN_spikesOrProbability=AN_spikesOrProbability;
75
saveMAPparamsName=MAPparamsName;
76

  
77
dt=1/sampleRate;
78
duration=length(inputSignal)/sampleRate;
79
% segmentDuration is specified in parameter file (must be >efferent delay)
80
segmentDuration=method.segmentDuration;
81
segmentLength=round(segmentDuration/ dt);
82
segmentTime=dt*(1:segmentLength); % used in debugging plots
83

  
84
% all spiking activity is computed using longer epochs
85
ANspeedUpFactor=AN_IHCsynapseParams.ANspeedUpFactor;  % e.g.5 times
86

  
87
% inputSignal must be  row vector
88
[r c]=size(inputSignal);
89
if r>c, inputSignal=inputSignal'; end       % transpose
90
% ignore stereo signals
91
inputSignal=inputSignal(1,:);               % drop any second channel
92
savedInputSignal=inputSignal;
93

  
94
% Segment the signal
95
% The sgment length is given but the signal length must be adjusted to be a
96
% multiple of both the segment length and the reduced segmentlength
97
[nSignalRows signalLength]=size(inputSignal);
98
segmentLength=ceil(segmentLength/ANspeedUpFactor)*ANspeedUpFactor;
99
% Make the signal length a whole multiple of the segment length
100
nSignalSegments=ceil(signalLength/segmentLength);
101
padSize=nSignalSegments*segmentLength-signalLength;
102
pad=zeros(nSignalRows,padSize);
103
inputSignal=[inputSignal pad];
104
[ignore signalLength]=size(inputSignal);
105

  
106
% AN (spikes) is computed at a lower sample rate when spikes required
107
%  so it has a reduced segment length (see 'ANspeeUpFactor' above)
108
% AN CN and IC all use this sample interval
109
ANdt=dt*ANspeedUpFactor;
110
reducedSegmentLength=round(segmentLength/ANspeedUpFactor);
111
reducedSignalLength= round(signalLength/ANspeedUpFactor);
112

  
113
%% Initialise with respect to each stage before computing
114
%  by allocating memory,
115
%  by computing constants
116
%  by establishing easy to read variable names
117
% The computations are made in segments and boundary conditions must
118
%  be established and stored. These are found in variables with
119
%  'boundary' or 'bndry' in the name
120

  
121
%% OME ---
122
% external ear resonances
123
OMEexternalResonanceFilters=OMEParams.externalResonanceFilters;
124
[nOMEExtFilters c]=size(OMEexternalResonanceFilters);
125
% details of external (outer ear) resonances
126
OMEgaindBs=OMEexternalResonanceFilters(:,1);
127
OMEgainScalars=10.^(OMEgaindBs/20);
128
OMEfilterOrder=OMEexternalResonanceFilters(:,2);
129
OMElowerCutOff=OMEexternalResonanceFilters(:,3);
130
OMEupperCutOff=OMEexternalResonanceFilters(:,4);
131
% external resonance coefficients
132
ExtFilter_b=cell(nOMEExtFilters,1);
133
ExtFilter_a=cell(nOMEExtFilters,1);
134
for idx=1:nOMEExtFilters
135
    Nyquist=sampleRate/2;
136
    [b, a] = butter(OMEfilterOrder(idx), ...
137
        [OMElowerCutOff(idx) OMEupperCutOff(idx)]...
138
        /Nyquist);
139
    ExtFilter_b{idx}=b;
140
    ExtFilter_a{idx}=a;
141
end
142
OMEExtFilterBndry=cell(2,1);
143
OMEextEarPressure=zeros(1,signalLength); % pressure at tympanic membrane
144

  
145
% pressure to velocity conversion using smoothing filter (50 Hz cutoff)
146
tau=1/(2*pi*50);
147
a1=dt/tau-1; a0=1;
148
b0=1+ a1;
149
TMdisp_b=b0; TMdisp_a=[a0 a1];
150
% figure(9), freqz(TMdisp_b, TMdisp_a)
151
OME_TMdisplacementBndry=[];
152

  
153
% OME high pass (simulates poor low frequency stapes response)
154
OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff;
155
Nyquist=sampleRate/2;
156
[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high');
157
% figure(10), freqz(stapesDisp_b, stapesDisp_a)
158

  
159
OMEhighPassBndry=[];
160

  
161
% OMEampStapes might be reducdant (use OMEParams.stapesScalar)
162
stapesScalar= OMEParams.stapesScalar;
163

  
164
% Acoustic reflex
165
efferentDelayPts=round(OMEParams.ARdelay/dt);
166
% smoothing filter
167
a1=dt/OMEParams.ARtau-1; a0=1;
168
b0=1+ a1;
169
ARfilt_b=b0; ARfilt_a=[a0 a1];
170

  
171
ARattenuation=ones(1,signalLength);
172
ARrateThreshold=OMEParams.ARrateThreshold; % may not be used
173
ARrateToAttenuationFactor=OMEParams.rateToAttenuationFactor;
174
ARrateToAttenuationFactorProb=OMEParams.rateToAttenuationFactorProb;
175
ARboundary=[];
176
ARboundaryProb=0;
177

  
178
% save complete OME record (stapes displacement)
179
OMEoutput=zeros(1,signalLength);
180
TMoutput=zeros(1,signalLength);
181

  
182
%% BM ---
183
% BM is represented as a list of locations identified by BF
184
DRNL_BFs=BFlist;
185
nBFs= length(DRNL_BFs);
186

  
187
% DRNLchannelParameters=DRNLParams.channelParameters;
188
DRNLresponse= zeros(nBFs, segmentLength);
189

  
190
MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor;
191
rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb;
192
MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb;
193

  
194
% smoothing filter for MOC
195
a1=dt/DRNLParams.MOCtau-1; a0=1;
196
b0=1+ a1;
197
MOCfilt_b=b0; MOCfilt_a=[a0 a1];
198
% figure(9), freqz(stapesDisp_b, stapesDisp_a)
199
MOCboundary=cell(nBFs,1);
200
MOCprobBoundary=cell(nBFs,1);
201

  
202
MOCattSegment=zeros(nBFs,reducedSegmentLength);
203
MOCattenuation=ones(nBFs,signalLength);
204

  
205
if DRNLParams.a>0
206
    DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ...
207
    log10(DRNLParams.b/DRNLParams.a));
208
else
209
    DRNLcompressionThreshold=inf;
210
end
211

  
212
DRNLlinearOrder= DRNLParams.linOrder;
213
DRNLnonlinearOrder= DRNLParams.nonlinOrder;
214

  
215
DRNLa=DRNLParams.a;
216
DRNLb=DRNLParams.b;
217
DRNLc=DRNLParams.c;
218
linGAIN=DRNLParams.g;
219
%
220
% gammatone filter coefficients for linear pathway
221
bw=DRNLParams.linBWs';
222
phi = 2 * pi * bw * dt;
223
cf=DRNLParams.linCFs';
224
theta = 2 * pi * cf * dt;
225
cos_theta = cos(theta);
226
sin_theta = sin(theta);
227
alpha = -exp(-phi).* cos_theta;
228
b0 = ones(nBFs,1);
229
b1 = 2 * alpha;
230
b2 = exp(-2 * phi);
231
z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i;
232
z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i;
233
z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i;
234
tf = (z2 + z3) ./ z1;
235
a0 = abs(tf);
236
a1 = alpha .* a0;
237
GTlin_a = [b0, b1, b2];
238
GTlin_b = [a0, a1];
239
GTlinOrder=DRNLlinearOrder;
240
GTlinBdry=cell(nBFs,GTlinOrder);
241

  
242
% nonlinear gammatone filter coefficients 
243
bw=DRNLParams.nlBWs';
244
phi = 2 * pi * bw * dt;
245
cf=DRNLParams.nonlinCFs';
246
theta = 2 * pi * cf * dt;
247
cos_theta = cos(theta);
248
sin_theta = sin(theta);
249
alpha = -exp(-phi).* cos_theta;
250
b0 = ones(nBFs,1);
251
b1 = 2 * alpha;
252
b2 = exp(-2 * phi);
253
z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i;
254
z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i;
255
z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i;
256
tf = (z2 + z3) ./ z1;
257
a0 = abs(tf);
258
a1 = alpha .* a0;
259
GTnonlin_a = [b0, b1, b2];
260
GTnonlin_b = [a0, a1];
261
GTnonlinOrder=DRNLnonlinearOrder;
262
GTnonlinBdry1=cell(nBFs, GTnonlinOrder);
263
GTnonlinBdry2=cell(nBFs, GTnonlinOrder);
264

  
265
% complete BM record (BM displacement)
266
DRNLoutput=zeros(nBFs, signalLength);
267

  
268

  
269
%% IHC ---
270
% IHC cilia activity and receptor potential
271
% viscous coupling between BM and stereocilia displacement
272
% Nyquist=sampleRate/2;
273
% IHCcutoff=1/(2*pi*IHC_cilia_RPParams.tc);
274
% [IHCciliaFilter_b,IHCciliaFilter_a]=...
275
%     butter(1, IHCcutoff/Nyquist, 'high');
276
a1=dt/IHC_cilia_RPParams.tc-1; a0=1;
277
b0=1+ a1;
278
% high pass (i.e. low pass reversed)
279
IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0;
280
% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a)
281

  
282
IHCciliaBndry=cell(nBFs,1);
283

  
284
% IHC apical conductance (Boltzman function)
285
IHC_C= IHC_cilia_RPParams.C;
286
IHCu0= IHC_cilia_RPParams.u0;
287
IHCu1= IHC_cilia_RPParams.u1;
288
IHCs0= IHC_cilia_RPParams.s0;
289
IHCs1= IHC_cilia_RPParams.s1;
290
IHCGmax= IHC_cilia_RPParams.Gmax;
291
IHCGa= IHC_cilia_RPParams.Ga; % (leakage)
292

  
293
IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1)));
294
IHCrestingCiliaCond=IHCGu0;
295

  
296
% Receptor potential
297
IHC_Cab= IHC_cilia_RPParams.Cab;
298
IHC_Gk= IHC_cilia_RPParams.Gk;
299
IHC_Et= IHC_cilia_RPParams.Et;
300
IHC_Ek= IHC_cilia_RPParams.Ek;
301
IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc;
302

  
303
IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk);
304

  
305
IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage
306
IHC_RP= zeros(nBFs,segmentLength);
307

  
308
% complete record of IHC receptor potential (V)
309
IHCciliaDisplacement= zeros(nBFs,segmentLength);
310
IHCoutput= zeros(nBFs,signalLength);
311
IHC_cilia_output= zeros(nBFs,signalLength);
312

  
313

  
314
%% pre-synapse ---
315
% Each BF is replicated using a different fiber type to make a 'channel'
316
% The number of channels is nBFs x nANfiberTypes
317
% Fiber types are specified in terms of tauCa
318
nANfiberTypes= length(IHCpreSynapseParams.tauCa);
319
tauCas= IHCpreSynapseParams.tauCa;
320
nANchannels= nANfiberTypes*nBFs;
321
synapticCa= zeros(nANchannels,segmentLength);
322

  
323
% Calcium control (more calcium, greater release rate)
324
ECa=IHCpreSynapseParams.ECa;
325
gamma=IHCpreSynapseParams.gamma;
326
beta=IHCpreSynapseParams.beta;
327
tauM=IHCpreSynapseParams.tauM;
328
mICa=zeros(nANchannels,segmentLength);
329
GmaxCa=IHCpreSynapseParams.GmaxCa;
330
synapse_z= IHCpreSynapseParams.z;
331
synapse_power=IHCpreSynapseParams.power;
332

  
333
% tauCa vector is established across channels to allow vectorization
334
%  (one tauCa per channel). Do not confuse with tauCas (one pre fiber type)
335
tauCa=repmat(tauCas, nBFs,1);
336
tauCa=reshape(tauCa, nANchannels, 1);
337

  
338
% presynapse startup values (vectors, length:nANchannels)
339
% proportion (0 - 1) of Ca channels open at IHCrestingV
340
mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)...
341
    *ones(nBFs*nANfiberTypes,1);
342
% corresponding startup currents
343
ICaCurrent= (GmaxCa*mICaCurrent.^3) * (IHCrestingV-ECa);
344
CaCurrent= ICaCurrent.*tauCa;
345

  
346
% vesicle release rate at startup (one per channel)
347
% kt0 is used only at initialisation
348
kt0= -synapse_z * CaCurrent.^synapse_power;
349

  
350

  
351
%% AN ---
352
% each row of the AN matrices represents one AN fiber
353
% The results computed either for probabiities *or* for spikes (not both)
354
% Spikes are necessary if CN and IC are to be computed
355
nFibersPerChannel= AN_IHCsynapseParams.numFibers;
356
nANfibers= nANchannels*nFibersPerChannel;
357
AN_refractory_period= AN_IHCsynapseParams.refractory_period;
358

  
359
y=AN_IHCsynapseParams.y;
360
l=AN_IHCsynapseParams.l;
361
x=AN_IHCsynapseParams.x;
362
r=AN_IHCsynapseParams.r;
363
M=round(AN_IHCsynapseParams.M);
364

  
365
% probability            (NB initial 'P' on everything)
366
PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nANchannels,1);
367
PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nANchannels,1);
368
PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nANchannels,1);
369
PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nANchannels,1);
370
PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt;
371
PAN_M=round(AN_IHCsynapseParams.M);
372

  
373
% compute starting values
374
Pcleft    = kt0* y* M ./ (y*(l+r)+ kt0* l);
375
Pavailable    = Pcleft*(l+r)./kt0;
376
Preprocess    = Pcleft*r/x; % canbe fractional
377

  
378
ANprobability=zeros(nANchannels,segmentLength);
379
ANprobRateOutput=zeros(nANchannels,signalLength);
380
lengthAbsRefractoryP= round(AN_refractory_period/dt);
381
% special variables for monitoring synaptic cleft (specialists only)
382
savePavailableSeg=zeros(nANchannels,segmentLength);
383
savePavailable=zeros(nANchannels,signalLength);
384

  
385
% spikes     % !  !  !    ! !        !   !  !
386
lengthAbsRefractory= round(AN_refractory_period/ANdt);
387

  
388
AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1);
389
AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1);
390
AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1);
391
AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1);
392
AN_rdt_plus_ldt= AN_rdt + AN_ldt;
393
AN_M= round(AN_IHCsynapseParams.M);
394

  
395
% kt0  is initial release rate
396
% Establish as a vector (length=channel x number of fibers)
397
kt0= repmat(kt0', nFibersPerChannel, 1);
398
kt0=reshape(kt0, nANfibers,1);
399

  
400
% starting values for reservoirs
401
AN_cleft    = kt0* y* M ./ (y*(l+r)+ kt0* l);
402
AN_available    = round(AN_cleft*(l+r)./kt0); %must be integer
403
AN_reprocess    = AN_cleft*r/x;
404

  
405
% output is in a logical array spikes = 1/ 0.
406
ANspikes= false(nANfibers,reducedSegmentLength);
407
ANoutput= false(nANfibers,reducedSignalLength);
408

  
409

  
410
%% CN (first brain stem nucleus - could be any subdivision of CN)
411
% Input to a CN neuorn is a random selection of AN fibers within a channel
412
%  The number of AN fibers used is ANfibersFanInToCN
413
% CNtauGk (Potassium time constant) determines the rate of firing of
414
%  the unit when driven hard by a DC input (not normally >350 sp/s)
415
% If there is more than one value, everything is replicated accordingly
416

  
417
ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers;
418
ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron;
419

  
420
CNtauGk=MacGregorMultiParams.tauGk; % row vector of CN types (by tauGk)
421
nCNtauGk=length(CNtauGk);
422

  
423
% the total number of 'channels' is now greater
424
nCNchannels=nANchannels*nCNtauGk;
425

  
426
nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF;
427
tauGk=repmat(CNtauGk, nCNneuronsPerChannel,1);
428
tauGk=reshape(tauGk,nCNneuronsPerChannel*nCNtauGk,1);
429

  
430
% Now the number of neurons has been increased
431
nCNneurons=nCNneuronsPerChannel*nCNchannels;
432
CNmembranePotential=zeros(nCNneurons,reducedSegmentLength);
433

  
434
% establish which ANfibers (by name) feed into which CN nuerons
435
CNinputfiberLists=zeros(nANchannels*nCNneuronsPerChannel, ANfibersFanInToCN);
436
unitNo=1;
437
for ch=1:nANchannels
438
    % Each channel contains a number of units =length(listOfFanInValues)
439
    for idx=1:nCNneuronsPerChannel
440
        for idx2=1:nCNtauGk
441
            fibersUsed=(ch-1)*ANavailableFibersPerChan + ...
442
                ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan);
443
            CNinputfiberLists(unitNo,:)=fibersUsed;
444
            unitNo=unitNo+1;
445
        end
446
    end
447
end
448

  
449
% input to CN units
450
AN_PSTH=zeros(nCNneurons,reducedSegmentLength);
451

  
452
% Generate CNalphaFunction function
453
%  by which spikes are converted to post-synaptic currents
454
CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq;
455
CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike;
456
CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq);
457
t=ANdt:ANdt:5*CNspikeToCurrentTau;
458
CNalphaFunction= (1 / ...
459
    CNspikeToCurrentTau)*t.*exp(-t /CNspikeToCurrentTau);
460
CNalphaFunction=CNalphaFunction*CNcurrentPerSpike;
461

  
462
% figure(98), plot(t,CNalphaFunction)
463
% working memory for implementing convolution
464

  
465
CNcurrentTemp=...
466
    zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1);
467
% trailing alphas are parts of humps carried forward to the next segment
468
CNtrailingAlphas=zeros(nCNneurons,length(CNalphaFunction));
469

  
470
CN_tauM=MacGregorMultiParams.tauM;
471
CN_tauTh=MacGregorMultiParams.tauTh;
472
CN_cap=MacGregorMultiParams.Cap;
473
CN_c=MacGregorMultiParams.c;
474
CN_b=MacGregorMultiParams.dGkSpike;
475
CN_Ek=MacGregorMultiParams.Ek;
476
CN_Eb= MacGregorMultiParams.Eb;
477
CN_Er=MacGregorMultiParams.Er;
478
CN_Th0= MacGregorMultiParams.Th0;
479
CN_E= zeros(nCNneurons,1);
480
CN_Gk= zeros(nCNneurons,1);
481
CN_Th= MacGregorMultiParams.Th0*ones(nCNneurons,1);
482
CN_Eb=CN_Eb.*ones(nCNneurons,1);
483
CN_Er=CN_Er.*ones(nCNneurons,1);
484
CNtimeSinceLastSpike=zeros(nCNneurons,1);
485
% tauGk is the main distinction between neurons
486
%  in fact they are all the same in the standard model
487
tauGk=repmat(tauGk,nANchannels,1);
488

  
489
CNoutput=false(nCNneurons,reducedSignalLength);
490

  
491

  
492
%% MacGregor (IC - second nucleus) --------
493
nICcells=nANchannels*nCNtauGk;  % one cell per channel
494
CN_PSTH=zeros(nICcells ,reducedSegmentLength);
495

  
496
ICspikeWidth=0.00015;   % this may need revisiting
497
epochsPerSpike=round(ICspikeWidth/ANdt);
498
if epochsPerSpike<1
499
    error(['MacGregorMulti: sample rate too low to support ' ...
500
        num2str(ICspikeWidth*1e6) '  microsec spikes']);
501
end
502

  
503
% short names
504
IC_tauM=MacGregorParams.tauM;
505
IC_tauGk=MacGregorParams.tauGk;
506
IC_tauTh=MacGregorParams.tauTh;
507
IC_cap=MacGregorParams.Cap;
508
IC_c=MacGregorParams.c;
509
IC_b=MacGregorParams.dGkSpike;
510
IC_Th0=MacGregorParams.Th0;
511
IC_Ek=MacGregorParams.Ek;
512
IC_Eb= MacGregorParams.Eb;
513
IC_Er=MacGregorParams.Er;
514

  
515
IC_E=zeros(nICcells,1);
516
IC_Gk=zeros(nICcells,1);
517
IC_Th=IC_Th0*ones(nICcells,1);
518

  
519
% Dendritic filtering, all spikes are replaced by CNalphaFunction functions
520
ICdendriteLPfreq= MacGregorParams.dendriteLPfreq;
521
ICcurrentPerSpike=MacGregorParams.currentPerSpike;
522
ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq);
523
t=ANdt:ANdt:3*ICspikeToCurrentTau;
524
IC_CNalphaFunction= (ICcurrentPerSpike / ...
525
    ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau);
526
% figure(98), plot(t,IC_CNalphaFunction)
527

  
528
% working space for implementing alpha function
529
ICcurrentTemp=...
530
    zeros(nICcells,reducedSegmentLength+length(IC_CNalphaFunction)-1);
531
ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction));
532

  
533
ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength);
534
ICoutput=false(nICcells,reducedSignalLength);
535

  
536
ICmembranePotential=zeros(nICcells,reducedSegmentLength);
537
ICmembraneOutput=zeros(nICcells,signalLength);
538

  
539

  
540
%% Main program %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%
541

  
542
%  Compute the entire model for each segment
543
segmentStartPTR=1;
544
reducedSegmentPTR=1; % when sampling rate is reduced
545
while segmentStartPTR<signalLength
546
    segmentEndPTR=segmentStartPTR+segmentLength-1;
547
    % shorter segments after speed up.
548
    shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1;
549

  
550
    inputPressureSegment=inputSignal...
551
        (:,segmentStartPTR:segmentStartPTR+segmentLength-1);
552

  
553
    % segment debugging plots
554
    % figure(98)
555
    % plot(segmentTime,inputPressureSegment), title('signalSegment')
556

  
557

  
558
    % OME ----------------------
559

  
560
    % OME Stage 1: external resonances. Add to inputSignal pressure wave
561
    y=inputPressureSegment;
562
    for n=1:nOMEExtFilters
563
        % any number of resonances can be used
564
        [x  OMEExtFilterBndry{n}] = ...
565
            filter(ExtFilter_b{n},ExtFilter_a{n},...
566
            inputPressureSegment, OMEExtFilterBndry{n});
567
        x= x* OMEgainScalars(n);
568
        % This is a parallel resonance so add it
569
        y=y+x;
570
    end
571
    inputPressureSegment=y;
572
    OMEextEarPressure(segmentStartPTR:segmentEndPTR)= inputPressureSegment;
573
    
574
    % OME stage 2: convert input pressure (velocity) to
575
    %  tympanic membrane(TM) displacement using low pass filter
576
    [TMdisplacementSegment  OME_TMdisplacementBndry] = ...
577
        filter(TMdisp_b,TMdisp_a,inputPressureSegment, ...
578
        OME_TMdisplacementBndry);
579
    % and save it
580
    TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment;
581

  
582
    % OME stage 3: middle ear high pass effect to simulate stapes inertia
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff