Mercurial > hg > map
changeset 35:25d53244d5c8
latest parameters
author | Ray Meddis <rmeddis@essex.ac.uk> |
---|---|
date | Thu, 15 Sep 2011 13:50:20 +0100 |
parents | e097e9044ef6 |
children | 3ea506487b3b |
files | Help and reference data/MAP 1_14 DEVELOPMENT log.doc Help and reference data/MAP1_14 quick reference.doc Help and reference data/May 20 parameters.doc Help and reference data/Meddis Oldenburg 2010.ppt Help and reference data/Surrey Meddis 2010.ppt Help and reference data/model talk 2010.ppt MAP/MAP1_14.m MAP/MAP1_14AP.m MAP/MAP1_14parallel.m MAP/MAPrunner.m MAP/old MAP files/MAP1_14AP.m MAP/old MAP files/MAP1_14parallel.m MAP/temp.m README.md documentation/Hearing dummy Talk.ppt documentation/MAP1_14 quick reference.doc documentation/Model description.doc documentation/MultiThreshold manual.doc documentation/Surrey Meddis 2010.ppt documentation/The multiThreshold guide to getting started.doc documentation/old model talk 2010.ppt multithreshold 1.46/MAP1_14variables.mat multithreshold 1.46/MTprofile10_0hr19_Aug_2011.m multithreshold 1.46/MTprofile17_14hr18_Aug_2011.m multithreshold 1.46/MTprofile17_32hr18_Aug_2011.m multithreshold 1.46/MTprofile17_33hr18_Aug_2011.m multithreshold 1.46/MTprofile17_44hr18_Aug_2011.m multithreshold 1.46/MTprofile7_44hr19_Aug_2011.m multithreshold 1.46/MTprofile8_19hr19_Aug_2011.m multithreshold 1.46/MTprofile8_24hr19_Aug_2011.m multithreshold 1.46/compare.m multithreshold 1.46/compareMicrophonic.m multithreshold 1.46/expGUI_MT.m multithreshold 1.46/nextStimulus.m multithreshold 1.46/paradigms/paradigm_training.m multithreshold 1.46/plotProfile.m multithreshold 1.46/savedData/12-Aug-2011 05_33_35.mat multithreshold 1.46/savedData/12-Aug-2011 05_41_36.mat multithreshold 1.46/savedData/12-Aug-2011 05_48_34.mat multithreshold 1.46/savedData/12-Aug-2011 05_56_54.mat multithreshold 1.46/savedData/12-Aug-2011 06_40_17.mat multithreshold 1.46/savedData/12-Aug-2011 06_56_59.mat multithreshold 1.46/savedData/12-Aug-2011 07_20_14.mat multithreshold 1.46/savedData/12-Aug-2011 07_29_20.mat multithreshold 1.46/savedData/12-Aug-2011 07_43_17.mat multithreshold 1.46/savedData/12-Aug-2011 07_49_00.mat multithreshold 1.46/savedData/mostRecentResults.mat multithreshold 1.46/savedData/profile10_53hr11_Aug_2011.mat multithreshold 1.46/savedData/profile10_55hr11_Aug_2011.mat multithreshold 1.46/subjGUI_MT.m multithreshold 1.46/temp.m parameterStore/MAPparamsNormal.m parameterStore/MAPparamsNormalIC.m testPrograms/LiebermanMOCdata.m testPrograms/LiebermanMOCtest.m testPrograms/demoTwisterProbability.m testPrograms/demoTwisterSpikes.m testPrograms/repeatTester.m testPrograms/temp.m testPrograms/termp.m testPrograms/testAN.m testPrograms/testANprob.m testPrograms/testBM.m testPrograms/testFM.m testPrograms/testOME.m testPrograms/testRP.m testPrograms/test_MAP1_14.m testPrograms/test_speechInNoise.m userFolder/large_CNout120.fig userFolder/waveform_120.fig utilities/UTIL_PSTHmaker.m utilities/UTIL_showMAP.m utilities/enframe.m utilities/stimulusCreate.m |
diffstat | 74 files changed, 3552 insertions(+), 4527 deletions(-) [+] |
line wrap: on
line diff
--- a/MAP/MAP1_14.m Fri Aug 19 16:07:07 2011 +0100 +++ b/MAP/MAP1_14.m Thu Sep 15 13:50:20 2011 +0100 @@ -23,6 +23,15 @@ restorePath=path; addpath (['..' filesep 'parameterStore']) +% clear global -regexp OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams +% clear global -regexp AN_IHCsynapseParams MacGregorParams MacGregorMultiParams +% clear global -regexp dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... +% savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... +% DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... +% IHCoutput ANprobRateOutput ANoutput savePavailable ANtauCas ... +% CNtauGk CNoutput ICoutput ICmembraneOutput ICfiberTypeRates ... +% MOCattenuation + global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams @@ -32,7 +41,8 @@ DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... IHCoutput ANprobRateOutput ANoutput savePavailable ANtauCas ... CNtauGk CNoutput ICoutput ICmembraneOutput ICfiberTypeRates ... - MOCattenuation + MOCattenuation + % Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be % needed by the user; so the following will suffice @@ -192,11 +202,18 @@ MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor; rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb; MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb; +minMOCattenuation=10^(DRNLParams.minMOCattenuationdB/20); % smoothing filter for MOC a1=dt/DRNLParams.MOCtau-1; a0=1; b0=1+ a1; MOCfilt_b=b0; MOCfilt_a=[a0 a1]; + +a1=dt/DRNLParams.MOCtauProb-1; a0=1; +b0=1+ a1; +MOCfiltProb_b=b0; MOCfiltProb_a=[a0 a1]; + + % figure(9), freqz(stapesDisp_b, stapesDisp_a) MOCboundary=cell(nBFs,1); MOCprobBoundary=cell(nBFs,1); @@ -210,14 +227,17 @@ % else % DRNLcompressionThreshold=inf; % end -DRNLcompressionThreshold=DRNLParams.cTh; +% DRNLcompressionThreshold=DRNLParams.cTh; DRNLlinearOrder= DRNLParams.linOrder; DRNLnonlinearOrder= DRNLParams.nonlinOrder; DRNLa=DRNLParams.a; -DRNLb=DRNLParams.b; +% DRNLa2=DRNLParams.a2; +% DRNLb=DRNLParams.b; DRNLc=DRNLParams.c; linGAIN=DRNLParams.g; +CtBM=10e-9*10^(DRNLParams.CtBMdB/20); +CtS=CtBM/DRNLa; % % gammatone filter coefficients for linear pathway bw=DRNLParams.linBWs'; @@ -629,7 +649,8 @@ else % no MOC available yet MOC=ones(1, segmentLength); end - % apply MOC to nonlinear input function + % apply MOC to nonlinear input function +% figure(88), plot(MOC) nonlinOutput=stapesDisplacement.* MOC; % first gammatone filter (nonlin path) @@ -639,47 +660,49 @@ nonlinOutput, GTnonlinBdry1{BFno,order}); end + % Nick's compression algorithm + abs_x = abs(nonlinOutput); + y(abs_x<CtS) = DRNLa * nonlinOutput(abs_x<CtS); + y(abs_x>=CtS) = sign(nonlinOutput(abs_x>=CtS)) * DRNLa * CtS .* ... + exp( DRNLc * log( abs_x(abs_x>=CtS)/CtS ) ); + nonlinOutput=y; + % % original broken stick instantaneous compression -% y= nonlinOutput.* DRNLa; % linear section. +% holdY=nonlinOutput; +% abs_x = abs(nonlinOutput); +% nonlinOutput=sign(nonlinOutput).*min(DRNLa*abs_x, DRNLb*abs_x.^DRNLc); +% + +% % new broken stick instantaneous compression +% y= nonlinOutput.* DRNLa; % linear section attenuation/gain. % % compress parts of the signal above the compression threshold -% abs_x = abs(nonlinOutput); -% idx=find(abs_x>DRNLcompressionThreshold); +% % holdY=y; +% abs_y = abs(y); +% idx=find(abs_y>DRNLcompressionThreshold); % if ~isempty(idx)>0 -% y(idx)=sign(y(idx)).* (DRNLb*abs_x(idx).^DRNLc); +% % y(idx)=sign(y(idx)).* (DRNLcompressionThreshold + ... +% % (abs_y(idx)-DRNLcompressionThreshold).^DRNLc); +% y(idx)=sign(y(idx)).* (DRNLcompressionThreshold + ... +% (abs_y(idx)-DRNLcompressionThreshold)*DRNLa2); % end % nonlinOutput=y; - - % new broken stick instantaneous compression - y= nonlinOutput.* DRNLa; % linear section attenuation/gain. - % compress parts of the signal above the compression threshold -% holdY=y; - abs_y = abs(y); - idx=find(abs_y>DRNLcompressionThreshold); - if ~isempty(idx)>0 -% y(idx)=sign(y(idx)).* (DRNLcompressionThreshold + ... -% (abs_y(idx)-DRNLcompressionThreshold).^DRNLc); - y(idx)=sign(y(idx)).* (DRNLcompressionThreshold + ... - (abs_y(idx)-DRNLcompressionThreshold)*DRNLc); - end - nonlinOutput=y; - -% % Boltzmann compression -% y=(nonlinOutput * DRNLa*100000); -% holdY=y; -% y=abs(y); -% s=10; u=0.0; -% x=1./(1+exp(-(y-u)/s))-0.5; -% nonlinOutput=sign(nonlinOutput).*x/10000; + % % Boltzmann compression function + % y=(nonlinOutput * DRNLa*100000); + % holdY=y; + % y=abs(y); + % s=10; u=0.0; + % x=1./(1+exp(-(y-u)/s))-0.5; + % nonlinOutput=sign(nonlinOutput).*x/10000; -% if segmentStartPTR==10*segmentLength+1 -% figure(90) -% plot(holdY,'b'), hold on -% plot(nonlinOutput, 'r'), hold off -% ylim([-1e-5 1e-5]) -% pause(1) -% end + % if segmentStartPTR==10*segmentLength+1 + % figure(90) + % plot(holdY,'b'), hold on + % plot(nonlinOutput, 'r'), hold off + % ylim([-1e-5 1e-5]) + % pause(1) + % end % second filter removes distortion products for order = 1 : GTnonlinOrder @@ -697,7 +720,7 @@ % figure(98) % if size(DRNLresponse,1)>3 % imagesc(DRNLresponse) % matrix display - % title('DRNLresponse'); % single or double channel response + % title('DRNLresponse'); % else % plot(segmentTime, DRNLresponse) % end @@ -867,23 +890,48 @@ MOCattenuation(:,segmentStartPTR:segmentEndPTR)= ... ones(size(rates))* -rateToAttenuationFactorProb; else + + % Nick's new code +% for idx=1:nBFs +% [smoothedRates, MOCprobBoundary{idx}] = ... +% filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... +% MOCprobBoundary{idx}); +% % smoothedRates=smoothedRates-MOCrateThresholdProb; +% % smoothedRates(smoothedRates<0)=0; +% % x = (1- smoothedRates* rateToAttenuationFactorProb); %ORIGINAL +% +% %NEW !!! +% x = -20*log10( max(smoothedRates/MOCrateThresholdProb,1) )*rateToAttenuationFactorProb; %dB attenuation +% x = 10.^(x/20); +% x = max(x,10^(-35/20)); +% % %ALSO - filter at the end - this will stop rapid attack +% % %and slow decay +% % [x, MOCprobBoundary{idx}] = ... +% % filter(MOCfilt_b, MOCfilt_a, x, ... +% % MOCprobBoundary{idx}); +% +% +% MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... +% x; +% end + + for idx=1:nBFs [smoothedRates, MOCprobBoundary{idx}] = ... - filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... + filter(MOCfiltProb_b, MOCfiltProb_a, rates(idx,:), ... MOCprobBoundary{idx}); smoothedRates=smoothedRates-MOCrateThresholdProb; smoothedRates=max(smoothedRates, 0); x=(1- smoothedRates* rateToAttenuationFactorProb); - x=max(x, 10^(-30/20)); MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= x; end end - MOCattenuation(MOCattenuation<0)=0.001; - - % plot(MOCattenuation) - - + + MOCattenuation(MOCattenuation<minMOCattenuation)= minMOCattenuation; + + % plot(MOCattenuation) + case 'spikes' ANtimeCount=0; % implement speed upt @@ -900,26 +948,18 @@ M_q=AN_M- AN_available; % number of missing vesicles M_q(M_q<0)= 0; % cannot be less than 0 - % AN_N1 converts probability to discrete events - % it considers each event that might occur - % (how many vesicles might be released) - % and returns a count of how many were released - - % slow line -% probabilities= 1-(1-releaseProb).^AN_available; +% probabilities= 1-(1-releaseProb).^AN_available; % slow probabilities= 1-intpow((1-releaseProb), AN_available); ejected= probabilities> rand(length(AN_available),1); reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft; reuptake = AN_rdt.* AN_cleft; - - % slow line -% probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; + +% probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; % slow probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q); reprocessed= probabilities>rand(length(M_q),1); - % slow line -% probabilities= 1-(1-AN_ydt).^M_q; +% probabilities= 1-(1-AN_ydt).^M_q; %slow probabilities= 1-intpow((1-AN_ydt), M_q); replenish= probabilities>rand(length(M_q),1); @@ -1142,6 +1182,7 @@ end ICspikes=ICmembranePotential> -0.01; + %figure(2),plot(ICmembranePotential(2,:)) % now remove any spike that is immediately followed by a spike % NB 'find' works on columns (whence the transposing) ICspikes=ICspikes'; @@ -1165,6 +1206,7 @@ end ICoutput(:,reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes; + % figure(3),plot(ICoutput(2,:)) % store membrane output on original dt scale % do this for single channel models only @@ -1183,31 +1225,35 @@ end ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x; end + % figure(4),plot(ICmembraneOutput(2,:)) % estimate efferent effects. % ARis based on LSR units. LSR channels are 1:nBF - if nANfiberTypes>1 % AR is multi-channel only - ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt; + if nANfiberTypes>1 % use only if model is multi-fiber + ARAttSeg=mean(ICspikes(1:nBFs,:),1)/ANdt; [ARAttSeg, ARboundary] = ... filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary); - ARAttSeg=ARAttSeg-ARrateThreshold; - ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths +% ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths % scale up to dt from ANdt - x= repmat(ARAttSeg, ANspeedUpFactor,1); - x=reshape(x,1,segmentLength); + x= repmat(ARAttSeg, ANspeedUpFactor,1); + x= reshape(x,1,segmentLength); ARattenuation(segmentStartPTR:segmentEndPTR)=... (1-ARrateToAttenuationFactor* x); + % max 60 dB attenuation ARattenuation(ARattenuation<0)=0.001; else - % single channel model; disable AR + % single fiber type; disable AR because no LSR fibers ARattenuation(segmentStartPTR:segmentEndPTR)=... ones(1,segmentLength); end % MOC attenuation using HSR response only - % Separate MOC effect for each BF + % separate MOC effect for each BF + % there is only one unit per channel HSRbegins=nBFs*(nANfiberTypes-1)+1; rates=ICspikes(HSRbegins:end,:)/ANdt; + % figure(4),plot(rates(1,:)) + for idx=1:nBFs [smoothedRates, MOCboundary{idx}] = ... filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... @@ -1219,8 +1265,13 @@ x= reshape(x,1,segmentLength); MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... (1- MOCrateToAttenuationFactor* x); + % figure(4),plot(x) end - MOCattenuation(MOCattenuation<0)=0.04; + % max attenuation is 30 dB + MOCattenuation(MOCattenuation<minMOCattenuation)=... + minMOCattenuation; + % figure(4),plot(MOCattenuation) + % segment debugging % plotInstructions.figureNo=98; % plotInstructions.displaydt=ANdt; @@ -1232,39 +1283,6 @@ segmentStartPTR=segmentStartPTR+segmentLength; reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength; - end % segment -%% apply refractory correction to spike probabilities - -% the probability of a spike's having occurred in the preceding -% refractory window -% pFired= 1 - II(1-p(t)), t= tnow-refractory period: tnow-1 -% we need a running account of cumProb=II(1-p(t)) -% cumProb(t)= cumProb(t-1)*(1-p(t-1))/(1-p(t-refracPeriod)) -% cumProb(0)=0 -% pFired(t)= 1-cumProb(t) -% whence -% p(t)= ANprobOutput(t) * pFired(t) -% where ANprobOutput is the uncorrected probability - - -% switch AN_spikesOrProbability -% case 'probability' -% ANprobOutput=ANprobRateOutput*dt; -% [r nEpochs]=size(ANprobOutput); -% % find probability of no spikes in refractory period -% pNoSpikesInRefrac=ones(size(ANprobOutput)); -% pSpike=zeros(size(ANprobOutput)); -% for epochNo=lengthAbsRefractoryP+2:nEpochs -% pNoSpikesInRefrac(:,epochNo)=... -% pNoSpikesInRefrac(:,epochNo-2)... -% .*(1-pSpike(:,epochNo-1))... -% ./(1-pSpike(:,epochNo-lengthAbsRefractoryP-1)); -% pSpike(:,epochNo)= ANprobOutput(:,epochNo)... -% .*pNoSpikesInRefrac(:,epochNo); -% end -% ANprobRateOutput=pSpike/dt; -% end - path(restorePath)
--- a/MAP/MAP1_14AP.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1254 +0,0 @@ - -function MAP1_14AP(inputSignal, sampleRate, BFlist, MAPparamsName, ... - AN_spikesOrProbability, paramChanges) -% To test this function use test_MAP1_14 in this folder -% -% All arguments are mandatory. -% -% BFlist is a vector of BFs but can be '-1' to allow MAPparams to choose -% MAPparamsName='Normal'; % source of model parameters -% AN_spikesOrProbability='spikes'; % or 'probability' -% paramChanges is a cell array of strings that can be used to make last -% minute parameter changes, e.g., to simulate OHC loss -% e.g. paramChanges{1}= 'DRNLParams.a=0;'; % disable OHCs -% e.g. paramchanges={}; % no changes -% The model parameters are established in the MAPparams<***> file -% and stored as global - -restorePath=path; -addpath (['..' filesep 'parameterStore']) - - -CONVOLUTION_CHANGE_TEST = 0; %for debug - - -global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams -global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams - -% All of the results of this function are stored as global -global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... - savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... - DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... - IHCoutput ANprobRateOutput ANoutput savePavailable tauCas ... - CNoutput ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation - -% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be -% needed by the user; so the following will suffice -% global ANdt ICoutput ANprobRateOutput - -% Note that sampleRate has not changed from the original function call and -% ANprobRateOutput is sampled at this rate -% However ANoutput, CNoutput and IC output are stored as logical -% 'spike' matrices using a lower sample rate (see ANdt). - -% When AN_spikesOrProbability is set to probability, -% no spike matrices are computed. -% When AN_spikesOrProbability is set to 'spikes', -% no probability output is computed - -% Efferent control variables are ARattenuation and MOCattenuation -% These are scalars between 1 (no attenuation) and 0. -% They are represented with dt=1/sampleRate (not ANdt) -% They are computed using either AN probability rate output -% or IC (spikes) output as approrpriate. -% AR is computed using across channel activity -% MOC is computed on a within-channel basis. - -if nargin<1 - error(' MAP1_14 is not a script but a function that must be called') -end - -if nargin<6 - paramChanges=[]; -end -% Read parameters from MAPparams<***> file in 'parameterStore' folder -% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<> -% It means that the calling program allows MAPparams to specify the list -cmd=['method=MAPparams' MAPparamsName ... - '(BFlist, sampleRate, 0, paramChanges);']; -eval(cmd); -BFlist=DRNLParams.nonlinCFs; - -% save as global for later plotting if required -savedBFlist=BFlist; -saveAN_spikesOrProbability=AN_spikesOrProbability; -saveMAPparamsName=MAPparamsName; - -dt=1/sampleRate; -duration=length(inputSignal)/sampleRate; -% segmentDuration is specified in parameter file (must be >efferent delay) -segmentDuration=method.segmentDuration; -segmentLength=round(segmentDuration/ dt); -segmentTime=dt*(1:segmentLength); % used in debugging plots - -% all spiking activity is computed using longer epochs -ANspeedUpFactor=AN_IHCsynapseParams.ANspeedUpFactor; % e.g.5 times - -% inputSignal must be row vector -[r c]=size(inputSignal); -if r>c, inputSignal=inputSignal'; end % transpose -% ignore stereo signals -inputSignal=inputSignal(1,:); % drop any second channel -savedInputSignal=inputSignal; - -% Segment the signal -% The sgment length is given but the signal length must be adjusted to be a -% multiple of both the segment length and the reduced segmentlength -[nSignalRows signalLength]=size(inputSignal); -segmentLength=ceil(segmentLength/ANspeedUpFactor)*ANspeedUpFactor; -% Make the signal length a whole multiple of the segment length -nSignalSegments=ceil(signalLength/segmentLength); -padSize=nSignalSegments*segmentLength-signalLength; -pad=zeros(nSignalRows,padSize); -inputSignal=[inputSignal pad]; -[ignore signalLength]=size(inputSignal); - -% AN (spikes) is computed at a lower sample rate when spikes required -% so it has a reduced segment length (see 'ANspeeUpFactor' above) -% AN CN and IC all use this sample interval -ANdt=dt*ANspeedUpFactor; -reducedSegmentLength=round(segmentLength/ANspeedUpFactor); -reducedSignalLength= round(signalLength/ANspeedUpFactor); - -%% Initialise with respect to each stage before computing -% by allocating memory, -% by computing constants -% by establishing easy to read variable names -% The computations are made in segments and boundary conditions must -% be established and stored. These are found in variables with -% 'boundary' or 'bndry' in the name - -%% OME --- -% external ear resonances -OMEexternalResonanceFilters=OMEParams.externalResonanceFilters; -[nOMEExtFilters c]=size(OMEexternalResonanceFilters); -% details of external (outer ear) resonances -OMEgaindBs=OMEexternalResonanceFilters(:,1); -OMEgainScalars=10.^(OMEgaindBs/20); -OMEfilterOrder=OMEexternalResonanceFilters(:,2); -OMElowerCutOff=OMEexternalResonanceFilters(:,3); -OMEupperCutOff=OMEexternalResonanceFilters(:,4); -% external resonance coefficients -ExtFilter_b=cell(nOMEExtFilters,1); -ExtFilter_a=cell(nOMEExtFilters,1); -for idx=1:nOMEExtFilters - Nyquist=sampleRate/2; - [b, a] = butter(OMEfilterOrder(idx), ... - [OMElowerCutOff(idx) OMEupperCutOff(idx)]... - /Nyquist); - ExtFilter_b{idx}=b; - ExtFilter_a{idx}=a; -end -OMEExtFilterBndry=cell(2,1); -OMEextEarPressure=zeros(1,signalLength); % pressure at tympanic membrane - -% pressure to velocity conversion using smoothing filter (50 Hz cutoff) -tau=1/(2*pi*50); -a1=dt/tau-1; a0=1; -b0=1+ a1; -TMdisp_b=b0; TMdisp_a=[a0 a1]; -% figure(9), freqz(TMdisp_b, TMdisp_a) -OME_TMdisplacementBndry=[]; - -% OME high pass (simulates poor low frequency stapes response) -OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff; -Nyquist=sampleRate/2; -[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high'); -% figure(10), freqz(stapesDisp_b, stapesDisp_a) - -OMEhighPassBndry=[]; - -% OMEampStapes might be reducdant (use OMEParams.stapesScalar) -stapesScalar= OMEParams.stapesScalar; - -% Acoustic reflex -efferentDelayPts=round(OMEParams.ARdelay/dt); -% smoothing filter -a1=dt/OMEParams.ARtau-1; a0=1; -b0=1+ a1; -ARfilt_b=b0; ARfilt_a=[a0 a1]; - -ARattenuation=ones(1,signalLength); -ARrateThreshold=OMEParams.ARrateThreshold; % may not be used -ARrateToAttenuationFactor=OMEParams.rateToAttenuationFactor; -ARrateToAttenuationFactorProb=OMEParams.rateToAttenuationFactorProb; -ARboundary=[]; -ARboundaryProb=0; - -% save complete OME record (stapes displacement) -OMEoutput=zeros(1,signalLength); -TMoutput=zeros(1,signalLength); - -%% BM --- -% BM is represented as a list of locations identified by BF -DRNL_BFs=BFlist; -nBFs= length(DRNL_BFs); - -% DRNLchannelParameters=DRNLParams.channelParameters; -DRNLresponse= zeros(nBFs, segmentLength); - -MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor; -rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb; -MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb; - -% smoothing filter for MOC -a1=dt/DRNLParams.MOCtau-1; a0=1; -b0=1+ a1; -MOCfilt_b=b0; MOCfilt_a=[a0 a1]; -% figure(9), freqz(stapesDisp_b, stapesDisp_a) -MOCboundary=cell(nBFs,1); -MOCprobBoundary=cell(nBFs,1); - -MOCattSegment=zeros(nBFs,reducedSegmentLength); -MOCattenuation=ones(nBFs,signalLength); - -if DRNLParams.a>0 - DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ... - log10(DRNLParams.b/DRNLParams.a)); -else - DRNLcompressionThreshold=inf; -end - -DRNLlinearOrder= DRNLParams.linOrder; -DRNLnonlinearOrder= DRNLParams.nonlinOrder; - -DRNLa=DRNLParams.a; -DRNLb=DRNLParams.b; -DRNLc=DRNLParams.c; -linGAIN=DRNLParams.g; -% -% gammatone filter coefficients for linear pathway -bw=DRNLParams.linBWs'; -phi = 2 * pi * bw * dt; -cf=DRNLParams.linCFs'; -theta = 2 * pi * cf * dt; -cos_theta = cos(theta); -sin_theta = sin(theta); -alpha = -exp(-phi).* cos_theta; -b0 = ones(nBFs,1); -b1 = 2 * alpha; -b2 = exp(-2 * phi); -z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; -z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; -z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; -tf = (z2 + z3) ./ z1; -a0 = abs(tf); -a1 = alpha .* a0; -GTlin_a = [b0, b1, b2]; -GTlin_b = [a0, a1]; -GTlinOrder=DRNLlinearOrder; -GTlinBdry=cell(nBFs,GTlinOrder); - -% nonlinear gammatone filter coefficients -bw=DRNLParams.nlBWs'; -phi = 2 * pi * bw * dt; -cf=DRNLParams.nonlinCFs'; -theta = 2 * pi * cf * dt; -cos_theta = cos(theta); -sin_theta = sin(theta); -alpha = -exp(-phi).* cos_theta; -b0 = ones(nBFs,1); -b1 = 2 * alpha; -b2 = exp(-2 * phi); -z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; -z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; -z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; -tf = (z2 + z3) ./ z1; -a0 = abs(tf); -a1 = alpha .* a0; -GTnonlin_a = [b0, b1, b2]; -GTnonlin_b = [a0, a1]; -GTnonlinOrder=DRNLnonlinearOrder; -GTnonlinBdry1=cell(nBFs, GTnonlinOrder); -GTnonlinBdry2=cell(nBFs, GTnonlinOrder); - -% complete BM record (BM displacement) -DRNLoutput=zeros(nBFs, signalLength); - - -%% IHC --- -% IHC cilia activity and receptor potential -% viscous coupling between BM and stereocilia displacement -% Nyquist=sampleRate/2; -% IHCcutoff=1/(2*pi*IHC_cilia_RPParams.tc); -% [IHCciliaFilter_b,IHCciliaFilter_a]=... -% butter(1, IHCcutoff/Nyquist, 'high'); -a1=dt/IHC_cilia_RPParams.tc-1; a0=1; -b0=1+ a1; -% high pass (i.e. low pass reversed) -IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0; -% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a) - -IHCciliaBndry=cell(nBFs,1); - -% IHC apical conductance (Boltzman function) -IHC_C= IHC_cilia_RPParams.C; -IHCu0= IHC_cilia_RPParams.u0; -IHCu1= IHC_cilia_RPParams.u1; -IHCs0= IHC_cilia_RPParams.s0; -IHCs1= IHC_cilia_RPParams.s1; -IHCGmax= IHC_cilia_RPParams.Gmax; -IHCGa= IHC_cilia_RPParams.Ga; % (leakage) - -IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1))); -IHCrestingCiliaCond=IHCGu0; - -% Receptor potential -IHC_Cab= IHC_cilia_RPParams.Cab; -IHC_Gk= IHC_cilia_RPParams.Gk; -IHC_Et= IHC_cilia_RPParams.Et; -IHC_Ek= IHC_cilia_RPParams.Ek; -IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc; - -IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk); - -IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage -IHC_RP= zeros(nBFs,segmentLength); - -% complete record of IHC receptor potential (V) -IHCciliaDisplacement= zeros(nBFs,segmentLength); -IHCoutput= zeros(nBFs,signalLength); -IHC_cilia_output= zeros(nBFs,signalLength); - - -%% pre-synapse --- -% Each BF is replicated using a different fiber type to make a 'channel' -% The number of channels is nBFs x nANfiberTypes -% Fiber types are specified in terms of tauCa -nANfiberTypes= length(IHCpreSynapseParams.tauCa); -tauCas= IHCpreSynapseParams.tauCa; -nANchannels= nANfiberTypes*nBFs; -synapticCa= zeros(nANchannels,segmentLength); - -% Calcium control (more calcium, greater release rate) -ECa=IHCpreSynapseParams.ECa; -gamma=IHCpreSynapseParams.gamma; -beta=IHCpreSynapseParams.beta; -tauM=IHCpreSynapseParams.tauM; -mICa=zeros(nANchannels,segmentLength); -GmaxCa=IHCpreSynapseParams.GmaxCa; -synapse_z= IHCpreSynapseParams.z; -synapse_power=IHCpreSynapseParams.power; - -% tauCa vector is established across channels to allow vectorization -% (one tauCa per channel). Do not confuse with tauCas (one pre fiber type) -tauCa=repmat(tauCas, nBFs,1); -tauCa=reshape(tauCa, nANchannels, 1); - -% presynapse startup values (vectors, length:nANchannels) -% proportion (0 - 1) of Ca channels open at IHCrestingV -mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)... - *ones(nBFs*nANfiberTypes,1); -% corresponding startup currents -ICaCurrent= (GmaxCa*mICaCurrent.^3) * (IHCrestingV-ECa); -CaCurrent= ICaCurrent.*tauCa; - -% vesicle release rate at startup (one per channel) -% kt0 is used only at initialisation -kt0= -synapse_z * CaCurrent.^synapse_power; - - -%% AN --- -% each row of the AN matrices represents one AN fiber -% The results computed either for probabiities *or* for spikes (not both) -% Spikes are necessary if CN and IC are to be computed -nFibersPerChannel= AN_IHCsynapseParams.numFibers; -nANfibers= nANchannels*nFibersPerChannel; -AN_refractory_period= AN_IHCsynapseParams.refractory_period; - -y=AN_IHCsynapseParams.y; -l=AN_IHCsynapseParams.l; -x=AN_IHCsynapseParams.x; -r=AN_IHCsynapseParams.r; -M=round(AN_IHCsynapseParams.M); - -% probability (NB initial 'P' on everything) -PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nANchannels,1); -PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nANchannels,1); -PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nANchannels,1); -PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nANchannels,1); -PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt; -PAN_M=round(AN_IHCsynapseParams.M); - -% compute starting values -Pcleft = kt0* y* M ./ (y*(l+r)+ kt0* l); -Pavailable = Pcleft*(l+r)./kt0; -Preprocess = Pcleft*r/x; % canbe fractional - -ANprobability=zeros(nANchannels,segmentLength); -ANprobRateOutput=zeros(nANchannels,signalLength); -lengthAbsRefractoryP= round(AN_refractory_period/dt); -% special variables for monitoring synaptic cleft (specialists only) -savePavailableSeg=zeros(nANchannels,segmentLength); -savePavailable=zeros(nANchannels,signalLength); - -% spikes % ! ! ! ! ! ! ! ! -lengthAbsRefractory= round(AN_refractory_period/ANdt); - -AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1); -AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1); -AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1); -AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1); -AN_rdt_plus_ldt= AN_rdt + AN_ldt; -AN_M= round(AN_IHCsynapseParams.M); - -% kt0 is initial release rate -% Establish as a vector (length=channel x number of fibers) -kt0= repmat(kt0', nFibersPerChannel, 1); -kt0=reshape(kt0, nANfibers,1); - -% starting values for reservoirs -AN_cleft = kt0* y* M ./ (y*(l+r)+ kt0* l); -AN_available = round(AN_cleft*(l+r)./kt0); %must be integer -AN_reprocess = AN_cleft*r/x; - -% output is in a logical array spikes = 1/ 0. -ANspikes= false(nANfibers,reducedSegmentLength); -ANoutput= false(nANfibers,reducedSignalLength); - - -%% CN (first brain stem nucleus - could be any subdivision of CN) -% Input to a CN neuorn is a random selection of AN fibers within a channel -% The number of AN fibers used is ANfibersFanInToCN -% CNtauGk (Potassium time constant) determines the rate of firing of -% the unit when driven hard by a DC input (not normally >350 sp/s) -% If there is more than one value, everything is replicated accordingly - -ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers; -ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron; - -CNtauGk=MacGregorMultiParams.tauGk; % row vector of CN types (by tauGk) -nCNtauGk=length(CNtauGk); - -% the total number of 'channels' is now greater -nCNchannels=nANchannels*nCNtauGk; - -nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF; -tauGk=repmat(CNtauGk, nCNneuronsPerChannel,1); -tauGk=reshape(tauGk,nCNneuronsPerChannel*nCNtauGk,1); - -% Now the number of neurons has been increased -nCNneurons=nCNneuronsPerChannel*nCNchannels; -CNmembranePotential=zeros(nCNneurons,reducedSegmentLength); - -% establish which ANfibers (by name) feed into which CN nuerons -CNinputfiberLists=zeros(nANchannels*nCNneuronsPerChannel, ANfibersFanInToCN); -unitNo=1; -for ch=1:nANchannels - % Each channel contains a number of units =length(listOfFanInValues) - for idx=1:nCNneuronsPerChannel - for idx2=1:nCNtauGk - fibersUsed=(ch-1)*ANavailableFibersPerChan + ... - ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan); - CNinputfiberLists(unitNo,:)=fibersUsed; - unitNo=unitNo+1; - end - end -end - -% input to CN units -AN_PSTH=zeros(nCNneurons,reducedSegmentLength); - -% Generate CNalphaFunction function -% by which spikes are converted to post-synaptic currents -CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq; -CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike; -CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq); -t=ANdt:ANdt:5*CNspikeToCurrentTau; -CNalphaFunction= (1 / ... - CNspikeToCurrentTau)*t.*exp(-t /CNspikeToCurrentTau); -CNalphaFunction=CNalphaFunction*CNcurrentPerSpike; - -% figure(98), plot(t,CNalphaFunction) -% working memory for implementing convolution - -CNcurrentTemp=... - zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1); -% trailing alphas are parts of humps carried forward to the next segment -CNtrailingAlphas=zeros(nCNneurons,length(CNalphaFunction)); - -CN_tauM=MacGregorMultiParams.tauM; -CN_tauTh=MacGregorMultiParams.tauTh; -CN_cap=MacGregorMultiParams.Cap; -CN_c=MacGregorMultiParams.c; -CN_b=MacGregorMultiParams.dGkSpike; -CN_Ek=MacGregorMultiParams.Ek; -CN_Eb= MacGregorMultiParams.Eb; -CN_Er=MacGregorMultiParams.Er; -CN_Th0= MacGregorMultiParams.Th0; -CN_E= zeros(nCNneurons,1); -CN_Gk= zeros(nCNneurons,1); -CN_Th= MacGregorMultiParams.Th0*ones(nCNneurons,1); -CN_Eb=CN_Eb.*ones(nCNneurons,1); -CN_Er=CN_Er.*ones(nCNneurons,1); -CNtimeSinceLastSpike=zeros(nCNneurons,1); -% tauGk is the main distinction between neurons -% in fact they are all the same in the standard model -tauGk=repmat(tauGk,nANchannels,1); - -CNoutput=false(nCNneurons,reducedSignalLength); - - -%% MacGregor (IC - second nucleus) -------- -nICcells=nANchannels*nCNtauGk; % one cell per channel -CN_PSTH=zeros(nICcells ,reducedSegmentLength); - -ICspikeWidth=0.00015; % this may need revisiting -epochsPerSpike=round(ICspikeWidth/ANdt); -if epochsPerSpike<1 - error(['MacGregorMulti: sample rate too low to support ' ... - num2str(ICspikeWidth*1e6) ' microsec spikes']); -end - -% short names -IC_tauM=MacGregorParams.tauM; -IC_tauGk=MacGregorParams.tauGk; -IC_tauTh=MacGregorParams.tauTh; -IC_cap=MacGregorParams.Cap; -IC_c=MacGregorParams.c; -IC_b=MacGregorParams.dGkSpike; -IC_Th0=MacGregorParams.Th0; -IC_Ek=MacGregorParams.Ek; -IC_Eb= MacGregorParams.Eb; -IC_Er=MacGregorParams.Er; - -IC_E=zeros(nICcells,1); -IC_Gk=zeros(nICcells,1); -IC_Th=IC_Th0*ones(nICcells,1); - -% Dendritic filtering, all spikes are replaced by CNalphaFunction functions -ICdendriteLPfreq= MacGregorParams.dendriteLPfreq; -ICcurrentPerSpike=MacGregorParams.currentPerSpike; -ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq); -t=ANdt:ANdt:3*ICspikeToCurrentTau; -IC_CNalphaFunction= (ICcurrentPerSpike / ... - ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau); -% figure(98), plot(t,IC_CNalphaFunction) - -% working space for implementing alpha function -ICcurrentTemp=... - zeros(nICcells,reducedSegmentLength+length(IC_CNalphaFunction)-1); -ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction)); - -ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength); -ICoutput=false(nICcells,reducedSignalLength); - -ICmembranePotential=zeros(nICcells,reducedSegmentLength); -ICmembraneOutput=zeros(nICcells,signalLength); - - -%% Main program %% %% %% %% %% %% %% %% %% %% %% %% %% %% - -% Compute the entire model for each segment -segmentStartPTR=1; -reducedSegmentPTR=1; % when sampling rate is reduced -while segmentStartPTR<signalLength - segmentEndPTR=segmentStartPTR+segmentLength-1; - % shorter segments after speed up. - shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1; - - inputPressureSegment=inputSignal... - (:,segmentStartPTR:segmentStartPTR+segmentLength-1); - - % segment debugging plots - % figure(98) - % plot(segmentTime,inputPressureSegment), title('signalSegment') - - - % OME ---------------------- - - % OME Stage 1: external resonances. Add to inputSignal pressure wave - y=inputPressureSegment; - for n=1:nOMEExtFilters - % any number of resonances can be used - [x OMEExtFilterBndry{n}] = ... - filter(ExtFilter_b{n},ExtFilter_a{n},... - inputPressureSegment, OMEExtFilterBndry{n}); - x= x* OMEgainScalars(n); - % This is a parallel resonance so add it - y=y+x; - end - inputPressureSegment=y; - OMEextEarPressure(segmentStartPTR:segmentEndPTR)= inputPressureSegment; - - % OME stage 2: convert input pressure (velocity) to - % tympanic membrane(TM) displacement using low pass filter - [TMdisplacementSegment OME_TMdisplacementBndry] = ... - filter(TMdisp_b,TMdisp_a,inputPressureSegment, ... - OME_TMdisplacementBndry); - % and save it - TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment; - - % OME stage 3: middle ear high pass effect to simulate stapes inertia - [stapesDisplacement OMEhighPassBndry] = ... - filter(stapesDisp_b,stapesDisp_a,TMdisplacementSegment, ... - OMEhighPassBndry); - - % OME stage 4: apply stapes scalar - stapesDisplacement=stapesDisplacement*stapesScalar; - - % OME stage 5: acoustic reflex stapes attenuation - % Attenuate the TM response using feedback from LSR fiber activity - if segmentStartPTR>efferentDelayPts - stapesDisplacement= stapesDisplacement.*... - ARattenuation(segmentStartPTR-efferentDelayPts:... - segmentEndPTR-efferentDelayPts); - end - - % segment debugging plots - % figure(98) - % plot(segmentTime, stapesDisplacement), title ('stapesDisplacement') - - % and save - OMEoutput(segmentStartPTR:segmentEndPTR)= stapesDisplacement; - - - %% BM ------------------------------ - % Each location is computed separately - for BFno=1:nBFs - - % *linear* path - linOutput = stapesDisplacement * linGAIN; % linear gain - for order = 1 : GTlinOrder - [linOutput GTlinBdry{BFno,order}] = ... - filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry{BFno,order}); - end - - % *nonLinear* path - % efferent attenuation (0 <> 1) - if segmentStartPTR>efferentDelayPts - MOC=MOCattenuation(BFno, segmentStartPTR-efferentDelayPts:... - segmentEndPTR-efferentDelayPts); - else % no MOC available yet - MOC=ones(1, segmentLength); - end - % apply MOC to nonlinear input function - nonlinOutput=stapesDisplacement.* MOC; - - % first gammatone filter (nonlin path) - for order = 1 : GTnonlinOrder - [nonlinOutput GTnonlinBdry1{BFno,order}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - nonlinOutput, GTnonlinBdry1{BFno,order}); - end - % broken stick instantaneous compression - y= nonlinOutput.* DRNLa; % linear section. - % compress parts of the signal above the compression threshold - abs_x = abs(nonlinOutput); - idx=find(abs_x>DRNLcompressionThreshold); - if ~isempty(idx)>0 - y(idx)=sign(y(idx)).* (DRNLb*abs_x(idx).^DRNLc); - end - nonlinOutput=y; - - % second filter removes distortion products - for order = 1 : GTnonlinOrder - [ nonlinOutput GTnonlinBdry2{BFno,order}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - nonlinOutput, GTnonlinBdry2{BFno,order}); - end - - % combine the two paths to give the DRNL displacement - DRNLresponse(BFno,:)=linOutput+nonlinOutput; - end % BF - - % segment debugging plots - % figure(98) - % if size(DRNLresponse,1)>3 - % imagesc(DRNLresponse) % matrix display - % title('DRNLresponse'); % single or double channel response - % else - % plot(segmentTime, DRNLresponse) - % end - - % and save it - DRNLoutput(:, segmentStartPTR:segmentEndPTR)= DRNLresponse; - - - %% IHC ------------------------------------ - % BM displacement to IHCciliaDisplacement is a high-pass filter - % because of viscous coupling - for idx=1:nBFs - [IHCciliaDisplacement(idx,:) IHCciliaBndry{idx}] = ... - filter(IHCciliaFilter_b,IHCciliaFilter_a, ... - DRNLresponse(idx,:), IHCciliaBndry{idx}); - end - - % apply scalar - IHCciliaDisplacement=IHCciliaDisplacement* IHC_C; - - % and save it - IHC_cilia_output(:,segmentStartPTR:segmentStartPTR+segmentLength-1)=... - IHCciliaDisplacement; - - % compute apical conductance - G=IHCGmax./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*... - (1+exp(-(IHCciliaDisplacement-IHCu1)/IHCs1))); - Gu=G + IHCGa; - - % Compute receptor potential - for idx=1:segmentLength - IHC_Vnow=IHC_Vnow+ (-Gu(:, idx).*(IHC_Vnow-IHC_Et)-... - IHC_Gk*(IHC_Vnow-IHC_Ekp))* dt/IHC_Cab; - IHC_RP(:,idx)=IHC_Vnow; - end - - % segment debugging plots - % if size(IHC_RP,1)>3 - % surf(IHC_RP), shading interp, title('IHC_RP') - % else - % plot(segmentTime, IHC_RP) - % end - - % and save it - IHCoutput(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=IHC_RP; - - - %% synapse ----------------------------- - % Compute the vesicle release rate for each fiber type at each BF - % replicate IHC_RP for each fiber type - Vsynapse=repmat(IHC_RP, nANfiberTypes,1); - - % look-up table of target fraction channels open for a given IHC_RP - mICaINF= 1./( 1 + exp(-gamma * Vsynapse) /beta); - % fraction of channel open - apply time constant - for idx=1:segmentLength - % mICaINF is the current 'target' value of mICa - mICaCurrent=mICaCurrent+(mICaINF(:,idx)-mICaCurrent)*dt./tauM; - mICa(:,idx)=mICaCurrent; - end - - ICa= (GmaxCa* mICa.^3) .* (Vsynapse- ECa); - - for idx=1:segmentLength - CaCurrent=CaCurrent + ICa(:,idx)*dt - CaCurrent*dt./tauCa; - synapticCa(:,idx)=CaCurrent; - end - synapticCa=-synapticCa; % treat IHCpreSynapseParams as positive substance - - % NB vesicleReleaseRate is /s and is independent of dt - vesicleReleaseRate = synapse_z * synapticCa.^synapse_power; % rate - - % segment debugging plots - % if size(vesicleReleaseRate,1)>3 - % surf(vesicleReleaseRate), shading interp, title('vesicleReleaseRate') - % else - % plot(segmentTime, vesicleReleaseRate) - % end - - - %% AN - switch AN_spikesOrProbability - case 'probability' - % No refractory effect is applied - for t = 1:segmentLength; - M_Pq=PAN_M-Pavailable; - M_Pq(M_Pq<0)=0; - Preplenish = M_Pq .* PAN_ydt; - Pejected = Pavailable.* vesicleReleaseRate(:,t)*dt; - Preprocessed = M_Pq.*Preprocess.* PAN_xdt; - - ANprobability(:,t)= min(Pejected,1); - reuptakeandlost= PAN_rdt_plus_ldt .* Pcleft; - reuptake= PAN_rdt.* Pcleft; - - Pavailable= Pavailable+ Preplenish- Pejected+ Preprocessed; - Pcleft= Pcleft + Pejected - reuptakeandlost; - Preprocess= Preprocess + reuptake - Preprocessed; - Pavailable(Pavailable<0)=0; - savePavailableSeg(:,t)=Pavailable; % synapse tracking - end - % and save it as *rate* - ANrate=ANprobability/dt; - ANprobRateOutput(:, segmentStartPTR:... - segmentStartPTR+segmentLength-1)= ANrate; - % monitor synapse contents (only sometimes used) - savePavailable(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=... - savePavailableSeg; - - % Estimate efferent effects. ARattenuation (0 <> 1) - % acoustic reflex - [r c]=size(ANrate); - if r>nBFs % Only if LSR fibers are computed - ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF - % smooth - [ARAttSeg, ARboundaryProb] = ... - filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb); - ARAttSeg=ARAttSeg-ARrateThreshold; - ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths - ARattenuation(segmentStartPTR:segmentEndPTR)=... - (1-ARrateToAttenuationFactorProb.* ARAttSeg); - end - % plot(ARattenuation) - - % MOC attenuation - % within-channel HSR response only - HSRbegins=nBFs*(nANfiberTypes-1)+1; - rates=ANrate(HSRbegins:end,:); - if rateToAttenuationFactorProb<0 - % negative factor implies a fixed attenuation - MOCattenuation(:,segmentStartPTR:segmentEndPTR)= ... - ones(size(rates))* -rateToAttenuationFactorProb; - else - for idx=1:nBFs - [smoothedRates, MOCprobBoundary{idx}] = ... - filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... - MOCprobBoundary{idx}); - smoothedRates=smoothedRates-MOCrateThresholdProb; - smoothedRates(smoothedRates<0)=0; - MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... - (1- smoothedRates* rateToAttenuationFactorProb); - end - end - MOCattenuation(MOCattenuation<0)=0.001; - - % plot(MOCattenuation) - - - case 'spikes' - ANtimeCount=0; - % implement speed upt - for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength; - ANtimeCount=ANtimeCount+1; - % convert release rate to probabilities - releaseProb=vesicleReleaseRate(:,t)*ANdt; - % releaseProb is the release probability per channel - % but each channel has many synapses - releaseProb=repmat(releaseProb',nFibersPerChannel,1); - releaseProb=reshape(releaseProb, nFibersPerChannel*nANchannels,1); - - % AN_available=round(AN_available); % vesicles must be integer, (?needed) - M_q=AN_M- AN_available; % number of missing vesicles - M_q(M_q<0)= 0; % cannot be less than 0 - - % AN_N1 converts probability to discrete events - % it considers each event that might occur - % (how many vesicles might be released) - % and returns a count of how many were released - - % slow line -% probabilities= 1-(1-releaseProb).^AN_available; - probabilities= 1-intpow((1-releaseProb), AN_available); - ejected= probabilities> rand(length(AN_available),1); - - reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft; - reuptake = AN_rdt.* AN_cleft; - - % slow line -% probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; - probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q); - reprocessed= probabilities>rand(length(M_q),1); - - % slow line -% probabilities= 1-(1-AN_ydt).^M_q; - probabilities= 1-intpow((1-AN_ydt), M_q); - - replenish= probabilities>rand(length(M_q),1); - - AN_available = AN_available + replenish - ejected ... - + reprocessed; - AN_cleft = AN_cleft + ejected - reuptakeandlost; - AN_reprocess = AN_reprocess + reuptake - reprocessed; - - % ANspikes is logical record of vesicle release events>0 - ANspikes(:, ANtimeCount)= ejected; - end % t - - % zero any events that are preceded by release events ... - % within the refractory period - % The refractory period consist of two periods - % 1) the absolute period where no spikes occur - % 2) a relative period where a spike may occur. This relative - % period is realised as a variable length interval - % where the length is chosen at random - % (esentially a linear ramp up) - - % Andreas has a fix for this - for t = 1:ANtimeCount-2*lengthAbsRefractory; - % identify all spikes across fiber array at time (t) - % idx is a list of channels where spikes occurred - % ?? try sparse matrices? - idx=find(ANspikes(:,t)); - for j=idx % consider each spike - % specify variable refractory period - % between abs and 2*abs refractory period - nPointsRefractory=lengthAbsRefractory+... - round(rand*lengthAbsRefractory); - % disable spike potential for refractory period - % set all values in this range to 0 - ANspikes(j,t+1:t+nPointsRefractory)=0; - end - end %t - - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(ANspikes, plotInstructions); - - % and save it. NB, AN is now on 'speedUp' time - ANoutput(:, reducedSegmentPTR: shorterSegmentEndPTR)=ANspikes; - - - %% CN Macgregor first neucleus ------------------------------- - % input is from AN so ANdt is used throughout - % Each CNneuron has a unique set of input fibers selected - % at random from the available AN fibers (CNinputfiberLists) - - % Create the dendritic current for that neuron - % First get input spikes to this neuron - synapseNo=1; - for ch=1:nCNchannels - for idx=1:nCNneuronsPerChannel - % determine candidate fibers for this unit - fibersUsed=CNinputfiberLists(synapseNo,:); - % ANpsth has a bin width of ANdt - % (just a simple sum across fibers) - AN_PSTH(synapseNo,:) = ... - sum(ANspikes(fibersUsed,:), 1); - synapseNo=synapseNo+1; - end - end - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - % One alpha function per spike - [alphaRows alphaCols]=size(CNtrailingAlphas); - - for unitNo=1:nCNneurons - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - CNcurrentTemp0(unitNo,:)= ... - conv(AN_PSTH(unitNo,:),CNalphaFunction); - - - - CNcurrentTemp(unitNo,:)= ... - conv2(AN_PSTH(unitNo,:),CNalphaFunction); - % Changed conv to conv2 because it runs faster. (Andreas) - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% -% -% f = CNalphaFunction; -% g = AN_PSTH(unitNo,:); -% -% -% g = [g zeros(1,length(f)-1)]; -% -% spikePos = find(g)'; -% -% result = zeros(1,length(g)); -% -% for index = 1:length(spikePos) -% k = spikePos(index); -% result(k:(k+length(f)-1)) = result(k:(k+length(f)-1)) + g(k)*f; -% end -% -% CNcurrentTemp2(unitNo,:) = result; - - - end - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - - f = CNalphaFunction; - g = AN_PSTH; - - g = [g zeros(size(g,1),length(f)-1)]; - - [r c] = find(g); - - CNcurrentTemp2 = zeros(size(g)); - - for index = 1:length(r) - - row = r(index); - col = c(index); - - CNcurrentTemp2(row,col:col+length(f)-1) = CNcurrentTemp2(row,col:col+length(f)-1) + f*g(row,col); - - end - - - -CONVOLUTION_CHANGE_TEST = CONVOLUTION_CHANGE_TEST + sum(abs(CNcurrentTemp2 - CNcurrentTemp))+ sum(abs(CNcurrentTemp0 - CNcurrentTemp)); - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - -% disp(['sum(AN_PSTH)= ' num2str(sum(AN_PSTH(1,:)))]) - % add post-synaptic current left over from previous segment - CNcurrentTemp(:,1:alphaCols)=... - CNcurrentTemp(:,1:alphaCols)+ CNtrailingAlphas; - - % take post-synaptic current for this segment - CNcurrentInput= CNcurrentTemp(:, 1:reducedSegmentLength); -% disp(['mean(CNcurrentInput)= ' num2str(mean(CNcurrentInput(1,:)))]) - - % trailingalphas are the ends of the alpha functions that - % spill over into the next segment - CNtrailingAlphas= ... - CNcurrentTemp(:, reducedSegmentLength+1:end); - - if CN_c>0 - % variable threshold condition (slow) - for t=1:reducedSegmentLength - CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt; - s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ; - CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike - dE =(-CN_E/CN_tauM + ... - CNcurrentInput(:,t)/CN_cap+(... - CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt; - dGk=-CN_Gk*ANdt./tauGk + CN_b*s; - dTh=-(CN_Th-CN_Th0)*ANdt/CN_tauTh + CN_c*s; - CN_E=CN_E+dE; - CN_Gk=CN_Gk+dGk; - CN_Th=CN_Th+dTh; - CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er; - end - else - % static threshold (faster) - E=zeros(1,reducedSegmentLength); - Gk=zeros(1,reducedSegmentLength); - ss=zeros(1,reducedSegmentLength); - for t=1:reducedSegmentLength - % time of previous spike moves back in time - CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt; - % action potential if E>threshold - % allow time for s to reset between events - s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ; - ss(t)=s(1); - CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike - dE = (-CN_E/CN_tauM + ... - CNcurrentInput(:,t)/CN_cap +... - (CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt; - dGk=-CN_Gk*ANdt./tauGk +CN_b*s; - CN_E=CN_E+dE; - CN_Gk=CN_Gk+dGk; - E(t)=CN_E(1); - Gk(t)=CN_Gk(1); - % add spike to CN_E and add resting potential (-60 mV) - CNmembranePotential(:,t)=CN_E +s.*(CN_Eb-CN_E)+CN_Er; - end - end -% disp(['CN_E= ' num2str(sum(CN_E(1,:)))]) -% disp(['CN_Gk= ' num2str(sum(CN_Gk(1,:)))]) -% disp(['CNmembranePotential= ' num2str(sum(CNmembranePotential(1,:)))]) -% plot(CNmembranePotential(1,:)) - - - % extract spikes. A spike is a substantial upswing in voltage - CN_spikes=CNmembranePotential> -0.02; -% disp(['CNspikesbefore= ' num2str(sum(sum(CN_spikes)))]) - - % now remove any spike that is immediately followed by a spike - % NB 'find' works on columns (whence the transposing) - % for each spike put a zero in the next epoch - CN_spikes=CN_spikes'; - idx=find(CN_spikes); - idx=idx(1:end-1); - CN_spikes(idx+1)=0; - CN_spikes=CN_spikes'; -% disp(['CNspikes= ' num2str(sum(sum(CN_spikes)))]) - - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(CN_spikes, plotInstructions); - - % and save it - CNoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=... - CN_spikes; - - - %% IC ---------------------------------------------- - % MacGregor or some other second order neurons - - % combine CN neurons in same channel, - % i.e. same BF & same tauCa - % to generate inputs to single IC unit - channelNo=0; - for idx=1:nCNneuronsPerChannel:nCNneurons-nCNneuronsPerChannel+1; - channelNo=channelNo+1; - CN_PSTH(channelNo,:)=... - sum(CN_spikes(idx:idx+nCNneuronsPerChannel-1,:)); - end - - [alphaRows alphaCols]=size(ICtrailingAlphas); - for ICneuronNo=1:nICcells - ICcurrentTemp(ICneuronNo,:)= ... - conv2(CN_PSTH(ICneuronNo,:), IC_CNalphaFunction); - % Changed conv to conv2 because it runs faster. (Andreas) - end - - % add the unused current from the previous convolution - ICcurrentTemp(:,1:alphaCols)=ICcurrentTemp(:,1:alphaCols)... - + ICtrailingAlphas; - % take what is required and keep the trailing part for next time - inputCurrent=ICcurrentTemp(:, 1:reducedSegmentLength); - ICtrailingAlphas=ICcurrentTemp(:, reducedSegmentLength+1:end); - - if IC_c==0 - % faster computation when threshold is stable (C==0) - for t=1:reducedSegmentLength - s=IC_E>IC_Th0; - dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +... - (IC_Gk/IC_cap).*(IC_Ek-IC_E))*ANdt; - dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s; - IC_E=IC_E+dE; - IC_Gk=IC_Gk+dGk; - ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; - end - else - % threshold is changing (IC_c>0; e.g. bushy cell) - for t=1:reducedSegmentLength - dE = (-IC_E/IC_tauM + ... - inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)... - .*(IC_Ek-IC_E))*ANdt; - IC_E=IC_E+dE; - s=IC_E>IC_Th; - ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; - dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s; - IC_Gk=IC_Gk+dGk; - - % After a spike, the threshold is raised - % otherwise it settles to its baseline - dTh=-(IC_Th-Th0)*ANdt/IC_tauTh +s*IC_c; - IC_Th=IC_Th+dTh; - end - end - - ICspikes=ICmembranePotential> -0.01; - % now remove any spike that is immediately followed by a spike - % NB 'find' works on columns (whence the transposing) - ICspikes=ICspikes'; - idx=find(ICspikes); - idx=idx(1:end-1); - ICspikes(idx+1)=0; - ICspikes=ICspikes'; - - nCellsPerTau= nICcells/nANfiberTypes; - firstCell=1; - lastCell=nCellsPerTau; - for tauCount=1:nANfiberTypes - % separate rates according to fiber types - % currently only the last segment is saved - ICfiberTypeRates(tauCount, ... - reducedSegmentPTR:shorterSegmentEndPTR)=... - sum(ICspikes(firstCell:lastCell, :))... - /(nCellsPerTau*ANdt); - firstCell=firstCell+nCellsPerTau; - lastCell=lastCell+nCellsPerTau; - end - - ICoutput(:,reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes; - - % store membrane output on original dt scale - if nBFs==1 % single channel - x= repmat(ICmembranePotential(1,:), ANspeedUpFactor,1); - x= reshape(x,1,segmentLength); - if nANfiberTypes>1 % save HSR and LSR - y=repmat(ICmembranePotential(end,:),... - ANspeedUpFactor,1); - y= reshape(y,1,segmentLength); - x=[x; y]; - end - ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x; - end - - % estimate efferent effects. - % ARis based on LSR units. LSR channels are 1:nBF - if nANfiberTypes>1 % AR is multi-channel only - ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt; - [ARAttSeg, ARboundary] = ... - filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary); - ARAttSeg=ARAttSeg-ARrateThreshold; - ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths - % scale up to dt from ANdt - x= repmat(ARAttSeg, ANspeedUpFactor,1); - x=reshape(x,1,segmentLength); - ARattenuation(segmentStartPTR:segmentEndPTR)=... - (1-ARrateToAttenuationFactor* x); - ARattenuation(ARattenuation<0)=0.001; - else - % single channel model; disable AR - ARattenuation(segmentStartPTR:segmentEndPTR)=... - ones(1,segmentLength); - end - - % MOC attenuation using HSR response only - % Separate MOC effect for each BF - HSRbegins=nBFs*(nANfiberTypes-1)+1; - rates=ICspikes(HSRbegins:end,:)/ANdt; - for idx=1:nBFs - [smoothedRates, MOCboundary{idx}] = ... - filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... - MOCboundary{idx}); - % spont 'rates' is zero for IC - MOCattSegment(idx,:)=smoothedRates; - % expand timescale back to model dt from ANdt - x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1); - x= reshape(x,1,segmentLength); - MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... - (1- MOCrateToAttenuationFactor* x); - end - MOCattenuation(MOCattenuation<0)=0.04; - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(ICspikes, plotInstructions); - - end % AN_spikesOrProbability - segmentStartPTR=segmentStartPTR+segmentLength; - reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength; - - -end % segment - -disp('CONVOLUTION_CHANGE_TEST (if followed by zero all is good)') -disp(max(CONVOLUTION_CHANGE_TEST)) %% for debugging - - -%% apply refractory correction to spike probabilities - -% switch AN_spikesOrProbability -% case 'probability' -% ANprobOutput=ANprobRateOutput*dt; -% [r nEpochs]=size(ANprobOutput); -% % find probability of no spikes in refractory period -% pNoSpikesInRefrac=ones(size(ANprobOutput)); -% pSpike=zeros(size(ANprobOutput)); -% for epochNo=lengthAbsRefractoryP+2:nEpochs -% pNoSpikesInRefrac(:,epochNo)=... -% pNoSpikesInRefrac(:,epochNo-2)... -% .*(1-pSpike(:,epochNo-1))... -% ./(1-pSpike(:,epochNo-lengthAbsRefractoryP-1)); -% pSpike(:,epochNo)= ANprobOutput(:,epochNo)... -% .*pNoSpikesInRefrac(:,epochNo); -% end -% ANprobRateOutput=pSpike/dt; -% end - -path(restorePath)
--- a/MAP/MAP1_14parallel.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1148 +0,0 @@ - -function MAP1_14parallel(inputSignal, sampleRate, BFlist, MAPparamsName, ... - AN_spikesOrProbability, paramChanges) -% To test this function use test_MAP1_14 in this folder -% -% All arguments are mandatory. -% -% BFlist is a list of BFs but can be '-1' to allow MAPparams to choose -% - -% MAPparamsName='Normal'; % source of model parameters -% AN_spikesOrProbability='spikes'; % or 'probability' -% paramChanges is a cell array of strings that can be used to make last -% minute parameter changes, e.g., to simulate OHC loss -% paramChanges{1}= 'DRNLParams.a=0;'; - -% The model parameters are established in the MAPparams<***> file -% and stored as global - -restorePath=path; -addpath (['..' filesep 'parameterStore']) - -global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams -global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams - -% All of the results of this function are stored as global -global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... - savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... - DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... - IHCoutput ANprobRateOutput ANoutput savePavailable tauCas ... - CNoutput ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation - -% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be -% needed by the user; so the following will suffice -% global ANdt ICoutput ANprobRateOutput - -% Note that sampleRate has not changed from the original function call and -% ANprobRateOutput is sampled at this rate -% However ANoutput, CNoutput and IC output are stored as logical -% 'spike' matrices using a lower sample rate (see ANdt). - -% When AN_spikesOrProbability is set to probability, -% no spike matrices are computed. -% When AN_spikesOrProbability is set to 'spikes', -% no probability output is computed - -% Efferent control variables are ARattenuation and MOCattenuation -% These are scalars between 1 (no attenuation) and 0. -% They are represented with dt=1/sampleRate (not ANdt) -% They are computed using either AN probability rate output -% or IC (spikes) output as approrpriate. -% AR is computed using across channel activity -% MOC is computed on a within-channel basis. - - -% save as global for later plotting if required -savedBFlist=BFlist; -saveAN_spikesOrProbability=AN_spikesOrProbability; -saveMAPparamsName=MAPparamsName; - -% Read parameters from MAPparams<***> file in 'parameterStore' folder -cmd=['method=MAPparams' MAPparamsName ... - '(BFlist, sampleRate, 0);']; -eval(cmd); - -% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<> -% if the calling program allows MAPparams to specify the list -BFlist=DRNLParams.nonlinCFs; - -% now accept last mintue parameter changes required by the calling program -if nargin>5 && ~isempty(paramChanges) - nChanges=length(paramChanges); - for idx=1:nChanges - eval(paramChanges{idx}) - end -end - -dt=1/sampleRate; -duration=length(inputSignal)/sampleRate; -% segmentDuration is specified in parameter file (must be >efferent delay) -segmentDuration=method.segmentDuration; -segmentLength=round(segmentDuration/ dt); -segmentTime=dt*(1:segmentLength); % used in debugging plots - -% all spiking activity is computed using longer epochs -ANspeedUpFactor=5; % 5 times longer - -% inputSignal must be row vector -[r c]=size(inputSignal); -if r>c, inputSignal=inputSignal'; end % transpose -% ignore stereo signals -inputSignal=inputSignal(1,:); % drop any second channel -savedInputSignal=inputSignal; - -% Segment the signal -% The sgment length is given but the signal length must be adjusted to be a -% multiple of both the segment length and the reduced segmentlength -[nSignalRows signalLength]=size(inputSignal); -segmentLength=ceil(segmentLength/ANspeedUpFactor)*ANspeedUpFactor; -% Make the signal length a whole multiple of the segment length -nSignalSegments=ceil(signalLength/segmentLength); -padSize=nSignalSegments*segmentLength-signalLength; -pad=zeros(nSignalRows,padSize); -inputSignal=[inputSignal pad]; -[ignore signalLength]=size(inputSignal); - -% AN (spikes) is computed at a lower sample rate when spikes required -% so it has a reduced segment length (see 'ANspeeUpFactor' above) -% AN CN and IC all use this sample interval -ANdt=dt*ANspeedUpFactor; -reducedSegmentLength=round(segmentLength/ANspeedUpFactor); -reducedSignalLength= round(signalLength/ANspeedUpFactor); - -%% Initialise with respect to each stage before computing -% by allocating memory, -% by computing constants -% by establishing easy to read variable names -% The computations are made in segments and boundary conditions must -% be established and stored. These are found in variables with -% 'boundary' or 'bndry' in the name - -%% OME --- -% external ear resonances -OMEexternalResonanceFilters=OMEParams.externalResonanceFilters; -[nOMEExtFilters c]=size(OMEexternalResonanceFilters); -% details of external (outer ear) resonances -OMEgaindBs=OMEexternalResonanceFilters(:,1); -OMEgainScalars=10.^(OMEgaindBs/20); -OMEfilterOrder=OMEexternalResonanceFilters(:,2); -OMElowerCutOff=OMEexternalResonanceFilters(:,3); -OMEupperCutOff=OMEexternalResonanceFilters(:,4); -% external resonance coefficients -ExtFilter_b=cell(nOMEExtFilters,1); -ExtFilter_a=cell(nOMEExtFilters,1); -for idx=1:nOMEExtFilters - Nyquist=sampleRate/2; - [b, a] = butter(OMEfilterOrder(idx), ... - [OMElowerCutOff(idx) OMEupperCutOff(idx)]... - /Nyquist); - ExtFilter_b{idx}=b; - ExtFilter_a{idx}=a; -end -OMEExtFilterBndry=cell(2,1); -OMEextEarPressure=zeros(1,signalLength); % pressure at tympanic membrane - -% pressure to velocity conversion using smoothing filter (50 Hz cutoff) -tau=1/(2*pi*50); -a1=dt/tau-1; a0=1; -b0=1+ a1; -TMdisp_b=b0; TMdisp_a=[a0 a1]; -% figure(9), freqz(TMdisp_b, TMdisp_a) -OME_TMdisplacementBndry=[]; - -% OME high pass (simulates poor low frequency stapes response) -OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff; -Nyquist=sampleRate/2; -[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high'); -% figure(10), freqz(stapesDisp_b, stapesDisp_a) - -OMEhighPassBndry=[]; - -% OMEampStapes might be reducdant (use OMEParams.stapesScalar) -stapesScalar= OMEParams.stapesScalar; - -% Acoustic reflex -efferentDelayPts=round(OMEParams.ARdelay/dt); -% smoothing filter -% Nyquist=(1/ANdt)/2; -% [ARfilt_b,ARfilt_a] = butter(1, (1/(2*pi*OMEParams.ARtau))/Nyquist, 'low'); -a1=dt/OMEParams.ARtau-1; a0=1; -b0=1+ a1; -ARfilt_b=b0; ARfilt_a=[a0 a1]; - -ARattenuation=ones(1,signalLength); -ARrateThreshold=OMEParams.ARrateThreshold; % may not be used -ARrateToAttenuationFactor=OMEParams.rateToAttenuationFactor; -ARrateToAttenuationFactorProb=OMEParams.rateToAttenuationFactorProb; -ARboundary=[]; -ARboundaryProb=0; - -% save complete OME record (stapes displacement) -OMEoutput=zeros(1,signalLength); -TMoutput=zeros(1,signalLength); - -%% BM --- -% BM is represented as a list of locations identified by BF -DRNL_BFs=BFlist; -nBFs= length(DRNL_BFs); - -% DRNLchannelParameters=DRNLParams.channelParameters; -DRNLresponse= zeros(nBFs, segmentLength); - -MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor; -rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb; -MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb; - -% smoothing filter for MOC -% Nyquist=(1/ANdt)/2; -% [MOCfilt_b,MOCfilt_a] = ... -% butter(1, (1/(2*pi*DRNLParams.MOCtau))/Nyquist, 'low'); -% figure(10), freqz(stapesDisp_b, stapesDisp_a) -a1=dt/DRNLParams.MOCtau-1; a0=1; -b0=1+ a1; -MOCfilt_b=b0; MOCfilt_a=[a0 a1]; -% figure(9), freqz(stapesDisp_b, stapesDisp_a) -MOCboundary=cell(nBFs,1); -MOCprobBoundary=cell(nBFs,1); - -MOCattSegment=zeros(nBFs,reducedSegmentLength); -MOCattenuation=ones(nBFs,signalLength); - -if DRNLParams.a>0 - DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ... - log10(DRNLParams.b/DRNLParams.a)); -else - DRNLcompressionThreshold=inf; -end - -DRNLlinearOrder= DRNLParams.linOrder; -DRNLnonlinearOrder= DRNLParams.nonlinOrder; - -DRNLa=DRNLParams.a; -DRNLb=DRNLParams.b; -DRNLc=DRNLParams.c; -linGAIN=DRNLParams.g; -% -% gammatone filter coefficients for linear pathway -bw=DRNLParams.linBWs'; -phi = 2 * pi * bw * dt; -cf=DRNLParams.linCFs'; -theta = 2 * pi * cf * dt; -cos_theta = cos(theta); -sin_theta = sin(theta); -alpha = -exp(-phi).* cos_theta; -b0 = ones(nBFs,1); -b1 = 2 * alpha; -b2 = exp(-2 * phi); -z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; -z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; -z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; -tf = (z2 + z3) ./ z1; -a0 = abs(tf); -a1 = alpha .* a0; -GTlin_a = [b0, b1, b2]; -GTlin_b = [a0, a1]; -GTlinOrder=DRNLlinearOrder; -GTlinBdry1=cell(nBFs); -GTlinBdry2=cell(nBFs); -GTlinBdry3=cell(nBFs); -GTlinBdry1out=cell(nBFs); -GTlinBdry2out=cell(nBFs); -GTlinBdry3out=cell(nBFs); - -% nonlinear gammatone filter coefficients -bw=DRNLParams.nlBWs'; -phi = 2 * pi * bw * dt; -cf=DRNLParams.nonlinCFs'; -theta = 2 * pi * cf * dt; -cos_theta = cos(theta); -sin_theta = sin(theta); -alpha = -exp(-phi).* cos_theta; -b0 = ones(nBFs,1); -b1 = 2 * alpha; -b2 = exp(-2 * phi); -z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; -z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; -z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; -tf = (z2 + z3) ./ z1; -a0 = abs(tf); -a1 = alpha .* a0; -GTnonlin_a = [b0, b1, b2]; -GTnonlin_b = [a0, a1]; -GTnonlinOrder=DRNLnonlinearOrder; -firstGTnonlinBdry1=cell(nBFs); -firstGTnonlinBdry2=cell(nBFs); -firstGTnonlinBdry3=cell(nBFs); -firstGTnonlinBdry1out=cell(nBFs); -firstGTnonlinBdry2out=cell(nBFs); -firstGTnonlinBdry3out=cell(nBFs); - -secondGTnonlinBdry1=cell(nBFs); -secondGTnonlinBdry2=cell(nBFs); -secondGTnonlinBdry3=cell(nBFs); -secondGTnonlinBdry1out=cell(nBFs); -secondGTnonlinBdry2out=cell(nBFs); -secondGTnonlinBdry3out=cell(nBFs); - -% complete BM record (BM displacement) -DRNLoutput=zeros(nBFs, signalLength); - - -%% IHC --- -% IHC cilia activity and receptor potential -% viscous coupling between BM and stereocilia displacement -% Nyquist=sampleRate/2; -% IHCcutoff=1/(2*pi*IHC_cilia_RPParams.tc); -% [IHCciliaFilter_b,IHCciliaFilter_a]=... -% butter(1, IHCcutoff/Nyquist, 'high'); -a1=dt/IHC_cilia_RPParams.tc-1; a0=1; -b0=1+ a1; -% high pass (i.e. low pass reversed) -IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0; -% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a) - -IHCciliaBndry=cell(nBFs,1); - -% IHC apical conductance (Boltzman function) -IHC_C= IHC_cilia_RPParams.C; -IHCu0= IHC_cilia_RPParams.u0; -IHCu1= IHC_cilia_RPParams.u1; -IHCs0= IHC_cilia_RPParams.s0; -IHCs1= IHC_cilia_RPParams.s1; -IHCGmax= IHC_cilia_RPParams.Gmax; -IHCGa= IHC_cilia_RPParams.Ga; % (leakage) - -IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1))); - -% Receptor potential -IHC_Cab= IHC_cilia_RPParams.Cab; -IHC_Gk= IHC_cilia_RPParams.Gk; -IHC_Et= IHC_cilia_RPParams.Et; -IHC_Ek= IHC_cilia_RPParams.Ek; -IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc; - -IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk); - -IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage -IHC_RP= zeros(nBFs,segmentLength); - -% complete record of IHC receptor potential (V) -IHCciliaDisplacement= zeros(nBFs,segmentLength); -IHCoutput= zeros(nBFs,signalLength); -IHC_cilia_output= zeros(nBFs,signalLength); - - -%% pre-synapse --- -% Each BF is replicated using a different fiber type to make a 'channel' -% The number of channels is nBFs x nANfiberTypes -% Fiber types are specified in terms of tauCa -nANfiberTypes= length(IHCpreSynapseParams.tauCa); -tauCas= IHCpreSynapseParams.tauCa; -nChannels= nANfiberTypes*nBFs; -synapticCa= zeros(nChannels,segmentLength); - -% Calcium control (more calcium, greater release rate) -ECa=IHCpreSynapseParams.ECa; -gamma=IHCpreSynapseParams.gamma; -beta=IHCpreSynapseParams.beta; -tauM=IHCpreSynapseParams.tauM; -mICa=zeros(nChannels,segmentLength); -GmaxCa=IHCpreSynapseParams.GmaxCa; -synapse_z= IHCpreSynapseParams.z; -synapse_power=IHCpreSynapseParams.power; - -% tauCa vector is established across channels to allow vectorization -% (one tauCa per channel). Do not confuse with tauCas (one pre fiber type) -tauCa=repmat(tauCas, nBFs,1); -tauCa=reshape(tauCa, nChannels, 1); - -% presynapse startup values (vectors, length:nChannels) -% proportion (0 - 1) of Ca channels open at IHCrestingV -mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)... - *ones(nBFs*nANfiberTypes,1); -% corresponding startup currents -ICaCurrent= (GmaxCa*mICaCurrent.^3) * (IHCrestingV-ECa); -CaCurrent= ICaCurrent.*tauCa; - -% vesicle release rate at startup (one per channel) -% kt0 is used only at initialisation -kt0= -synapse_z * CaCurrent.^synapse_power; - - -%% AN --- -% each row of the AN matrices represents one AN fiber -% The results computed either for probabiities *or* for spikes (not both) -% Spikes are necessary if CN and IC are to be computed -nFibersPerChannel= AN_IHCsynapseParams.numFibers; -nANfibers= nChannels*nFibersPerChannel; - -y=AN_IHCsynapseParams.y; -l=AN_IHCsynapseParams.l; -x=AN_IHCsynapseParams.x; -r=AN_IHCsynapseParams.r; -M=round(AN_IHCsynapseParams.M); - -% probability (NB initial 'P' on everything) -PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nChannels,1); -PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nChannels,1); -PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nChannels,1); -PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nChannels,1); -PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt; -PAN_M=round(AN_IHCsynapseParams.M); - -% compute starting values -Pcleft = kt0* y* M ./ (y*(l+r)+ kt0* l); -Pavailable = Pcleft*(l+r)./kt0; -Preprocess = Pcleft*r/x; % canbe fractional - -ANprobability=zeros(nChannels,segmentLength); -ANprobRateOutput=zeros(nChannels,signalLength); -% special variables for monitoring synaptic cleft (specialists only) -savePavailableSeg=zeros(nChannels,segmentLength); -savePavailable=zeros(nChannels,signalLength); - -% spikes % ! ! ! ! ! ! ! ! -AN_refractory_period= AN_IHCsynapseParams.refractory_period; -lengthAbsRefractory= round(AN_refractory_period/ANdt); - -AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1); -AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1); -AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1); -AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1); -AN_rdt_plus_ldt= AN_rdt + AN_ldt; -AN_M= round(AN_IHCsynapseParams.M); - -% kt0 is initial release rate -% Establish as a vector (length=channel x number of fibers) -kt0= repmat(kt0', nFibersPerChannel, 1); -kt0=reshape(kt0, nANfibers,1); - -% starting values for reservoirs -AN_cleft = kt0* y* M ./ (y*(l+r)+ kt0* l); -AN_available = round(AN_cleft*(l+r)./kt0); %must be integer -AN_reprocess = AN_cleft*r/x; - -% output is in a logical array spikes = 1/ 0. -ANspikes= false(nANfibers,reducedSegmentLength); -ANoutput= false(nANfibers,reducedSignalLength); - - -%% CN (first brain stem nucleus - could be any subdivision of CN) -% Input to a CN neuorn is a random selection of AN fibers within a channel -% The number of AN fibers used is ANfibersFanInToCN -ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron; -nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF; -% CNtauGk (Potassium time constant) determines the rate of firing of -% the unit when driven hard by a DC input (not normally >350 sp/s) -CNtauGk=MacGregorMultiParams.tauGk; -ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers; -nCNneurons=nCNneuronsPerChannel*nChannels; -% nCNneuronsPerFiberType= nCNneurons/nANfiberTypes; - -CNmembranePotential=zeros(nCNneurons,reducedSegmentLength); - -% establish which ANfibers (by name) feed into which CN nuerons -CNinputfiberLists=zeros(nChannels*nCNneuronsPerChannel, ANfibersFanInToCN); -unitNo=1; -for ch=1:nChannels - % Each channel contains a number of units =length(listOfFanInValues) - for idx=1:nCNneuronsPerChannel - fibersUsed=(ch-1)*ANavailableFibersPerChan + ... - ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan); - CNinputfiberLists(unitNo,:)=fibersUsed; - unitNo=unitNo+1; - end -end - -% input to CN units -AN_PSTH=zeros(nCNneurons,reducedSegmentLength); - -% Generate CNalphaFunction function -% by which spikes are converted to post-synaptic currents -CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq; -CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike; -CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq); -t=ANdt:ANdt:5*CNspikeToCurrentTau; -CNalphaFunction=... - (CNcurrentPerSpike/CNspikeToCurrentTau)*t.*exp(-t/CNspikeToCurrentTau); -% figure(98), plot(t,CNalphaFunction) -% working memory for implementing convolution -CNcurrentTemp=... - zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1); -% trailing alphas are parts of humps carried forward to the next segment -CNtrailingAlphas=zeros(nCNneurons,length(CNalphaFunction)); - -CN_tauM=MacGregorMultiParams.tauM; -CN_tauTh=MacGregorMultiParams.tauTh; -CN_cap=MacGregorMultiParams.Cap; -CN_c=MacGregorMultiParams.c; -CN_b=MacGregorMultiParams.dGkSpike; -CN_Ek=MacGregorMultiParams.Ek; -CN_Eb= MacGregorMultiParams.Eb; -CN_Er=MacGregorMultiParams.Er; -CN_Th0= MacGregorMultiParams.Th0; -CN_E= zeros(nCNneurons,1); -CN_Gk= zeros(nCNneurons,1); -CN_Th= MacGregorMultiParams.Th0*ones(nCNneurons,1); -CN_Eb=CN_Eb.*ones(nCNneurons,1); -CN_Er=CN_Er.*ones(nCNneurons,1); -CNtimeSinceLastSpike=zeros(nCNneurons,1); -% tauGk is the main distinction between neurons -% in fact they are all the same in the standard model -tauGk=repmat(CNtauGk,nChannels*nCNneuronsPerChannel,1); - -CN_PSTH=zeros(nChannels,reducedSegmentLength); -CNoutput=false(nCNneurons,reducedSignalLength); - - -%% MacGregor (IC - second nucleus) -------- -nICcells=nChannels; % one cell per channel - -ICspikeWidth=0.00015; % this may need revisiting -epochsPerSpike=round(ICspikeWidth/ANdt); -if epochsPerSpike<1 - error(['MacGregorMulti: sample rate too low to support ' ... - num2str(ICspikeWidth*1e6) ' microsec spikes']); -end - -% short names -IC_tauM=MacGregorParams.tauM; -IC_tauGk=MacGregorParams.tauGk; -IC_tauTh=MacGregorParams.tauTh; -IC_cap=MacGregorParams.Cap; -IC_c=MacGregorParams.c; -IC_b=MacGregorParams.dGkSpike; -IC_Th0=MacGregorParams.Th0; -IC_Ek=MacGregorParams.Ek; -IC_Eb= MacGregorParams.Eb; -IC_Er=MacGregorParams.Er; - -IC_E=zeros(nICcells,1); -IC_Gk=zeros(nICcells,1); -IC_Th=IC_Th0*ones(nICcells,1); - -% Dendritic filtering, all spikes are replaced by CNalphaFunction functions -ICdendriteLPfreq= MacGregorParams.dendriteLPfreq; -ICcurrentPerSpike=MacGregorParams.currentPerSpike; -ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq); -t=ANdt:ANdt:3*ICspikeToCurrentTau; -IC_CNalphaFunction= (ICcurrentPerSpike / ... - ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau); -% figure(98), plot(t,IC_CNalphaFunction) - -% working space for implementing alpha function -ICcurrentTemp=... - zeros(nICcells,reducedSegmentLength+length(IC_CNalphaFunction)-1); -ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction)); - -ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength); -ICoutput=false(nChannels,reducedSignalLength); - -ICmembranePotential=zeros(nICcells,reducedSegmentLength); -ICmembraneOutput=zeros(nICcells,signalLength); - - -%% Main program %% %% %% %% %% %% %% %% %% %% %% %% %% %% - -% Compute the entire model for each segment -segmentStartPTR=1; -reducedSegmentPTR=1; % when sampling rate is reduced -while segmentStartPTR<signalLength - segmentEndPTR=segmentStartPTR+segmentLength-1; - % shorter segments after speed up. - shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1; - - iputPressureSegment=inputSignal... - (:,segmentStartPTR:segmentStartPTR+segmentLength-1); - - % segment debugging plots - % figure(98) - % plot(segmentTime,iputPressureSegment), title('signalSegment') - - - % OME ---------------------- - - % OME Stage 1: external resonances. Add to inputSignal pressure wave - y=iputPressureSegment; - for n=1:nOMEExtFilters - % any number of resonances can be used - [x OMEExtFilterBndry{n}] = ... - filter(ExtFilter_b{n},ExtFilter_a{n},... - iputPressureSegment, OMEExtFilterBndry{n}); - x= x* OMEgainScalars(n); - % This is a parallel resonance so add it - y=y+x; - end - iputPressureSegment=y; - OMEextEarPressure(segmentStartPTR:segmentEndPTR)= iputPressureSegment; - - % OME stage 2: convert input pressure (velocity) to - % tympanic membrane(TM) displacement using low pass filter - [TMdisplacementSegment OME_TMdisplacementBndry] = ... - filter(TMdisp_b,TMdisp_a,iputPressureSegment, ... - OME_TMdisplacementBndry); - % and save it - TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment; - - % OME stage 3: middle ear high pass effect to simulate stapes inertia - [stapesDisplacement OMEhighPassBndry] = ... - filter(stapesDisp_b,stapesDisp_a,TMdisplacementSegment, ... - OMEhighPassBndry); - - % OME stage 4: apply stapes scalar - stapesDisplacement=stapesDisplacement*stapesScalar; - - % OME stage 5: acoustic reflex stapes attenuation - % Attenuate the TM response using feedback from LSR fiber activity - if segmentStartPTR>efferentDelayPts - stapesDisplacement= stapesDisplacement.*... - ARattenuation(segmentStartPTR-efferentDelayPts:... - segmentEndPTR-efferentDelayPts); - end - - % segment debugging plots - % figure(98) - % plot(segmentTime, stapesDisplacement), title ('stapesDisplacement') - - % and save - OMEoutput(segmentStartPTR:segmentEndPTR)= stapesDisplacement; - - % needed for parallel processing - if segmentStartPTR>efferentDelayPts - MOCatt=MOCattenuation(:, segmentStartPTR-efferentDelayPts:... - segmentEndPTR-efferentDelayPts); - else % no MOC available yet - MOCatt=ones(nBFs, segmentLength); - end - %% BM ------------------------------ - % Each BM location is computed separately - parfor BFno=1:nBFs - - % *linear* path - % repeats used to avoid parallel processin problems - linOutput = stapesDisplacement * linGAIN; % linear gain - [linOutput GTlinBdry1out{BFno}] = ... - filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry1{BFno}); - [linOutput GTlinBdry2out{BFno}] = ... - filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry2{BFno}); - [linOutput GTlinBdry3out{BFno}] = ... - filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry3{BFno}); - - % *nonLinear* path - % efferent attenuation (0 <> 1) - MOC=MOCatt(BFno); - - - % first gammatone filter - [nonlinOutput firstGTnonlinBdry1out{BFno}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - stapesDisplacement, firstGTnonlinBdry1{BFno}); - - [nonlinOutput firstGTnonlinBdry2out{BFno}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - stapesDisplacement, firstGTnonlinBdry2{BFno}); - - [nonlinOutput firstGTnonlinBdry3out{BFno}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - stapesDisplacement, firstGTnonlinBdry3{BFno}); - - % broken stick instantaneous compression - % nonlinear gain is weakend by MOC before applied to BM response - y= nonlinOutput.*(MOC* DRNLa); % linear section. - % compress those parts of the signal above the compression - % threshold - abs_x = abs(nonlinOutput); - idx=find(abs_x>DRNLcompressionThreshold); - if ~isempty(idx)>0 - y(idx)=sign(nonlinOutput(idx)).*... - (DRNLb*abs_x(idx).^DRNLc); - end - nonlinOutput=y; - - % second filter removes distortion products - [nonlinOutput secondGTnonlinBdry1out{BFno}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - nonlinOutput, secondGTnonlinBdry1{BFno}); - - [nonlinOutput secondGTnonlinBdry2out{BFno}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - nonlinOutput, secondGTnonlinBdry2{BFno}); - - [nonlinOutput secondGTnonlinBdry3out{BFno}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - nonlinOutput, secondGTnonlinBdry3{BFno}); - - - % combine the two paths to give the DRNL displacement - DRNLresponse(BFno,:)=linOutput+nonlinOutput; - end % BF - GTlinBdry1=GTlinBdry1out; - GTlinBdry2=GTlinBdry2out; - GTlinBdry3=GTlinBdry3out; - firstGTnonlinBdry1=firstGTnonlinBdry1out; - firstGTnonlinBdry2=firstGTnonlinBdry2out; - firstGTnonlinBdry3=firstGTnonlinBdry3out; - secondGTnonlinBdry1=secondGTnonlinBdry1out; - secondGTnonlinBdry2=secondGTnonlinBdry2out; - secondGTnonlinBdry3=secondGTnonlinBdry3out; - % segment debugging plots - % figure(98) - % if size(DRNLresponse,1)>3 - % imagesc(DRNLresponse) % matrix display - % title('DRNLresponse'); % single or double channel response - % else - % plot(segmentTime, DRNLresponse) - % end - - % and save it - DRNLoutput(:, segmentStartPTR:segmentEndPTR)= DRNLresponse; - - - %% IHC ------------------------------------ - % BM displacement to IHCciliaDisplacement is a high-pass filter - % because of viscous coupling - for idx=1:nBFs - [IHCciliaDisplacement(idx,:) IHCciliaBndry{idx}] = ... - filter(IHCciliaFilter_b,IHCciliaFilter_a, ... - DRNLresponse(idx,:), IHCciliaBndry{idx}); - end - - % apply scalar - IHCciliaDisplacement=IHCciliaDisplacement* IHC_C; - - % and save it - IHC_cilia_output(:,segmentStartPTR:segmentStartPTR+segmentLength-1)=... - IHCciliaDisplacement; - - % compute apical conductance - G=IHCGmax./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*... - (1+exp(-(IHCciliaDisplacement-IHCu1)/IHCs1))); - Gu=G + IHCGa; - - % Compute receptor potential - for idx=1:segmentLength - IHC_Vnow=IHC_Vnow+ (-Gu(:, idx).*(IHC_Vnow-IHC_Et)-... - IHC_Gk*(IHC_Vnow-IHC_Ekp))* dt/IHC_Cab; - IHC_RP(:,idx)=IHC_Vnow; - end - - % segment debugging plots - % if size(IHC_RP,1)>3 - % surf(IHC_RP), shading interp, title('IHC_RP') - % else - % plot(segmentTime, IHC_RP) - % end - - % and save it - IHCoutput(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=IHC_RP; - - - %% synapse ----------------------------- - % Compute the vesicle release rate for each fiber type at each BF - % replicate IHC_RP for each fiber type - Vsynapse=repmat(IHC_RP, nANfiberTypes,1); - - % look-up table of target fraction channels open for a given IHC_RP - mICaINF= 1./( 1 + exp(-gamma * Vsynapse) /beta); - % fraction of channel open - apply time constant - for idx=1:segmentLength - % mICaINF is the current 'target' value of mICa - mICaCurrent=mICaCurrent+(mICaINF(:,idx)-mICaCurrent)*dt./tauM; - mICa(:,idx)=mICaCurrent; - end - - ICa= (GmaxCa* mICa.^3) .* (Vsynapse- ECa); - - for idx=1:segmentLength - CaCurrent=CaCurrent + ICa(:,idx)*dt - CaCurrent*dt./tauCa; - synapticCa(:,idx)=CaCurrent; - end - synapticCa=-synapticCa; % treat IHCpreSynapseParams as positive substance - - % NB vesicleReleaseRate is /s and is independent of dt - vesicleReleaseRate = synapse_z * synapticCa.^synapse_power; % rate - - % segment debugging plots - % if size(vesicleReleaseRate,1)>3 - % surf(vesicleReleaseRate), shading interp, title('vesicleReleaseRate') - % else - % plot(segmentTime, vesicleReleaseRate) - % end - - - %% AN - switch AN_spikesOrProbability - case 'probability' - % No refractory effect is applied - for t = 1:segmentLength; - M_Pq=PAN_M-Pavailable; - M_Pq(M_Pq<0)=0; - Preplenish = M_Pq .* PAN_ydt; - Pejected = Pavailable.* vesicleReleaseRate(:,t)*dt; - Preprocessed = M_Pq.*Preprocess.* PAN_xdt; - - ANprobability(:,t)= min(Pejected,1); - reuptakeandlost= PAN_rdt_plus_ldt .* Pcleft; - reuptake= PAN_rdt.* Pcleft; - - Pavailable= Pavailable+ Preplenish- Pejected+ Preprocessed; - Pcleft= Pcleft + Pejected - reuptakeandlost; - Preprocess= Preprocess + reuptake - Preprocessed; - Pavailable(Pavailable<0)=0; - savePavailableSeg(:,t)=Pavailable; % synapse tracking - end - % and save it as *rate* - ANrate=ANprobability/dt; - ANprobRateOutput(:, segmentStartPTR:... - segmentStartPTR+segmentLength-1)= ANrate; - % monitor synapse contents (only sometimes used) - savePavailable(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=... - savePavailableSeg; - - % Estimate efferent effects. ARattenuation (0 <> 1) - % acoustic reflex - ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF - % smooth - [ARAttSeg, ARboundaryProb] = ... - filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb); - ARAttSeg=ARAttSeg-ARrateThreshold; - ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths - ARattenuation(segmentStartPTR:segmentEndPTR)=... - (1-ARrateToAttenuationFactorProb.* ARAttSeg); - - % MOC attenuation - % within-channel HSR response only - HSRbegins=nBFs*(nANfiberTypes-1)+1; - rates=ANrate(HSRbegins:end,:); - for idx=1:nBFs - [smoothedRates, MOCprobBoundary{idx}] = ... - filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... - MOCprobBoundary{idx}); - smoothedRates=smoothedRates-MOCrateThresholdProb; - smoothedRates(smoothedRates<0)=0; - MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... - (1- smoothedRates* rateToAttenuationFactorProb); - end - MOCattenuation(MOCattenuation<0)=0.001; - - - case 'spikes' - ANtimeCount=0; - % implement speed upt - for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength; - ANtimeCount=ANtimeCount+1; - % convert release rate to probabilities - releaseProb=vesicleReleaseRate(:,t)*ANdt; - % releaseProb is the release probability per channel - % but each channel has many synapses - releaseProb=repmat(releaseProb',nFibersPerChannel,1); - releaseProb=reshape(releaseProb, nFibersPerChannel*nChannels,1); - - % AN_available=round(AN_available); % vesicles must be integer, (?needed) - M_q=AN_M- AN_available; % number of missing vesicles - M_q(M_q<0)= 0; % cannot be less than 0 - - % AN_N1 converts probability to discrete events - % it considers each event that might occur - % (how many vesicles might be released) - % and returns a count of how many were released - - % slow line -% probabilities= 1-(1-releaseProb).^AN_available; - probabilities= 1-intpow((1-releaseProb), AN_available); - ejected= probabilities> rand(length(AN_available),1); - - reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft; - reuptake = AN_rdt.* AN_cleft; - - % slow line -% probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; - probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q); - reprocessed= probabilities>rand(length(M_q),1); - - % slow line -% probabilities= 1-(1-AN_ydt).^M_q; - probabilities= 1-intpow((1-AN_ydt), M_q); - - replenish= probabilities>rand(length(M_q),1); - - AN_available = AN_available + replenish - ejected ... - + reprocessed; - AN_cleft = AN_cleft + ejected - reuptakeandlost; - AN_reprocess = AN_reprocess + reuptake - reprocessed; - - % ANspikes is logical record of vesicle release events>0 - ANspikes(:, ANtimeCount)= ejected; - end % t - - % zero any events that are preceded by release events ... - % within the refractory period - % The refractory period consist of two periods - % 1) the absolute period where no spikes occur - % 2) a relative period where a spike may occur. This relative - % period is realised as a variable length interval - % where the length is chosen at random - % (esentially a linear ramp up) - - % Andreas has a fix for this - for t = 1:ANtimeCount-2*lengthAbsRefractory; - % identify all spikes across fiber array at time (t) - % idx is a list of channels where spikes occurred - % ?? try sparse matrices? - idx=find(ANspikes(:,t)); - for j=idx % consider each spike - % specify variable refractory period - % between abs and 2*abs refractory period - nPointsRefractory=lengthAbsRefractory+... - round(rand*lengthAbsRefractory); - % disable spike potential for refractory period - % set all values in this range to 0 - ANspikes(j,t+1:t+nPointsRefractory)=0; - end - end %t - - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(ANspikes, plotInstructions); - - % and save it. NB, AN is now on 'speedUp' time - ANoutput(:, reducedSegmentPTR: shorterSegmentEndPTR)=ANspikes; - - - %% CN Macgregor first neucleus ------------------------------- - % input is from AN so ANdt is used throughout - % Each CNneuron has a unique set of input fibers selected - % at random from the available AN fibers (CNinputfiberLists) - - % Create the dendritic current for that neuron - % First get input spikes to this neuron - synapseNo=1; - for ch=1:nChannels - for idx=1:nCNneuronsPerChannel - % determine candidate fibers for this unit - fibersUsed=CNinputfiberLists(synapseNo,:); - % ANpsth has a bin width of dt - % (just a simple sum across fibers) - AN_PSTH(synapseNo,:) = ... - sum(ANspikes(fibersUsed,:), 1); - synapseNo=synapseNo+1; - end - end - - % One alpha function per spike - [alphaRows alphaCols]=size(CNtrailingAlphas); - - for unitNo=1:nCNneurons - CNcurrentTemp(unitNo,:)= ... - conv(AN_PSTH(unitNo,:),CNalphaFunction); - end - % add post-synaptic current left over from previous segment - CNcurrentTemp(:,1:alphaCols)=... - CNcurrentTemp(:,1:alphaCols)+ CNtrailingAlphas; - - % take post-synaptic current for this segment - CNcurrentInput= CNcurrentTemp(:, 1:reducedSegmentLength); - - % trailingalphas are the ends of the alpha functions that - % spill over into the next segment - CNtrailingAlphas= ... - CNcurrentTemp(:, reducedSegmentLength+1:end); - - if CN_c>0 - % variable threshold condition (slow) - for t=1:reducedSegmentLength - CNtimeSinceLastSpike=CNtimeSinceLastSpike-dts; - s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ; - CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike - dE =(-CN_E/CN_tauM + ... - CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt; - dGk=-CN_Gk*dt./tauGk + CN_b*s; - dTh=-(CN_Th-CN_Th0)*dt/CN_tauTh + CN_c*s; - CN_E=CN_E+dE; - CN_Gk=CN_Gk+dGk; - CN_Th=CN_Th+dTh; - CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er; - end - else - % static threshold (faster) - for t=1:reducedSegmentLength - CNtimeSinceLastSpike=CNtimeSinceLastSpike-dt; - s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ; % =1 if both conditions met - CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike - dE = (-CN_E/CN_tauM + ... - CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt; - dGk=-CN_Gk*dt./tauGk +CN_b*s; - CN_E=CN_E+dE; - CN_Gk=CN_Gk+dGk; - % add spike to CN_E and add resting potential (-60 mV) - CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er; - end - end - - % extract spikes. A spike is a substantial upswing in voltage - CN_spikes=CNmembranePotential> -0.01; - - % now remove any spike that is immediately followed by a spike - % NB 'find' works on columns (whence the transposing) - CN_spikes=CN_spikes'; - idx=find(CN_spikes); - idx=idx(1:end-1); - CN_spikes(idx+1)=0; - CN_spikes=CN_spikes'; - - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(CN_spikes, plotInstructions); - - % and save it - CNoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=... - CN_spikes; - - - %% IC ---------------------------------------------- - % MacGregor or some other second order neurons - - % combine CN neurons in same channel, i.e. same BF & same tauCa - % to generate inputs to single IC unit - channelNo=0; - for idx=1:nCNneuronsPerChannel:nCNneurons-nCNneuronsPerChannel+1; - channelNo=channelNo+1; - CN_PSTH(channelNo,:)=... - sum(CN_spikes(idx:idx+nCNneuronsPerChannel-1,:)); - end - - [alphaRows alphaCols]=size(ICtrailingAlphas); - for ICneuronNo=1:nICcells - ICcurrentTemp(ICneuronNo,:)= ... - conv(CN_PSTH(ICneuronNo,:), IC_CNalphaFunction); - end - - % add the unused current from the previous convolution - ICcurrentTemp(:,1:alphaCols)=ICcurrentTemp(:,1:alphaCols)... - + ICtrailingAlphas; - % take what is required and keep the trailing part for next time - inputCurrent=ICcurrentTemp(:, 1:reducedSegmentLength); - ICtrailingAlphas=ICcurrentTemp(:, reducedSegmentLength+1:end); - - if IC_c==0 - % faster computation when threshold is stable (C==0) - for t=1:reducedSegmentLength - s=IC_E>IC_Th0; - dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +... - (IC_Gk/IC_cap).*(IC_Ek-IC_E))*dt; - dGk=-IC_Gk*dt/IC_tauGk +IC_b*s; - IC_E=IC_E+dE; - IC_Gk=IC_Gk+dGk; - ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; - end - else - % threshold is changing (IC_c>0; e.g. bushy cell) - for t=1:reducedSegmentLength - dE = (-IC_E/IC_tauM + ... - inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)... - .*(IC_Ek-IC_E))*dt; - IC_E=IC_E+dE; - s=IC_E>IC_Th; - ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; - dGk=-IC_Gk*dt/IC_tauGk +IC_b*s; - IC_Gk=IC_Gk+dGk; - - % After a spike, the threshold is raised - % otherwise it settles to its baseline - dTh=-(IC_Th-Th0)*dt/IC_tauTh +s*IC_c; - IC_Th=IC_Th+dTh; - end - end - - ICspikes=ICmembranePotential> -0.01; - % now remove any spike that is immediately followed by a spike - % NB 'find' works on columns (whence the transposing) - ICspikes=ICspikes'; - idx=find(ICspikes); - idx=idx(1:end-1); - ICspikes(idx+1)=0; - ICspikes=ICspikes'; - - nCellsPerTau= nICcells/nANfiberTypes; - firstCell=1; - lastCell=nCellsPerTau; - for tauCount=1:nANfiberTypes - % separate rates according to fiber types - ICfiberTypeRates(tauCount, ... - reducedSegmentPTR:shorterSegmentEndPTR)=... - sum(ICspikes(firstCell:lastCell, :))... - /(nCellsPerTau*ANdt); - firstCell=firstCell+nCellsPerTau; - lastCell=lastCell+nCellsPerTau; - end - ICoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes; - - if nBFs==1 % single channel - x= repmat(ICmembranePotential(1,:), ANspeedUpFactor,1); - x= reshape(x,1,segmentLength); - if nANfiberTypes>1 % save HSR and LSR - y= repmat(ICmembranePotential(end,:), ANspeedUpFactor,1); - y= reshape(y,1,segmentLength); - x=[x; y]; - end - ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x; - end - - % estimate efferent effects. - % ARis based on LSR units. LSR channels are 1:nBF - if nANfiberTypes>1 % AR is multi-channel only - ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt; - [ARAttSeg, ARboundary] = ... - filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary); - ARAttSeg=ARAttSeg-ARrateThreshold; - ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths - % scale up to dt from ANdt - x= repmat(ARAttSeg, ANspeedUpFactor,1); - x=reshape(x,1,segmentLength); - ARattenuation(segmentStartPTR:segmentEndPTR)=... - (1-ARrateToAttenuationFactor* x); - ARattenuation(ARattenuation<0)=0.001; - else - % single channel model; disable AR - ARattenuation(segmentStartPTR:segmentEndPTR)=... - ones(1,segmentLength); - end - - % MOC attenuation using HSR response only - % Separate MOC effect for each BF - HSRbegins=nBFs*(nANfiberTypes-1)+1; - rates=ICspikes(HSRbegins:end,:)/ANdt; - for idx=1:nBFs - [smoothedRates, MOCboundary{idx}] = ... - filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... - MOCboundary{idx}); - MOCattSegment(idx,:)=smoothedRates; - % expand timescale back to model dt from ANdt - x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1); - x= reshape(x,1,segmentLength); - MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... - (1- MOCrateToAttenuationFactor* x); - end - MOCattenuation(MOCattenuation<0)=0.04; - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(ICspikes, plotInstructions); - - end % AN_spikesOrProbability - segmentStartPTR=segmentStartPTR+segmentLength; - reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength; - - -end % segment - -path(restorePath)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAP/MAPrunner.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,71 @@ +function MAPrunner(MAPparamsName, AN_spikesOrProbability, ... + signalCharacteristics, paramChanges, showMapOptions) + +dbstop if error +restorePath=path; +addpath (['..' filesep 'MAP'], ['..' filesep 'wavFileStore'], ... + ['..' filesep 'utilities']) + + +%% #3 pure tone, harmonic sequence or speech file input +signalType= signalCharacteristics.type; +sampleRate= signalCharacteristics.sampleRate; +duration=signalCharacteristics.duration; % seconds +rampDuration=signalCharacteristics.rampDuration; % raised cosine ramp (seconds) +beginSilence=signalCharacteristics.beginSilence; +endSilence=signalCharacteristics.endSilence; +toneFrequency= signalCharacteristics.toneFrequency; % or a pure tone (Hz) +leveldBSPL=signalCharacteristics.leveldBSPL; + +BFlist=-1; + + +%% Generate stimuli + +switch signalType + case 'tones' + % Create pure tone stimulus + dt=1/sampleRate; % seconds + time=dt: dt: duration; + inputSignal=sum(sin(2*pi*toneFrequency'*time), 1); + amp=10^(leveldBSPL/20)*28e-6; % converts to Pascals (peak) + inputSignal=amp*inputSignal; + % apply ramps + % catch rampTime error + if rampDuration>0.5*duration, rampDuration=duration/2; end + rampTime=dt:dt:rampDuration; + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(time)-length(rampTime))]; + inputSignal=inputSignal.*ramp; + ramp=fliplr(ramp); + inputSignal=inputSignal.*ramp; + % add silence + intialSilence= zeros(1,round(beginSilence/dt)); + finalSilence= zeros(1,round(endSilence/dt)); + inputSignal= [intialSilence inputSignal finalSilence]; + + case 'file' + %% file input simple or mixed + [inputSignal sampleRate]=wavread(fileName); + dt=1/sampleRate; + inputSignal=inputSignal(:,1); + targetRMS=20e-6*10^(leveldBSPL/20); + rms=(mean(inputSignal.^2))^0.5; + amp=targetRMS/rms; + inputSignal=inputSignal*amp; + intialSilence= zeros(1,round(0.1/dt)); + finalSilence= zeros(1,round(0.2/dt)); + inputSignal= [intialSilence inputSignal' finalSilence]; +end + + +%% run the model + +MAP1_14(inputSignal, sampleRate, BFlist, ... + MAPparamsName, AN_spikesOrProbability, paramChanges); + +%% the model run is now complete. Now display the results +UTIL_showMAP(showMapOptions, paramChanges) + +path(restorePath) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAP/old MAP files/MAP1_14AP.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,1254 @@ + +function MAP1_14AP(inputSignal, sampleRate, BFlist, MAPparamsName, ... + AN_spikesOrProbability, paramChanges) +% To test this function use test_MAP1_14 in this folder +% +% All arguments are mandatory. +% +% BFlist is a vector of BFs but can be '-1' to allow MAPparams to choose +% MAPparamsName='Normal'; % source of model parameters +% AN_spikesOrProbability='spikes'; % or 'probability' +% paramChanges is a cell array of strings that can be used to make last +% minute parameter changes, e.g., to simulate OHC loss +% e.g. paramChanges{1}= 'DRNLParams.a=0;'; % disable OHCs +% e.g. paramchanges={}; % no changes +% The model parameters are established in the MAPparams<***> file +% and stored as global + +restorePath=path; +addpath (['..' filesep 'parameterStore']) + + +CONVOLUTION_CHANGE_TEST = 0; %for debug + + +global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams +global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams + +% All of the results of this function are stored as global +global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... + savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... + DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... + IHCoutput ANprobRateOutput ANoutput savePavailable tauCas ... + CNoutput ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation + +% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be +% needed by the user; so the following will suffice +% global ANdt ICoutput ANprobRateOutput + +% Note that sampleRate has not changed from the original function call and +% ANprobRateOutput is sampled at this rate +% However ANoutput, CNoutput and IC output are stored as logical +% 'spike' matrices using a lower sample rate (see ANdt). + +% When AN_spikesOrProbability is set to probability, +% no spike matrices are computed. +% When AN_spikesOrProbability is set to 'spikes', +% no probability output is computed + +% Efferent control variables are ARattenuation and MOCattenuation +% These are scalars between 1 (no attenuation) and 0. +% They are represented with dt=1/sampleRate (not ANdt) +% They are computed using either AN probability rate output +% or IC (spikes) output as approrpriate. +% AR is computed using across channel activity +% MOC is computed on a within-channel basis. + +if nargin<1 + error(' MAP1_14 is not a script but a function that must be called') +end + +if nargin<6 + paramChanges=[]; +end +% Read parameters from MAPparams<***> file in 'parameterStore' folder +% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<> +% It means that the calling program allows MAPparams to specify the list +cmd=['method=MAPparams' MAPparamsName ... + '(BFlist, sampleRate, 0, paramChanges);']; +eval(cmd); +BFlist=DRNLParams.nonlinCFs; + +% save as global for later plotting if required +savedBFlist=BFlist; +saveAN_spikesOrProbability=AN_spikesOrProbability; +saveMAPparamsName=MAPparamsName; + +dt=1/sampleRate; +duration=length(inputSignal)/sampleRate; +% segmentDuration is specified in parameter file (must be >efferent delay) +segmentDuration=method.segmentDuration; +segmentLength=round(segmentDuration/ dt); +segmentTime=dt*(1:segmentLength); % used in debugging plots + +% all spiking activity is computed using longer epochs +ANspeedUpFactor=AN_IHCsynapseParams.ANspeedUpFactor; % e.g.5 times + +% inputSignal must be row vector +[r c]=size(inputSignal); +if r>c, inputSignal=inputSignal'; end % transpose +% ignore stereo signals +inputSignal=inputSignal(1,:); % drop any second channel +savedInputSignal=inputSignal; + +% Segment the signal +% The sgment length is given but the signal length must be adjusted to be a +% multiple of both the segment length and the reduced segmentlength +[nSignalRows signalLength]=size(inputSignal); +segmentLength=ceil(segmentLength/ANspeedUpFactor)*ANspeedUpFactor; +% Make the signal length a whole multiple of the segment length +nSignalSegments=ceil(signalLength/segmentLength); +padSize=nSignalSegments*segmentLength-signalLength; +pad=zeros(nSignalRows,padSize); +inputSignal=[inputSignal pad]; +[ignore signalLength]=size(inputSignal); + +% AN (spikes) is computed at a lower sample rate when spikes required +% so it has a reduced segment length (see 'ANspeeUpFactor' above) +% AN CN and IC all use this sample interval +ANdt=dt*ANspeedUpFactor; +reducedSegmentLength=round(segmentLength/ANspeedUpFactor); +reducedSignalLength= round(signalLength/ANspeedUpFactor); + +%% Initialise with respect to each stage before computing +% by allocating memory, +% by computing constants +% by establishing easy to read variable names +% The computations are made in segments and boundary conditions must +% be established and stored. These are found in variables with +% 'boundary' or 'bndry' in the name + +%% OME --- +% external ear resonances +OMEexternalResonanceFilters=OMEParams.externalResonanceFilters; +[nOMEExtFilters c]=size(OMEexternalResonanceFilters); +% details of external (outer ear) resonances +OMEgaindBs=OMEexternalResonanceFilters(:,1); +OMEgainScalars=10.^(OMEgaindBs/20); +OMEfilterOrder=OMEexternalResonanceFilters(:,2); +OMElowerCutOff=OMEexternalResonanceFilters(:,3); +OMEupperCutOff=OMEexternalResonanceFilters(:,4); +% external resonance coefficients +ExtFilter_b=cell(nOMEExtFilters,1); +ExtFilter_a=cell(nOMEExtFilters,1); +for idx=1:nOMEExtFilters + Nyquist=sampleRate/2; + [b, a] = butter(OMEfilterOrder(idx), ... + [OMElowerCutOff(idx) OMEupperCutOff(idx)]... + /Nyquist); + ExtFilter_b{idx}=b; + ExtFilter_a{idx}=a; +end +OMEExtFilterBndry=cell(2,1); +OMEextEarPressure=zeros(1,signalLength); % pressure at tympanic membrane + +% pressure to velocity conversion using smoothing filter (50 Hz cutoff) +tau=1/(2*pi*50); +a1=dt/tau-1; a0=1; +b0=1+ a1; +TMdisp_b=b0; TMdisp_a=[a0 a1]; +% figure(9), freqz(TMdisp_b, TMdisp_a) +OME_TMdisplacementBndry=[]; + +% OME high pass (simulates poor low frequency stapes response) +OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff; +Nyquist=sampleRate/2; +[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high'); +% figure(10), freqz(stapesDisp_b, stapesDisp_a) + +OMEhighPassBndry=[]; + +% OMEampStapes might be reducdant (use OMEParams.stapesScalar) +stapesScalar= OMEParams.stapesScalar; + +% Acoustic reflex +efferentDelayPts=round(OMEParams.ARdelay/dt); +% smoothing filter +a1=dt/OMEParams.ARtau-1; a0=1; +b0=1+ a1; +ARfilt_b=b0; ARfilt_a=[a0 a1]; + +ARattenuation=ones(1,signalLength); +ARrateThreshold=OMEParams.ARrateThreshold; % may not be used +ARrateToAttenuationFactor=OMEParams.rateToAttenuationFactor; +ARrateToAttenuationFactorProb=OMEParams.rateToAttenuationFactorProb; +ARboundary=[]; +ARboundaryProb=0; + +% save complete OME record (stapes displacement) +OMEoutput=zeros(1,signalLength); +TMoutput=zeros(1,signalLength); + +%% BM --- +% BM is represented as a list of locations identified by BF +DRNL_BFs=BFlist; +nBFs= length(DRNL_BFs); + +% DRNLchannelParameters=DRNLParams.channelParameters; +DRNLresponse= zeros(nBFs, segmentLength); + +MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor; +rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb; +MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb; + +% smoothing filter for MOC +a1=dt/DRNLParams.MOCtau-1; a0=1; +b0=1+ a1; +MOCfilt_b=b0; MOCfilt_a=[a0 a1]; +% figure(9), freqz(stapesDisp_b, stapesDisp_a) +MOCboundary=cell(nBFs,1); +MOCprobBoundary=cell(nBFs,1); + +MOCattSegment=zeros(nBFs,reducedSegmentLength); +MOCattenuation=ones(nBFs,signalLength); + +if DRNLParams.a>0 + DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ... + log10(DRNLParams.b/DRNLParams.a)); +else + DRNLcompressionThreshold=inf; +end + +DRNLlinearOrder= DRNLParams.linOrder; +DRNLnonlinearOrder= DRNLParams.nonlinOrder; + +DRNLa=DRNLParams.a; +DRNLb=DRNLParams.b; +DRNLc=DRNLParams.c; +linGAIN=DRNLParams.g; +% +% gammatone filter coefficients for linear pathway +bw=DRNLParams.linBWs'; +phi = 2 * pi * bw * dt; +cf=DRNLParams.linCFs'; +theta = 2 * pi * cf * dt; +cos_theta = cos(theta); +sin_theta = sin(theta); +alpha = -exp(-phi).* cos_theta; +b0 = ones(nBFs,1); +b1 = 2 * alpha; +b2 = exp(-2 * phi); +z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; +z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; +z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; +tf = (z2 + z3) ./ z1; +a0 = abs(tf); +a1 = alpha .* a0; +GTlin_a = [b0, b1, b2]; +GTlin_b = [a0, a1]; +GTlinOrder=DRNLlinearOrder; +GTlinBdry=cell(nBFs,GTlinOrder); + +% nonlinear gammatone filter coefficients +bw=DRNLParams.nlBWs'; +phi = 2 * pi * bw * dt; +cf=DRNLParams.nonlinCFs'; +theta = 2 * pi * cf * dt; +cos_theta = cos(theta); +sin_theta = sin(theta); +alpha = -exp(-phi).* cos_theta; +b0 = ones(nBFs,1); +b1 = 2 * alpha; +b2 = exp(-2 * phi); +z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; +z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; +z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; +tf = (z2 + z3) ./ z1; +a0 = abs(tf); +a1 = alpha .* a0; +GTnonlin_a = [b0, b1, b2]; +GTnonlin_b = [a0, a1]; +GTnonlinOrder=DRNLnonlinearOrder; +GTnonlinBdry1=cell(nBFs, GTnonlinOrder); +GTnonlinBdry2=cell(nBFs, GTnonlinOrder); + +% complete BM record (BM displacement) +DRNLoutput=zeros(nBFs, signalLength); + + +%% IHC --- +% IHC cilia activity and receptor potential +% viscous coupling between BM and stereocilia displacement +% Nyquist=sampleRate/2; +% IHCcutoff=1/(2*pi*IHC_cilia_RPParams.tc); +% [IHCciliaFilter_b,IHCciliaFilter_a]=... +% butter(1, IHCcutoff/Nyquist, 'high'); +a1=dt/IHC_cilia_RPParams.tc-1; a0=1; +b0=1+ a1; +% high pass (i.e. low pass reversed) +IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0; +% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a) + +IHCciliaBndry=cell(nBFs,1); + +% IHC apical conductance (Boltzman function) +IHC_C= IHC_cilia_RPParams.C; +IHCu0= IHC_cilia_RPParams.u0; +IHCu1= IHC_cilia_RPParams.u1; +IHCs0= IHC_cilia_RPParams.s0; +IHCs1= IHC_cilia_RPParams.s1; +IHCGmax= IHC_cilia_RPParams.Gmax; +IHCGa= IHC_cilia_RPParams.Ga; % (leakage) + +IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1))); +IHCrestingCiliaCond=IHCGu0; + +% Receptor potential +IHC_Cab= IHC_cilia_RPParams.Cab; +IHC_Gk= IHC_cilia_RPParams.Gk; +IHC_Et= IHC_cilia_RPParams.Et; +IHC_Ek= IHC_cilia_RPParams.Ek; +IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc; + +IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk); + +IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage +IHC_RP= zeros(nBFs,segmentLength); + +% complete record of IHC receptor potential (V) +IHCciliaDisplacement= zeros(nBFs,segmentLength); +IHCoutput= zeros(nBFs,signalLength); +IHC_cilia_output= zeros(nBFs,signalLength); + + +%% pre-synapse --- +% Each BF is replicated using a different fiber type to make a 'channel' +% The number of channels is nBFs x nANfiberTypes +% Fiber types are specified in terms of tauCa +nANfiberTypes= length(IHCpreSynapseParams.tauCa); +tauCas= IHCpreSynapseParams.tauCa; +nANchannels= nANfiberTypes*nBFs; +synapticCa= zeros(nANchannels,segmentLength); + +% Calcium control (more calcium, greater release rate) +ECa=IHCpreSynapseParams.ECa; +gamma=IHCpreSynapseParams.gamma; +beta=IHCpreSynapseParams.beta; +tauM=IHCpreSynapseParams.tauM; +mICa=zeros(nANchannels,segmentLength); +GmaxCa=IHCpreSynapseParams.GmaxCa; +synapse_z= IHCpreSynapseParams.z; +synapse_power=IHCpreSynapseParams.power; + +% tauCa vector is established across channels to allow vectorization +% (one tauCa per channel). Do not confuse with tauCas (one pre fiber type) +tauCa=repmat(tauCas, nBFs,1); +tauCa=reshape(tauCa, nANchannels, 1); + +% presynapse startup values (vectors, length:nANchannels) +% proportion (0 - 1) of Ca channels open at IHCrestingV +mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)... + *ones(nBFs*nANfiberTypes,1); +% corresponding startup currents +ICaCurrent= (GmaxCa*mICaCurrent.^3) * (IHCrestingV-ECa); +CaCurrent= ICaCurrent.*tauCa; + +% vesicle release rate at startup (one per channel) +% kt0 is used only at initialisation +kt0= -synapse_z * CaCurrent.^synapse_power; + + +%% AN --- +% each row of the AN matrices represents one AN fiber +% The results computed either for probabiities *or* for spikes (not both) +% Spikes are necessary if CN and IC are to be computed +nFibersPerChannel= AN_IHCsynapseParams.numFibers; +nANfibers= nANchannels*nFibersPerChannel; +AN_refractory_period= AN_IHCsynapseParams.refractory_period; + +y=AN_IHCsynapseParams.y; +l=AN_IHCsynapseParams.l; +x=AN_IHCsynapseParams.x; +r=AN_IHCsynapseParams.r; +M=round(AN_IHCsynapseParams.M); + +% probability (NB initial 'P' on everything) +PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nANchannels,1); +PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nANchannels,1); +PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nANchannels,1); +PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nANchannels,1); +PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt; +PAN_M=round(AN_IHCsynapseParams.M); + +% compute starting values +Pcleft = kt0* y* M ./ (y*(l+r)+ kt0* l); +Pavailable = Pcleft*(l+r)./kt0; +Preprocess = Pcleft*r/x; % canbe fractional + +ANprobability=zeros(nANchannels,segmentLength); +ANprobRateOutput=zeros(nANchannels,signalLength); +lengthAbsRefractoryP= round(AN_refractory_period/dt); +% special variables for monitoring synaptic cleft (specialists only) +savePavailableSeg=zeros(nANchannels,segmentLength); +savePavailable=zeros(nANchannels,signalLength); + +% spikes % ! ! ! ! ! ! ! ! +lengthAbsRefractory= round(AN_refractory_period/ANdt); + +AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1); +AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1); +AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1); +AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1); +AN_rdt_plus_ldt= AN_rdt + AN_ldt; +AN_M= round(AN_IHCsynapseParams.M); + +% kt0 is initial release rate +% Establish as a vector (length=channel x number of fibers) +kt0= repmat(kt0', nFibersPerChannel, 1); +kt0=reshape(kt0, nANfibers,1); + +% starting values for reservoirs +AN_cleft = kt0* y* M ./ (y*(l+r)+ kt0* l); +AN_available = round(AN_cleft*(l+r)./kt0); %must be integer +AN_reprocess = AN_cleft*r/x; + +% output is in a logical array spikes = 1/ 0. +ANspikes= false(nANfibers,reducedSegmentLength); +ANoutput= false(nANfibers,reducedSignalLength); + + +%% CN (first brain stem nucleus - could be any subdivision of CN) +% Input to a CN neuorn is a random selection of AN fibers within a channel +% The number of AN fibers used is ANfibersFanInToCN +% CNtauGk (Potassium time constant) determines the rate of firing of +% the unit when driven hard by a DC input (not normally >350 sp/s) +% If there is more than one value, everything is replicated accordingly + +ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers; +ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron; + +CNtauGk=MacGregorMultiParams.tauGk; % row vector of CN types (by tauGk) +nCNtauGk=length(CNtauGk); + +% the total number of 'channels' is now greater +nCNchannels=nANchannels*nCNtauGk; + +nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF; +tauGk=repmat(CNtauGk, nCNneuronsPerChannel,1); +tauGk=reshape(tauGk,nCNneuronsPerChannel*nCNtauGk,1); + +% Now the number of neurons has been increased +nCNneurons=nCNneuronsPerChannel*nCNchannels; +CNmembranePotential=zeros(nCNneurons,reducedSegmentLength); + +% establish which ANfibers (by name) feed into which CN nuerons +CNinputfiberLists=zeros(nANchannels*nCNneuronsPerChannel, ANfibersFanInToCN); +unitNo=1; +for ch=1:nANchannels + % Each channel contains a number of units =length(listOfFanInValues) + for idx=1:nCNneuronsPerChannel + for idx2=1:nCNtauGk + fibersUsed=(ch-1)*ANavailableFibersPerChan + ... + ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan); + CNinputfiberLists(unitNo,:)=fibersUsed; + unitNo=unitNo+1; + end + end +end + +% input to CN units +AN_PSTH=zeros(nCNneurons,reducedSegmentLength); + +% Generate CNalphaFunction function +% by which spikes are converted to post-synaptic currents +CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq; +CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike; +CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq); +t=ANdt:ANdt:5*CNspikeToCurrentTau; +CNalphaFunction= (1 / ... + CNspikeToCurrentTau)*t.*exp(-t /CNspikeToCurrentTau); +CNalphaFunction=CNalphaFunction*CNcurrentPerSpike; + +% figure(98), plot(t,CNalphaFunction) +% working memory for implementing convolution + +CNcurrentTemp=... + zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1); +% trailing alphas are parts of humps carried forward to the next segment +CNtrailingAlphas=zeros(nCNneurons,length(CNalphaFunction)); + +CN_tauM=MacGregorMultiParams.tauM; +CN_tauTh=MacGregorMultiParams.tauTh; +CN_cap=MacGregorMultiParams.Cap; +CN_c=MacGregorMultiParams.c; +CN_b=MacGregorMultiParams.dGkSpike; +CN_Ek=MacGregorMultiParams.Ek; +CN_Eb= MacGregorMultiParams.Eb; +CN_Er=MacGregorMultiParams.Er; +CN_Th0= MacGregorMultiParams.Th0; +CN_E= zeros(nCNneurons,1); +CN_Gk= zeros(nCNneurons,1); +CN_Th= MacGregorMultiParams.Th0*ones(nCNneurons,1); +CN_Eb=CN_Eb.*ones(nCNneurons,1); +CN_Er=CN_Er.*ones(nCNneurons,1); +CNtimeSinceLastSpike=zeros(nCNneurons,1); +% tauGk is the main distinction between neurons +% in fact they are all the same in the standard model +tauGk=repmat(tauGk,nANchannels,1); + +CNoutput=false(nCNneurons,reducedSignalLength); + + +%% MacGregor (IC - second nucleus) -------- +nICcells=nANchannels*nCNtauGk; % one cell per channel +CN_PSTH=zeros(nICcells ,reducedSegmentLength); + +ICspikeWidth=0.00015; % this may need revisiting +epochsPerSpike=round(ICspikeWidth/ANdt); +if epochsPerSpike<1 + error(['MacGregorMulti: sample rate too low to support ' ... + num2str(ICspikeWidth*1e6) ' microsec spikes']); +end + +% short names +IC_tauM=MacGregorParams.tauM; +IC_tauGk=MacGregorParams.tauGk; +IC_tauTh=MacGregorParams.tauTh; +IC_cap=MacGregorParams.Cap; +IC_c=MacGregorParams.c; +IC_b=MacGregorParams.dGkSpike; +IC_Th0=MacGregorParams.Th0; +IC_Ek=MacGregorParams.Ek; +IC_Eb= MacGregorParams.Eb; +IC_Er=MacGregorParams.Er; + +IC_E=zeros(nICcells,1); +IC_Gk=zeros(nICcells,1); +IC_Th=IC_Th0*ones(nICcells,1); + +% Dendritic filtering, all spikes are replaced by CNalphaFunction functions +ICdendriteLPfreq= MacGregorParams.dendriteLPfreq; +ICcurrentPerSpike=MacGregorParams.currentPerSpike; +ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq); +t=ANdt:ANdt:3*ICspikeToCurrentTau; +IC_CNalphaFunction= (ICcurrentPerSpike / ... + ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau); +% figure(98), plot(t,IC_CNalphaFunction) + +% working space for implementing alpha function +ICcurrentTemp=... + zeros(nICcells,reducedSegmentLength+length(IC_CNalphaFunction)-1); +ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction)); + +ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength); +ICoutput=false(nICcells,reducedSignalLength); + +ICmembranePotential=zeros(nICcells,reducedSegmentLength); +ICmembraneOutput=zeros(nICcells,signalLength); + + +%% Main program %% %% %% %% %% %% %% %% %% %% %% %% %% %% + +% Compute the entire model for each segment +segmentStartPTR=1; +reducedSegmentPTR=1; % when sampling rate is reduced +while segmentStartPTR<signalLength + segmentEndPTR=segmentStartPTR+segmentLength-1; + % shorter segments after speed up. + shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1; + + inputPressureSegment=inputSignal... + (:,segmentStartPTR:segmentStartPTR+segmentLength-1); + + % segment debugging plots + % figure(98) + % plot(segmentTime,inputPressureSegment), title('signalSegment') + + + % OME ---------------------- + + % OME Stage 1: external resonances. Add to inputSignal pressure wave + y=inputPressureSegment; + for n=1:nOMEExtFilters + % any number of resonances can be used + [x OMEExtFilterBndry{n}] = ... + filter(ExtFilter_b{n},ExtFilter_a{n},... + inputPressureSegment, OMEExtFilterBndry{n}); + x= x* OMEgainScalars(n); + % This is a parallel resonance so add it + y=y+x; + end + inputPressureSegment=y; + OMEextEarPressure(segmentStartPTR:segmentEndPTR)= inputPressureSegment; + + % OME stage 2: convert input pressure (velocity) to + % tympanic membrane(TM) displacement using low pass filter + [TMdisplacementSegment OME_TMdisplacementBndry] = ... + filter(TMdisp_b,TMdisp_a,inputPressureSegment, ... + OME_TMdisplacementBndry); + % and save it + TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment; + + % OME stage 3: middle ear high pass effect to simulate stapes inertia + [stapesDisplacement OMEhighPassBndry] = ... + filter(stapesDisp_b,stapesDisp_a,TMdisplacementSegment, ... + OMEhighPassBndry); + + % OME stage 4: apply stapes scalar + stapesDisplacement=stapesDisplacement*stapesScalar; + + % OME stage 5: acoustic reflex stapes attenuation + % Attenuate the TM response using feedback from LSR fiber activity + if segmentStartPTR>efferentDelayPts + stapesDisplacement= stapesDisplacement.*... + ARattenuation(segmentStartPTR-efferentDelayPts:... + segmentEndPTR-efferentDelayPts); + end + + % segment debugging plots + % figure(98) + % plot(segmentTime, stapesDisplacement), title ('stapesDisplacement') + + % and save + OMEoutput(segmentStartPTR:segmentEndPTR)= stapesDisplacement; + + + %% BM ------------------------------ + % Each location is computed separately + for BFno=1:nBFs + + % *linear* path + linOutput = stapesDisplacement * linGAIN; % linear gain + for order = 1 : GTlinOrder + [linOutput GTlinBdry{BFno,order}] = ... + filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry{BFno,order}); + end + + % *nonLinear* path + % efferent attenuation (0 <> 1) + if segmentStartPTR>efferentDelayPts + MOC=MOCattenuation(BFno, segmentStartPTR-efferentDelayPts:... + segmentEndPTR-efferentDelayPts); + else % no MOC available yet + MOC=ones(1, segmentLength); + end + % apply MOC to nonlinear input function + nonlinOutput=stapesDisplacement.* MOC; + + % first gammatone filter (nonlin path) + for order = 1 : GTnonlinOrder + [nonlinOutput GTnonlinBdry1{BFno,order}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + nonlinOutput, GTnonlinBdry1{BFno,order}); + end + % broken stick instantaneous compression + y= nonlinOutput.* DRNLa; % linear section. + % compress parts of the signal above the compression threshold + abs_x = abs(nonlinOutput); + idx=find(abs_x>DRNLcompressionThreshold); + if ~isempty(idx)>0 + y(idx)=sign(y(idx)).* (DRNLb*abs_x(idx).^DRNLc); + end + nonlinOutput=y; + + % second filter removes distortion products + for order = 1 : GTnonlinOrder + [ nonlinOutput GTnonlinBdry2{BFno,order}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + nonlinOutput, GTnonlinBdry2{BFno,order}); + end + + % combine the two paths to give the DRNL displacement + DRNLresponse(BFno,:)=linOutput+nonlinOutput; + end % BF + + % segment debugging plots + % figure(98) + % if size(DRNLresponse,1)>3 + % imagesc(DRNLresponse) % matrix display + % title('DRNLresponse'); % single or double channel response + % else + % plot(segmentTime, DRNLresponse) + % end + + % and save it + DRNLoutput(:, segmentStartPTR:segmentEndPTR)= DRNLresponse; + + + %% IHC ------------------------------------ + % BM displacement to IHCciliaDisplacement is a high-pass filter + % because of viscous coupling + for idx=1:nBFs + [IHCciliaDisplacement(idx,:) IHCciliaBndry{idx}] = ... + filter(IHCciliaFilter_b,IHCciliaFilter_a, ... + DRNLresponse(idx,:), IHCciliaBndry{idx}); + end + + % apply scalar + IHCciliaDisplacement=IHCciliaDisplacement* IHC_C; + + % and save it + IHC_cilia_output(:,segmentStartPTR:segmentStartPTR+segmentLength-1)=... + IHCciliaDisplacement; + + % compute apical conductance + G=IHCGmax./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*... + (1+exp(-(IHCciliaDisplacement-IHCu1)/IHCs1))); + Gu=G + IHCGa; + + % Compute receptor potential + for idx=1:segmentLength + IHC_Vnow=IHC_Vnow+ (-Gu(:, idx).*(IHC_Vnow-IHC_Et)-... + IHC_Gk*(IHC_Vnow-IHC_Ekp))* dt/IHC_Cab; + IHC_RP(:,idx)=IHC_Vnow; + end + + % segment debugging plots + % if size(IHC_RP,1)>3 + % surf(IHC_RP), shading interp, title('IHC_RP') + % else + % plot(segmentTime, IHC_RP) + % end + + % and save it + IHCoutput(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=IHC_RP; + + + %% synapse ----------------------------- + % Compute the vesicle release rate for each fiber type at each BF + % replicate IHC_RP for each fiber type + Vsynapse=repmat(IHC_RP, nANfiberTypes,1); + + % look-up table of target fraction channels open for a given IHC_RP + mICaINF= 1./( 1 + exp(-gamma * Vsynapse) /beta); + % fraction of channel open - apply time constant + for idx=1:segmentLength + % mICaINF is the current 'target' value of mICa + mICaCurrent=mICaCurrent+(mICaINF(:,idx)-mICaCurrent)*dt./tauM; + mICa(:,idx)=mICaCurrent; + end + + ICa= (GmaxCa* mICa.^3) .* (Vsynapse- ECa); + + for idx=1:segmentLength + CaCurrent=CaCurrent + ICa(:,idx)*dt - CaCurrent*dt./tauCa; + synapticCa(:,idx)=CaCurrent; + end + synapticCa=-synapticCa; % treat IHCpreSynapseParams as positive substance + + % NB vesicleReleaseRate is /s and is independent of dt + vesicleReleaseRate = synapse_z * synapticCa.^synapse_power; % rate + + % segment debugging plots + % if size(vesicleReleaseRate,1)>3 + % surf(vesicleReleaseRate), shading interp, title('vesicleReleaseRate') + % else + % plot(segmentTime, vesicleReleaseRate) + % end + + + %% AN + switch AN_spikesOrProbability + case 'probability' + % No refractory effect is applied + for t = 1:segmentLength; + M_Pq=PAN_M-Pavailable; + M_Pq(M_Pq<0)=0; + Preplenish = M_Pq .* PAN_ydt; + Pejected = Pavailable.* vesicleReleaseRate(:,t)*dt; + Preprocessed = M_Pq.*Preprocess.* PAN_xdt; + + ANprobability(:,t)= min(Pejected,1); + reuptakeandlost= PAN_rdt_plus_ldt .* Pcleft; + reuptake= PAN_rdt.* Pcleft; + + Pavailable= Pavailable+ Preplenish- Pejected+ Preprocessed; + Pcleft= Pcleft + Pejected - reuptakeandlost; + Preprocess= Preprocess + reuptake - Preprocessed; + Pavailable(Pavailable<0)=0; + savePavailableSeg(:,t)=Pavailable; % synapse tracking + end + % and save it as *rate* + ANrate=ANprobability/dt; + ANprobRateOutput(:, segmentStartPTR:... + segmentStartPTR+segmentLength-1)= ANrate; + % monitor synapse contents (only sometimes used) + savePavailable(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=... + savePavailableSeg; + + % Estimate efferent effects. ARattenuation (0 <> 1) + % acoustic reflex + [r c]=size(ANrate); + if r>nBFs % Only if LSR fibers are computed + ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF + % smooth + [ARAttSeg, ARboundaryProb] = ... + filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb); + ARAttSeg=ARAttSeg-ARrateThreshold; + ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths + ARattenuation(segmentStartPTR:segmentEndPTR)=... + (1-ARrateToAttenuationFactorProb.* ARAttSeg); + end + % plot(ARattenuation) + + % MOC attenuation + % within-channel HSR response only + HSRbegins=nBFs*(nANfiberTypes-1)+1; + rates=ANrate(HSRbegins:end,:); + if rateToAttenuationFactorProb<0 + % negative factor implies a fixed attenuation + MOCattenuation(:,segmentStartPTR:segmentEndPTR)= ... + ones(size(rates))* -rateToAttenuationFactorProb; + else + for idx=1:nBFs + [smoothedRates, MOCprobBoundary{idx}] = ... + filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... + MOCprobBoundary{idx}); + smoothedRates=smoothedRates-MOCrateThresholdProb; + smoothedRates(smoothedRates<0)=0; + MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... + (1- smoothedRates* rateToAttenuationFactorProb); + end + end + MOCattenuation(MOCattenuation<0)=0.001; + + % plot(MOCattenuation) + + + case 'spikes' + ANtimeCount=0; + % implement speed upt + for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength; + ANtimeCount=ANtimeCount+1; + % convert release rate to probabilities + releaseProb=vesicleReleaseRate(:,t)*ANdt; + % releaseProb is the release probability per channel + % but each channel has many synapses + releaseProb=repmat(releaseProb',nFibersPerChannel,1); + releaseProb=reshape(releaseProb, nFibersPerChannel*nANchannels,1); + + % AN_available=round(AN_available); % vesicles must be integer, (?needed) + M_q=AN_M- AN_available; % number of missing vesicles + M_q(M_q<0)= 0; % cannot be less than 0 + + % AN_N1 converts probability to discrete events + % it considers each event that might occur + % (how many vesicles might be released) + % and returns a count of how many were released + + % slow line +% probabilities= 1-(1-releaseProb).^AN_available; + probabilities= 1-intpow((1-releaseProb), AN_available); + ejected= probabilities> rand(length(AN_available),1); + + reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft; + reuptake = AN_rdt.* AN_cleft; + + % slow line +% probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; + probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q); + reprocessed= probabilities>rand(length(M_q),1); + + % slow line +% probabilities= 1-(1-AN_ydt).^M_q; + probabilities= 1-intpow((1-AN_ydt), M_q); + + replenish= probabilities>rand(length(M_q),1); + + AN_available = AN_available + replenish - ejected ... + + reprocessed; + AN_cleft = AN_cleft + ejected - reuptakeandlost; + AN_reprocess = AN_reprocess + reuptake - reprocessed; + + % ANspikes is logical record of vesicle release events>0 + ANspikes(:, ANtimeCount)= ejected; + end % t + + % zero any events that are preceded by release events ... + % within the refractory period + % The refractory period consist of two periods + % 1) the absolute period where no spikes occur + % 2) a relative period where a spike may occur. This relative + % period is realised as a variable length interval + % where the length is chosen at random + % (esentially a linear ramp up) + + % Andreas has a fix for this + for t = 1:ANtimeCount-2*lengthAbsRefractory; + % identify all spikes across fiber array at time (t) + % idx is a list of channels where spikes occurred + % ?? try sparse matrices? + idx=find(ANspikes(:,t)); + for j=idx % consider each spike + % specify variable refractory period + % between abs and 2*abs refractory period + nPointsRefractory=lengthAbsRefractory+... + round(rand*lengthAbsRefractory); + % disable spike potential for refractory period + % set all values in this range to 0 + ANspikes(j,t+1:t+nPointsRefractory)=0; + end + end %t + + % segment debugging + % plotInstructions.figureNo=98; + % plotInstructions.displaydt=ANdt; + % plotInstructions.numPlots=1; + % plotInstructions.subPlotNo=1; + % UTIL_plotMatrix(ANspikes, plotInstructions); + + % and save it. NB, AN is now on 'speedUp' time + ANoutput(:, reducedSegmentPTR: shorterSegmentEndPTR)=ANspikes; + + + %% CN Macgregor first neucleus ------------------------------- + % input is from AN so ANdt is used throughout + % Each CNneuron has a unique set of input fibers selected + % at random from the available AN fibers (CNinputfiberLists) + + % Create the dendritic current for that neuron + % First get input spikes to this neuron + synapseNo=1; + for ch=1:nCNchannels + for idx=1:nCNneuronsPerChannel + % determine candidate fibers for this unit + fibersUsed=CNinputfiberLists(synapseNo,:); + % ANpsth has a bin width of ANdt + % (just a simple sum across fibers) + AN_PSTH(synapseNo,:) = ... + sum(ANspikes(fibersUsed,:), 1); + synapseNo=synapseNo+1; + end + end + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + % One alpha function per spike + [alphaRows alphaCols]=size(CNtrailingAlphas); + + for unitNo=1:nCNneurons + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + CNcurrentTemp0(unitNo,:)= ... + conv(AN_PSTH(unitNo,:),CNalphaFunction); + + + + CNcurrentTemp(unitNo,:)= ... + conv2(AN_PSTH(unitNo,:),CNalphaFunction); + % Changed conv to conv2 because it runs faster. (Andreas) + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% +% +% f = CNalphaFunction; +% g = AN_PSTH(unitNo,:); +% +% +% g = [g zeros(1,length(f)-1)]; +% +% spikePos = find(g)'; +% +% result = zeros(1,length(g)); +% +% for index = 1:length(spikePos) +% k = spikePos(index); +% result(k:(k+length(f)-1)) = result(k:(k+length(f)-1)) + g(k)*f; +% end +% +% CNcurrentTemp2(unitNo,:) = result; + + + end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + + f = CNalphaFunction; + g = AN_PSTH; + + g = [g zeros(size(g,1),length(f)-1)]; + + [r c] = find(g); + + CNcurrentTemp2 = zeros(size(g)); + + for index = 1:length(r) + + row = r(index); + col = c(index); + + CNcurrentTemp2(row,col:col+length(f)-1) = CNcurrentTemp2(row,col:col+length(f)-1) + f*g(row,col); + + end + + + +CONVOLUTION_CHANGE_TEST = CONVOLUTION_CHANGE_TEST + sum(abs(CNcurrentTemp2 - CNcurrentTemp))+ sum(abs(CNcurrentTemp0 - CNcurrentTemp)); + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + +% disp(['sum(AN_PSTH)= ' num2str(sum(AN_PSTH(1,:)))]) + % add post-synaptic current left over from previous segment + CNcurrentTemp(:,1:alphaCols)=... + CNcurrentTemp(:,1:alphaCols)+ CNtrailingAlphas; + + % take post-synaptic current for this segment + CNcurrentInput= CNcurrentTemp(:, 1:reducedSegmentLength); +% disp(['mean(CNcurrentInput)= ' num2str(mean(CNcurrentInput(1,:)))]) + + % trailingalphas are the ends of the alpha functions that + % spill over into the next segment + CNtrailingAlphas= ... + CNcurrentTemp(:, reducedSegmentLength+1:end); + + if CN_c>0 + % variable threshold condition (slow) + for t=1:reducedSegmentLength + CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt; + s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ; + CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike + dE =(-CN_E/CN_tauM + ... + CNcurrentInput(:,t)/CN_cap+(... + CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt; + dGk=-CN_Gk*ANdt./tauGk + CN_b*s; + dTh=-(CN_Th-CN_Th0)*ANdt/CN_tauTh + CN_c*s; + CN_E=CN_E+dE; + CN_Gk=CN_Gk+dGk; + CN_Th=CN_Th+dTh; + CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er; + end + else + % static threshold (faster) + E=zeros(1,reducedSegmentLength); + Gk=zeros(1,reducedSegmentLength); + ss=zeros(1,reducedSegmentLength); + for t=1:reducedSegmentLength + % time of previous spike moves back in time + CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt; + % action potential if E>threshold + % allow time for s to reset between events + s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ; + ss(t)=s(1); + CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike + dE = (-CN_E/CN_tauM + ... + CNcurrentInput(:,t)/CN_cap +... + (CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt; + dGk=-CN_Gk*ANdt./tauGk +CN_b*s; + CN_E=CN_E+dE; + CN_Gk=CN_Gk+dGk; + E(t)=CN_E(1); + Gk(t)=CN_Gk(1); + % add spike to CN_E and add resting potential (-60 mV) + CNmembranePotential(:,t)=CN_E +s.*(CN_Eb-CN_E)+CN_Er; + end + end +% disp(['CN_E= ' num2str(sum(CN_E(1,:)))]) +% disp(['CN_Gk= ' num2str(sum(CN_Gk(1,:)))]) +% disp(['CNmembranePotential= ' num2str(sum(CNmembranePotential(1,:)))]) +% plot(CNmembranePotential(1,:)) + + + % extract spikes. A spike is a substantial upswing in voltage + CN_spikes=CNmembranePotential> -0.02; +% disp(['CNspikesbefore= ' num2str(sum(sum(CN_spikes)))]) + + % now remove any spike that is immediately followed by a spike + % NB 'find' works on columns (whence the transposing) + % for each spike put a zero in the next epoch + CN_spikes=CN_spikes'; + idx=find(CN_spikes); + idx=idx(1:end-1); + CN_spikes(idx+1)=0; + CN_spikes=CN_spikes'; +% disp(['CNspikes= ' num2str(sum(sum(CN_spikes)))]) + + % segment debugging + % plotInstructions.figureNo=98; + % plotInstructions.displaydt=ANdt; + % plotInstructions.numPlots=1; + % plotInstructions.subPlotNo=1; + % UTIL_plotMatrix(CN_spikes, plotInstructions); + + % and save it + CNoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=... + CN_spikes; + + + %% IC ---------------------------------------------- + % MacGregor or some other second order neurons + + % combine CN neurons in same channel, + % i.e. same BF & same tauCa + % to generate inputs to single IC unit + channelNo=0; + for idx=1:nCNneuronsPerChannel:nCNneurons-nCNneuronsPerChannel+1; + channelNo=channelNo+1; + CN_PSTH(channelNo,:)=... + sum(CN_spikes(idx:idx+nCNneuronsPerChannel-1,:)); + end + + [alphaRows alphaCols]=size(ICtrailingAlphas); + for ICneuronNo=1:nICcells + ICcurrentTemp(ICneuronNo,:)= ... + conv2(CN_PSTH(ICneuronNo,:), IC_CNalphaFunction); + % Changed conv to conv2 because it runs faster. (Andreas) + end + + % add the unused current from the previous convolution + ICcurrentTemp(:,1:alphaCols)=ICcurrentTemp(:,1:alphaCols)... + + ICtrailingAlphas; + % take what is required and keep the trailing part for next time + inputCurrent=ICcurrentTemp(:, 1:reducedSegmentLength); + ICtrailingAlphas=ICcurrentTemp(:, reducedSegmentLength+1:end); + + if IC_c==0 + % faster computation when threshold is stable (C==0) + for t=1:reducedSegmentLength + s=IC_E>IC_Th0; + dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +... + (IC_Gk/IC_cap).*(IC_Ek-IC_E))*ANdt; + dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s; + IC_E=IC_E+dE; + IC_Gk=IC_Gk+dGk; + ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; + end + else + % threshold is changing (IC_c>0; e.g. bushy cell) + for t=1:reducedSegmentLength + dE = (-IC_E/IC_tauM + ... + inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)... + .*(IC_Ek-IC_E))*ANdt; + IC_E=IC_E+dE; + s=IC_E>IC_Th; + ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; + dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s; + IC_Gk=IC_Gk+dGk; + + % After a spike, the threshold is raised + % otherwise it settles to its baseline + dTh=-(IC_Th-Th0)*ANdt/IC_tauTh +s*IC_c; + IC_Th=IC_Th+dTh; + end + end + + ICspikes=ICmembranePotential> -0.01; + % now remove any spike that is immediately followed by a spike + % NB 'find' works on columns (whence the transposing) + ICspikes=ICspikes'; + idx=find(ICspikes); + idx=idx(1:end-1); + ICspikes(idx+1)=0; + ICspikes=ICspikes'; + + nCellsPerTau= nICcells/nANfiberTypes; + firstCell=1; + lastCell=nCellsPerTau; + for tauCount=1:nANfiberTypes + % separate rates according to fiber types + % currently only the last segment is saved + ICfiberTypeRates(tauCount, ... + reducedSegmentPTR:shorterSegmentEndPTR)=... + sum(ICspikes(firstCell:lastCell, :))... + /(nCellsPerTau*ANdt); + firstCell=firstCell+nCellsPerTau; + lastCell=lastCell+nCellsPerTau; + end + + ICoutput(:,reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes; + + % store membrane output on original dt scale + if nBFs==1 % single channel + x= repmat(ICmembranePotential(1,:), ANspeedUpFactor,1); + x= reshape(x,1,segmentLength); + if nANfiberTypes>1 % save HSR and LSR + y=repmat(ICmembranePotential(end,:),... + ANspeedUpFactor,1); + y= reshape(y,1,segmentLength); + x=[x; y]; + end + ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x; + end + + % estimate efferent effects. + % ARis based on LSR units. LSR channels are 1:nBF + if nANfiberTypes>1 % AR is multi-channel only + ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt; + [ARAttSeg, ARboundary] = ... + filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary); + ARAttSeg=ARAttSeg-ARrateThreshold; + ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths + % scale up to dt from ANdt + x= repmat(ARAttSeg, ANspeedUpFactor,1); + x=reshape(x,1,segmentLength); + ARattenuation(segmentStartPTR:segmentEndPTR)=... + (1-ARrateToAttenuationFactor* x); + ARattenuation(ARattenuation<0)=0.001; + else + % single channel model; disable AR + ARattenuation(segmentStartPTR:segmentEndPTR)=... + ones(1,segmentLength); + end + + % MOC attenuation using HSR response only + % Separate MOC effect for each BF + HSRbegins=nBFs*(nANfiberTypes-1)+1; + rates=ICspikes(HSRbegins:end,:)/ANdt; + for idx=1:nBFs + [smoothedRates, MOCboundary{idx}] = ... + filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... + MOCboundary{idx}); + % spont 'rates' is zero for IC + MOCattSegment(idx,:)=smoothedRates; + % expand timescale back to model dt from ANdt + x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1); + x= reshape(x,1,segmentLength); + MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... + (1- MOCrateToAttenuationFactor* x); + end + MOCattenuation(MOCattenuation<0)=0.04; + % segment debugging + % plotInstructions.figureNo=98; + % plotInstructions.displaydt=ANdt; + % plotInstructions.numPlots=1; + % plotInstructions.subPlotNo=1; + % UTIL_plotMatrix(ICspikes, plotInstructions); + + end % AN_spikesOrProbability + segmentStartPTR=segmentStartPTR+segmentLength; + reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength; + + +end % segment + +disp('CONVOLUTION_CHANGE_TEST (if followed by zero all is good)') +disp(max(CONVOLUTION_CHANGE_TEST)) %% for debugging + + +%% apply refractory correction to spike probabilities + +% switch AN_spikesOrProbability +% case 'probability' +% ANprobOutput=ANprobRateOutput*dt; +% [r nEpochs]=size(ANprobOutput); +% % find probability of no spikes in refractory period +% pNoSpikesInRefrac=ones(size(ANprobOutput)); +% pSpike=zeros(size(ANprobOutput)); +% for epochNo=lengthAbsRefractoryP+2:nEpochs +% pNoSpikesInRefrac(:,epochNo)=... +% pNoSpikesInRefrac(:,epochNo-2)... +% .*(1-pSpike(:,epochNo-1))... +% ./(1-pSpike(:,epochNo-lengthAbsRefractoryP-1)); +% pSpike(:,epochNo)= ANprobOutput(:,epochNo)... +% .*pNoSpikesInRefrac(:,epochNo); +% end +% ANprobRateOutput=pSpike/dt; +% end + +path(restorePath)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAP/old MAP files/MAP1_14parallel.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,1148 @@ + +function MAP1_14parallel(inputSignal, sampleRate, BFlist, MAPparamsName, ... + AN_spikesOrProbability, paramChanges) +% To test this function use test_MAP1_14 in this folder +% +% All arguments are mandatory. +% +% BFlist is a list of BFs but can be '-1' to allow MAPparams to choose +% + +% MAPparamsName='Normal'; % source of model parameters +% AN_spikesOrProbability='spikes'; % or 'probability' +% paramChanges is a cell array of strings that can be used to make last +% minute parameter changes, e.g., to simulate OHC loss +% paramChanges{1}= 'DRNLParams.a=0;'; + +% The model parameters are established in the MAPparams<***> file +% and stored as global + +restorePath=path; +addpath (['..' filesep 'parameterStore']) + +global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams +global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams + +% All of the results of this function are stored as global +global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... + savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... + DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... + IHCoutput ANprobRateOutput ANoutput savePavailable tauCas ... + CNoutput ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation + +% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be +% needed by the user; so the following will suffice +% global ANdt ICoutput ANprobRateOutput + +% Note that sampleRate has not changed from the original function call and +% ANprobRateOutput is sampled at this rate +% However ANoutput, CNoutput and IC output are stored as logical +% 'spike' matrices using a lower sample rate (see ANdt). + +% When AN_spikesOrProbability is set to probability, +% no spike matrices are computed. +% When AN_spikesOrProbability is set to 'spikes', +% no probability output is computed + +% Efferent control variables are ARattenuation and MOCattenuation +% These are scalars between 1 (no attenuation) and 0. +% They are represented with dt=1/sampleRate (not ANdt) +% They are computed using either AN probability rate output +% or IC (spikes) output as approrpriate. +% AR is computed using across channel activity +% MOC is computed on a within-channel basis. + + +% save as global for later plotting if required +savedBFlist=BFlist; +saveAN_spikesOrProbability=AN_spikesOrProbability; +saveMAPparamsName=MAPparamsName; + +% Read parameters from MAPparams<***> file in 'parameterStore' folder +cmd=['method=MAPparams' MAPparamsName ... + '(BFlist, sampleRate, 0);']; +eval(cmd); + +% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<> +% if the calling program allows MAPparams to specify the list +BFlist=DRNLParams.nonlinCFs; + +% now accept last mintue parameter changes required by the calling program +if nargin>5 && ~isempty(paramChanges) + nChanges=length(paramChanges); + for idx=1:nChanges + eval(paramChanges{idx}) + end +end + +dt=1/sampleRate; +duration=length(inputSignal)/sampleRate; +% segmentDuration is specified in parameter file (must be >efferent delay) +segmentDuration=method.segmentDuration; +segmentLength=round(segmentDuration/ dt); +segmentTime=dt*(1:segmentLength); % used in debugging plots + +% all spiking activity is computed using longer epochs +ANspeedUpFactor=5; % 5 times longer + +% inputSignal must be row vector +[r c]=size(inputSignal); +if r>c, inputSignal=inputSignal'; end % transpose +% ignore stereo signals +inputSignal=inputSignal(1,:); % drop any second channel +savedInputSignal=inputSignal; + +% Segment the signal +% The sgment length is given but the signal length must be adjusted to be a +% multiple of both the segment length and the reduced segmentlength +[nSignalRows signalLength]=size(inputSignal); +segmentLength=ceil(segmentLength/ANspeedUpFactor)*ANspeedUpFactor; +% Make the signal length a whole multiple of the segment length +nSignalSegments=ceil(signalLength/segmentLength); +padSize=nSignalSegments*segmentLength-signalLength; +pad=zeros(nSignalRows,padSize); +inputSignal=[inputSignal pad]; +[ignore signalLength]=size(inputSignal); + +% AN (spikes) is computed at a lower sample rate when spikes required +% so it has a reduced segment length (see 'ANspeeUpFactor' above) +% AN CN and IC all use this sample interval +ANdt=dt*ANspeedUpFactor; +reducedSegmentLength=round(segmentLength/ANspeedUpFactor); +reducedSignalLength= round(signalLength/ANspeedUpFactor); + +%% Initialise with respect to each stage before computing +% by allocating memory, +% by computing constants +% by establishing easy to read variable names +% The computations are made in segments and boundary conditions must +% be established and stored. These are found in variables with +% 'boundary' or 'bndry' in the name + +%% OME --- +% external ear resonances +OMEexternalResonanceFilters=OMEParams.externalResonanceFilters; +[nOMEExtFilters c]=size(OMEexternalResonanceFilters); +% details of external (outer ear) resonances +OMEgaindBs=OMEexternalResonanceFilters(:,1); +OMEgainScalars=10.^(OMEgaindBs/20); +OMEfilterOrder=OMEexternalResonanceFilters(:,2); +OMElowerCutOff=OMEexternalResonanceFilters(:,3); +OMEupperCutOff=OMEexternalResonanceFilters(:,4); +% external resonance coefficients +ExtFilter_b=cell(nOMEExtFilters,1); +ExtFilter_a=cell(nOMEExtFilters,1); +for idx=1:nOMEExtFilters + Nyquist=sampleRate/2; + [b, a] = butter(OMEfilterOrder(idx), ... + [OMElowerCutOff(idx) OMEupperCutOff(idx)]... + /Nyquist); + ExtFilter_b{idx}=b; + ExtFilter_a{idx}=a; +end +OMEExtFilterBndry=cell(2,1); +OMEextEarPressure=zeros(1,signalLength); % pressure at tympanic membrane + +% pressure to velocity conversion using smoothing filter (50 Hz cutoff) +tau=1/(2*pi*50); +a1=dt/tau-1; a0=1; +b0=1+ a1; +TMdisp_b=b0; TMdisp_a=[a0 a1]; +% figure(9), freqz(TMdisp_b, TMdisp_a) +OME_TMdisplacementBndry=[]; + +% OME high pass (simulates poor low frequency stapes response) +OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff; +Nyquist=sampleRate/2; +[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high'); +% figure(10), freqz(stapesDisp_b, stapesDisp_a) + +OMEhighPassBndry=[]; + +% OMEampStapes might be reducdant (use OMEParams.stapesScalar) +stapesScalar= OMEParams.stapesScalar; + +% Acoustic reflex +efferentDelayPts=round(OMEParams.ARdelay/dt); +% smoothing filter +% Nyquist=(1/ANdt)/2; +% [ARfilt_b,ARfilt_a] = butter(1, (1/(2*pi*OMEParams.ARtau))/Nyquist, 'low'); +a1=dt/OMEParams.ARtau-1; a0=1; +b0=1+ a1; +ARfilt_b=b0; ARfilt_a=[a0 a1]; + +ARattenuation=ones(1,signalLength); +ARrateThreshold=OMEParams.ARrateThreshold; % may not be used +ARrateToAttenuationFactor=OMEParams.rateToAttenuationFactor; +ARrateToAttenuationFactorProb=OMEParams.rateToAttenuationFactorProb; +ARboundary=[]; +ARboundaryProb=0; + +% save complete OME record (stapes displacement) +OMEoutput=zeros(1,signalLength); +TMoutput=zeros(1,signalLength); + +%% BM --- +% BM is represented as a list of locations identified by BF +DRNL_BFs=BFlist; +nBFs= length(DRNL_BFs); + +% DRNLchannelParameters=DRNLParams.channelParameters; +DRNLresponse= zeros(nBFs, segmentLength); + +MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor; +rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb; +MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb; + +% smoothing filter for MOC +% Nyquist=(1/ANdt)/2; +% [MOCfilt_b,MOCfilt_a] = ... +% butter(1, (1/(2*pi*DRNLParams.MOCtau))/Nyquist, 'low'); +% figure(10), freqz(stapesDisp_b, stapesDisp_a) +a1=dt/DRNLParams.MOCtau-1; a0=1; +b0=1+ a1; +MOCfilt_b=b0; MOCfilt_a=[a0 a1]; +% figure(9), freqz(stapesDisp_b, stapesDisp_a) +MOCboundary=cell(nBFs,1); +MOCprobBoundary=cell(nBFs,1); + +MOCattSegment=zeros(nBFs,reducedSegmentLength); +MOCattenuation=ones(nBFs,signalLength); + +if DRNLParams.a>0 + DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ... + log10(DRNLParams.b/DRNLParams.a)); +else + DRNLcompressionThreshold=inf; +end + +DRNLlinearOrder= DRNLParams.linOrder; +DRNLnonlinearOrder= DRNLParams.nonlinOrder; + +DRNLa=DRNLParams.a; +DRNLb=DRNLParams.b; +DRNLc=DRNLParams.c; +linGAIN=DRNLParams.g; +% +% gammatone filter coefficients for linear pathway +bw=DRNLParams.linBWs'; +phi = 2 * pi * bw * dt; +cf=DRNLParams.linCFs'; +theta = 2 * pi * cf * dt; +cos_theta = cos(theta); +sin_theta = sin(theta); +alpha = -exp(-phi).* cos_theta; +b0 = ones(nBFs,1); +b1 = 2 * alpha; +b2 = exp(-2 * phi); +z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; +z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; +z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; +tf = (z2 + z3) ./ z1; +a0 = abs(tf); +a1 = alpha .* a0; +GTlin_a = [b0, b1, b2]; +GTlin_b = [a0, a1]; +GTlinOrder=DRNLlinearOrder; +GTlinBdry1=cell(nBFs); +GTlinBdry2=cell(nBFs); +GTlinBdry3=cell(nBFs); +GTlinBdry1out=cell(nBFs); +GTlinBdry2out=cell(nBFs); +GTlinBdry3out=cell(nBFs); + +% nonlinear gammatone filter coefficients +bw=DRNLParams.nlBWs'; +phi = 2 * pi * bw * dt; +cf=DRNLParams.nonlinCFs'; +theta = 2 * pi * cf * dt; +cos_theta = cos(theta); +sin_theta = sin(theta); +alpha = -exp(-phi).* cos_theta; +b0 = ones(nBFs,1); +b1 = 2 * alpha; +b2 = exp(-2 * phi); +z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; +z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; +z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; +tf = (z2 + z3) ./ z1; +a0 = abs(tf); +a1 = alpha .* a0; +GTnonlin_a = [b0, b1, b2]; +GTnonlin_b = [a0, a1]; +GTnonlinOrder=DRNLnonlinearOrder; +firstGTnonlinBdry1=cell(nBFs); +firstGTnonlinBdry2=cell(nBFs); +firstGTnonlinBdry3=cell(nBFs); +firstGTnonlinBdry1out=cell(nBFs); +firstGTnonlinBdry2out=cell(nBFs); +firstGTnonlinBdry3out=cell(nBFs); + +secondGTnonlinBdry1=cell(nBFs); +secondGTnonlinBdry2=cell(nBFs); +secondGTnonlinBdry3=cell(nBFs); +secondGTnonlinBdry1out=cell(nBFs); +secondGTnonlinBdry2out=cell(nBFs); +secondGTnonlinBdry3out=cell(nBFs); + +% complete BM record (BM displacement) +DRNLoutput=zeros(nBFs, signalLength); + + +%% IHC --- +% IHC cilia activity and receptor potential +% viscous coupling between BM and stereocilia displacement +% Nyquist=sampleRate/2; +% IHCcutoff=1/(2*pi*IHC_cilia_RPParams.tc); +% [IHCciliaFilter_b,IHCciliaFilter_a]=... +% butter(1, IHCcutoff/Nyquist, 'high'); +a1=dt/IHC_cilia_RPParams.tc-1; a0=1; +b0=1+ a1; +% high pass (i.e. low pass reversed) +IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0; +% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a) + +IHCciliaBndry=cell(nBFs,1); + +% IHC apical conductance (Boltzman function) +IHC_C= IHC_cilia_RPParams.C; +IHCu0= IHC_cilia_RPParams.u0; +IHCu1= IHC_cilia_RPParams.u1; +IHCs0= IHC_cilia_RPParams.s0; +IHCs1= IHC_cilia_RPParams.s1; +IHCGmax= IHC_cilia_RPParams.Gmax; +IHCGa= IHC_cilia_RPParams.Ga; % (leakage) + +IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1))); + +% Receptor potential +IHC_Cab= IHC_cilia_RPParams.Cab; +IHC_Gk= IHC_cilia_RPParams.Gk; +IHC_Et= IHC_cilia_RPParams.Et; +IHC_Ek= IHC_cilia_RPParams.Ek; +IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc; + +IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk); + +IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage +IHC_RP= zeros(nBFs,segmentLength); + +% complete record of IHC receptor potential (V) +IHCciliaDisplacement= zeros(nBFs,segmentLength); +IHCoutput= zeros(nBFs,signalLength); +IHC_cilia_output= zeros(nBFs,signalLength); + + +%% pre-synapse --- +% Each BF is replicated using a different fiber type to make a 'channel' +% The number of channels is nBFs x nANfiberTypes +% Fiber types are specified in terms of tauCa +nANfiberTypes= length(IHCpreSynapseParams.tauCa); +tauCas= IHCpreSynapseParams.tauCa; +nChannels= nANfiberTypes*nBFs; +synapticCa= zeros(nChannels,segmentLength); + +% Calcium control (more calcium, greater release rate) +ECa=IHCpreSynapseParams.ECa; +gamma=IHCpreSynapseParams.gamma; +beta=IHCpreSynapseParams.beta; +tauM=IHCpreSynapseParams.tauM; +mICa=zeros(nChannels,segmentLength); +GmaxCa=IHCpreSynapseParams.GmaxCa; +synapse_z= IHCpreSynapseParams.z; +synapse_power=IHCpreSynapseParams.power; + +% tauCa vector is established across channels to allow vectorization +% (one tauCa per channel). Do not confuse with tauCas (one pre fiber type) +tauCa=repmat(tauCas, nBFs,1); +tauCa=reshape(tauCa, nChannels, 1); + +% presynapse startup values (vectors, length:nChannels) +% proportion (0 - 1) of Ca channels open at IHCrestingV +mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)... + *ones(nBFs*nANfiberTypes,1); +% corresponding startup currents +ICaCurrent= (GmaxCa*mICaCurrent.^3) * (IHCrestingV-ECa); +CaCurrent= ICaCurrent.*tauCa; + +% vesicle release rate at startup (one per channel) +% kt0 is used only at initialisation +kt0= -synapse_z * CaCurrent.^synapse_power; + + +%% AN --- +% each row of the AN matrices represents one AN fiber +% The results computed either for probabiities *or* for spikes (not both) +% Spikes are necessary if CN and IC are to be computed +nFibersPerChannel= AN_IHCsynapseParams.numFibers; +nANfibers= nChannels*nFibersPerChannel; + +y=AN_IHCsynapseParams.y; +l=AN_IHCsynapseParams.l; +x=AN_IHCsynapseParams.x; +r=AN_IHCsynapseParams.r; +M=round(AN_IHCsynapseParams.M); + +% probability (NB initial 'P' on everything) +PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nChannels,1); +PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nChannels,1); +PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nChannels,1); +PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nChannels,1); +PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt; +PAN_M=round(AN_IHCsynapseParams.M); + +% compute starting values +Pcleft = kt0* y* M ./ (y*(l+r)+ kt0* l); +Pavailable = Pcleft*(l+r)./kt0; +Preprocess = Pcleft*r/x; % canbe fractional + +ANprobability=zeros(nChannels,segmentLength); +ANprobRateOutput=zeros(nChannels,signalLength); +% special variables for monitoring synaptic cleft (specialists only) +savePavailableSeg=zeros(nChannels,segmentLength); +savePavailable=zeros(nChannels,signalLength); + +% spikes % ! ! ! ! ! ! ! ! +AN_refractory_period= AN_IHCsynapseParams.refractory_period; +lengthAbsRefractory= round(AN_refractory_period/ANdt); + +AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1); +AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1); +AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1); +AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1); +AN_rdt_plus_ldt= AN_rdt + AN_ldt; +AN_M= round(AN_IHCsynapseParams.M); + +% kt0 is initial release rate +% Establish as a vector (length=channel x number of fibers) +kt0= repmat(kt0', nFibersPerChannel, 1); +kt0=reshape(kt0, nANfibers,1); + +% starting values for reservoirs +AN_cleft = kt0* y* M ./ (y*(l+r)+ kt0* l); +AN_available = round(AN_cleft*(l+r)./kt0); %must be integer +AN_reprocess = AN_cleft*r/x; + +% output is in a logical array spikes = 1/ 0. +ANspikes= false(nANfibers,reducedSegmentLength); +ANoutput= false(nANfibers,reducedSignalLength); + + +%% CN (first brain stem nucleus - could be any subdivision of CN) +% Input to a CN neuorn is a random selection of AN fibers within a channel +% The number of AN fibers used is ANfibersFanInToCN +ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron; +nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF; +% CNtauGk (Potassium time constant) determines the rate of firing of +% the unit when driven hard by a DC input (not normally >350 sp/s) +CNtauGk=MacGregorMultiParams.tauGk; +ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers; +nCNneurons=nCNneuronsPerChannel*nChannels; +% nCNneuronsPerFiberType= nCNneurons/nANfiberTypes; + +CNmembranePotential=zeros(nCNneurons,reducedSegmentLength); + +% establish which ANfibers (by name) feed into which CN nuerons +CNinputfiberLists=zeros(nChannels*nCNneuronsPerChannel, ANfibersFanInToCN); +unitNo=1; +for ch=1:nChannels + % Each channel contains a number of units =length(listOfFanInValues) + for idx=1:nCNneuronsPerChannel + fibersUsed=(ch-1)*ANavailableFibersPerChan + ... + ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan); + CNinputfiberLists(unitNo,:)=fibersUsed; + unitNo=unitNo+1; + end +end + +% input to CN units +AN_PSTH=zeros(nCNneurons,reducedSegmentLength); + +% Generate CNalphaFunction function +% by which spikes are converted to post-synaptic currents +CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq; +CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike; +CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq); +t=ANdt:ANdt:5*CNspikeToCurrentTau; +CNalphaFunction=... + (CNcurrentPerSpike/CNspikeToCurrentTau)*t.*exp(-t/CNspikeToCurrentTau); +% figure(98), plot(t,CNalphaFunction) +% working memory for implementing convolution +CNcurrentTemp=... + zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1); +% trailing alphas are parts of humps carried forward to the next segment +CNtrailingAlphas=zeros(nCNneurons,length(CNalphaFunction)); + +CN_tauM=MacGregorMultiParams.tauM; +CN_tauTh=MacGregorMultiParams.tauTh; +CN_cap=MacGregorMultiParams.Cap; +CN_c=MacGregorMultiParams.c; +CN_b=MacGregorMultiParams.dGkSpike; +CN_Ek=MacGregorMultiParams.Ek; +CN_Eb= MacGregorMultiParams.Eb; +CN_Er=MacGregorMultiParams.Er; +CN_Th0= MacGregorMultiParams.Th0; +CN_E= zeros(nCNneurons,1); +CN_Gk= zeros(nCNneurons,1); +CN_Th= MacGregorMultiParams.Th0*ones(nCNneurons,1); +CN_Eb=CN_Eb.*ones(nCNneurons,1); +CN_Er=CN_Er.*ones(nCNneurons,1); +CNtimeSinceLastSpike=zeros(nCNneurons,1); +% tauGk is the main distinction between neurons +% in fact they are all the same in the standard model +tauGk=repmat(CNtauGk,nChannels*nCNneuronsPerChannel,1); + +CN_PSTH=zeros(nChannels,reducedSegmentLength); +CNoutput=false(nCNneurons,reducedSignalLength); + + +%% MacGregor (IC - second nucleus) -------- +nICcells=nChannels; % one cell per channel + +ICspikeWidth=0.00015; % this may need revisiting +epochsPerSpike=round(ICspikeWidth/ANdt); +if epochsPerSpike<1 + error(['MacGregorMulti: sample rate too low to support ' ... + num2str(ICspikeWidth*1e6) ' microsec spikes']); +end + +% short names +IC_tauM=MacGregorParams.tauM; +IC_tauGk=MacGregorParams.tauGk; +IC_tauTh=MacGregorParams.tauTh; +IC_cap=MacGregorParams.Cap; +IC_c=MacGregorParams.c; +IC_b=MacGregorParams.dGkSpike; +IC_Th0=MacGregorParams.Th0; +IC_Ek=MacGregorParams.Ek; +IC_Eb= MacGregorParams.Eb; +IC_Er=MacGregorParams.Er; + +IC_E=zeros(nICcells,1); +IC_Gk=zeros(nICcells,1); +IC_Th=IC_Th0*ones(nICcells,1); + +% Dendritic filtering, all spikes are replaced by CNalphaFunction functions +ICdendriteLPfreq= MacGregorParams.dendriteLPfreq; +ICcurrentPerSpike=MacGregorParams.currentPerSpike; +ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq); +t=ANdt:ANdt:3*ICspikeToCurrentTau; +IC_CNalphaFunction= (ICcurrentPerSpike / ... + ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau); +% figure(98), plot(t,IC_CNalphaFunction) + +% working space for implementing alpha function +ICcurrentTemp=... + zeros(nICcells,reducedSegmentLength+length(IC_CNalphaFunction)-1); +ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction)); + +ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength); +ICoutput=false(nChannels,reducedSignalLength); + +ICmembranePotential=zeros(nICcells,reducedSegmentLength); +ICmembraneOutput=zeros(nICcells,signalLength); + + +%% Main program %% %% %% %% %% %% %% %% %% %% %% %% %% %% + +% Compute the entire model for each segment +segmentStartPTR=1; +reducedSegmentPTR=1; % when sampling rate is reduced +while segmentStartPTR<signalLength + segmentEndPTR=segmentStartPTR+segmentLength-1; + % shorter segments after speed up. + shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1; + + iputPressureSegment=inputSignal... + (:,segmentStartPTR:segmentStartPTR+segmentLength-1); + + % segment debugging plots + % figure(98) + % plot(segmentTime,iputPressureSegment), title('signalSegment') + + + % OME ---------------------- + + % OME Stage 1: external resonances. Add to inputSignal pressure wave + y=iputPressureSegment; + for n=1:nOMEExtFilters + % any number of resonances can be used + [x OMEExtFilterBndry{n}] = ... + filter(ExtFilter_b{n},ExtFilter_a{n},... + iputPressureSegment, OMEExtFilterBndry{n}); + x= x* OMEgainScalars(n); + % This is a parallel resonance so add it + y=y+x; + end + iputPressureSegment=y; + OMEextEarPressure(segmentStartPTR:segmentEndPTR)= iputPressureSegment; + + % OME stage 2: convert input pressure (velocity) to + % tympanic membrane(TM) displacement using low pass filter + [TMdisplacementSegment OME_TMdisplacementBndry] = ... + filter(TMdisp_b,TMdisp_a,iputPressureSegment, ... + OME_TMdisplacementBndry); + % and save it + TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment; + + % OME stage 3: middle ear high pass effect to simulate stapes inertia + [stapesDisplacement OMEhighPassBndry] = ... + filter(stapesDisp_b,stapesDisp_a,TMdisplacementSegment, ... + OMEhighPassBndry); + + % OME stage 4: apply stapes scalar + stapesDisplacement=stapesDisplacement*stapesScalar; + + % OME stage 5: acoustic reflex stapes attenuation + % Attenuate the TM response using feedback from LSR fiber activity + if segmentStartPTR>efferentDelayPts + stapesDisplacement= stapesDisplacement.*... + ARattenuation(segmentStartPTR-efferentDelayPts:... + segmentEndPTR-efferentDelayPts); + end + + % segment debugging plots + % figure(98) + % plot(segmentTime, stapesDisplacement), title ('stapesDisplacement') + + % and save + OMEoutput(segmentStartPTR:segmentEndPTR)= stapesDisplacement; + + % needed for parallel processing + if segmentStartPTR>efferentDelayPts + MOCatt=MOCattenuation(:, segmentStartPTR-efferentDelayPts:... + segmentEndPTR-efferentDelayPts); + else % no MOC available yet + MOCatt=ones(nBFs, segmentLength); + end + %% BM ------------------------------ + % Each BM location is computed separately + parfor BFno=1:nBFs + + % *linear* path + % repeats used to avoid parallel processin problems + linOutput = stapesDisplacement * linGAIN; % linear gain + [linOutput GTlinBdry1out{BFno}] = ... + filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry1{BFno}); + [linOutput GTlinBdry2out{BFno}] = ... + filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry2{BFno}); + [linOutput GTlinBdry3out{BFno}] = ... + filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry3{BFno}); + + % *nonLinear* path + % efferent attenuation (0 <> 1) + MOC=MOCatt(BFno); + + + % first gammatone filter + [nonlinOutput firstGTnonlinBdry1out{BFno}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + stapesDisplacement, firstGTnonlinBdry1{BFno}); + + [nonlinOutput firstGTnonlinBdry2out{BFno}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + stapesDisplacement, firstGTnonlinBdry2{BFno}); + + [nonlinOutput firstGTnonlinBdry3out{BFno}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + stapesDisplacement, firstGTnonlinBdry3{BFno}); + + % broken stick instantaneous compression + % nonlinear gain is weakend by MOC before applied to BM response + y= nonlinOutput.*(MOC* DRNLa); % linear section. + % compress those parts of the signal above the compression + % threshold + abs_x = abs(nonlinOutput); + idx=find(abs_x>DRNLcompressionThreshold); + if ~isempty(idx)>0 + y(idx)=sign(nonlinOutput(idx)).*... + (DRNLb*abs_x(idx).^DRNLc); + end + nonlinOutput=y; + + % second filter removes distortion products + [nonlinOutput secondGTnonlinBdry1out{BFno}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + nonlinOutput, secondGTnonlinBdry1{BFno}); + + [nonlinOutput secondGTnonlinBdry2out{BFno}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + nonlinOutput, secondGTnonlinBdry2{BFno}); + + [nonlinOutput secondGTnonlinBdry3out{BFno}] = ... + filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... + nonlinOutput, secondGTnonlinBdry3{BFno}); + + + % combine the two paths to give the DRNL displacement + DRNLresponse(BFno,:)=linOutput+nonlinOutput; + end % BF + GTlinBdry1=GTlinBdry1out; + GTlinBdry2=GTlinBdry2out; + GTlinBdry3=GTlinBdry3out; + firstGTnonlinBdry1=firstGTnonlinBdry1out; + firstGTnonlinBdry2=firstGTnonlinBdry2out; + firstGTnonlinBdry3=firstGTnonlinBdry3out; + secondGTnonlinBdry1=secondGTnonlinBdry1out; + secondGTnonlinBdry2=secondGTnonlinBdry2out; + secondGTnonlinBdry3=secondGTnonlinBdry3out; + % segment debugging plots + % figure(98) + % if size(DRNLresponse,1)>3 + % imagesc(DRNLresponse) % matrix display + % title('DRNLresponse'); % single or double channel response + % else + % plot(segmentTime, DRNLresponse) + % end + + % and save it + DRNLoutput(:, segmentStartPTR:segmentEndPTR)= DRNLresponse; + + + %% IHC ------------------------------------ + % BM displacement to IHCciliaDisplacement is a high-pass filter + % because of viscous coupling + for idx=1:nBFs + [IHCciliaDisplacement(idx,:) IHCciliaBndry{idx}] = ... + filter(IHCciliaFilter_b,IHCciliaFilter_a, ... + DRNLresponse(idx,:), IHCciliaBndry{idx}); + end + + % apply scalar + IHCciliaDisplacement=IHCciliaDisplacement* IHC_C; + + % and save it + IHC_cilia_output(:,segmentStartPTR:segmentStartPTR+segmentLength-1)=... + IHCciliaDisplacement; + + % compute apical conductance + G=IHCGmax./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*... + (1+exp(-(IHCciliaDisplacement-IHCu1)/IHCs1))); + Gu=G + IHCGa; + + % Compute receptor potential + for idx=1:segmentLength + IHC_Vnow=IHC_Vnow+ (-Gu(:, idx).*(IHC_Vnow-IHC_Et)-... + IHC_Gk*(IHC_Vnow-IHC_Ekp))* dt/IHC_Cab; + IHC_RP(:,idx)=IHC_Vnow; + end + + % segment debugging plots + % if size(IHC_RP,1)>3 + % surf(IHC_RP), shading interp, title('IHC_RP') + % else + % plot(segmentTime, IHC_RP) + % end + + % and save it + IHCoutput(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=IHC_RP; + + + %% synapse ----------------------------- + % Compute the vesicle release rate for each fiber type at each BF + % replicate IHC_RP for each fiber type + Vsynapse=repmat(IHC_RP, nANfiberTypes,1); + + % look-up table of target fraction channels open for a given IHC_RP + mICaINF= 1./( 1 + exp(-gamma * Vsynapse) /beta); + % fraction of channel open - apply time constant + for idx=1:segmentLength + % mICaINF is the current 'target' value of mICa + mICaCurrent=mICaCurrent+(mICaINF(:,idx)-mICaCurrent)*dt./tauM; + mICa(:,idx)=mICaCurrent; + end + + ICa= (GmaxCa* mICa.^3) .* (Vsynapse- ECa); + + for idx=1:segmentLength + CaCurrent=CaCurrent + ICa(:,idx)*dt - CaCurrent*dt./tauCa; + synapticCa(:,idx)=CaCurrent; + end + synapticCa=-synapticCa; % treat IHCpreSynapseParams as positive substance + + % NB vesicleReleaseRate is /s and is independent of dt + vesicleReleaseRate = synapse_z * synapticCa.^synapse_power; % rate + + % segment debugging plots + % if size(vesicleReleaseRate,1)>3 + % surf(vesicleReleaseRate), shading interp, title('vesicleReleaseRate') + % else + % plot(segmentTime, vesicleReleaseRate) + % end + + + %% AN + switch AN_spikesOrProbability + case 'probability' + % No refractory effect is applied + for t = 1:segmentLength; + M_Pq=PAN_M-Pavailable; + M_Pq(M_Pq<0)=0; + Preplenish = M_Pq .* PAN_ydt; + Pejected = Pavailable.* vesicleReleaseRate(:,t)*dt; + Preprocessed = M_Pq.*Preprocess.* PAN_xdt; + + ANprobability(:,t)= min(Pejected,1); + reuptakeandlost= PAN_rdt_plus_ldt .* Pcleft; + reuptake= PAN_rdt.* Pcleft; + + Pavailable= Pavailable+ Preplenish- Pejected+ Preprocessed; + Pcleft= Pcleft + Pejected - reuptakeandlost; + Preprocess= Preprocess + reuptake - Preprocessed; + Pavailable(Pavailable<0)=0; + savePavailableSeg(:,t)=Pavailable; % synapse tracking + end + % and save it as *rate* + ANrate=ANprobability/dt; + ANprobRateOutput(:, segmentStartPTR:... + segmentStartPTR+segmentLength-1)= ANrate; + % monitor synapse contents (only sometimes used) + savePavailable(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=... + savePavailableSeg; + + % Estimate efferent effects. ARattenuation (0 <> 1) + % acoustic reflex + ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF + % smooth + [ARAttSeg, ARboundaryProb] = ... + filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb); + ARAttSeg=ARAttSeg-ARrateThreshold; + ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths + ARattenuation(segmentStartPTR:segmentEndPTR)=... + (1-ARrateToAttenuationFactorProb.* ARAttSeg); + + % MOC attenuation + % within-channel HSR response only + HSRbegins=nBFs*(nANfiberTypes-1)+1; + rates=ANrate(HSRbegins:end,:); + for idx=1:nBFs + [smoothedRates, MOCprobBoundary{idx}] = ... + filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... + MOCprobBoundary{idx}); + smoothedRates=smoothedRates-MOCrateThresholdProb; + smoothedRates(smoothedRates<0)=0; + MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... + (1- smoothedRates* rateToAttenuationFactorProb); + end + MOCattenuation(MOCattenuation<0)=0.001; + + + case 'spikes' + ANtimeCount=0; + % implement speed upt + for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength; + ANtimeCount=ANtimeCount+1; + % convert release rate to probabilities + releaseProb=vesicleReleaseRate(:,t)*ANdt; + % releaseProb is the release probability per channel + % but each channel has many synapses + releaseProb=repmat(releaseProb',nFibersPerChannel,1); + releaseProb=reshape(releaseProb, nFibersPerChannel*nChannels,1); + + % AN_available=round(AN_available); % vesicles must be integer, (?needed) + M_q=AN_M- AN_available; % number of missing vesicles + M_q(M_q<0)= 0; % cannot be less than 0 + + % AN_N1 converts probability to discrete events + % it considers each event that might occur + % (how many vesicles might be released) + % and returns a count of how many were released + + % slow line +% probabilities= 1-(1-releaseProb).^AN_available; + probabilities= 1-intpow((1-releaseProb), AN_available); + ejected= probabilities> rand(length(AN_available),1); + + reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft; + reuptake = AN_rdt.* AN_cleft; + + % slow line +% probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; + probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q); + reprocessed= probabilities>rand(length(M_q),1); + + % slow line +% probabilities= 1-(1-AN_ydt).^M_q; + probabilities= 1-intpow((1-AN_ydt), M_q); + + replenish= probabilities>rand(length(M_q),1); + + AN_available = AN_available + replenish - ejected ... + + reprocessed; + AN_cleft = AN_cleft + ejected - reuptakeandlost; + AN_reprocess = AN_reprocess + reuptake - reprocessed; + + % ANspikes is logical record of vesicle release events>0 + ANspikes(:, ANtimeCount)= ejected; + end % t + + % zero any events that are preceded by release events ... + % within the refractory period + % The refractory period consist of two periods + % 1) the absolute period where no spikes occur + % 2) a relative period where a spike may occur. This relative + % period is realised as a variable length interval + % where the length is chosen at random + % (esentially a linear ramp up) + + % Andreas has a fix for this + for t = 1:ANtimeCount-2*lengthAbsRefractory; + % identify all spikes across fiber array at time (t) + % idx is a list of channels where spikes occurred + % ?? try sparse matrices? + idx=find(ANspikes(:,t)); + for j=idx % consider each spike + % specify variable refractory period + % between abs and 2*abs refractory period + nPointsRefractory=lengthAbsRefractory+... + round(rand*lengthAbsRefractory); + % disable spike potential for refractory period + % set all values in this range to 0 + ANspikes(j,t+1:t+nPointsRefractory)=0; + end + end %t + + % segment debugging + % plotInstructions.figureNo=98; + % plotInstructions.displaydt=ANdt; + % plotInstructions.numPlots=1; + % plotInstructions.subPlotNo=1; + % UTIL_plotMatrix(ANspikes, plotInstructions); + + % and save it. NB, AN is now on 'speedUp' time + ANoutput(:, reducedSegmentPTR: shorterSegmentEndPTR)=ANspikes; + + + %% CN Macgregor first neucleus ------------------------------- + % input is from AN so ANdt is used throughout + % Each CNneuron has a unique set of input fibers selected + % at random from the available AN fibers (CNinputfiberLists) + + % Create the dendritic current for that neuron + % First get input spikes to this neuron + synapseNo=1; + for ch=1:nChannels + for idx=1:nCNneuronsPerChannel + % determine candidate fibers for this unit + fibersUsed=CNinputfiberLists(synapseNo,:); + % ANpsth has a bin width of dt + % (just a simple sum across fibers) + AN_PSTH(synapseNo,:) = ... + sum(ANspikes(fibersUsed,:), 1); + synapseNo=synapseNo+1; + end + end + + % One alpha function per spike + [alphaRows alphaCols]=size(CNtrailingAlphas); + + for unitNo=1:nCNneurons + CNcurrentTemp(unitNo,:)= ... + conv(AN_PSTH(unitNo,:),CNalphaFunction); + end + % add post-synaptic current left over from previous segment + CNcurrentTemp(:,1:alphaCols)=... + CNcurrentTemp(:,1:alphaCols)+ CNtrailingAlphas; + + % take post-synaptic current for this segment + CNcurrentInput= CNcurrentTemp(:, 1:reducedSegmentLength); + + % trailingalphas are the ends of the alpha functions that + % spill over into the next segment + CNtrailingAlphas= ... + CNcurrentTemp(:, reducedSegmentLength+1:end); + + if CN_c>0 + % variable threshold condition (slow) + for t=1:reducedSegmentLength + CNtimeSinceLastSpike=CNtimeSinceLastSpike-dts; + s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ; + CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike + dE =(-CN_E/CN_tauM + ... + CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt; + dGk=-CN_Gk*dt./tauGk + CN_b*s; + dTh=-(CN_Th-CN_Th0)*dt/CN_tauTh + CN_c*s; + CN_E=CN_E+dE; + CN_Gk=CN_Gk+dGk; + CN_Th=CN_Th+dTh; + CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er; + end + else + % static threshold (faster) + for t=1:reducedSegmentLength + CNtimeSinceLastSpike=CNtimeSinceLastSpike-dt; + s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ; % =1 if both conditions met + CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike + dE = (-CN_E/CN_tauM + ... + CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt; + dGk=-CN_Gk*dt./tauGk +CN_b*s; + CN_E=CN_E+dE; + CN_Gk=CN_Gk+dGk; + % add spike to CN_E and add resting potential (-60 mV) + CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er; + end + end + + % extract spikes. A spike is a substantial upswing in voltage + CN_spikes=CNmembranePotential> -0.01; + + % now remove any spike that is immediately followed by a spike + % NB 'find' works on columns (whence the transposing) + CN_spikes=CN_spikes'; + idx=find(CN_spikes); + idx=idx(1:end-1); + CN_spikes(idx+1)=0; + CN_spikes=CN_spikes'; + + % segment debugging + % plotInstructions.figureNo=98; + % plotInstructions.displaydt=ANdt; + % plotInstructions.numPlots=1; + % plotInstructions.subPlotNo=1; + % UTIL_plotMatrix(CN_spikes, plotInstructions); + + % and save it + CNoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=... + CN_spikes; + + + %% IC ---------------------------------------------- + % MacGregor or some other second order neurons + + % combine CN neurons in same channel, i.e. same BF & same tauCa + % to generate inputs to single IC unit + channelNo=0; + for idx=1:nCNneuronsPerChannel:nCNneurons-nCNneuronsPerChannel+1; + channelNo=channelNo+1; + CN_PSTH(channelNo,:)=... + sum(CN_spikes(idx:idx+nCNneuronsPerChannel-1,:)); + end + + [alphaRows alphaCols]=size(ICtrailingAlphas); + for ICneuronNo=1:nICcells + ICcurrentTemp(ICneuronNo,:)= ... + conv(CN_PSTH(ICneuronNo,:), IC_CNalphaFunction); + end + + % add the unused current from the previous convolution + ICcurrentTemp(:,1:alphaCols)=ICcurrentTemp(:,1:alphaCols)... + + ICtrailingAlphas; + % take what is required and keep the trailing part for next time + inputCurrent=ICcurrentTemp(:, 1:reducedSegmentLength); + ICtrailingAlphas=ICcurrentTemp(:, reducedSegmentLength+1:end); + + if IC_c==0 + % faster computation when threshold is stable (C==0) + for t=1:reducedSegmentLength + s=IC_E>IC_Th0; + dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +... + (IC_Gk/IC_cap).*(IC_Ek-IC_E))*dt; + dGk=-IC_Gk*dt/IC_tauGk +IC_b*s; + IC_E=IC_E+dE; + IC_Gk=IC_Gk+dGk; + ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; + end + else + % threshold is changing (IC_c>0; e.g. bushy cell) + for t=1:reducedSegmentLength + dE = (-IC_E/IC_tauM + ... + inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)... + .*(IC_Ek-IC_E))*dt; + IC_E=IC_E+dE; + s=IC_E>IC_Th; + ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; + dGk=-IC_Gk*dt/IC_tauGk +IC_b*s; + IC_Gk=IC_Gk+dGk; + + % After a spike, the threshold is raised + % otherwise it settles to its baseline + dTh=-(IC_Th-Th0)*dt/IC_tauTh +s*IC_c; + IC_Th=IC_Th+dTh; + end + end + + ICspikes=ICmembranePotential> -0.01; + % now remove any spike that is immediately followed by a spike + % NB 'find' works on columns (whence the transposing) + ICspikes=ICspikes'; + idx=find(ICspikes); + idx=idx(1:end-1); + ICspikes(idx+1)=0; + ICspikes=ICspikes'; + + nCellsPerTau= nICcells/nANfiberTypes; + firstCell=1; + lastCell=nCellsPerTau; + for tauCount=1:nANfiberTypes + % separate rates according to fiber types + ICfiberTypeRates(tauCount, ... + reducedSegmentPTR:shorterSegmentEndPTR)=... + sum(ICspikes(firstCell:lastCell, :))... + /(nCellsPerTau*ANdt); + firstCell=firstCell+nCellsPerTau; + lastCell=lastCell+nCellsPerTau; + end + ICoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes; + + if nBFs==1 % single channel + x= repmat(ICmembranePotential(1,:), ANspeedUpFactor,1); + x= reshape(x,1,segmentLength); + if nANfiberTypes>1 % save HSR and LSR + y= repmat(ICmembranePotential(end,:), ANspeedUpFactor,1); + y= reshape(y,1,segmentLength); + x=[x; y]; + end + ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x; + end + + % estimate efferent effects. + % ARis based on LSR units. LSR channels are 1:nBF + if nANfiberTypes>1 % AR is multi-channel only + ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt; + [ARAttSeg, ARboundary] = ... + filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary); + ARAttSeg=ARAttSeg-ARrateThreshold; + ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths + % scale up to dt from ANdt + x= repmat(ARAttSeg, ANspeedUpFactor,1); + x=reshape(x,1,segmentLength); + ARattenuation(segmentStartPTR:segmentEndPTR)=... + (1-ARrateToAttenuationFactor* x); + ARattenuation(ARattenuation<0)=0.001; + else + % single channel model; disable AR + ARattenuation(segmentStartPTR:segmentEndPTR)=... + ones(1,segmentLength); + end + + % MOC attenuation using HSR response only + % Separate MOC effect for each BF + HSRbegins=nBFs*(nANfiberTypes-1)+1; + rates=ICspikes(HSRbegins:end,:)/ANdt; + for idx=1:nBFs + [smoothedRates, MOCboundary{idx}] = ... + filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... + MOCboundary{idx}); + MOCattSegment(idx,:)=smoothedRates; + % expand timescale back to model dt from ANdt + x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1); + x= reshape(x,1,segmentLength); + MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... + (1- MOCrateToAttenuationFactor* x); + end + MOCattenuation(MOCattenuation<0)=0.04; + % segment debugging + % plotInstructions.figureNo=98; + % plotInstructions.displaydt=ANdt; + % plotInstructions.numPlots=1; + % plotInstructions.subPlotNo=1; + % UTIL_plotMatrix(ICspikes, plotInstructions); + + end % AN_spikesOrProbability + segmentStartPTR=segmentStartPTR+segmentLength; + reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength; + + +end % segment + +path(restorePath)
--- a/MAP/temp.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1128 +0,0 @@ - -function MAP1_14(inputSignal, sampleRate, BFlist, MAPparamsName, ... - AN_spikesOrProbability, paramChanges) -% To test this function use test_MAP1_14 in this folder -% -% All arguments are mandatory. -% -% BFlist is a list of BFs but can be '-1' to allow MAPparams to choose -% - -% MAPparamsName='Normal'; % source of model parameters -% AN_spikesOrProbability='spikes'; % or 'probability' -% paramChanges is a cell array of strings that can be used to make last -% minute parameter changes, e.g., to simulate OHC loss -% paramChanges{1}= 'DRNLParams.a=0;'; - -% The model parameters are established in the MAPparams<***> file -% and stored as global - -restorePath=path; -addpath (['..' filesep 'parameterStore']) - -global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams -global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams - -% All of the results of this function are stored as global -global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... - savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... - DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... - IHCoutput ANprobRateOutput ANoutput savePavailable tauCas ... - CNoutput ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation - -% Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be -% needed by the user; so the following will suffice -% global ANdt ICoutput ANprobRateOutput - -% Note that sampleRate has not changed from the original function call and -% ANprobRateOutput is sampled at this rate -% However ANoutput, CNoutput and IC output are stored as logical -% 'spike' matrices using a lower sample rate (see ANdt). - -% When AN_spikesOrProbability is set to probability, -% no spike matrices are computed. -% When AN_spikesOrProbability is set to 'spikes', -% no probability output is computed - -% Efferent control variables are ARattenuation and MOCattenuation -% These are scalars between 1 (no attenuation) and 0. -% They are represented with dt=1/sampleRate (not ANdt) -% They are computed using either AN probability rate output -% or IC (spikes) output as approrpriate. -% AR is computed using across channel activity -% MOC is computed on a within-channel basis. - - -% save as global for later plotting if required -savedBFlist=BFlist; -saveAN_spikesOrProbability=AN_spikesOrProbability; -saveMAPparamsName=MAPparamsName; - -% Read parameters from MAPparams<***> file in 'parameterStore' folder -cmd=['method=MAPparams' MAPparamsName ... - '(BFlist, sampleRate, 0);']; -eval(cmd); - -% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<> -% if the calling program allows MAPparams to specify the list -BFlist=DRNLParams.nonlinCFs; - -% now accept last mintue parameter changes required by the calling program -if nargin>5 && ~isempty(paramChanges) - nChanges=length(paramChanges); - for idx=1:nChanges - eval(paramChanges{idx}) - end -end - -dt=1/sampleRate; -duration=length(inputSignal)/sampleRate; -% segmentDuration is specified in parameter file (must be >efferent delay) -segmentDuration=method.segmentDuration; -segmentLength=round(segmentDuration/ dt); -segmentTime=dt*(1:segmentLength); % used in debugging plots - -% all spiking activity is computed using longer epochs -ANspeedUpFactor=AN_IHCsynapseParams.ANspeedUpFactor; % e.g.5 times - -% inputSignal must be row vector -[r c]=size(inputSignal); -if r>c, inputSignal=inputSignal'; end % transpose -% ignore stereo signals -inputSignal=inputSignal(1,:); % drop any second channel -savedInputSignal=inputSignal; - -% Segment the signal -% The sgment length is given but the signal length must be adjusted to be a -% multiple of both the segment length and the reduced segmentlength -[nSignalRows signalLength]=size(inputSignal); -segmentLength=ceil(segmentLength/ANspeedUpFactor)*ANspeedUpFactor; -% Make the signal length a whole multiple of the segment length -nSignalSegments=ceil(signalLength/segmentLength); -padSize=nSignalSegments*segmentLength-signalLength; -pad=zeros(nSignalRows,padSize); -inputSignal=[inputSignal pad]; -[ignore signalLength]=size(inputSignal); - -% AN (spikes) is computed at a lower sample rate when spikes required -% so it has a reduced segment length (see 'ANspeeUpFactor' above) -% AN CN and IC all use this sample interval -ANdt=dt*ANspeedUpFactor; -reducedSegmentLength=round(segmentLength/ANspeedUpFactor); -reducedSignalLength= round(signalLength/ANspeedUpFactor); - -%% Initialise with respect to each stage before computing -% by allocating memory, -% by computing constants -% by establishing easy to read variable names -% The computations are made in segments and boundary conditions must -% be established and stored. These are found in variables with -% 'boundary' or 'bndry' in the name - -%% OME --- -% external ear resonances -OMEexternalResonanceFilters=OMEParams.externalResonanceFilters; -[nOMEExtFilters c]=size(OMEexternalResonanceFilters); -% details of external (outer ear) resonances -OMEgaindBs=OMEexternalResonanceFilters(:,1); -OMEgainScalars=10.^(OMEgaindBs/20); -OMEfilterOrder=OMEexternalResonanceFilters(:,2); -OMElowerCutOff=OMEexternalResonanceFilters(:,3); -OMEupperCutOff=OMEexternalResonanceFilters(:,4); -% external resonance coefficients -ExtFilter_b=cell(nOMEExtFilters,1); -ExtFilter_a=cell(nOMEExtFilters,1); -for idx=1:nOMEExtFilters - Nyquist=sampleRate/2; - [b, a] = butter(OMEfilterOrder(idx), ... - [OMElowerCutOff(idx) OMEupperCutOff(idx)]... - /Nyquist); - ExtFilter_b{idx}=b; - ExtFilter_a{idx}=a; -end -OMEExtFilterBndry=cell(2,1); -OMEextEarPressure=zeros(1,signalLength); % pressure at tympanic membrane - -% pressure to velocity conversion using smoothing filter (50 Hz cutoff) -tau=1/(2*pi*50); -a1=dt/tau-1; a0=1; -b0=1+ a1; -TMdisp_b=b0; TMdisp_a=[a0 a1]; -% figure(9), freqz(TMdisp_b, TMdisp_a) -OME_TMdisplacementBndry=[]; - -% OME high pass (simulates poor low frequency stapes response) -OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff; -Nyquist=sampleRate/2; -[stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high'); -% figure(10), freqz(stapesDisp_b, stapesDisp_a) - -OMEhighPassBndry=[]; - -% OMEampStapes might be reducdant (use OMEParams.stapesScalar) -stapesScalar= OMEParams.stapesScalar; - -% Acoustic reflex -efferentDelayPts=round(OMEParams.ARdelay/dt); -% smoothing filter -a1=dt/OMEParams.ARtau-1; a0=1; -b0=1+ a1; -ARfilt_b=b0; ARfilt_a=[a0 a1]; - -ARattenuation=ones(1,signalLength); -ARrateThreshold=OMEParams.ARrateThreshold; % may not be used -ARrateToAttenuationFactor=OMEParams.rateToAttenuationFactor; -ARrateToAttenuationFactorProb=OMEParams.rateToAttenuationFactorProb; -ARboundary=[]; -ARboundaryProb=0; - -% save complete OME record (stapes displacement) -OMEoutput=zeros(1,signalLength); -TMoutput=zeros(1,signalLength); - -%% BM --- -% BM is represented as a list of locations identified by BF -DRNL_BFs=BFlist; -nBFs= length(DRNL_BFs); - -% DRNLchannelParameters=DRNLParams.channelParameters; -DRNLresponse= zeros(nBFs, segmentLength); - -MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor; -rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb; -MOCrateThreshold=DRNLParams.MOCrateThreshold; - -% smoothing filter for MOC -a1=dt/DRNLParams.MOCtau-1; a0=1; -b0=1+ a1; -MOCfilt_b=b0; MOCfilt_a=[a0 a1]; -% figure(9), freqz(stapesDisp_b, stapesDisp_a) -MOCboundary=cell(nBFs,1); -MOCprobBoundary=cell(nBFs,1); - -MOCattSegment=zeros(nBFs,reducedSegmentLength); -MOCattenuation=ones(nBFs,signalLength); - -if DRNLParams.a>0 - DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ... - log10(DRNLParams.b/DRNLParams.a)); -else - DRNLcompressionThreshold=inf; -end - -DRNLlinearOrder= DRNLParams.linOrder; -DRNLnonlinearOrder= DRNLParams.nonlinOrder; - -DRNLa=DRNLParams.a; -DRNLb=DRNLParams.b; -DRNLc=DRNLParams.c; -linGAIN=DRNLParams.g; -% -% gammatone filter coefficients for linear pathway -bw=DRNLParams.linBWs'; -phi = 2 * pi * bw * dt; -cf=DRNLParams.linCFs'; -theta = 2 * pi * cf * dt; -cos_theta = cos(theta); -sin_theta = sin(theta); -alpha = -exp(-phi).* cos_theta; -b0 = ones(nBFs,1); -b1 = 2 * alpha; -b2 = exp(-2 * phi); -z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; -z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; -z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; -tf = (z2 + z3) ./ z1; -a0 = abs(tf); -a1 = alpha .* a0; -GTlin_a = [b0, b1, b2]; -GTlin_b = [a0, a1]; -GTlinOrder=DRNLlinearOrder; -GTlinBdry=cell(nBFs,GTlinOrder); - -% nonlinear gammatone filter coefficients -bw=DRNLParams.nlBWs'; -phi = 2 * pi * bw * dt; -cf=DRNLParams.nonlinCFs'; -theta = 2 * pi * cf * dt; -cos_theta = cos(theta); -sin_theta = sin(theta); -alpha = -exp(-phi).* cos_theta; -b0 = ones(nBFs,1); -b1 = 2 * alpha; -b2 = exp(-2 * phi); -z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i; -z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i; -z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i; -tf = (z2 + z3) ./ z1; -a0 = abs(tf); -a1 = alpha .* a0; -GTnonlin_a = [b0, b1, b2]; -GTnonlin_b = [a0, a1]; -GTnonlinOrder=DRNLnonlinearOrder; -GTnonlinBdry1=cell(nBFs, GTnonlinOrder); -GTnonlinBdry2=cell(nBFs, GTnonlinOrder); - -% complete BM record (BM displacement) -DRNLoutput=zeros(nBFs, signalLength); - - -%% IHC --- -% IHC cilia activity and receptor potential -% viscous coupling between BM and stereocilia displacement -% Nyquist=sampleRate/2; -% IHCcutoff=1/(2*pi*IHC_cilia_RPParams.tc); -% [IHCciliaFilter_b,IHCciliaFilter_a]=... -% butter(1, IHCcutoff/Nyquist, 'high'); -a1=dt/IHC_cilia_RPParams.tc-1; a0=1; -b0=1+ a1; -% high pass (i.e. low pass reversed) -IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0; -% figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a) - -IHCciliaBndry=cell(nBFs,1); - -% IHC apical conductance (Boltzman function) -IHC_C= IHC_cilia_RPParams.C; -IHCu0= IHC_cilia_RPParams.u0; -IHCu1= IHC_cilia_RPParams.u1; -IHCs0= IHC_cilia_RPParams.s0; -IHCs1= IHC_cilia_RPParams.s1; -IHCGmax= IHC_cilia_RPParams.Gmax; -IHCGa= IHC_cilia_RPParams.Ga; % (leakage) - -IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1))); -IHCrestingCiliaCond=IHCGu0; - -% Receptor potential -IHC_Cab= IHC_cilia_RPParams.Cab; -IHC_Gk= IHC_cilia_RPParams.Gk; -IHC_Et= IHC_cilia_RPParams.Et; -IHC_Ek= IHC_cilia_RPParams.Ek; -IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc; - -IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk); - -IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage -IHC_RP= zeros(nBFs,segmentLength); - -% complete record of IHC receptor potential (V) -IHCciliaDisplacement= zeros(nBFs,segmentLength); -IHCoutput= zeros(nBFs,signalLength); -IHC_cilia_output= zeros(nBFs,signalLength); - - -%% pre-synapse --- -% Each BF is replicated using a different fiber type to make a 'channel' -% The number of channels is nBFs x nANfiberTypes -% Fiber types are specified in terms of tauCa -nANfiberTypes= length(IHCpreSynapseParams.tauCa); -tauCas= IHCpreSynapseParams.tauCa; -nChannels= nANfiberTypes*nBFs; -synapticCa= zeros(nChannels,segmentLength); - -% Calcium control (more calcium, greater release rate) -ECa=IHCpreSynapseParams.ECa; -gamma=IHCpreSynapseParams.gamma; -beta=IHCpreSynapseParams.beta; -tauM=IHCpreSynapseParams.tauM; -mICa=zeros(nChannels,segmentLength); -GmaxCa=IHCpreSynapseParams.GmaxCa; -synapse_z= IHCpreSynapseParams.z; -synapse_power=IHCpreSynapseParams.power; - -% tauCa vector is established across channels to allow vectorization -% (one tauCa per channel). Do not confuse with tauCas (one pre fiber type) -tauCa=repmat(tauCas, nBFs,1); -tauCa=reshape(tauCa, nChannels, 1); - -% presynapse startup values (vectors, length:nChannels) -% proportion (0 - 1) of Ca channels open at IHCrestingV -mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)... - *ones(nBFs*nANfiberTypes,1); -% corresponding startup currents -ICaCurrent= (GmaxCa*mICaCurrent.^3) * (IHCrestingV-ECa); -CaCurrent= ICaCurrent.*tauCa; - -% vesicle release rate at startup (one per channel) -% kt0 is used only at initialisation -kt0= -synapse_z * CaCurrent.^synapse_power; - - -%% AN --- -% each row of the AN matrices represents one AN fiber -% The results computed either for probabiities *or* for spikes (not both) -% Spikes are necessary if CN and IC are to be computed -nFibersPerChannel= AN_IHCsynapseParams.numFibers; -nANfibers= nChannels*nFibersPerChannel; - -y=AN_IHCsynapseParams.y; -l=AN_IHCsynapseParams.l; -x=AN_IHCsynapseParams.x; -r=AN_IHCsynapseParams.r; -M=round(AN_IHCsynapseParams.M); - -% probability (NB initial 'P' on everything) -PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nChannels,1); -PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nChannels,1); -PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nChannels,1); -PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nChannels,1); -PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt; -PAN_M=round(AN_IHCsynapseParams.M); - -% compute starting values -Pcleft = kt0* y* M ./ (y*(l+r)+ kt0* l); -Pavailable = Pcleft*(l+r)./kt0; -Preprocess = Pcleft*r/x; % canbe fractional - -ANprobability=zeros(nChannels,segmentLength); -ANprobRateOutput=zeros(nChannels,signalLength); -% special variables for monitoring synaptic cleft (specialists only) -savePavailableSeg=zeros(nChannels,segmentLength); -savePavailable=zeros(nChannels,signalLength); - -% spikes % ! ! ! ! ! ! ! ! -AN_refractory_period= AN_IHCsynapseParams.refractory_period; -lengthAbsRefractory= round(AN_refractory_period/ANdt); - -AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1); -AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1); -AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1); -AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1); -AN_rdt_plus_ldt= AN_rdt + AN_ldt; -AN_M= round(AN_IHCsynapseParams.M); - -% kt0 is initial release rate -% Establish as a vector (length=channel x number of fibers) -kt0= repmat(kt0', nFibersPerChannel, 1); -kt0=reshape(kt0, nANfibers,1); - -% starting values for reservoirs -AN_cleft = kt0* y* M ./ (y*(l+r)+ kt0* l); -AN_available = round(AN_cleft*(l+r)./kt0); %must be integer -AN_reprocess = AN_cleft*r/x; - -% output is in a logical array spikes = 1/ 0. -ANspikes= false(nANfibers,reducedSegmentLength); -ANoutput= false(nANfibers,reducedSignalLength); - - -%% CN (first brain stem nucleus - could be any subdivision of CN) -% Input to a CN neuorn is a random selection of AN fibers within a channel -% The number of AN fibers used is ANfibersFanInToCN -ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron; -nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF; -% CNtauGk (Potassium time constant) determines the rate of firing of -% the unit when driven hard by a DC input (not normally >350 sp/s) -CNtauGk=MacGregorMultiParams.tauGk; -ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers; -nCNneurons=nCNneuronsPerChannel*nChannels; -% nCNneuronsPerFiberType= nCNneurons/nANfiberTypes; - -CNmembranePotential=zeros(nCNneurons,reducedSegmentLength); - -% establish which ANfibers (by name) feed into which CN nuerons -CNinputfiberLists=zeros(nChannels*nCNneuronsPerChannel, ANfibersFanInToCN); -unitNo=1; -for ch=1:nChannels - % Each channel contains a number of units =length(listOfFanInValues) - for idx=1:nCNneuronsPerChannel - fibersUsed=(ch-1)*ANavailableFibersPerChan + ... - ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan); - CNinputfiberLists(unitNo,:)=fibersUsed; - unitNo=unitNo+1; - end -end - -% input to CN units -AN_PSTH=zeros(nCNneurons,reducedSegmentLength); - -% Generate CNalphaFunction function -% by which spikes are converted to post-synaptic currents -CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq; -CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike; -CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq); -t=ANdt:ANdt:5*CNspikeToCurrentTau; -CNalphaFunction= (1 / ... - CNspikeToCurrentTau)*t.*exp(-t /CNspikeToCurrentTau); -CNalphaFunction=CNalphaFunction*CNcurrentPerSpike; - -% figure(98), plot(t,CNalphaFunction) -% working memory for implementing convolution - -CNcurrentTemp=... - zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1); -% trailing alphas are parts of humps carried forward to the next segment -CNtrailingAlphas=zeros(nCNneurons,length(CNalphaFunction)); - -CN_tauM=MacGregorMultiParams.tauM; -CN_tauTh=MacGregorMultiParams.tauTh; -CN_cap=MacGregorMultiParams.Cap; -CN_c=MacGregorMultiParams.c; -CN_b=MacGregorMultiParams.dGkSpike; -CN_Ek=MacGregorMultiParams.Ek; -CN_Eb= MacGregorMultiParams.Eb; -CN_Er=MacGregorMultiParams.Er; -CN_Th0= MacGregorMultiParams.Th0; -CN_E= zeros(nCNneurons,1); -CN_Gk= zeros(nCNneurons,1); -CN_Th= MacGregorMultiParams.Th0*ones(nCNneurons,1); -CN_Eb=CN_Eb.*ones(nCNneurons,1); -CN_Er=CN_Er.*ones(nCNneurons,1); -CNtimeSinceLastSpike=zeros(nCNneurons,1); -% tauGk is the main distinction between neurons -% in fact they are all the same in the standard model -tauGk=repmat(CNtauGk,nChannels*nCNneuronsPerChannel,1); - -CN_PSTH=zeros(nChannels,reducedSegmentLength); -CNoutput=false(nCNneurons,reducedSignalLength); - - -%% MacGregor (IC - second nucleus) -------- -nICcells=nChannels; % one cell per channel - -ICspikeWidth=0.00015; % this may need revisiting -epochsPerSpike=round(ICspikeWidth/ANdt); -if epochsPerSpike<1 - error(['MacGregorMulti: sample rate too low to support ' ... - num2str(ICspikeWidth*1e6) ' microsec spikes']); -end - -% short names -IC_tauM=MacGregorParams.tauM; -IC_tauGk=MacGregorParams.tauGk; -IC_tauTh=MacGregorParams.tauTh; -IC_cap=MacGregorParams.Cap; -IC_c=MacGregorParams.c; -IC_b=MacGregorParams.dGkSpike; -IC_Th0=MacGregorParams.Th0; -IC_Ek=MacGregorParams.Ek; -IC_Eb= MacGregorParams.Eb; -IC_Er=MacGregorParams.Er; - -IC_E=zeros(nICcells,1); -IC_Gk=zeros(nICcells,1); -IC_Th=IC_Th0*ones(nICcells,1); - -% Dendritic filtering, all spikes are replaced by CNalphaFunction functions -ICdendriteLPfreq= MacGregorParams.dendriteLPfreq; -ICcurrentPerSpike=MacGregorParams.currentPerSpike; -ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq); -t=ANdt:ANdt:3*ICspikeToCurrentTau; -IC_CNalphaFunction= (ICcurrentPerSpike / ... - ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau); -% figure(98), plot(t,IC_CNalphaFunction) - -% working space for implementing alpha function -ICcurrentTemp=... - zeros(nICcells,reducedSegmentLength+length(IC_CNalphaFunction)-1); -ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction)); - -ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength); -ICoutput=false(nChannels,reducedSignalLength); - -ICmembranePotential=zeros(nICcells,reducedSegmentLength); -ICmembraneOutput=zeros(nICcells,signalLength); - - -%% Main program %% %% %% %% %% %% %% %% %% %% %% %% %% %% - -% Compute the entire model for each segment -segmentStartPTR=1; -reducedSegmentPTR=1; % when sampling rate is reduced -while segmentStartPTR<signalLength - segmentEndPTR=segmentStartPTR+segmentLength-1; - % shorter segments after speed up. - shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1; - - iputPressureSegment=inputSignal... - (:,segmentStartPTR:segmentStartPTR+segmentLength-1); - - % segment debugging plots - % figure(98) - % plot(segmentTime,iputPressureSegment), title('signalSegment') - - - % OME ---------------------- - - % OME Stage 1: external resonances. Add to inputSignal pressure wave - y=iputPressureSegment; - for n=1:nOMEExtFilters - % any number of resonances can be used - [x OMEExtFilterBndry{n}] = ... - filter(ExtFilter_b{n},ExtFilter_a{n},... - iputPressureSegment, OMEExtFilterBndry{n}); - x= x* OMEgainScalars(n); - % This is a parallel resonance so add it - y=y+x; - end - iputPressureSegment=y; - OMEextEarPressure(segmentStartPTR:segmentEndPTR)= iputPressureSegment; - - % OME stage 2: convert input pressure (velocity) to - % tympanic membrane(TM) displacement using low pass filter - [TMdisplacementSegment OME_TMdisplacementBndry] = ... - filter(TMdisp_b,TMdisp_a,iputPressureSegment, ... - OME_TMdisplacementBndry); - % and save it - TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment; - - % OME stage 3: middle ear high pass effect to simulate stapes inertia - [stapesDisplacement OMEhighPassBndry] = ... - filter(stapesDisp_b,stapesDisp_a,TMdisplacementSegment, ... - OMEhighPassBndry); - - % OME stage 4: apply stapes scalar - stapesDisplacement=stapesDisplacement*stapesScalar; - - % OME stage 5: acoustic reflex stapes attenuation - % Attenuate the TM response using feedback from LSR fiber activity - if segmentStartPTR>efferentDelayPts - stapesDisplacement= stapesDisplacement.*... - ARattenuation(segmentStartPTR-efferentDelayPts:... - segmentEndPTR-efferentDelayPts); - end - - % segment debugging plots - % figure(98) - % plot(segmentTime, stapesDisplacement), title ('stapesDisplacement') - - % and save - OMEoutput(segmentStartPTR:segmentEndPTR)= stapesDisplacement; - - - %% BM ------------------------------ - % Each location is computed separately - for BFno=1:nBFs - - % *linear* path - linOutput = stapesDisplacement * linGAIN; % linear gain - for order = 1 : GTlinOrder - [linOutput GTlinBdry{BFno,order}] = ... - filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry{BFno,order}); - end - - % *nonLinear* path - % efferent attenuation (0 <> 1) - if segmentStartPTR>efferentDelayPts - MOC=MOCattenuation(BFno, segmentStartPTR-efferentDelayPts:... - segmentEndPTR-efferentDelayPts); - else % no MOC available yet - MOC=ones(1, segmentLength); - end - - % first gammatone filter - for order = 1 : GTnonlinOrder - [nonlinOutput GTnonlinBdry1{BFno,order}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ... - stapesDisplacement, GTnonlinBdry1{BFno,order}); - end - - % broken stick instantaneous compression - % nonlinear gain is weakend by MOC before applied to BM response - y= nonlinOutput.*(MOC* DRNLa); % linear section. - % compress those parts of the signal above the compression - % threshold - abs_x = abs(nonlinOutput); - idx=find(abs_x>DRNLcompressionThreshold); - if ~isempty(idx)>0 - y(idx)=sign(nonlinOutput(idx)).*... - (DRNLb*abs_x(idx).^DRNLc); - end - nonlinOutput=y; - - % second filter removes distortion products - for order = 1 : GTnonlinOrder - [ nonlinOutput GTnonlinBdry2{BFno,order}] = ... - filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), nonlinOutput, GTnonlinBdry2{BFno,order}); - end - - % combine the two paths to give the DRNL displacement - DRNLresponse(BFno,:)=linOutput+nonlinOutput; - end % BF - - % segment debugging plots - % figure(98) - % if size(DRNLresponse,1)>3 - % imagesc(DRNLresponse) % matrix display - % title('DRNLresponse'); % single or double channel response - % else - % plot(segmentTime, DRNLresponse) - % end - - % and save it - DRNLoutput(:, segmentStartPTR:segmentEndPTR)= DRNLresponse; - - - %% IHC ------------------------------------ - % BM displacement to IHCciliaDisplacement is a high-pass filter - % because of viscous coupling - for idx=1:nBFs - [IHCciliaDisplacement(idx,:) IHCciliaBndry{idx}] = ... - filter(IHCciliaFilter_b,IHCciliaFilter_a, ... - DRNLresponse(idx,:), IHCciliaBndry{idx}); - end - - % apply scalar - IHCciliaDisplacement=IHCciliaDisplacement* IHC_C; - - % and save it - IHC_cilia_output(:,segmentStartPTR:segmentStartPTR+segmentLength-1)=... - IHCciliaDisplacement; - - % compute apical conductance - G=IHCGmax./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*... - (1+exp(-(IHCciliaDisplacement-IHCu1)/IHCs1))); - Gu=G + IHCGa; - - % Compute receptor potential - for idx=1:segmentLength - IHC_Vnow=IHC_Vnow+ (-Gu(:, idx).*(IHC_Vnow-IHC_Et)-... - IHC_Gk*(IHC_Vnow-IHC_Ekp))* dt/IHC_Cab; - IHC_RP(:,idx)=IHC_Vnow; - end - - % segment debugging plots - % if size(IHC_RP,1)>3 - % surf(IHC_RP), shading interp, title('IHC_RP') - % else - % plot(segmentTime, IHC_RP) - % end - - % and save it - IHCoutput(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=IHC_RP; - - - %% synapse ----------------------------- - % Compute the vesicle release rate for each fiber type at each BF - % replicate IHC_RP for each fiber type - Vsynapse=repmat(IHC_RP, nANfiberTypes,1); - - % look-up table of target fraction channels open for a given IHC_RP - mICaINF= 1./( 1 + exp(-gamma * Vsynapse) /beta); - % fraction of channel open - apply time constant - for idx=1:segmentLength - % mICaINF is the current 'target' value of mICa - mICaCurrent=mICaCurrent+(mICaINF(:,idx)-mICaCurrent)*dt./tauM; - mICa(:,idx)=mICaCurrent; - end - - ICa= (GmaxCa* mICa.^3) .* (Vsynapse- ECa); - - for idx=1:segmentLength - CaCurrent=CaCurrent + ICa(:,idx)*dt - CaCurrent*dt./tauCa; - synapticCa(:,idx)=CaCurrent; - end - synapticCa=-synapticCa; % treat IHCpreSynapseParams as positive substance - - % NB vesicleReleaseRate is /s and is independent of dt - vesicleReleaseRate = synapse_z * synapticCa.^synapse_power; % rate - - % segment debugging plots - % if size(vesicleReleaseRate,1)>3 - % surf(vesicleReleaseRate), shading interp, title('vesicleReleaseRate') - % else - % plot(segmentTime, vesicleReleaseRate) - % end - - - %% AN - switch AN_spikesOrProbability - case 'probability' - % No refractory effect is applied - for t = 1:segmentLength; - M_Pq=PAN_M-Pavailable; - M_Pq(M_Pq<0)=0; - Preplenish = M_Pq .* PAN_ydt; - Pejected = Pavailable.* vesicleReleaseRate(:,t)*dt; - Preprocessed = M_Pq.*Preprocess.* PAN_xdt; - - ANprobability(:,t)= min(Pejected,1); - reuptakeandlost= PAN_rdt_plus_ldt .* Pcleft; - reuptake= PAN_rdt.* Pcleft; - - Pavailable= Pavailable+ Preplenish- Pejected+ Preprocessed; - Pcleft= Pcleft + Pejected - reuptakeandlost; - Preprocess= Preprocess + reuptake - Preprocessed; - Pavailable(Pavailable<0)=0; - savePavailableSeg(:,t)=Pavailable; % synapse tracking - end - % and save it as *rate* - ANrate=ANprobability/dt; - ANprobRateOutput(:, segmentStartPTR:... - segmentStartPTR+segmentLength-1)= ANrate; - % monitor synapse contents (only sometimes used) - savePavailable(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=... - savePavailableSeg; - - % Estimate efferent effects. ARattenuation (0 <> 1) - % acoustic reflex - ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF - % smooth - [ARAttSeg, ARboundaryProb] = ... - filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb); - ARAttSeg=ARAttSeg-ARrateThreshold; - ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths - ARattenuation(segmentStartPTR:segmentEndPTR)=... - (1-ARrateToAttenuationFactorProb.* ARAttSeg); - - % MOC attenuation - % within-channel HSR response only - HSRbegins=nBFs*(nANfiberTypes-1)+1; - rates=ANrate(HSRbegins:end,:); - for idx=1:nBFs - [smoothedRates, MOCprobBoundary{idx}] = ... - filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... - MOCprobBoundary{idx}); - smoothedRates=smoothedRates-MOCrateThreshold; - smoothedRates(smoothedRates<0)=0; - MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... - (1- smoothedRates* rateToAttenuationFactorProb); - end - MOCattenuation(MOCattenuation<0)=0.001; - - - case 'spikes' - ANtimeCount=0; - % implement speed upt - for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength; - ANtimeCount=ANtimeCount+1; - % convert release rate to probabilities - releaseProb=vesicleReleaseRate(:,t)*ANdt; - % releaseProb is the release probability per channel - % but each channel has many synapses - releaseProb=repmat(releaseProb',nFibersPerChannel,1); - releaseProb=reshape(releaseProb, nFibersPerChannel*nChannels,1); - - % AN_available=round(AN_available); % vesicles must be integer, (?needed) - M_q=AN_M- AN_available; % number of missing vesicles - M_q(M_q<0)= 0; % cannot be less than 0 - - % AN_N1 converts probability to discrete events - % it considers each event that might occur - % (how many vesicles might be released) - % and returns a count of how many were released - - % slow line -% probabilities= 1-(1-releaseProb).^AN_available; - probabilities= 1-intpow((1-releaseProb), AN_available); - ejected= probabilities> rand(length(AN_available),1); - - reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft; - reuptake = AN_rdt.* AN_cleft; - - % slow line -% probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q; - probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q); - reprocessed= probabilities>rand(length(M_q),1); - - % slow line -% probabilities= 1-(1-AN_ydt).^M_q; - probabilities= 1-intpow((1-AN_ydt), M_q); - - replenish= probabilities>rand(length(M_q),1); - - AN_available = AN_available + replenish - ejected ... - + reprocessed; - AN_cleft = AN_cleft + ejected - reuptakeandlost; - AN_reprocess = AN_reprocess + reuptake - reprocessed; - - % ANspikes is logical record of vesicle release events>0 - ANspikes(:, ANtimeCount)= ejected; - end % t - - % zero any events that are preceded by release events ... - % within the refractory period - % The refractory period consist of two periods - % 1) the absolute period where no spikes occur - % 2) a relative period where a spike may occur. This relative - % period is realised as a variable length interval - % where the length is chosen at random - % (esentially a linear ramp up) - - % Andreas has a fix for this - for t = 1:ANtimeCount-2*lengthAbsRefractory; - % identify all spikes across fiber array at time (t) - % idx is a list of channels where spikes occurred - % ?? try sparse matrices? - idx=find(ANspikes(:,t)); - for j=idx % consider each spike - % specify variable refractory period - % between abs and 2*abs refractory period - nPointsRefractory=lengthAbsRefractory+... - round(rand*lengthAbsRefractory); - % disable spike potential for refractory period - % set all values in this range to 0 - ANspikes(j,t+1:t+nPointsRefractory)=0; - end - end %t - - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(ANspikes, plotInstructions); - - % and save it. NB, AN is now on 'speedUp' time - ANoutput(:, reducedSegmentPTR: shorterSegmentEndPTR)=ANspikes; - - - %% CN Macgregor first neucleus ------------------------------- - % input is from AN so ANdt is used throughout - % Each CNneuron has a unique set of input fibers selected - % at random from the available AN fibers (CNinputfiberLists) - - % Create the dendritic current for that neuron - % First get input spikes to this neuron - synapseNo=1; - for ch=1:nChannels - for idx=1:nCNneuronsPerChannel - % determine candidate fibers for this unit - fibersUsed=CNinputfiberLists(synapseNo,:); - % ANpsth has a bin width of ANdt - % (just a simple sum across fibers) - AN_PSTH(synapseNo,:) = ... - sum(ANspikes(fibersUsed,:), 1); - synapseNo=synapseNo+1; - end - end - - % One alpha function per spike - [alphaRows alphaCols]=size(CNtrailingAlphas); - - for unitNo=1:nCNneurons - CNcurrentTemp(unitNo,:)= ... - conv(AN_PSTH(unitNo,:),CNalphaFunction); - end -% disp(['sum(AN_PSTH)= ' num2str(sum(AN_PSTH(1,:)))]) - % add post-synaptic current left over from previous segment - CNcurrentTemp(:,1:alphaCols)=... - CNcurrentTemp(:,1:alphaCols)+ CNtrailingAlphas; - - % take post-synaptic current for this segment - CNcurrentInput= CNcurrentTemp(:, 1:reducedSegmentLength); -% disp(['mean(CNcurrentInput)= ' num2str(mean(CNcurrentInput(1,:)))]) - - % trailingalphas are the ends of the alpha functions that - % spill over into the next segment - CNtrailingAlphas= ... - CNcurrentTemp(:, reducedSegmentLength+1:end); - - if CN_c>0 - % variable threshold condition (slow) - for t=1:reducedSegmentLength - CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt; - s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ; - CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike - dE =(-CN_E/CN_tauM + ... - CNcurrentInput(:,t)/CN_cap+(... - CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt; - dGk=-CN_Gk*ANdt./tauGk + CN_b*s; - dTh=-(CN_Th-CN_Th0)*ANdt/CN_tauTh + CN_c*s; - CN_E=CN_E+dE; - CN_Gk=CN_Gk+dGk; - CN_Th=CN_Th+dTh; - CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er; - end - else - % static threshold (faster) - E=zeros(1,reducedSegmentLength); - Gk=zeros(1,reducedSegmentLength); - ss=zeros(1,reducedSegmentLength); - for t=1:reducedSegmentLength - % time of previous spike moves back in time - CNtimeSinceLastSpike=CNtimeSinceLastSpike-ANdt; - % action potential if E>threshold - % allow time for s to reset between events - s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ; - ss(t)=s(1); - CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike - dE = (-CN_E/CN_tauM + ... - CNcurrentInput(:,t)/CN_cap +... - (CN_Gk/CN_cap).*(CN_Ek-CN_E))*ANdt; - dGk=-CN_Gk*ANdt./tauGk +CN_b*s; - CN_E=CN_E+dE; - CN_Gk=CN_Gk+dGk; - E(t)=CN_E(1); - Gk(t)=CN_Gk(1); - % add spike to CN_E and add resting potential (-60 mV) - CNmembranePotential(:,t)=CN_E +s.*(CN_Eb-CN_E)+CN_Er; - end - end -% disp(['CN_E= ' num2str(sum(CN_E(1,:)))]) -% disp(['CN_Gk= ' num2str(sum(CN_Gk(1,:)))]) -% disp(['CNmembranePotential= ' num2str(sum(CNmembranePotential(1,:)))]) -% plot(CNmembranePotential(1,:)) - - - % extract spikes. A spike is a substantial upswing in voltage - CN_spikes=CNmembranePotential> -0.02; -% disp(['CNspikesbefore= ' num2str(sum(sum(CN_spikes)))]) - - % now remove any spike that is immediately followed by a spike - % NB 'find' works on columns (whence the transposing) - % for each spike put a zero in the next epoch - CN_spikes=CN_spikes'; - idx=find(CN_spikes); - idx=idx(1:end-1); - CN_spikes(idx+1)=0; - CN_spikes=CN_spikes'; -% disp(['CNspikes= ' num2str(sum(sum(CN_spikes)))]) - - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(CN_spikes, plotInstructions); - - % and save it - CNoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=... - CN_spikes; - - - %% IC ---------------------------------------------- - % MacGregor or some other second order neurons - - % combine CN neurons in same channel, i.e. same BF & same tauCa - % to generate inputs to single IC unit - channelNo=0; - for idx=1:nCNneuronsPerChannel:nCNneurons-nCNneuronsPerChannel+1; - channelNo=channelNo+1; - CN_PSTH(channelNo,:)=... - sum(CN_spikes(idx:idx+nCNneuronsPerChannel-1,:)); - end - - [alphaRows alphaCols]=size(ICtrailingAlphas); - for ICneuronNo=1:nICcells - ICcurrentTemp(ICneuronNo,:)= ... - conv(CN_PSTH(ICneuronNo,:), IC_CNalphaFunction); - end - - % add the unused current from the previous convolution - ICcurrentTemp(:,1:alphaCols)=ICcurrentTemp(:,1:alphaCols)... - + ICtrailingAlphas; - % take what is required and keep the trailing part for next time - inputCurrent=ICcurrentTemp(:, 1:reducedSegmentLength); - ICtrailingAlphas=ICcurrentTemp(:, reducedSegmentLength+1:end); - - if IC_c==0 - % faster computation when threshold is stable (C==0) - for t=1:reducedSegmentLength - s=IC_E>IC_Th0; - dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +... - (IC_Gk/IC_cap).*(IC_Ek-IC_E))*ANdt; - dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s; - IC_E=IC_E+dE; - IC_Gk=IC_Gk+dGk; - ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; - end - else - % threshold is changing (IC_c>0; e.g. bushy cell) - for t=1:reducedSegmentLength - dE = (-IC_E/IC_tauM + ... - inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)... - .*(IC_Ek-IC_E))*ANdt; - IC_E=IC_E+dE; - s=IC_E>IC_Th; - ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er; - dGk=-IC_Gk*ANdt/IC_tauGk +IC_b*s; - IC_Gk=IC_Gk+dGk; - - % After a spike, the threshold is raised - % otherwise it settles to its baseline - dTh=-(IC_Th-Th0)*ANdt/IC_tauTh +s*IC_c; - IC_Th=IC_Th+dTh; - end - end - - ICspikes=ICmembranePotential> -0.01; - % now remove any spike that is immediately followed by a spike - % NB 'find' works on columns (whence the transposing) - ICspikes=ICspikes'; - idx=find(ICspikes); - idx=idx(1:end-1); - ICspikes(idx+1)=0; - ICspikes=ICspikes'; - - nCellsPerTau= nICcells/nANfiberTypes; - firstCell=1; - lastCell=nCellsPerTau; - for tauCount=1:nANfiberTypes - % separate rates according to fiber types - % currently only the last segment is saved - ICfiberTypeRates(tauCount, ... - reducedSegmentPTR:shorterSegmentEndPTR)=... - sum(ICspikes(firstCell:lastCell, :))... - /(nCellsPerTau*ANdt); - firstCell=firstCell+nCellsPerTau; - lastCell=lastCell+nCellsPerTau; - end - - ICoutput(:,reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes; - - % store membrane output on original dt scale - if nBFs==1 % single channel - x= repmat(ICmembranePotential(1,:), ANspeedUpFactor,1); - x= reshape(x,1,segmentLength); - if nANfiberTypes>1 % save HSR and LSR - y=repmat(ICmembranePotential(end,:),... - ANspeedUpFactor,1); - y= reshape(y,1,segmentLength); - x=[x; y]; - end - ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x; - end - - % estimate efferent effects. - % ARis based on LSR units. LSR channels are 1:nBF - if nANfiberTypes>1 % AR is multi-channel only - ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt; - [ARAttSeg, ARboundary] = ... - filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary); - ARAttSeg=ARAttSeg-ARrateThreshold; - ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths - % scale up to dt from ANdt - x= repmat(ARAttSeg, ANspeedUpFactor,1); - x=reshape(x,1,segmentLength); - ARattenuation(segmentStartPTR:segmentEndPTR)=... - (1-ARrateToAttenuationFactor* x); - ARattenuation(ARattenuation<0)=0.001; - else - % single channel model; disable AR - ARattenuation(segmentStartPTR:segmentEndPTR)=... - ones(1,segmentLength); - end - - % MOC attenuation using HSR response only - % Separate MOC effect for each BF - HSRbegins=nBFs*(nANfiberTypes-1)+1; - rates=ICspikes(HSRbegins:end,:)/ANdt; - for idx=1:nBFs - [smoothedRates, MOCboundary{idx}] = ... - filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ... - MOCboundary{idx}); - MOCattSegment(idx,:)=smoothedRates; - % expand timescale back to model dt from ANdt - x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1); - x= reshape(x,1,segmentLength); - MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ... - (1- MOCrateToAttenuationFactor* x); - end - MOCattenuation(MOCattenuation<0)=0.04; - % segment debugging - % plotInstructions.figureNo=98; - % plotInstructions.displaydt=ANdt; - % plotInstructions.numPlots=1; - % plotInstructions.subPlotNo=1; - % UTIL_plotMatrix(ICspikes, plotInstructions); - - end % AN_spikesOrProbability - segmentStartPTR=segmentStartPTR+segmentLength; - reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength; - - -end % segment - -path(restorePath)
--- a/README.md Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -This is the new readMe file ----------------------------- - -Look in the 'Help and reference data folder' for advice. \ No newline at end of file
--- a/multithreshold 1.46/MTprofile10_0hr19_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -function x = MTprofile10_0hr19_Aug_2011 -%created: 10_0hr19_Aug_2011 - -x.BFs = [250 500 1000 2000 4000 8000]; - -x.LongTone = [16.1 13.1 9.24 9.67 15.4 20.6]; -x.ShortTone = [18.9 16 12.3 12.7 20.8 26.6]; - -x.Gaps = [0.01 0.03 0.05 0.07 0.09]; -x.TMCFreq = [250 500 1000 2000 4000 8000]; -x.TMC = [ -36.2 31.2 35.2 54.4 38.2 37 -69.5 42.5 52.6 64.8 62.9 39.8 -77.8 65.2 52.2 66.7 72.3 42.2 -80.7 71.5 70.7 71.2 80.6 44.4 -89.6 82.3 77.8 74.9 78.2 68.2 -]; -x.TMC = x.TMC'; - -x.MaskerRatio = [0.5 0.7 0.9 1 1.1 1.3 1.6]; -x.IFMCFreq = [250 500 1000 2000 4000 8000]; -x.IFMCs = [ -68.2 79.3 77.9 75.2 77.4 83.2 -58 66.9 69.2 74.7 83.1 88 -52.4 38.3 39.6 53.2 74.6 41.5 -41.7 32.1 31.3 46.9 40.4 39.4 -35 29.2 23.9 56.3 40.4 37.2 -43.3 37.7 70.7 80.1 91.7 89 -78.7 80.7 85.5 91 99.7 102 -]; -x.IFMCs = x.IFMCs';
--- a/multithreshold 1.46/MTprofile17_14hr18_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -function x = MTprofile17_14hr18_Aug_2011 -%created: 17_14hr18_Aug_2011 - -x.BFs = [1000]; - -x.LongTone = [9.11]; -x.ShortTone = [11.6]; - -x.Gaps = [0.01 0.03 0.05 0.07 0.09]; -x.TMCFreq = [1000]; -x.TMC = [ -34.5 -37.9 -42 -52 -55.7 -]; -x.TMC = x.TMC'; - -x.MaskerRatio = [0.5 0.7 0.9 1 1.1 1.3 1.6]; -x.IFMCFreq = [1000]; -x.IFMCs = [ -64.9 -48.4 -33.9 -32.7 -28.9 -38.6 -60.9 -]; -x.IFMCs = x.IFMCs';
--- a/multithreshold 1.46/MTprofile17_32hr18_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -function x = MTprofile17_32hr18_Aug_2011 -%created: 17_32hr18_Aug_2011 - -x.BFs = [1000]; - -x.LongTone = [9.11]; -x.ShortTone = [11.6]; -
--- a/multithreshold 1.46/MTprofile17_33hr18_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -function x = MTprofile17_33hr18_Aug_2011 -%created: 17_33hr18_Aug_2011 - -x.BFs = [1000]; - -x.LongTone = [9.11]; -x.ShortTone = [11.6]; - -x.Gaps = [0.01 0.03 0.05 0.07 0.09]; -x.TMCFreq = [1000]; -x.TMC = [ -34.5 37.9 42 52 55.7 -]; -x.TMC = x.TMC'; - -x.MaskerRatio = [0.5 0.7 0.9 1 1.1 1.3 1.6]; -x.IFMCFreq = [1000]; -x.IFMCs = [ -64.9 48.4 33.9 32.7 28.9 38.6 60.9 -]; -x.IFMCs = x.IFMCs';
--- a/multithreshold 1.46/MTprofile17_44hr18_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -function x = MTprofile17_44hr18_Aug_2011 -%created: 17_44hr18_Aug_2011 - -x.BFs = [250 500 1000 2000 4000 8000]; - -x.LongTone = [16.1 12.7 8.93 8.95 14 20.9]; -x.ShortTone = [18.8 15.5 11.9 13.6 20.2 25.3]; - -x.Gaps = [0.01 0.03 0.05 0.07 0.09]; -x.TMCFreq = [250 500 1000 2000 4000 8000]; -x.TMC = [ -51.3 49.7 43.7 56.1 45.7 35.3 -59.2 52.9 57.9 63.8 58 39.2 -63.3 65.6 58.6 67.5 63.9 45.4 -77 72 70.5 68.8 69.7 39.7 -82.7 77.3 75.1 73.3 70.4 70.4 -]; -x.TMC = x.TMC'; - -x.MaskerRatio = [0.5 0.7 0.9 1 1.1 1.3 1.6]; -x.IFMCFreq = [250 500 1000 2000 4000 8000]; -x.IFMCs = [ -61.1 74.9 78.7 76.7 78.8 84.8 -55.9 64.3 64.8 76.9 85.3 89.9 -52.4 53.1 47.8 59.3 62 37.6 -48.8 44 45 54.9 56.9 36.7 -53.7 47.4 43.2 63.6 45.9 39.7 -52.5 55 61.7 74.5 82.5 72.1 -59.2 68.7 90.1 104 102 103 -]; -x.IFMCs = x.IFMCs';
--- a/multithreshold 1.46/MTprofile7_44hr19_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -function x = MTprofile7_44hr19_Aug_2011 -%created: 7_44hr19_Aug_2011 - -x.BFs = [1000]; - -x.LongTone = [9.83]; -x.ShortTone = [12.3]; - -x.Gaps = [0.01 0.03 0.05 0.07 0.09]; -x.TMCFreq = [1000]; -x.TMC = [ -63.5 -66.8 -72 -82.7 -90.2 -]; -x.TMC = x.TMC'; - -x.MaskerRatio = [0.5 0.7 0.9 1 1.1 1.3 1.6]; -x.IFMCFreq = [1000]; -x.IFMCs = [ -81 -73.3 -63.4 -60.3 -65.5 -79 -88 -]; -x.IFMCs = x.IFMCs';
--- a/multithreshold 1.46/MTprofile8_19hr19_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -function x = MTprofile8_19hr19_Aug_2011 -%created: 8_19hr19_Aug_2011 - -x.BFs = [250 500 1000 2000 4000 8000]; - -x.LongTone = [16.5 13 9.2 9.64 15.4 21.2]; -x.ShortTone = [19.6 15.4 12.2 12.6 20.5 25.2]; - -x.Gaps = [0.01 0.03 0.05 0.07 0.09]; -x.TMCFreq = [250 500 1000 2000 4000 8000]; -x.TMC = [ -75.2 55.2 60.6 62.6 63.2 37 -81 67.3 69 70.4 73.5 38.4 -88.3 71.1 74.2 74.6 77.7 39.4 -99 84.9 78.2 75.4 80.9 48.2 -NaN 86.9 83.4 79.8 83.8 66.2 -]; -x.TMC = x.TMC'; - -x.MaskerRatio = [0.01 0.03 0.05 0.07 0.09]; -x.IFMCFreq = [250 500 1000 2000 4000 8000]; -x.IFMCs = [ -75.2 55.2 60.6 62.6 63.2 37 -81 67.3 69 70.4 73.5 38.4 -88.3 71.1 74.2 74.6 77.7 39.4 -99 84.9 78.2 75.4 80.9 48.2 -NaN 86.9 83.4 79.8 83.8 66.2 -]; -x.IFMCs = x.IFMCs';
--- a/multithreshold 1.46/MTprofile8_24hr19_Aug_2011.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -function x = MTprofile8_24hr19_Aug_2011 -%created: 8_24hr19_Aug_2011 - -x.BFs = [1000]; - -x.LongTone = [10.7]; -x.ShortTone = [13.6]; - -x.Gaps = [0.01 0.03 0.05 0.07 0.09]; -x.TMCFreq = [1000]; -x.TMC = [ -53.2 -68.6 -72.4 -75 -85.1 -]; -x.TMC = x.TMC'; - -x.MaskerRatio = [0.5 0.7 0.9 1 1.1 1.3 1.6]; -x.IFMCFreq = [1000]; -x.IFMCs = [ -79.9 -73.8 -61 -52.3 -63.3 -77.8 -88.4 -]; -x.IFMCs = x.IFMCs';
--- a/multithreshold 1.46/compare.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -f=[100 200 500 1000 2000 5000 10000]; -levels=-10:10:90; - -without=[ -1.44E-10 8.24E-10 1.15E-09 1.43E-09 1.08E-09 4.75E-10 1.43E-09 -4.56E-10 2.61E-09 3.63E-09 4.52E-09 3.37E-09 1.50E-09 4.52E-09 -1.44E-09 8.24E-09 1.15E-08 1.44E-08 1.06E-08 4.75E-09 1.44E-08 -4.56E-09 2.61E-08 4.45E-08 5.16E-08 3.73E-08 1.15E-08 5.16E-08 -1.44E-08 7.05E-08 9.57E-08 9.34E-08 7.44E-08 1.98E-08 9.34E-08 -4.56E-08 1.28E-07 1.46E-07 1.34E-07 1.04E-07 4.35E-08 1.34E-07 -1.06E-07 1.76E-07 2.29E-07 1.99E-07 1.47E-07 5.80E-08 1.99E-07 -1.72E-07 2.48E-07 3.65E-07 3.94E-07 3.39E-07 1.31E-07 3.94E-07 -2.54E-07 3.59E-07 7.88E-07 9.97E-07 9.07E-07 3.51E-07 9.97E-07 -3.82E-07 6.00E-07 2.13E-06 2.85E-06 2.66E-06 1.03E-06 2.85E-06 -5.81E-07 1.37E-06 6.30E-06 8.65E-06 8.17E-06 3.30E-06 8.65E-06 -]; -with=[ -2.60E-11 1.48E-10 2.09E-10 2.61E-10 1.93E-10 8.54E-11 2.61E-10 -8.21E-11 4.69E-10 6.61E-10 8.25E-10 6.10E-10 2.70E-10 8.25E-10 -2.60E-10 1.48E-09 2.09E-09 2.61E-09 1.93E-09 8.54E-10 2.61E-09 -8.21E-10 4.69E-09 6.61E-09 8.25E-09 6.10E-09 2.70E-09 8.25E-09 -2.60E-09 1.48E-08 2.35E-08 3.10E-08 1.96E-08 8.54E-09 3.10E-08 -8.21E-09 4.56E-08 7.17E-08 7.64E-08 5.59E-08 1.33E-08 7.64E-08 -2.60E-08 1.02E-07 1.20E-07 1.16E-07 9.13E-08 3.13E-08 1.16E-07 -7.49E-08 1.51E-07 1.79E-07 1.70E-07 1.25E-07 4.88E-08 1.70E-07 -1.38E-07 2.10E-07 2.90E-07 2.70E-07 2.24E-07 8.63E-08 2.70E-07 -2.10E-07 3.02E-07 5.08E-07 6.24E-07 5.58E-07 2.15E-07 6.24E-07 -3.13E-07 4.33E-07 1.29E-06 1.70E-06 1.57E-06 6.05E-07 1.70E-06 -]; -figure(7), clf -criterion = 1e-7; -c1=contour(f, levels, with,[criterion criterion]) -hold on -c2=contour(f, levels, without,[criterion criterion]) -title(['criterion= ' num2str(criterion)]) -set(gca,'Xscale','log')
--- a/multithreshold 1.46/compareMicrophonic.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -% these data are generated by the testBM program - - -f=[250 500 1000 2000 4000 8000]; -levels=-10:10:90; - -with=[ -3.00036e-010 2.9476e-010 3.67369e-010 2.69424e-010 2.61262e-010 7.18365e-011 -9.48796e-010 9.32111e-010 1.16172e-009 8.51994e-010 8.26184e-010 2.27167e-010 -3.00036e-009 2.9476e-009 3.67369e-009 2.69424e-009 2.61262e-009 7.18365e-010 -9.48796e-009 9.32126e-009 1.16172e-008 8.51994e-009 8.26184e-009 2.27167e-009 -2.98964e-008 3.30801e-008 4.3799e-008 2.85983e-008 2.12715e-008 7.18365e-009 -8.08142e-008 1.0005e-007 1.0854e-007 8.23884e-008 6.41103e-008 1.57936e-008 -1.4489e-007 1.70294e-007 1.67989e-007 1.37031e-007 9.77912e-008 3.74565e-008 -1.9871e-007 2.56245e-007 2.50429e-007 1.82704e-007 1.2266e-007 5.73054e-008 -2.80266e-007 4.15464e-007 4.42073e-007 3.65116e-007 3.24109e-007 6.7619e-008 -4.49308e-007 8.26643e-007 1.0501e-006 9.22625e-007 9.46576e-007 2.13766e-007 -8.73737e-007 2.1498e-006 2.9006e-006 2.61691e-006 2.90337e-006 6.36048e-007 -]; - -without=[ -1.85179e-009 1.84842e-009 2.29365e-009 1.68885e-009 1.64802e-009 4.53194e-010 -5.85587e-009 5.84521e-009 7.25317e-009 5.34061e-009 5.2115e-009 1.43313e-009 -1.85179e-008 1.84842e-008 2.39525e-008 1.67348e-008 1.41015e-008 4.53194e-009 -5.70059e-008 6.97074e-008 8.049e-008 5.93827e-008 4.75289e-008 1.43313e-008 -1.21363e-007 1.42557e-007 1.42791e-007 1.14796e-007 8.59727e-008 2.31062e-008 -1.7631e-007 2.1607e-007 2.05558e-007 1.61584e-007 1.09552e-007 5.05732e-008 -2.41242e-007 3.44485e-007 3.25688e-007 2.57527e-007 2.17035e-007 6.31655e-008 -3.64591e-007 5.90911e-007 7.23077e-007 6.17822e-007 6.09472e-007 1.38217e-007 -6.52753e-007 1.44434e-006 1.89854e-006 1.69908e-006 1.84634e-006 4.09033e-007 -1.43691e-006 4.03513e-006 5.54045e-006 5.04855e-006 5.73398e-006 1.24307e-006 -3.75649e-006 1.20961e-005 1.69372e-005 1.55783e-005 1.7989e-005 3.87293e-006 -]; - - -figure(7), clf -criterion = 1e-7; -c1=contour(f, levels, with,[criterion criterion]) - -hold on -c2=contour(f, levels, without,[criterion criterion]) -title(['criterion= ' num2str(criterion)]) -set(gca,'Xscale','log')
--- a/multithreshold 1.46/expGUI_MT.m Fri Aug 19 16:07:07 2011 +0100 +++ b/multithreshold 1.46/expGUI_MT.m Thu Sep 15 13:50:20 2011 +0100 @@ -676,6 +676,15 @@ set(handles.editstopCriteriaBox,'string','30') % nTrials pause(.1) run (handles) + if experiment.stop + disp(errormsg) + optionNo=strmatch('profile',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + experiment.paradigm='profile'; + experiment.stop=-0; + aParadigmSelection(handles) + return + end IFMCs=resultsTable(2:end,2:end); offBFs=resultsTable(2:end,1);
--- a/multithreshold 1.46/nextStimulus.m Fri Aug 19 16:07:07 2011 +0100 +++ b/multithreshold 1.46/nextStimulus.m Thu Sep 15 13:50:20 2011 +0100 @@ -149,27 +149,31 @@ set(handles.textMSG,'string', stimulusParameters.subjectText) % select the new levels of the between runs variables -num=betweenRuns.runNumber; +thisRunNumber=betweenRuns.runNumber; cmd=(['stimulusParameters.' betweenRuns.variableName1 '= ' ... - num2str(betweenRuns.var1Sequence(num)) ';']); + num2str(betweenRuns.var1Sequence(thisRunNumber)) ';']); % e.g. stimulusParameters.targetFrequency= 1000; eval(cmd); cmd=(['stimulusParameters.' betweenRuns.variableName2 '= ' ... - num2str(betweenRuns.var2Sequence(num)) ';']); + num2str(betweenRuns.var2Sequence(thisRunNumber)) ';']); % e.g. stimulusParameters.targetDuration= 0.1; eval(cmd); -switch experiment.paradigm - % target level may vary between runs - case {'trainingIFMC', 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms','IFMC_16ms'} - idx=floor(num/length(betweenRuns.variableList1)-0.01)+1; - cmd=(['stimulusParameters.targetLevel = ' ... - num2str(stimulusParameters.targetLevels(idx)) ';']); - eval(cmd); - if withinRuns.trialNumber==1 - disp(['targetLevel=' num2str(stimulusParameters.targetLevel)]) - end +% When variableList2 is 'targetFrequency' targetLevel may vary between runs +% If so, it is changed at the end of each variableList1. +if strcmp(betweenRuns.variableName2, 'maskerRelativeFrequency') && ... + length(stimulusParameters.targetLevels)>1 + switch experiment.paradigm + case {'trainingIFMC', 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms','IFMC_16ms'} + idx=floor(thisRunNumber/length(betweenRuns.variableList1)-0.01)+1; + cmd=(['stimulusParameters.targetLevel = ' ... + num2str(stimulusParameters.targetLevels(idx)) ';']); + eval(cmd); + if withinRuns.trialNumber==1 + disp(['targetLevel=' num2str(stimulusParameters.targetLevel)]) + end + end end @@ -316,13 +320,14 @@ end % ----------------------------- calibration of sound output +% seperate calibration for each frequency to match headphones calibrationCorrectiondB=stimulusParameters.calibrationdB; if calibrationCorrectiondB<-50 if maskerFrequency==targetFrequency load 'calibrationFile' % calibrationFrequency calibrationAttenutation idx=find(calibrationFrequency==targetFrequency); if isempty(idx) - error('Calibration bty file; frequency not found') + error('Calibration by file; frequency not found') else calibrationCorrectiondB=calibrationAttenutation(idx) end
--- a/multithreshold 1.46/paradigms/paradigm_training.m Fri Aug 19 16:07:07 2011 +0100 +++ b/multithreshold 1.46/paradigms/paradigm_training.m Thu Sep 15 13:50:20 2011 +0100 @@ -18,7 +18,7 @@ % {'tone','noise', 'pinkNoise','whiteNoise','OHIO'} stimulusParameters.WRVname='targetLevel'; -stimulusParameters.WRVstartValues=20 ; +stimulusParameters.WRVstartValues=30 ; stimulusParameters.WRVsteps=[10 2]; stimulusParameters.WRVlimits=[-30 110];
--- a/multithreshold 1.46/plotProfile.m Fri Aug 19 16:07:07 2011 +0100 +++ b/multithreshold 1.46/plotProfile.m Thu Sep 15 13:50:20 2011 +0100 @@ -20,6 +20,7 @@ % absolute thresholds figure(90), clf +set(gcf, 'name', 'Profile') subplot(2,1,2) semilogx(foreground.BFs,foreground.LongTone,'ko-','lineWidth',2); hold on semilogx(foreground.BFs,foreground.ShortTone,'bo-','lineWidth',2); hold on
--- a/multithreshold 1.46/subjGUI_MT.m Fri Aug 19 16:07:07 2011 +0100 +++ b/multithreshold 1.46/subjGUI_MT.m Thu Sep 15 13:50:20 2011 +0100 @@ -669,7 +669,12 @@ {'Please,click on the GO button'}]; set(handles.textMSG,'string',msg) [y,fs]=wavread('ding.wav'); - wavplay(y/100,fs) + if ispc + wavplay(y/100,fs) + else + sound(y/100,fs) + end + % raise catch trial rate temporarily. % this is normally reduced on each new trial (see GO) @@ -1295,7 +1300,7 @@ [y,fs,nbits]=wavread('TADA.wav'); musicGain=10^(stimulusParameters.musicLeveldB/20); y=y*musicGain; - wavplay(y/100,fs, 'async') + if ispc, wavplay(y/100,fs, 'async'), else sound(y/100,fs, 'async'), end % update experimenter GUI addToMsg('Experiment completed.',1) @@ -1333,7 +1338,8 @@ [y,fs,nbits]=wavread('CHIMES.wav'); musicGain=10^(stimulusParameters.musicLeveldB/20); y=y*musicGain; - wavplay(y/100,fs,'async') + if ispc, wavplay(y/100,fs, 'async'), else sound(y/100,fs, 'async'), end + end % -----------------------------------------------------MAPmodelRunsGUI
--- a/multithreshold 1.46/temp.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -foreground = MTprofile17_14hr18_Aug_2011 - -fileName=['MTprofile' Util_timeStamp]; -longTone=foreground.LongTone; -shortTone=foreground.ShortTone; -gaps=foreground.Gaps; -BFs=foreground.BFs; -TMC=foreground.TMC; -offBFs=foreground.MaskerRatio; -IFMCs=foreground.IFMCs; -profile2mFile(longTone, shortTone, gaps', BFs, TMC', offBFs', IFMCs',... - fileName) -pause(1) -plotProfile(fileName, 'profile_CMA_L')
--- a/parameterStore/MAPparamsNormal.m Fri Aug 19 16:07:07 2011 +0100 +++ b/parameterStore/MAPparamsNormal.m Thu Sep 15 13:50:20 2011 +0100 @@ -1,21 +1,22 @@ function method=MAPparamsNormal ... (BFlist, sampleRate, showParams, paramChanges) % MAPparams<> establishes a complete set of MAP parameters -% Parameter file names must be of the form <MAPparams> <name> +% Parameter file names must be of the form <MAPparams><name> % -% input arguments +% Input arguments % BFlist (optional) specifies the desired list of channel BFs % otherwise defaults set below % sampleRate (optional), default is 50000. % showParams (optional) =1 prints out the complete set of parameters -% output argument +% Output argument % method passes a miscelleny of values +% the use of 'method' is being phased out. use globals global inputStimulusParams OMEParams DRNLParams IHC_cilia_RPParams -global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams +global IHCpreSynapseParams AN_IHCsynapseParams global MacGregorParams MacGregorMultiParams filteredSACFParams -global experiment % used by calls from multiThreshold only - +global experiment % used only by calls from multiThreshold +% global IHC_VResp_VivoParams currentFile=mfilename; % i.e. the name of this mfile method.parameterSource=currentFile(10:end); % for the record @@ -30,7 +31,7 @@ % 21 chs (250-8k)includes BFs at 250 500 1000 2000 4000 8000 BFlist=round(logspace(log10(lowestBF),log10(highestBF),numChannels)); end -% BFlist=1000; +% BFlist=1000; % single channel option % preserve for backward campatibility method.nonlinCF=BFlist; @@ -54,69 +55,67 @@ OMEParams.OMEstapesLPcutoff= 1000; OMEParams.stapesScalar= 45e-9; -% Acoustic reflex: maximum attenuation should be around 25 dB Price (1966) +% Acoustic reflex: maximum attenuation should be around 25 dB (Price, 1966) % i.e. a minimum ratio of 0.056. % 'spikes' model: AR based on brainstem spiking activity (LSR) -OMEParams.rateToAttenuationFactor=0.01; % * N(all ICspikes) -% OMEParams.rateToAttenuationFactor=0; % * N(all ICspikes) +OMEParams.rateToAttenuationFactor=0.008; % * N(all ICspikes) +% OMEParams.rateToAttenuationFactor=0; % i.e. no AR % 'probability model': Ar based on AN firing probabilities (LSR) -OMEParams.rateToAttenuationFactorProb=0.006;% * N(all ANrates) -% OMEParams.rateToAttenuationFactorProb=0;% * N(all ANrates) +OMEParams.rateToAttenuationFactorProb=0.006; % * N(all ANrates) +% OMEParams.rateToAttenuationFactorProb=0; % i.e. no AR % asymptote should be around 100-200 ms -OMEParams.ARtau=.05; % AR smoothing function +OMEParams.ARtau=.250; % AR smoothing function 250 ms fits Hung and Dallos % delay must be longer than the segment length OMEParams.ARdelay=efferentDelay; %Moss gives 8.5 ms latency OMEParams.ARrateThreshold=40; %% #3 DRNL DRNLParams=[]; % clear the structure first -DRNLParams.BFlist=BFlist; +% DRNLParams.BFlist=BFlist; -% DRNL nonlinear path -DRNLParams.a=5e4; % DRNL.a=0 means no OHCs (no nonlinear path) +% *** DRNL nonlinear path +% broken stick compression +DRNLParams.a=5e4; % DRNL.a=0 means no OHCs (no nonlinear path) +DRNLParams.c=.2; % compression exponent +DRNLParams.CtBMdB = 10; %Compression threshold dB re 10e-9 m displacement -DRNLParams.b=8e-6; % *compression threshold raised compression -% DRNLParams.b=1; % b=1 means no compression -DRNLParams.cTh= 5e-8; % compression threshold in meters. - -DRNLParams.c=9e-2; % compression exponent -% nonlinear filters +% filters +DRNLParams.nonlinOrder= 3; % order of nonlinear gammatone filters DRNLParams.nonlinCFs=BFlist; -DRNLParams.nonlinOrder= 3; % order of nonlinear gammatone filters -p=0.2895; q=170; % human (% p=0.14; q=366; % cat) -p=0.2895; q=250; % human (% p=0.14; q=366; % cat) +p=0.2895; q=250; % human (% p=0.14; q=366; % cat) DRNLParams.nlBWs= p * BFlist + q; DRNLParams.p=p; DRNLParams.q=q; % save p and q for printing only -% DRNL linear path: -DRNLParams.g=100; % linear path gain factor +% *** DRNL linear path: +DRNLParams.g=200; % linear path gain factor +DRNLParams.linOrder=3; % order of linear gammatone filters % linCF is not necessarily the same as nonlinCF minLinCF=153.13; coeffLinCF=0.7341; % linCF>nonlinBF for BF < 1 kHz DRNLParams.linCFs=minLinCF+coeffLinCF*BFlist; -DRNLParams.linOrder= 3; % order of linear gammatone filters +% bandwidths (linear) minLinBW=100; coeffLinBW=0.6531; DRNLParams.linBWs=minLinBW + coeffLinBW*BFlist; % bandwidths of linear filters -% DRNL MOC efferents +% *** DRNL MOC efferents DRNLParams.MOCdelay = efferentDelay; % must be < segment length! +DRNLParams.minMOCattenuationdB=-30; % 'spikes' model: MOC based on brainstem spiking activity (HSR) -DRNLParams.rateToAttenuationFactor = .009; % strength of MOC -% DRNLParams.rateToAttenuationFactor = 0; % strength of MOC +DRNLParams.MOCtau =.025; % smoothing for MOC +DRNLParams.rateToAttenuationFactor = .00635; % strength of MOC +% DRNLParams.rateToAttenuationFactor = 0; % strength of MOC + % 'probability' model: MOC based on AN spiking activity (HSR) -DRNLParams.rateToAttenuationFactorProb = 0.0045; % strength of MOC +DRNLParams.MOCtauProb =.285; % smoothing for MOC +DRNLParams.rateToAttenuationFactorProb = 0.0075; % strength of MOC % DRNLParams.rateToAttenuationFactorProb = .0; % strength of MOC DRNLParams.MOCrateThresholdProb =50; % spikes/s probability only -DRNLParams.MOCtau =.1; % smoothing for MOC - %% #4 IHC_cilia_RPParams - IHC_cilia_RPParams.tc= 0.0003; % 0.0003 filter time simulates viscocity -% IHC_cilia_RPParams.tc= 0.0005; % 0.0003 filter time simulates viscocity IHC_cilia_RPParams.C= 0.03; % 0.1 scalar (C_cilia ) IHC_cilia_RPParams.u0= 5e-9; IHC_cilia_RPParams.s0= 30e-9; @@ -140,7 +139,7 @@ %% #5 IHCpreSynapse IHCpreSynapseParams=[]; IHCpreSynapseParams.GmaxCa= 14e-9;% maximum calcium conductance -IHCpreSynapseParams.GmaxCa= 12e-9;% maximum calcium conductance +% IHCpreSynapseParams.GmaxCa= 12e-9;% maximum calcium conductance IHCpreSynapseParams.ECa= 0.066; % calcium equilibrium potential IHCpreSynapseParams.beta= 400; % determine Ca channel opening IHCpreSynapseParams.gamma= 100; % determine Ca channel opening @@ -149,15 +148,21 @@ % reminder: changing z has a strong effect on HF thresholds (like Et) IHCpreSynapseParams.z= 2e42; % scalar Ca -> vesicle release rate -LSRtauCa=35e-6; HSRtauCa=80e-6; % seconds -% LSRtauCa=35e-6; HSRtauCa=70e-6; % seconds -IHCpreSynapseParams.tauCa= [15e-6 80e-6]; %LSR and HSR fiber +LSRtauCa=40e-6; HSRtauCa=80e-6; % seconds +% IHCpreSynapseParams.tauCa= [15e-6 80e-6]; %LSR and HSR fiber IHCpreSynapseParams.tauCa= [LSRtauCa HSRtauCa]; %LSR and HSR fiber %% #6 AN_IHCsynapse +AN_IHCsynapseParams=[]; % clear the structure first +% number of AN fibers at each BF (used only for spike generation) +AN_IHCsynapseParams.numFibers= 100; +% absolute refractory period. Relative refractory period is the same. +AN_IHCsynapseParams.refractory_period= 0.00075; +AN_IHCsynapseParams.TWdelay=0.004; % ?delay before stimulus first spike +AN_IHCsynapseParams.ANspeedUpFactor=5; % longer epochs for computing spikes. + % c=kym/(y(l+r)+kl) (spontaneous rate) % c=(approx) ym/l (saturated rate) -AN_IHCsynapseParams=[]; % clear the structure first AN_IHCsynapseParams.M= 12; % maximum vesicles at synapse AN_IHCsynapseParams.y= 4; % depleted vesicle replacement rate AN_IHCsynapseParams.y= 6; % depleted vesicle replacement rate @@ -172,12 +177,6 @@ AN_IHCsynapseParams.r= 500; % *reuptake rate from cleft into cell % AN_IHCsynapseParams.r= 300; % *reuptake rate from cleft into cell -AN_IHCsynapseParams.refractory_period= 0.00075; -% number of AN fibers at each BF (used only for spike generation) -AN_IHCsynapseParams.numFibers= 100; -AN_IHCsynapseParams.TWdelay=0.004; % ?delay before stimulus first spike - -AN_IHCsynapseParams.ANspeedUpFactor=5; % longer epochs for computing spikes. %% #7 MacGregorMulti (first order brainstem neurons) MacGregorMultiParams=[]; @@ -204,7 +203,6 @@ MacGregorMultiParams.nNeuronsPerBF= 10; % N neurons per BF MacGregorMultiParams.type = 'chopper cell'; MacGregorMultiParams.fibersPerNeuron=10; % N input fibers -% MacGregorMultiParams.fibersPerNeuron=6; % N input fibers MacGregorMultiParams.dendriteLPfreq=50; % dendritic filter MacGregorMultiParams.currentPerSpike=35e-9; % *per spike @@ -235,7 +233,7 @@ MacGregorParams.tauM=0.002; % membrane time constant (s) MacGregorParams.Ek=-0.01; % K+ eq. potential (V) MacGregorParams.dGkSpike=1.33e-4; % K+ cond.shift on spike,S -MacGregorParams.tauGk= 0.0005; % K+ conductance tau (s) +MacGregorParams.tauGk= 0.0012; % K+ conductance tau (s) MacGregorParams.Th0= 0.01; % equilibrium threshold (V) MacGregorParams.c= 0; % threshold shift on spike, (V) MacGregorParams.tauTh= 0.02; % variable threshold tau @@ -270,8 +268,34 @@ %% now accept last minute parameter changes required by the calling program % paramChanges if nargin>3 && ~isempty(paramChanges) + if ~iscellstr(paramChanges) + error(['paramChanges error: paramChanges not a cell array']) + end + nChanges=length(paramChanges); for idx=1:nChanges + x=paramChanges{idx}; + x=deblank(x); + if ~isempty(x) + if ~strcmp(x(end),';') + error(['paramChanges error (terminate with semicolon) ' x]) + end + st=strtrim(x(1:strfind(x,'.')-1)); + fld=strtrim(x(strfind(x,'.')+1:strfind(x,'=')-1)); + value=x(strfind(x,'=')+1:end); + if isempty(st) || isempty(fld) || isempty(value) + error(['paramChanges error:' x]) + end + + x1=eval(['isstruct(' st ')']); + cmd=['isfield(' st ',''' fld ''')']; + x2=eval(cmd); + if ~(x1*x2) + error(['paramChanges error:' x]) + end + end + + % no problems so go ahead eval(paramChanges{idx}) end end
--- a/parameterStore/MAPparamsNormalIC.m Fri Aug 19 16:07:07 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,302 +0,0 @@ -function method=MAPparamsNormalIC ... - (BFlist, sampleRate, showParams, paramChanges) -% MAPparams<> establishes a complete set of MAP parameters -% Parameter file names must be of the form <MAPparams> <name> -% -% input arguments -% BFlist (optional) specifies the desired list of channel BFs -% otherwise defaults set below -% sampleRate (optional), default is 50000. -% showParams (optional) =1 prints out the complete set of parameters -% output argument -% method passes a miscelleny of values - -global inputStimulusParams OMEParams DRNLParams IHC_cilia_RPParams -global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams -global MacGregorParams MacGregorMultiParams filteredSACFParams -global experiment % used by calls from multiThreshold only - - -currentFile=mfilename; % i.e. the name of this mfile -method.parameterSource=currentFile(10:end); % for the record - -efferentDelay=0.010; -method.segmentDuration=efferentDelay; - -if nargin<3, showParams=0; end -if nargin<2, sampleRate=50000; end -if nargin<1 || BFlist(1)<0 % if BFlist= -1, set BFlist to default - lowestBF=250; highestBF= 8000; numChannels=21; - % 21 chs (250-8k)includes BFs at 250 500 1000 2000 4000 8000 - BFlist=round(logspace(log10(lowestBF),log10(highestBF),numChannels)); -end -% BFlist=1000; - -% preserve for backward campatibility -method.nonlinCF=BFlist; -method.dt=1/sampleRate; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% set model parameters -%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% #1 inputStimulus -inputStimulusParams=[]; -inputStimulusParams.sampleRate= sampleRate; - -%% #2 outerMiddleEar -OMEParams=[]; % clear the structure first -% outer ear resonances band pass filter [gain lp order hp] -OMEParams.externalResonanceFilters= [ 10 1 1000 4000]; - -% highpass stapes filter -% Huber gives 2e-9 m at 80 dB and 1 kHz (2e-13 at 0 dB SPL) -OMEParams.OMEstapesLPcutoff= 1000; -OMEParams.stapesScalar= 45e-9; - -% Acoustic reflex: maximum attenuation should be around 25 dB Price (1966) -% i.e. a minimum ratio of 0.056. -% 'spikes' model: AR based on brainstem spiking activity (LSR) -OMEParams.rateToAttenuationFactor=0.006; % * N(all ICspikes) -% OMEParams.rateToAttenuationFactor=0; % * N(all ICspikes) - -% 'probability model': Ar based on AN firing probabilities (LSR) -OMEParams.rateToAttenuationFactorProb=0.01;% * N(all ANrates) -% OMEParams.rateToAttenuationFactorProb=0;% * N(all ANrates) - -% asymptote should be around 100-200 ms -OMEParams.ARtau=.05; % AR smoothing function -% delay must be longer than the segment length -OMEParams.ARdelay=efferentDelay; %Moss gives 8.5 ms latency -OMEParams.ARrateThreshold=0; - -%% #3 DRNL -DRNLParams=[]; % clear the structure first -DRNLParams.BFlist=BFlist; - -% DRNL nonlinear path -DRNLParams.a=5e4; % DRNL.a=0 means no OHCs (no nonlinear path) -DRNLParams.a=2e4; % DRNL.a=0 means no OHCs (no nonlinear path) - -DRNLParams.b=8e-6; % *compression threshold raised compression -% DRNLParams.b=1; % b=1 means no compression - -DRNLParams.c=0.2; % compression exponent -% nonlinear filters -DRNLParams.nonlinCFs=BFlist; -DRNLParams.nonlinOrder= 3; % order of nonlinear gammatone filters -p=0.2895; q=170; % human (% p=0.14; q=366; % cat) -DRNLParams.nlBWs= p * BFlist + q; -DRNLParams.p=p; DRNLParams.q=q; % save p and q for printing only - -% DRNL linear path: -DRNLParams.g=100; % linear path gain factor -% linCF is not necessarily the same as nonlinCF -minLinCF=153.13; coeffLinCF=0.7341; % linCF>nonlinBF for BF < 1 kHz -DRNLParams.linCFs=minLinCF+coeffLinCF*BFlist; -DRNLParams.linOrder= 3; % order of linear gammatone filters -minLinBW=100; coeffLinBW=0.6531; -DRNLParams.linBWs=minLinBW + coeffLinBW*BFlist; % bandwidths of linear filters - -% DRNL MOC efferents -DRNLParams.MOCdelay = efferentDelay; % must be < segment length! - -% 'spikes' model: MOC based on brainstem spiking activity (HSR) -DRNLParams.rateToAttenuationFactor = .01; % strength of MOC -% DRNLParams.rateToAttenuationFactor = 0; % strength of MOC -% 'probability' model: MOC based on AN spiking activity (HSR) -DRNLParams.rateToAttenuationFactorProb = .0055; % strength of MOC -% DRNLParams.rateToAttenuationFactorProb = .0; % strength of MOC -DRNLParams.MOCrateThresholdProb =70; % spikes/s probability only - -DRNLParams.MOCtau =.1; % smoothing for MOC - - -%% #4 IHC_cilia_RPParams - -IHC_cilia_RPParams.tc= 0.0003; % 0.0003 filter time simulates viscocity -% IHC_cilia_RPParams.tc= 0.0005; % 0.0003 filter time simulates viscocity -IHC_cilia_RPParams.C= 0.03; % 0.1 scalar (C_cilia ) -IHC_cilia_RPParams.u0= 5e-9; -IHC_cilia_RPParams.s0= 30e-9; -IHC_cilia_RPParams.u1= 1e-9; -IHC_cilia_RPParams.s1= 1e-9; - -IHC_cilia_RPParams.Gmax= 6e-9; % 2.5e-9 maximum conductance (Siemens) -IHC_cilia_RPParams.Ga= 1e-9; % 4.3e-9 fixed apical membrane conductance -IHC_cilia_RPParams.Ga= .8e-9; % 4.3e-9 fixed apical membrane conductance - -% #5 IHC_RP -IHC_cilia_RPParams.Cab= 4e-012; % IHC capacitance (F) -% IHC_cilia_RPParams.Cab= 1e-012; % IHC capacitance (F) -IHC_cilia_RPParams.Et= 0.100; % endocochlear potential (V) - -IHC_cilia_RPParams.Gk= 2e-008; % 1e-8 potassium conductance (S) -IHC_cilia_RPParams.Ek= -0.08; % -0.084 K equilibrium potential -IHC_cilia_RPParams.Rpc= 0.04; % combined resistances - - -%% #5 IHCpreSynapse -IHCpreSynapseParams=[]; -IHCpreSynapseParams.GmaxCa= 14e-9;% maximum calcium conductance -IHCpreSynapseParams.GmaxCa= 12e-9;% maximum calcium conductance -IHCpreSynapseParams.ECa= 0.066; % calcium equilibrium potential -IHCpreSynapseParams.beta= 400; % determine Ca channel opening -IHCpreSynapseParams.gamma= 100; % determine Ca channel opening -IHCpreSynapseParams.tauM= 0.00005; % membrane time constant ?0.1ms -IHCpreSynapseParams.power= 3; -% reminder: changing z has a strong effect on HF thresholds (like Et) -IHCpreSynapseParams.z= 2e42; % scalar Ca -> vesicle release rate - -LSRtauCa=35e-6; HSRtauCa=85e-6; % seconds -% LSRtauCa=35e-6; HSRtauCa=70e-6; % seconds -IHCpreSynapseParams.tauCa= [ HSRtauCa]; %LSR and HSR fiber - -%% #6 AN_IHCsynapse -% c=kym/(y(l+r)+kl) (spontaneous rate) -% c=(approx) ym/l (saturated rate) -AN_IHCsynapseParams=[]; % clear the structure first -AN_IHCsynapseParams.M= 12; % maximum vesicles at synapse -AN_IHCsynapseParams.y= 4; % depleted vesicle replacement rate -AN_IHCsynapseParams.y= 6; % depleted vesicle replacement rate - -AN_IHCsynapseParams.x= 30; % replenishment from re-uptake store -AN_IHCsynapseParams.x= 60; % replenishment from re-uptake store - -% reduce l to increase saturated rate -AN_IHCsynapseParams.l= 100; % *loss rate of vesicles from the cleft -AN_IHCsynapseParams.l= 250; % *loss rate of vesicles from the cleft - -AN_IHCsynapseParams.r= 500; % *reuptake rate from cleft into cell -% AN_IHCsynapseParams.r= 300; % *reuptake rate from cleft into cell - -AN_IHCsynapseParams.refractory_period= 0.00075; -% number of AN fibers at each BF (used only for spike generation) -AN_IHCsynapseParams.numFibers= 100; -AN_IHCsynapseParams.TWdelay=0.004; % ?delay before stimulus first spike - -AN_IHCsynapseParams.ANspeedUpFactor=5; % longer epochs for computing spikes. - -%% #7 MacGregorMulti (first order brainstem neurons) -MacGregorMultiParams=[]; -MacGregorMultiType='chopper'; % MacGregorMultiType='primary-like'; %choose -switch MacGregorMultiType - case 'primary-like' - MacGregorMultiParams.nNeuronsPerBF= 10; % N neurons per BF - MacGregorMultiParams.type = 'primary-like cell'; - MacGregorMultiParams.fibersPerNeuron=4; % N input fibers - MacGregorMultiParams.dendriteLPfreq=200; % dendritic filter - MacGregorMultiParams.currentPerSpike=0.11e-6; % (A) per spike - MacGregorMultiParams.Cap=4.55e-9; % cell capacitance (Siemens) - MacGregorMultiParams.tauM=5e-4; % membrane time constant (s) - MacGregorMultiParams.Ek=-0.01; % K+ eq. potential (V) - MacGregorMultiParams.dGkSpike=3.64e-5; % K+ cond.shift on spike,S - MacGregorMultiParams.tauGk= 0.0012; % K+ conductance tau (s) - MacGregorMultiParams.Th0= 0.01; % equilibrium threshold (V) - MacGregorMultiParams.c= 0.01; % threshold shift on spike, (V) - MacGregorMultiParams.tauTh= 0.015; % variable threshold tau - MacGregorMultiParams.Er=-0.06; % resting potential (V) - MacGregorMultiParams.Eb=0.06; % spike height (V) - - case 'chopper' - MacGregorMultiParams.nNeuronsPerBF= 10; % N neurons per BF - MacGregorMultiParams.type = 'chopper cell'; - MacGregorMultiParams.fibersPerNeuron=10; % N input fibers -% MacGregorMultiParams.fibersPerNeuron=6; % N input fibers - - MacGregorMultiParams.dendriteLPfreq=50; % dendritic filter - MacGregorMultiParams.currentPerSpike=35e-9; % *per spike -% MacGregorMultiParams.currentPerSpike=30e-9; % *per spike - - MacGregorMultiParams.Cap=1.67e-8; % ??cell capacitance (Siemens) - MacGregorMultiParams.tauM=0.002; % membrane time constant (s) - MacGregorMultiParams.Ek=-0.01; % K+ eq. potential (V) - MacGregorMultiParams.dGkSpike=1.33e-4; % K+ cond.shift on spike,S - MacGregorMultiParams.tauGk= [0.0005:0.0001:0.002];% K+ conductance tau (s) - MacGregorMultiParams.Th0= 0.01; % equilibrium threshold (V) - MacGregorMultiParams.c= 0; % threshold shift on spike, (V) - MacGregorMultiParams.tauTh= 0.02; % variable threshold tau - MacGregorMultiParams.Er=-0.06; % resting potential (V) - MacGregorMultiParams.Eb=0.06; % spike height (V) - MacGregorMultiParams.PSTHbinWidth= 1e-4; -end - -%% #8 MacGregor (second-order neuron). Only one per channel -MacGregorParams=[]; % clear the structure first -MacGregorParams.type = 'chopper cell'; -MacGregorParams.fibersPerNeuron=10; % N input fibers -MacGregorParams.dendriteLPfreq=100; % dendritic filter -MacGregorParams.currentPerSpike=120e-9;% *(A) per spike -MacGregorParams.currentPerSpike=40e-9;% *(A) per spike - -MacGregorParams.Cap=16.7e-9; % cell capacitance (Siemens) -MacGregorParams.tauM=0.002; % membrane time constant (s) -MacGregorParams.Ek=-0.01; % K+ eq. potential (V) -MacGregorParams.dGkSpike=1.33e-4; % K+ cond.shift on spike,S -MacGregorParams.tauGk= 0.0005; % K+ conductance tau (s) -MacGregorParams.Th0= 0.01; % equilibrium threshold (V) -MacGregorParams.c= 0; % threshold shift on spike, (V) -MacGregorParams.tauTh= 0.02; % variable threshold tau -MacGregorParams.Er=-0.06; % resting potential (V) -MacGregorParams.Eb=0.06; % spike height (V) -MacGregorParams.debugging=0; % (special) -% wideband accepts input from all channels (of same fiber type) -% use wideband to create inhibitory units -MacGregorParams.wideband=0; % special for wideband units -% MacGregorParams.saveAllData=0; - -%% #9 filteredSACF -minPitch= 300; maxPitch= 3000; numPitches=60; % specify lags -pitches=100*log10(logspace(minPitch/100, maxPitch/100, numPitches)); -filteredSACFParams.lags=1./pitches; % autocorrelation lags vector -filteredSACFParams.acfTau= .003; % time constant of running ACF -filteredSACFParams.lambda= 0.12; % slower filter to smooth ACF -filteredSACFParams.plotFilteredSACF=1; % 0 plots unfiltered ACFs -filteredSACFParams.plotACFs=0; % special plot (see code) -% filteredSACFParams.usePressnitzer=0; % attenuates ACF at long lags -filteredSACFParams.lagsProcedure= 'useAllLags'; -% filteredSACFParams.lagsProcedure= 'useBernsteinLagWeights'; -% filteredSACFParams.lagsProcedure= 'omitShortLags'; -filteredSACFParams.criterionForOmittingLags=3; - -% checks -if AN_IHCsynapseParams.numFibers<MacGregorMultiParams.fibersPerNeuron - error('MacGregorMulti: too few input fibers for input to MacG unit') -end - - -%% now accept last minute parameter changes required by the calling program -% paramChanges -if nargin>3 && ~isempty(paramChanges) - nChanges=length(paramChanges); - for idx=1:nChanges - eval(paramChanges{idx}) - end -end - - -%% write all parameters to the command window -% showParams is currently set at the top of htis function -if showParams - fprintf('\n %%%%%%%%\n') - fprintf('\n%s\n', method.parameterSource) - fprintf('\n') - nm=UTIL_paramsList(whos); - for i=1:length(nm) - % eval(['UTIL_showStruct(' nm{i} ', ''' nm{i} ''')']) - if ~strcmp(nm(i), 'method') - eval(['UTIL_showStructureSummary(' nm{i} ', ''' nm{i} ''', 10)']) - end - end - - % highlight parameter changes made locally - if nargin>3 && ~isempty(paramChanges) - fprintf('\n Local parameter changes:\n') - for i=1:length(paramChanges) - disp(paramChanges{i}) - end - end -end - -% for backward compatibility -experiment.comparisonData=[];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testPrograms/LiebermanMOCdata.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,79 @@ +function LibermanData= LiebermanMOCdata + +LibermanData=[ + 2 0.2; +2.1 0.19; +2.2 0.18; +2.3 0.18; +2.4 0.16; +2.5 0.15; +2.6 0.15; +2.7 0.15; +2.8 0.12; +2.9 0.12; +3 0.1; +3.1 0.1; +3.2 0.05; +3.3 0.05; +3.4 0; +3.5 -0.1; +3.6 -0.4; +3.7 -1.2; +3.8 -1.6; +3.9 -1.8; +4 -1.85; +4.1 -2; +4.2 -2.05; +4.3 -2.05; +4.4 -2.15; +4.5 -2.2; +4.6 -2.15; +4.7 -2.1; +4.8 -2.15; +4.9 -2.2; +5 -2.1; +5.1 -2.1; +5.2 -2.25; +5.3 -2.1; +5.4 -2.15; +5.5 -2.1; +5.6 -2.15; +5.7 -2.1; +5.8 -2.2; +5.9 -2.05; +6 -2.15; +6.1 -2.05; +6.2 -2; +6.3 -2.2; +6.4 -2.1; +6.5 -2.05; +6.6 -2.05; +6.7 -2.05; +6.8 -2.2; +6.9 -2.1; +7 -2.05; +7.1 -2.05; +7.2 -0.7; +7.3 -0.1; +7.4 0; +7.5 0.1; +7.6 0.2; +7.7 0.35; +7.8 0.2; +7.9 0.15; +8 0.2; +8.1 0.15; +8.2 0.15; +8.3 0.15; +8.4 0.12; +8.5 0.1; +8.6 0.09; +8.7 0.08; +8.8 0.07; +8.9 0.06; +9 0.05; +]; +figure(98), subplot(2,1,2), hold on +scalar=-15; +plot(LibermanData(:,1)-2.5,scalar*LibermanData(:,2)) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testPrograms/LiebermanMOCtest.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,155 @@ +function LiebermanMOCtest + +% In test_MAP1_14.m set these parameters + +% AN_spikesOrProbability='spikes'; + +% global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... +% savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... +% DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... +% IHCoutput ANprobRateOutput ANoutput savePavailable ANtauCas ... +% CNtauGk CNoutput ICoutput ICmembraneOutput ICfiberTypeRates ... +% MOCattenuation +global dt ANdt saveAN_spikesOrProbability ANprobRateOutput ICoutput + +global DRNLParams + +LibermanData=[ + 2 0.2; +2.1 0.19;2.2 0.18;2.3 0.18;2.4 0.16;2.5 0.15;2.6 0.15;2.7 0.15; +2.8 0.12;2.9 0.12;3 0.1;3.1 0.1;3.2 0.05;3.3 0.05;3.4 0;3.5 -0.1; +3.6 -0.4;3.7 -1.2;3.8 -1.6;3.9 -1.8;4 -1.85;4.1 -2;4.2 -2.05; +4.3 -2.05;4.4 -2.15;4.5 -2.2;4.6 -2.15;4.7 -2.1;4.8 -2.15;4.9 -2.2; +5 -2.1;5.1 -2.1;5.2 -2.25;5.3 -2.1;5.4 -2.15;5.5 -2.1;5.6 -2.15; +5.7 -2.1;5.8 -2.2;5.9 -2.05;6 -2.15;6.1 -2.05;6.2 -2;6.3 -2.2;6.4 -2.1; +6.5 -2.05;6.6 -2.05;6.7 -2.05;6.8 -2.2;6.9 -2.1;7 -2.05;7.1 -2.05;7.2 -0.7; +7.3 -0.1;7.4 0;7.5 0.1;7.6 0.2;7.7 0.35;7.8 0.2;7.9 0.15;8 0.2;8.1 0.15;8.2 0.15; +8.3 0.15;8.4 0.12;8.5 0.1;8.6 0.09;8.7 0.08;8.8 0.07;8.9 0.06;9 0.05; +]; + +restorePath=path; +addpath (['..' filesep 'MAP'], ['..' filesep 'wavFileStore'], ... + ['..' filesep 'utilities']) + +%% #1 parameter file name +MAPparamsName='Normal'; + + +%% #2 probability (fast) or spikes (slow) representation +AN_spikesOrProbability='spikes'; +% or +% AN_spikesOrProbability='probability'; + + +%% #3 pure tone, harmonic sequence or speech file input +signalType= 'tones'; +sampleRate= 50000; +rampDuration=.005; % raised cosine ramp (seconds) +toneFrequency= 1000; % or a pure tone (Hz) +duration=3.6; % Lieberman test +beginSilence=1; % 1 for Lieberman +endSilence=1; % 1 for Lieberman + +%% #4 rms level +% signal details +leveldBSPL= 80; % dB SPL (80 for Lieberman) + + +%% #5 number of channels in the model + +numChannels=1; +BFlist=toneFrequency; + + +%% #6 change model parameters +paramChanges={}; + +%% delare 'showMap' options to control graphical output +showMapOptions.printModelParameters=1; % prints all parameters +showMapOptions.showModelOutput=1; % plot of all stages +showMapOptions.printFiringRates=1; % prints stage activity levels +showMapOptions.showACF=0; % shows SACF (probability only) +showMapOptions.showEfferent=1; % tracks of AR and MOC +showMapOptions.surfProbability=1; % 2D plot of HSR response +showMapOptions.surfSpikes=0; % 2D plot of spikes histogram +showMapOptions.ICrates=0; % IC rates by CNtauGk + +%% Generate stimuli + + % Create pure tone stimulus + dt=1/sampleRate; % seconds + time=dt: dt: duration; + inputSignal=sum(sin(2*pi*toneFrequency'*time), 1); + amp=10^(leveldBSPL/20)*28e-6; % converts to Pascals (peak) + inputSignal=amp*inputSignal; + % apply ramps + % catch rampTime error + if rampDuration>0.5*duration, rampDuration=duration/2; end + rampTime=dt:dt:rampDuration; + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(time)-length(rampTime))]; + inputSignal=inputSignal.*ramp; + ramp=fliplr(ramp); + inputSignal=inputSignal.*ramp; + % add silence + intialSilence= zeros(1,round(beginSilence/dt)); + finalSilence= zeros(1,round(endSilence/dt)); + inputSignal= [intialSilence inputSignal finalSilence]; + +%% run the model +tic +fprintf('\n') +disp(['Signal duration= ' num2str(length(inputSignal)/sampleRate)]) +disp([num2str(numChannels) ' channel model: ' AN_spikesOrProbability]) +disp('Computing ...') + +MAP1_14(inputSignal, sampleRate, BFlist, ... + MAPparamsName, AN_spikesOrProbability, paramChanges); + + +%% the model run is now complete. Now display the results +UTIL_showMAP(showMapOptions, paramChanges) + +if strcmp(signalType,'tones') + disp(['duration=' num2str(duration)]) + disp(['level=' num2str(leveldBSPL)]) + disp(['toneFrequency=' num2str(toneFrequency)]) + disp(['attenuation factor =' ... + num2str(DRNLParams.rateToAttenuationFactor, '%5.3f') ]) + disp(['attenuation factor (probability)=' ... + num2str(DRNLParams.rateToAttenuationFactorProb, '%5.3f') ]) + disp(AN_spikesOrProbability) +end +disp(paramChanges) + + + +%% superimpose Lieberman data + +global DRNLParams +% scale up DPOAE results to a maximum of whatever MAP_14 uses as its +% maximum +scalar=-DRNLParams.minMOCattenuationdB/min(LibermanData(:,2)); + +figure(98), subplot(2,1,2), hold on +plot(LibermanData(:,1)-2.5,scalar*LibermanData(:,2),'r:') + +PSTHbinwidth=0.001; + +if strcmp(saveAN_spikesOrProbability,'probability') + PSTH=UTIL_PSTHmaker... + (ANprobRateOutput(2,:), ANdt, PSTHbinwidth)*ANdt/PSTHbinwidth; +else + PSTH=UTIL_PSTHmaker(ICoutput(2,:), dt, PSTHbinwidth)*dt/PSTHbinwidth; +end + +time=PSTHbinwidth:PSTHbinwidth:PSTHbinwidth*length(PSTH); +figure(89) +plot(time, PSTH) +set(gcf,'name', 'Lieberman') +title(saveAN_spikesOrProbability) + +toc +path(restorePath) + +% figure(88), plot(MOCattenuation)
--- a/testPrograms/demoTwisterProbability.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/demoTwisterProbability.m Thu Sep 15 13:50:20 2011 +0100 @@ -17,7 +17,6 @@ %% #3 speech file input -signalType= 'file'; fileName='twister_44kHz'; @@ -31,24 +30,17 @@ lowestBF=250; highestBF= 8000; BFlist=round(logspace(log10(lowestBF), log10(highestBF), numChannels)); + %% #6 no change to model parameters paramChanges=[]; %% Generate stimuli - -switch signalType - case 'tones' - inputSignal=createMultiTone(sampleRate, toneFrequency, ... - leveldBSPL, duration, rampDuration); - - case 'file' [inputSignal sampleRate]=wavread(fileName); inputSignal(:,1); targetRMS=20e-6*10^(leveldBSPL/20); rms=(mean(inputSignal.^2))^0.5; amp=targetRMS/rms; inputSignal=inputSignal*amp; -end %% run the model @@ -78,28 +70,3 @@ toc path(restorePath) - - -function inputSignal=createMultiTone(sampleRate, toneFrequency, ... - leveldBSPL, duration, rampDuration) -% Create pure tone stimulus -dt=1/sampleRate; % seconds -time=dt: dt: duration; -inputSignal=sum(sin(2*pi*toneFrequency'*time), 1); -amp=10^(leveldBSPL/20)*28e-6; % converts to Pascals (peak) -inputSignal=amp*inputSignal; - -% apply ramps -% catch rampTime error -if rampDuration>0.5*duration, rampDuration=duration/2; end -rampTime=dt:dt:rampDuration; -ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... - ones(1,length(time)-length(rampTime))]; -inputSignal=inputSignal.*ramp; -ramp=fliplr(ramp); -inputSignal=inputSignal.*ramp; - -% add 10 ms silence -silence= zeros(1,round(0.03/dt)); -% inputSignal= [silence inputSignal silence]; -
--- a/testPrograms/demoTwisterSpikes.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/demoTwisterSpikes.m Thu Sep 15 13:50:20 2011 +0100 @@ -17,7 +17,6 @@ %% #3 speech file input -signalType= 'file'; fileName='twister_44kHz'; @@ -29,7 +28,7 @@ %% #5 number of channels in the model % 21-channel model (log spacing) numChannels=21; -lowestBF=250; highestBF= 8000; +lowestBF=250; highestBF= 8000; BFlist=round(logspace(log10(lowestBF), log10(highestBF), numChannels)); @@ -40,28 +39,21 @@ showMapOptions=[]; % use defaults % or (example: show everything including an smoothed SACF output - showMapOptions.printModelParameters=1; - showMapOptions.showModelOutput=1; - showMapOptions.printFiringRates=1; - showMapOptions.showACF=0; - showMapOptions.showEfferent=0; - showMapOptions.surfSpikes=0; - showMapOptions.surfProbability=0; % 2D plot of HSR response +showMapOptions.printModelParameters=1; +showMapOptions.showModelOutput=1; +showMapOptions.printFiringRates=1; +showMapOptions.showACF=0; +showMapOptions.showEfferent=0; +showMapOptions.surfSpikes=0; +showMapOptions.surfProbability=0; % 2D plot of HSR response %% Generate stimuli -switch signalType - case 'tones' - inputSignal=createMultiTone(sampleRate, toneFrequency, ... - leveldBSPL, duration, rampDuration); - - case 'file' - [inputSignal sampleRate]=wavread(fileName); - inputSignal(:,1); - targetRMS=20e-6*10^(leveldBSPL/20); - rms=(mean(inputSignal.^2))^0.5; - amp=targetRMS/rms; - inputSignal=inputSignal*amp; -end +[inputSignal sampleRate]=wavread(fileName); +inputSignal(:,1); +targetRMS=20e-6*10^(leveldBSPL/20); +rms=(mean(inputSignal.^2))^0.5; +amp=targetRMS/rms; +inputSignal=inputSignal*amp; %% run the model @@ -82,26 +74,3 @@ toc path(restorePath) -function inputSignal=createMultiTone(sampleRate, toneFrequency, ... - leveldBSPL, duration, rampDuration) -% Create pure tone stimulus -dt=1/sampleRate; % seconds -time=dt: dt: duration; -inputSignal=sum(sin(2*pi*toneFrequency'*time), 1); -amp=10^(leveldBSPL/20)*28e-6; % converts to Pascals (peak) -inputSignal=amp*inputSignal; - -% apply ramps -% catch rampTime error -if rampDuration>0.5*duration, rampDuration=duration/2; end -rampTime=dt:dt:rampDuration; -ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... - ones(1,length(time)-length(rampTime))]; -inputSignal=inputSignal.*ramp; -ramp=fliplr(ramp); -inputSignal=inputSignal.*ramp; - -% add 10 ms silence -silence= zeros(1,round(0.03/dt)); -% inputSignal= [silence inputSignal silence]; -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testPrograms/repeatTester.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,52 @@ +restorePath=path; +addpath (['..' filesep 'MAP'], ['..' filesep 'wavFileStore'], ... + ['..' filesep 'utilities']) + +global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams +global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams +global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... + savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... + DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... + IHCoutput ANprobRateOutput ANoutput savePavailable ANtauCas ... + CNtauGk CNoutput ICoutput ICmembraneOutput ICfiberTypeRates ... + MOCattenuation + +signalCharacteristics.type='tones'; +signalCharacteristicssignalCharacteristics.sampleRate=50000; +signalCharacteristics.duration= 1; +signalCharacteristics.rampDuration=0.05; +signalCharacteristics.beginSilence=0.05; +signalCharacteristics.endSilence=0.05; +signalCharacteristics.toneFrequency=1000; +signalCharacteristics.leveldBSPL=50; + +showMapOptions.printModelParameters=0; % prints all parameters +showMapOptions.showModelOutput=0; % plot of all stages +showMapOptions.printFiringRates=0; % prints stage activity levels +showMapOptions.showACF=0; % shows SACF (probability only) +showMapOptions.showEfferent=0; % tracks of AR and MOC +showMapOptions.surfProbability=0; % 2D plot of HSR response +showMapOptions.surfSpikes=0; % 2D plot of spikes histogram +showMapOptions.ICrates=0; % IC rates by CNtauGk + +tic +fprintf('\n') +disp('Computing ...') + +levels=80:10:100; + figure(10), clf + +for level=levels +signalCharacteristics.leveldBSPL=level; +% MAPrunner(MAPparamsName, AN_spikesOrProbability, ... +% signalCharacteristics, paramChanges, showMapOptions) +MAPrunner('Normal', 'spikes', ... + signalCharacteristics, {}, showMapOptions) +ARmin=min(ARattenuation); +disp([num2str(level) ':' num2str(ARmin)]) +time=dt:dt:dt*length(ARattenuation); +hold on, plot(time,(1-ARattenuation)/(1-min(ARattenuation))) +pause(0.1) +end + +path(restorePath)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testPrograms/temp.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,41 @@ +global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams +global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams +global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... + savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... + DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... + IHCoutput ANprobRateOutput ANoutput savePavailable ANtauCas ... + CNtauGk CNoutput ICoutput ICmembraneOutput ICfiberTypeRates ... + MOCattenuation + +signalCharacteristics.type='tones'; +signalCharacteristicssignalCharacteristics.sampleRate=50000; +signalCharacteristics.duration= 0.3; +signalCharacteristics.rampDuration=5; +signalCharacteristics.beginSilence=0.05; +signalCharacteristics.endSilence=0.05; +signalCharacteristics.toneFrequency=1000; +signalCharacteristics.leveldBSPL=50; + +showMapOptions.printModelParameters=0; % prints all parameters +showMapOptions.showModelOutput=0; % plot of all stages +showMapOptions.printFiringRates=0; % prints stage activity levels +showMapOptions.showACF=0; % shows SACF (probability only) +showMapOptions.showEfferent=0; % tracks of AR and MOC +showMapOptions.surfProbability=0; % 2D plot of HSR response +showMapOptions.surfSpikes=0; % 2D plot of spikes histogram +showMapOptions.ICrates=0; % IC rates by CNtauGk + +tic +fprintf('\n') +disp('Computing ...') + +durations=[20:20:100]; +for duration=durations +signalCharacteristics.duration= duration; +% MAPrunner(MAPparamsName, AN_spikesOrProbability, ... +% signalCharacteristics, paramChanges, showMapOptions) +MAPrunner('Normal', 'spikes', ... + signalCharacteristics, {}, showMapOptions) +ARmin=min(ARattenuation); +disp([num2str(level) ':' num2str(ARmin)]) +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testPrograms/termp.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,13 @@ + +DRNLParams.a=10; +paramChanges={'DRNL.a=2;'} +for idx=1:length(paramChanges) +x=paramChanges{idx}; +st=x(1:strfind(x,'.')-1); +fld=x(strfind(x,'.')+1:strfind(x,'=')-1); +x1=eval(['isstruct(' st ')']); +x2=eval(['isfield(' st ',''' fld ''')']); +if ~x1*x2 + disp([' paramChange is faulty: ' x]) +end +end \ No newline at end of file
--- a/testPrograms/testAN.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/testAN.m Thu Sep 15 13:50:20 2011 +0100 @@ -1,14 +1,15 @@ -function vectorStrength=testAN(targetFrequency,BFlist, levels, ... +function vectorStrength=testAN(probeFrequency,BFlist, levels, ... paramsName,paramChanges) % generates rate/level functions for AN and brainstem units. % also other information like PSTHs, MOC efferent activity levels. +% e.g. % testAN(1000,1000, -10:10:80,'Normal',[]); global IHC_VResp_VivoParams IHC_cilia_RPParams IHCpreSynapseParams global AN_IHCsynapseParams global ANoutput ANdt CNoutput ICoutput ICmembraneOutput ANtauCas global ARattenuation MOCattenuation - +tic dbstop if error restorePath=path; addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... @@ -17,9 +18,8 @@ if nargin<5, paramChanges=[]; end if nargin<4, paramsName='Normal'; end -if nargin<3 - levels=-10:10:80; -end +if nargin<3, levels=-10:10:80; end +if nargin==0, probeFrequency=1000; BFlist=1000; end nLevels=length(levels); toneDuration=.2; rampDuration=0.002; silenceDuration=.02; @@ -27,14 +27,14 @@ %% guarantee that the sample rate is at least 10 times the frequency sampleRate=50000; -while sampleRate< 10* targetFrequency +while sampleRate< 10* probeFrequency sampleRate=sampleRate+10000; end %% adjust sample rate so that the pure tone stimulus has an integer %% numver of epochs in a period dt=1/sampleRate; -period=1/targetFrequency; +period=1/probeFrequency; ANspeedUpFactor=5; %anticipating MAP (needs clearing up) ANdt=dt*ANspeedUpFactor; ANdt=period/round(period/ANdt); @@ -78,12 +78,12 @@ silence=zeros(1,round(silenceDuration/dt)); - inputSignal=amp*sin(2*pi*targetFrequency'*time); + inputSignal=amp*sin(2*pi*probeFrequency'*time); inputSignal= ramp.*inputSignal; inputSignal=[silence inputSignal]; %% run the model - AN_spikesOrProbability='spikes' + AN_spikesOrProbability='spikes'; MAP1_14(inputSignal, 1/dt, BFlist, ... paramsName, AN_spikesOrProbability, paramChanges); @@ -125,7 +125,7 @@ % AN - vector strength PSTH=sum(HSRspikes); [PH, binTimes]=UTIL_periodHistogram... - (PSTH, ANdt, targetFrequency); + (PSTH, ANdt, probeFrequency); VS=UTIL_vectorStrength(PH); vectorStrength(levelNo)=VS; disp(['sat rate= ' num2str(AN_HSRsaturated(levelNo)) ... @@ -308,3 +308,4 @@ max(vectorStrength)) path(restorePath) +toc
--- a/testPrograms/testANprob.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/testANprob.m Thu Sep 15 13:50:20 2011 +0100 @@ -15,17 +15,10 @@ ['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... ['..' filesep 'testPrograms']) -if nargin<5 - paramChanges=[]; -end - -if nargin<4 - paramsName='Normal'; -end - -if nargin<3 - levels=-10:10:80; -end +if nargin<5, paramChanges=[]; end +if nargin<4, paramsName='Normal'; end +if nargin<3, levels=-10:10:80; end +if nargin==0, targetFrequency=1000; BFlist=1000; end nLevels=length(levels); @@ -113,7 +106,7 @@ AN_HSRsaturated(levelNo)= mean(PSTH(round(length(PSTH)/2): end)); figure(15), subplot(2,2,4) - hold off, bar(PSTHtime,PSTH, 'b') + hold off, bar(PSTHtime,PSTH, 'k') hold on, bar(PSTHtime,PSTHLSR,'r') ylim([0 1000]) xlim([0 length(PSTH)*localPSTHbinwidth]) @@ -169,7 +162,8 @@ subplot(nRows,nCols,2) plot(levels,AN_LSRsaturated, 'ro'), hold on plot(levels,AN_HSRsaturated, 'ko'), hold off -ylim([0 340]) +maxYlim=340; +ylim([0 maxYlim]) set(gca,'ytick',0:50:300) xlim([min(levels) max(levels)]) set(gca,'xtick',[levels(1):20:levels(end)]) @@ -178,7 +172,7 @@ ' sat=' num2str(mean(AN_HSRsaturated(end,1)),'%4.0f')]; title( ttl) xlabel('level dB SPL'), ylabel ('adapted rate (sp/s)') -text(0, 340, 'AN adapted', 'fontsize', 14), grid on +text(0, maxYlim-50, 'AN adapted', 'fontsize', 14), grid on allData=[ levels' AN_HSRonset AN_HSRsaturated... AN_LSRonset AN_LSRsaturated ];
--- a/testPrograms/testBM.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/testBM.m Thu Sep 15 13:50:20 2011 +0100 @@ -1,4 +1,4 @@ -function testBM (BMlocations, paramsName,... +function testBM (BFlist, paramsName,... relativeFrequencies, AN_spikesOrProbability, paramChanges) % testBM generates input output functions for DRNL model for any number % of locations. @@ -13,13 +13,10 @@ global DRNLParams -if nargin<5 - paramChanges=[]; -end - -if nargin<4 - AN_spikesOrProbability='spikes'; -end +if nargin<5, paramChanges=[]; end +if nargin<4, AN_spikesOrProbability='spikes'; end +if nargin==0, BFlist=1000; paramsName='Normal'; + relativeFrequencies=1; end savePath=path; addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) @@ -32,7 +29,8 @@ % ? adjust for frequency refBMdisplacement= 1e-8; % adjusted for 10 nm at 1 kHz -toneDuration=.200; +toneDuration=.5; +% toneDuration=.050; rampDuration=0.01; silenceDuration=0.01; @@ -45,9 +43,9 @@ pause(0.1) finalSummary=[]; -nBFs=length(BMlocations); +nBFs=length(BFlist); BFno=0; plotCount=0; -for BF=BMlocations +for BF=BFlist BFno=BFno+1; plotCount=plotCount+nBFs; stimulusFrequencies=BF* relativeFrequencies; @@ -151,7 +149,8 @@ subplot(maxRows,nBFs,nBFs+BFno), cla plot(levels,20*log10(peakEfferent), 'linewidth',2) ylabel('MOC (dB attenuation)'), xlabel('level') - title(['peak MOC: model= ' AN_spikesOrProbability]) + title(['MOC: (' AN_spikesOrProbability ') duration= ' ... + num2str(1000*toneDuration,'%5.0f') ' ms']) grid on if length(levels)>1, xlim([min(levels) max(levels)]), end
--- a/testPrograms/testFM.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/testFM.m Thu Sep 15 13:50:20 2011 +0100 @@ -13,16 +13,21 @@ global inputStimulusParams outerMiddleEarParams DRNLParams global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams global ANprobRateOutput ANoutput ANtauCas ANdt - dbstop if error - restorePath=path; addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... ['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... ['..' filesep 'testPrograms']) -if nargin<3 +if nargin==0 + BFlist=1000; + paramsName=('Normal'); + AN_spikesOrProbability='spikes'; paramChanges=[]; +else + if nargin<3 + paramChanges=[]; + end end % masker and probe levels are relative to this threshold
--- a/testPrograms/testOME.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/testOME.m Thu Sep 15 13:50:20 2011 +0100 @@ -1,4 +1,9 @@ function testOME(paramsName, paramChanges) +% testOME compute the stapes response at a number of frequencies +% and compares the stapes displacement with in vivo data +% collected by Huber et al.2001. +% e.g. +% testOME('Normal',{}) savePath=path; addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) @@ -22,7 +27,7 @@ 3.0E-10 2.0E-10 1.0E-10]; % m; % HuberVelocityAt80dBSPL= 2*pi*HuberFrequencies.*HuberDisplacementAt80dBSPL; -figure(2), clf, subplot(2,1,1) +figure(2), clf, subplot(2,1,2) set(2,'position',[5 349 268 327]) semilogx(HuberFrequencies, 20*log10(HuberDisplacementAt80dBSPL/1e-10),... 'ko', 'MarkerFaceColor','k', 'Marker','o', 'markerSize',6) @@ -39,9 +44,11 @@ showPlotsAndDetails=0; AN_spikesOrProbability='probability'; + % switch off AR & MOC (Huber's patients were deaf) - paramChanges{1}='OMEParams.rateToAttenuationFactorProb=0;'; - paramChanges{2}='DRNLParams.rateToAttenuationFactorProb = 0;'; + idx=length(paramChanges); + paramChanges{idx+1}='OMEParams.rateToAttenuationFactorProb=0;'; + paramChanges{idx+2}='DRNLParams.rateToAttenuationFactorProb = 0;'; global OMEoutput OMEextEarPressure TMoutput ARattenuation % BF is irrelevant @@ -52,7 +59,6 @@ peakResponses=[peakResponses peakDisplacement]; peakTMpressure=[peakTMpressure max(OMEextEarPressure)]; - disp([' AR attenuation (dB): ' num2str(20*log10(min(ARattenuation)))]) end %% Report @@ -61,20 +67,20 @@ fprintf('%6.0f \t%10.3e\n',[frequencies' peakResponses']') % stapes peak displacement -figure(2), subplot(2,1,1), hold on +figure(2), subplot(2,1,2), hold on semilogx(frequencies, 20*log10(peakResponses/1e-10), 'r', 'linewidth',4) set(gca,'xScale','log') % ylim([1e-11 1e-8]) xlim([100 10000]), ylim([0 30]) grid on -title(['stapes at ' num2str(leveldBSPL) ' (NB deaf)']) +title(['stapes at ' num2str(leveldBSPL)]) ylabel('disp: dB re 1e-10m') xlabel('stimulus frequency (Hz)') legend({'Huber et al','model'},'location','southWest') set(gcf,'name','OME') % external ear resonance -figure(2), subplot(2,1,2),hold off +figure(2), subplot(2,1,1),hold off semilogx(frequencies, 20*log10(peakTMpressure/28e-6)-leveldBSPL,... 'k', 'linewidth',2) xlim([100 10000]) %, ylim([-10 30])
--- a/testPrograms/testRP.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/testRP.m Thu Sep 15 13:50:20 2011 +0100 @@ -1,5 +1,7 @@ function testRP(BFs,MAPparamsName,paramChanges) % testIHC used for IHC I/O function +% multiple BFs can be used but only one is easier to interpret. +% e.g. testRP(1000,'Normal',{}); global experiment method inputStimulusParams global stimulusParameters IHC_VResp_VivoParams IHC_cilia_RPParams
--- a/testPrograms/test_MAP1_14.m Fri Aug 19 16:07:07 2011 +0100 +++ b/testPrograms/test_MAP1_14.m Thu Sep 15 13:50:20 2011 +0100 @@ -43,37 +43,39 @@ %% #2 probability (fast) or spikes (slow) representation AN_spikesOrProbability='spikes'; - -% or +% or % AN_spikesOrProbability='probability'; %% #3 pure tone, harmonic sequence or speech file input signalType= 'tones'; sampleRate= 50000; -duration=0.250; % seconds -toneFrequency= 1000; % or a pure tone (Hz8 +duration=0.500; % seconds +rampDuration=.005; % raised cosine ramp (seconds) +beginSilence=0.250; +endSilence=0.250; +toneFrequency= 1000; % or a pure tone (Hz) -F0=210; -toneFrequency= F0:F0:8000; % harmonic sequence (Hz) +% or +% harmonic sequence (Hz) +% F0=210; +% toneFrequency= F0:F0:8000; -rampDuration=.005; % raised cosine ramp (seconds) - -% or - +% or % signalType= 'file'; % fileName='twister_44kHz'; + %% #4 rms level % signal details -leveldBSPL= 50; % dB SPL +leveldBSPL= 90; % dB SPL (80 for Lieberman) %% #5 number of channels in the model % 21-channel model (log spacing) numChannels=21; -lowestBF=250; highestBF= 8000; +lowestBF=250; highestBF= 6000; BFlist=round(logspace(log10(lowestBF), log10(highestBF), numChannels)); % or specify your own channel BFs @@ -82,30 +84,17 @@ %% #6 change model parameters -paramChanges=[]; - -% or % Parameter changes can be used to change one or more model parameters % *after* the MAPparams file has been read % This example declares only one fiber type with a calcium clearance time % constant of 80e-6 s (HSR fiber) when the probability option is selected. - % paramChanges={'AN_IHCsynapseParams.ANspeedUpFactor=5;', ... % 'IHCpreSynapseParams.tauCa=86e-6;'}; -% paramChanges={'DRNLParams.rateToAttenuationFactorProb = 0;'}; +paramChanges={}; -% paramChanges={'IHCpreSynapseParams.tauCa=86e-6;', -% 'AN_IHCsynapseParams.numFibers= 1000;'}; - -% fixed MOC attenuation(using negative factor) -% paramChanges={'DRNLParams.rateToAttenuationFactorProb=-0.005;'}; - -% slow the CN chopping rate -paramChanges={' MacGregorMultiParams.tauGk= 0.0004;'}; %% delare 'showMap' options to control graphical output - showMapOptions.printModelParameters=1; % prints all parameters showMapOptions.showModelOutput=1; % plot of all stages showMapOptions.printFiringRates=1; % prints stage activity levels @@ -120,9 +109,8 @@ % avoid nonsensical options showMapOptions.surfProbability=0; showMapOptions.showACF=0; -else - showMapOptions.surfSpikes=0; end + if strcmp(signalType, 'file') % needed for labeling plot showMapOptions.fileName=fileName; @@ -134,8 +122,25 @@ switch signalType case 'tones' - inputSignal=createMultiTone(sampleRate, toneFrequency, ... - leveldBSPL, duration, rampDuration); + % Create pure tone stimulus + dt=1/sampleRate; % seconds + time=dt: dt: duration; + inputSignal=sum(sin(2*pi*toneFrequency'*time), 1); + amp=10^(leveldBSPL/20)*28e-6; % converts to Pascals (peak) + inputSignal=amp*inputSignal; + % apply ramps + % catch rampTime error + if rampDuration>0.5*duration, rampDuration=duration/2; end + rampTime=dt:dt:rampDuration; + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(time)-length(rampTime))]; + inputSignal=inputSignal.*ramp; + ramp=fliplr(ramp); + inputSignal=inputSignal.*ramp; + % add silence + intialSilence= zeros(1,round(beginSilence/dt)); + finalSilence= zeros(1,round(endSilence/dt)); + inputSignal= [intialSilence inputSignal finalSilence]; case 'file' %% file input simple or mixed @@ -146,50 +151,38 @@ rms=(mean(inputSignal.^2))^0.5; amp=targetRMS/rms; inputSignal=inputSignal*amp; - silence= zeros(1,round(0.1/dt)); - inputSignal= [silence inputSignal' silence]; + intialSilence= zeros(1,round(0.1/dt)); + finalSilence= zeros(1,round(0.2/dt)); + inputSignal= [intialSilence inputSignal' finalSilence]; end %% run the model tic - fprintf('\n') disp(['Signal duration= ' num2str(length(inputSignal)/sampleRate)]) -disp([num2str(numChannels) ' channel model']) +disp([num2str(numChannels) ' channel model: ' AN_spikesOrProbability]) disp('Computing ...') MAP1_14(inputSignal, sampleRate, BFlist, ... MAPparamsName, AN_spikesOrProbability, paramChanges); -% the model run is now complete. Now display the results +%% the model run is now complete. Now display the results UTIL_showMAP(showMapOptions, paramChanges) +if strcmp(signalType,'tones') + disp(['duration=' num2str(duration)]) + disp(['level=' num2str(leveldBSPL)]) + disp(['toneFrequency=' num2str(toneFrequency)]) + global DRNLParams + disp(['attenuation factor =' ... + num2str(DRNLParams.rateToAttenuationFactor, '%5.3f') ]) + disp(['attenuation factor (probability)=' ... + num2str(DRNLParams.rateToAttenuationFactorProb, '%5.3f') ]) + disp(AN_spikesOrProbability) +end +disp(paramChanges) toc path(restorePath) - -function inputSignal=createMultiTone(sampleRate, toneFrequency, ... - leveldBSPL, duration, rampDuration) -% Create pure tone stimulus -dt=1/sampleRate; % seconds -time=dt: dt: duration; -inputSignal=sum(sin(2*pi*toneFrequency'*time), 1); -amp=10^(leveldBSPL/20)*28e-6; % converts to Pascals (peak) -inputSignal=amp*inputSignal; - -% apply ramps -% catch rampTime error -if rampDuration>0.5*duration, rampDuration=duration/2; end -rampTime=dt:dt:rampDuration; -ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... - ones(1,length(time)-length(rampTime))]; -inputSignal=inputSignal.*ramp; -ramp=fliplr(ramp); -inputSignal=inputSignal.*ramp; - -% add 10 ms silence -silence= zeros(1,round(0.05/dt)); -inputSignal= [silence inputSignal silence]; -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testPrograms/test_speechInNoise.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,215 @@ +function test_speechInNoise +% test_MAP1_14 is a general purpose test routine that can be adjusted to +% test a number of different applications of MAP1_14 +% +% A range of options are supplied in the early part of the program +% +% One use of the function is to create demonstrations; filenames <demoxx> +% to illustrate particular features +% +% #1 +% Identify the file (in 'MAPparamsName') containing the model parameters +% +% #2 +% Identify the kind of model required (in 'AN_spikesOrProbability'). +% A full brainstem model (spikes) can be computed or a shorter model +% (probability) that computes only so far as the auditory nerve +% +% #3 +% Choose between a tone signal or file input (in 'signalType') +% +% #4 +% Set the signal rms level (in leveldBSPL) +% +% #5 +% Identify the channels in terms of their best frequencies in the vector +% BFlist. +% +% Last minute changes to the parameters fetched earlier can be made using +% the cell array of strings 'paramChanges'. +% Each string must have the same format as the corresponding line in the +% file identified in 'MAPparamsName' +% +% When the demonstration is satisfactory, freeze it by renaming it <demoxx> + +dbstop if error +restorePath=path; +addpath (['..' filesep 'MAP'], ['..' filesep 'wavFileStore'], ... + ['..' filesep 'utilities']) + +%% #1 parameter file name +MAPparamsName='Normal'; + + +%% #2 probability (fast) or spikes (slow) representation +AN_spikesOrProbability='spikes'; +% or +% AN_spikesOrProbability='probability'; + + +%% #3 pure tone, harmonic sequence or speech file input +% signalType= 'tones'; +% sampleRate= 50000; +% toneFrequency= 1000; % or a pure tone (Hz8 +% duration=.5; % seconds +% beginSilence=.2; +% endSilence=0.5; + +% F0=210; +% toneFrequency= F0:F0:8000; % harmonic sequence (Hz) + +rampDuration=.005; % raised cosine ramp (seconds) + +% or +signalType= 'file'; +fileName='twister_44kHz'; +beginSilence=1; +endSilence=0.5; + +%% #4 rms level +% signal details +leveldBSPL= 60; % dB SPL + +% leveldBSPLNoise=leveldBSPL; +leveldBSPLNoise=0; + +%% #5 number of channels in the model +% 21-channel model (log spacing) +numChannels=21; +lowestBF=300; highestBF= 6000; +BFlist=round(logspace(log10(lowestBF), log10(highestBF), numChannels)); + +% or specify your own channel BFs +% numChannels=1; +% BFlist=toneFrequency; + + +%% #6 change model parameters +% Parameter changes can be used to change one or more model parameters +% *after* the MAPparams file has been read +% This example declares only one fiber type with a calcium clearance time +% constant of 80e-6 s (HSR fiber) when the probability option is selected. +% paramChanges={'AN_IHCsynapseParams.ANspeedUpFactor=5;', ... +% 'IHCpreSynapseParams.tauCa=86e-6;'}; + +% paramChanges={}; + +paramChanges{1}='DRNLParams.MOCtau =.3;'; +paramChanges{2}='IHCpreSynapseParams.tauCa= IHCpreSynapseParams.tauCa(2);'; +paramChanges{3}='DRNLParams.rateToAttenuationFactorProb = 0.05;'; +paramChanges{3}='DRNLParams.rateToAttenuationFactorProb = 0;'; + +% paramChanges={... +% 'DRNLParams.MOCtau =.055;DRNLParams.rateToAttenuationFactor = 002;'}; +% paramChanges=... +% {'DRNLParams.MOCtau =.3; DRNLParams.rateToAttenuationFactor=0.0123;'}; + +%% delare 'showMap' options to control graphical output +showMapOptions.printModelParameters=1; % prints all parameters +showMapOptions.showModelOutput=1; % plot of all stages +showMapOptions.printFiringRates=1; % prints stage activity levels +showMapOptions.showACF=0; % shows SACF (probability only) +showMapOptions.showEfferent=1; % tracks of AR and MOC +showMapOptions.surfProbability=0; % 2D plot of HSR response +showMapOptions.surfSpikes=0; % 2D plot of spikes histogram +showMapOptions.ICrates=0; % IC rates by CNtauGk + +% disable certain silly options +if strcmp(AN_spikesOrProbability, 'spikes') + % avoid nonsensical options + showMapOptions.surfProbability=0; + showMapOptions.showACF=0; +else + showMapOptions.surfSpikes=0; +end +if strcmp(signalType, 'file') + % needed for labeling plot + showMapOptions.fileName=fileName; +else + showMapOptions.fileName=[]; +end + +%% Generate stimuli + +switch signalType + case 'tones' + % inputSignal=createMultiTone(sampleRate, toneFrequency, ... + % leveldBSPL, duration, rampDuration); + % Create pure tone stimulus + dt=1/sampleRate; % seconds + time=dt: dt: duration; + inputSignal=sum(sin(2*pi*toneFrequency'*time), 1); + amp=10^(leveldBSPL/20)*28e-6; % converts to Pascals (peak) + inputSignal=amp*inputSignal; + + % apply ramps + % catch rampTime error + if rampDuration>0.5*duration, rampDuration=duration/2; end + rampTime=dt:dt:rampDuration; + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(time)-length(rampTime))]; + inputSignal=inputSignal.*ramp; + ramp=fliplr(ramp); + inputSignal=inputSignal.*ramp; + + % add silences + intialSilence= zeros(1,round(beginSilence/dt)); + finalSilence= zeros(1,round(endSilence/dt)); + inputSignal= [intialSilence inputSignal finalSilence]; + + case 'file' + %% file input simple or mixed + [inputSignal sampleRate]=wavread(fileName); + dt=1/sampleRate; + inputSignal=inputSignal(:,1); + targetRMS=20e-6*10^(leveldBSPL/20); + rms=(mean(inputSignal.^2))^0.5; + amp=targetRMS/rms; + inputSignal=inputSignal*amp; + + % add silences + intialSilence= zeros(1,round(beginSilence*sampleRate)); + finalSilence= zeros(1,round(endSilence*sampleRate)); + inputSignal= [intialSilence inputSignal' finalSilence]; + + [inputNoise sampleRateN]=wavread('babble'); + inputNoise=inputNoise(1:length(inputSignal)); + inputNoise=inputNoise(:,1); + targetRMS=20e-6*10^(leveldBSPLNoise/20); + rms=(mean(inputNoise.^2))^0.5; + amp=targetRMS/rms; + inputNoise=inputNoise*amp; + inputSignal=inputSignal+inputNoise'; + +end + + +%% run the model +tic + +fprintf('\n') +disp(['Signal duration= ' num2str(length(inputSignal)/sampleRate)]) +disp([num2str(numChannels) ' channel model']) +disp('Computing ...') + +MAP1_14(inputSignal, sampleRate, BFlist, ... + MAPparamsName, AN_spikesOrProbability, paramChanges); + + +%% the model run is now complete. Now display the results +UTIL_showMAP(showMapOptions, paramChanges) +disp(['duration=' num2str(duration)]) +disp(['level=' num2str(leveldBSPL)]) +disp(['noise level=' num2str(leveldBSPLNoise)]) + +disp(['toneFrequency=' num2str(toneFrequency)]) +global DRNLParams +disp(['attenuation factor =' ... + num2str(DRNLParams.rateToAttenuationFactor, '%5.3f') ]) +disp(['attenuation factor (probability)=' ... + num2str(DRNLParams.rateToAttenuationFactorProb, '%5.3f') ]) +disp(AN_spikesOrProbability) +disp(paramChanges) +toc +path(restorePath) +
--- a/utilities/UTIL_PSTHmaker.m Fri Aug 19 16:07:07 2011 +0100 +++ b/utilities/UTIL_PSTHmaker.m Thu Sep 15 13:50:20 2011 +0100 @@ -6,8 +6,12 @@ % % arguments % inputData is a channel x time matrix +% dt is the sampling interval of the input signal (not clear why this is +% returned?!) % PSTH is the reduced matrix, the sum of all elements in the bin % +% e.g. +% [PSTH dt]=UTIL_PSTHmaker(inputData, dt, PSTHbinWidth) [numChannels numDataPoints]= size(inputData);
--- a/utilities/UTIL_showMAP.m Fri Aug 19 16:07:07 2011 +0100 +++ b/utilities/UTIL_showMAP.m Thu Sep 15 13:50:20 2011 +0100 @@ -12,7 +12,7 @@ % showMapOptions.surfProbability=0; % HSR (probability) surf plot % showMapOptions.fileName=[]; % parameter filename for plot title -dbstop if warning +% dbstop if warning global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName... savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ... @@ -60,7 +60,7 @@ %% summarise firing rates in command window if showMapOptions.printFiringRates %% print summary firing rates - fprintf('\n\n') + fprintf('\n') disp('summary') disp(['AR: ' num2str(min(ARattenuation))]) disp(['MOC: ' num2str(min(min(MOCattenuation)))]) @@ -78,7 +78,7 @@ /(nHSRCNneuronss*duration))]) nICneurons=size(ICoutput,1); nHSRICneurons= round(nICneurons/nANfiberTypes); - ICrate=sum(sum(ICoutput(end-nHSRICneurons:end,:)))/duration/nHSRICneurons; + ICrate=sum(sum(ICoutput(end-nHSRICneurons+1:end,:)))/duration/nHSRICneurons; disp(['IC(HSR): ' num2str(ICrate)]) % disp(['IC by type: ' num2str(mean(ICfiberTypeRates,2)')]) else @@ -93,7 +93,9 @@ %% figure (99): display output from all model stages if showMapOptions.showModelOutput plotInstructions.figureNo=99; - signalRMS=mean(savedInputSignal.^2)^0.5; + + % ignore zero elements in signal + signalRMS=mean(savedInputSignal(find(savedInputSignal)).^2)^0.5; signalRMSdb=20*log10(signalRMS/20e-6); % plot signal (1) @@ -101,21 +103,28 @@ plotInstructions.numPlots=6; plotInstructions.subPlotNo=1; plotInstructions.title=... - ['stimulus: ' num2str(signalRMSdb, '%4.0f') ' dB SPL']; + ['stimulus (Pa). ' num2str(signalRMSdb, '%4.0f') ' dB SPL']; r=size(savedInputSignal,1); if r==1, savedInputSignal=savedInputSignal'; end UTIL_plotMatrix(savedInputSignal', plotInstructions); % stapes (2) plotInstructions.subPlotNo=2; - plotInstructions.title= ['stapes displacement']; + plotInstructions.title= ['stapes displacement (m)']; UTIL_plotMatrix(OMEoutput, plotInstructions); % DRNL (3) plotInstructions.subPlotNo=3; - plotInstructions.title= ['BM displacement']; plotInstructions.yValues= savedBFlist; + [r c]=size(DRNLoutput); + if r>1 + plotInstructions.title= ['BM displacement']; + UTIL_plotMatrix(abs(DRNLoutput), plotInstructions); + else + plotInstructions.title= ['BM displacement. BF=' ... + num2str(savedBFlist) ' Hz']; UTIL_plotMatrix(DRNLoutput, plotInstructions); + end switch saveAN_spikesOrProbability case 'spikes' @@ -148,7 +157,7 @@ % IC (6) plotInstructions.displaydt=ANdt; plotInstructions.subPlotNo=6; - plotInstructions.title='IC'; + plotInstructions.title='Brainstem 2nd level'; if size(ICoutput,1)>1 if sum(sum(ICoutput))<100 plotInstructions.rasterDotSize=3; @@ -165,17 +174,23 @@ otherwise % AN rate based on probability of firing PSTHbinWidth=0.001; PSTH= UTIL_PSTHmakerb(ANprobRateOutput, dt, PSTHbinWidth); +% PSTH = makeANsmooth(PSTH, 1/PSTHbinWidth); plotInstructions.displaydt=PSTHbinWidth; plotInstructions.numPlots=2; plotInstructions.subPlotNo=2; plotInstructions.yLabel='BF'; + plotInstructions.xLabel='time'; + plotInstructions.zValuesRange= [0 300]; if nANfiberTypes>1, plotInstructions.yLabel='LSR HSR'; plotInstructions.plotDivider=1; end plotInstructions.title='AN - spike rate'; UTIL_plotMatrix(PSTH, plotInstructions); + shading interp + colorbar('southOutside') end + set(gcf,'name','MAP output') end if showMapOptions.surfProbability &&... @@ -204,10 +219,12 @@ title (['firing probability of HSR fibers only. Level= ' ... num2str(signalRMSdb,'% 3.0f') ' dB']) + colorbar('southOutside') end -if showMapOptions.surfSpikes - %% surface plot of AN spikes +%% surface plot of AN spikes +if showMapOptions.surfSpikes ... + && strcmp(saveAN_spikesOrProbability, 'spikes') figure(97), clf % select only HSR fibers at the bottom of the matrix ANoutput= ANoutput(end-length(savedBFlist)+1:end,:); @@ -227,6 +244,7 @@ view([-20 60]) % view([0 90]) title ([showMapOptions.fileName ': ' num2str(signalRMSdb,'% 3.0f') ' dB']) + set(97,'name', 'spikes surface plot') end @@ -236,22 +254,53 @@ plotInstructions.figureNo=98; figure(98), clf plotInstructions.displaydt=dt; - plotInstructions.numPlots=2; + plotInstructions.numPlots=4; plotInstructions.subPlotNo=1; + plotInstructions.zValuesRange= [-1 1]; + plotInstructions.title= ['RMS level='... + num2str(signalRMSdb, '%4.0f') ' dB SPL']; + UTIL_plotMatrix(savedInputSignal', plotInstructions); + + + plotInstructions.subPlotNo=2; plotInstructions.zValuesRange=[ -25 0]; - plotInstructions.title= ['AR strength. Signal level= ' ... - num2str(signalRMSdb,'%4.0f') ' dB SPL']; + plotInstructions.title= ['AR stapes attenuation (dB); tau='... + num2str(OMEParams.ARtau, '%4.3f') ' s']; UTIL_plotMatrix(20*log10(ARattenuation), plotInstructions); + % MOCattenuation + plotInstructions.numPlots=2; plotInstructions.subPlotNo=2; plotInstructions.yValues= savedBFlist; - plotInstructions.yLabel= 'BF'; - plotInstructions.title= ['MOC strength']; - plotInstructions.zValuesRange=[ -25 0]; - subplot(2,1,2) - % imagesc(MOCattenuation) - UTIL_plotMatrix(20*log10(MOCattenuation), plotInstructions); - colorbar + plotInstructions.yLabel= 'dB'; + if strcmp(saveAN_spikesOrProbability,'spikes') + rate2atten=DRNLParams.rateToAttenuationFactor; + plotInstructions.title= ['MOC atten; tau=' ... + num2str(DRNLParams.MOCtau) '; factor='... + num2str(rate2atten, '%6.4f')]; + else + rate2atten=DRNLParams.rateToAttenuationFactorProb; + plotInstructions.title= ['MOC atten; tauProb=' ... + num2str(DRNLParams.MOCtauProb) '; factor='... + num2str(rate2atten, '%6.4f')]; + end + plotInstructions.zValuesRange=[0 -DRNLParams.minMOCattenuationdB+5]; + UTIL_plotMatrix(-20*log10(MOCattenuation), plotInstructions); + hold on + [r c]=size(MOCattenuation); + if r>2 + colorbar('southOutside') + end + set(plotInstructions.figureNo, 'name', 'AR/ MOC') + + binwidth=0.1; + [PSTH ]=UTIL_PSTHmaker(20*log10(MOCattenuation), dt, binwidth); + PSTH=PSTH*length(PSTH)/length(MOCattenuation); + t=binwidth:binwidth:binwidth*length(PSTH); + fprintf('\n\n') +% UTIL_printTabTable([t' PSTH']) +% fprintf('\n\n') + end %% ACF plot if required @@ -327,19 +376,41 @@ path(restorePath) + %% IC chopper analysis -global ICrate -if showMapOptions.ICrates -[r nEpochs]=size(ICoutput); -ICrate=zeros(1,length(CNtauGk)); -% convert ICoutput to a 4-D matrix (time, CNtau, BF, fiberType) -% NB only one IC unit for any combination. -y=reshape(ICoutput', ... - nEpochs, length(CNtauGk),length(savedBFlist),length(ANtauCas)); -for i=1:length(CNtauGk) - ICrate(i)=sum(sum(sum(y(:,i,:,:))))/duration; - fprintf('%10.5f\t%6.0f\n', CNtauGk(i), ICrate(i)) -end -figure(95), plot(CNtauGk,ICrate) -title ('ICrate'), xlabel('CNtauGk'), ylabel('ICrate') -end +% global ICrate +% if showMapOptions.ICrates +% [r nEpochs]=size(ICoutput); +% ICrate=zeros(1,length(CNtauGk)); +% % convert ICoutput to a 4-D matrix (time, CNtau, BF, fiberType) +% % NB only one IC unit for any combination. +% y=reshape(ICoutput', ... +% nEpochs, length(CNtauGk),length(savedBFlist),length(ANtauCas)); +% for i=1:length(CNtauGk) +% ICrate(i)=sum(sum(sum(y(:,i,:,:))))/duration; +% fprintf('%10.5f\t%6.0f\n', CNtauGk(i), ICrate(i)) +% end +% figure(95), plot(CNtauGk,ICrate) +% title ('ICrate'), xlabel('CNtauGk'), ylabel('ICrate') +% end + +function ANsmooth = makeANsmooth(ANresponse, sampleRate, winSize, hopSize) + if nargin < 3 + winSize = 25; %default 25 ms window + end + if nargin < 4 + hopSize = 10; %default 10 ms jump between windows + end + + winSizeSamples = round(winSize*sampleRate/1000); + hopSizeSamples = round(hopSize*sampleRate/1000); + + % smooth + hann = hanning(winSizeSamples); + + ANsmooth = [];%Cannot pre-allocate a size as it is unknown until the enframing + for chan = 1:size(ANresponse,1) + f = enframe(ANresponse(chan,:), hann, hopSizeSamples); + ANsmooth(chan,:) = mean(f,2)'; %#ok<AGROW> see above comment + end +% end% ------ OF makeANsmooth
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/enframe.m Thu Sep 15 13:50:20 2011 +0100 @@ -0,0 +1,59 @@ +function f=enframe(x,win,inc) +%ENFRAME split signal up into (overlapping) frames: one per row. F=(X,WIN,INC) +% +% F = ENFRAME(X,LEN) splits the vector X(:) up into +% frames. Each frame is of length LEN and occupies +% one row of the output matrix. The last few frames of X +% will be ignored if its length is not divisible by LEN. +% It is an error if X is shorter than LEN. +% +% F = ENFRAME(X,LEN,INC) has frames beginning at increments of INC +% The centre of frame I is X((I-1)*INC+(LEN+1)/2) for I=1,2,... +% The number of frames is fix((length(X)-LEN+INC)/INC) +% +% F = ENFRAME(X,WINDOW) or ENFRAME(X,WINDOW,INC) multiplies +% each frame by WINDOW(:) + +% Copyright (C) Mike Brookes 1997 +% Version: $Id: enframe.m,v 1.4 2006/06/22 19:07:50 dmb Exp $ +% +% VOICEBOX is a MATLAB toolbox for speech processing. +% Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This program is free software; you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation; either version 2 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You can obtain a copy of the GNU General Public License from +% http://www.gnu.org/copyleft/gpl.html or by writing to +% Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +nx=length(x(:)); +nwin=length(win); +if (nwin == 1) + len = win; +else + len = nwin; +end +if (nargin < 3) + inc = len; +end +nf = fix((nx-len+inc)/inc); +f=zeros(nf,len); +indf= inc*(0:(nf-1)).'; +inds = (1:len); +f(:) = x(indf(:,ones(1,len))+inds(ones(nf,1),:)); +if (nwin > 1) + w = win(:)'; + f = f .* w(ones(nf,1),:); +end + +
--- a/utilities/stimulusCreate.m Fri Aug 19 16:07:07 2011 +0100 +++ b/utilities/stimulusCreate.m Thu Sep 15 13:50:20 2011 +0100 @@ -500,6 +500,12 @@ audio=audio/globalStimParams.audioOutCorrection; if globalStimParams.doPlay + if ispc + wavplay(audio,globalStimParams.FS) + else + sound(audio,globalStimParams.FS) + end + wavplay(audio,globalStimParams.FS) end % all Done