Mercurial > hg > map
diff userProgramsMathiasDietz/test_binaural.m @ 38:c2204b18f4a2 tip
End nov big change
author | Ray Meddis <rmeddis@essex.ac.uk> |
---|---|
date | Mon, 28 Nov 2011 13:34:28 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userProgramsMathiasDietz/test_binaural.m Mon Nov 28 13:34:28 2011 +0000 @@ -0,0 +1,433 @@ +function test_binaural +% test_binaural is a first attempt to produce a binaural model +% incorporating MSO and IC models. +% The monaural response is computed first for left and right stimuli +% before using the CN response as input to the binaural MSO model +% that, in turn, feeds a single cell IC model. +% +% The function has no arguments and everything is set up internally +% +% #1 +% Identify the file (in 'MAPparamsName') containing the model parameters +% the default is 'PL' which uses primary like neurons in the CN to +% simulate spherical bushy cells +% +% #2 +% Set AN_spikesOrProbability'). to 'spikes' +% +% #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. This is currently a single-channel model, so only one BF needed +% +% #6 +% 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' +% Currently this is used to specify that only HSR fibers are used and +% for changing the current per AN spike at the CN dendrite +% +% #7 +% specify the parameters of the MSO cells in the MSOParams structure +% +% #8 +% specify the parameters of the IC cells in the ICMSOParams structure +% +% #9 +% identify the plots required from MAP1_14 (i.e. before the bonaural model) +% +% #10 +% Specify ITDs. The program cycles through different ITDs +% + +global CNoutput dtSpikes +dbstop if error +restorePath=path; +addpath (['..' filesep 'MAP'], ['..' filesep 'wavFileStore'], ... + ['..' filesep 'utilities']) + +%% #1 monaural model parameter file name +MAPparamsName='PL'; + + +%% #2 'spikes' are mandatory for this model +AN_spikesOrProbability='spikes'; + + +%% #3 pure tone, harmonic sequence or speech file input +signalType= 'tones'; +sampleRate= 50000; +duration=0.050; % seconds +rampDuration=.005; % raised cosine ramp (seconds) +beginSilence=0.050; +endSilence=0.050; +toneFrequency= 750; % or a pure tone (Hz) + +% or +% harmonic sequence (Hz) +% F0=210; +% toneFrequency= F0:F0:8000; + +% or +% signalType= 'file'; +% fileName='twister_44kHz'; + +if strcmp(signalType, 'file') + % needed for labeling plot + showMapOptions.fileName=fileName; +else + showMapOptions.fileName=[]; +end + +%% #4 rms level +leveldBSPL= 70; + + +%% #5 number of channels in the model +BFlist=toneFrequency; + +%% #6 change model parameters + +paramChanges={'IHCpreSynapseParams.tauCa=80e-6;',... + 'MacGregorMultiParams.currentPerSpike=0.800e-6;'}; + +% Parameter changes can be used to change one or more model parameters +% *after* the MAPparams file has been read + +%% #7 MSO parameters +MSOParams.nNeuronsPerBF= 10; % N neurons per BF +MSOParams.type = 'primary-like cell'; +MSOParams.fibersPerNeuron=4; % N input fibers +MSOParams.dendriteLPfreq=2000; % dendritic filter +MSOParams.currentPerSpike=0.11e-6; % (A) per spike +MSOParams.currentPerSpike=0.5e-6; % (A) per spike +MSOParams.Cap=4.55e-9; % cell capacitance (Siemens) +MSOParams.tauM=5e-4; % membrane time constant (s) +MSOParams.Ek=-0.01; % K+ eq. potential (V) +MSOParams.dGkSpike=3.64e-5; % K+ cond.shift on spike,S +MSOParams.tauGk= 0.0012; % K+ conductance tau (s) +MSOParams.Th0= 0.01; % equilibrium threshold (V) +MSOParams.c= 0.01; % threshold shift on spike, (V) +MSOParams.tauTh= 0.015; % variable threshold tau +MSOParams.Er=-0.06; % resting potential (V) +MSOParams.Eb=0.06; % spike height (V) +MSOParams.debugging=0; % (special) +MSOParams.wideband=0; % special for wideband units + +%% #8 IC parameters +ICchopperParams.nNeuronsPerBF= 10; % N neurons per BF +ICchopperParams.type = 'chopper cell'; +ICchopperParams.fibersPerNeuron=10; % N input fibers +ICchopperParams.dendriteLPfreq=50; % dendritic filter +ICchopperParams.currentPerSpike=50e-9; % *per spike +ICchopperParams.currentPerSpike=100e-9; % *per spike +ICchopperParams.Cap=1.67e-8; % ??cell capacitance (Siemens) +ICchopperParams.tauM=0.002; % membrane time constant (s) +ICchopperParams.Ek=-0.01; % K+ eq. potential (V) +ICchopperParams.dGkSpike=1.33e-4; % K+ cond.shift on spike,S +ICchopperParams.tauGk= 0.0005;% K+ conductance tau (s) +ICchopperParams.Th0= 0.01; % equilibrium threshold (V) +ICchopperParams.c= 0; % threshold shift on spike, (V) +ICchopperParams.tauTh= 0.02; % variable threshold tau +ICchopperParams.Er=-0.06; % resting potential (V) +ICchopperParams.Eb=0.06; % spike height (V) +ICchopperParams.PSTHbinWidth= 1e-4; + +%% #9 delare 'showMap' options to control graphical output +% this applies to the monaural input model only +showMapOptions.printModelParameters=0; % prints all parameters +showMapOptions.showModelOutput=1; % plot all stages if monaural input + +%% #10 ITDs +% the program cycles through a range of stimulus ITDs +ITDs=0e-6:100e-6:2000e-6; +% ITDs=0; % single shot + +%% Now start computing! +figure(98), clf, set(gcf, 'name', 'binaural demo') +MSOcounts=zeros(1,length(ITDs)); +ICcounts=zeros(1,length(ITDs)); +ITDcount=0; +for ITD=ITDs + ITDcount=ITDcount+1; + delaySamples=round(ITD* sampleRate); + %% 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 monaural model twice + t=dt:dt:dt*length(inputSignal); + for ear={'left','right'} + figure(98), subplot(4,1,1), colour='b'; hold off + switch ear{1} + case 'right' + inputSignal=circshift(inputSignal', delaySamples)'; + hold on + colour='r'; + end + plot(t, inputSignal, colour) + title ('binaural inputs signals') + ylabel('Pa'), xlabel('time') + xlim([0 max(t)]) + + % call to monaural model + MAP1_14(inputSignal, sampleRate, BFlist, ... + MAPparamsName, AN_spikesOrProbability, paramChanges); + + % the model run is now complete. Now display the results + UTIL_showMAP(showMapOptions, paramChanges) + + % copy the CN inputspiking pattern to the binaural display + figure(98) + switch ear{1} + case 'left' + CNoutputLeft=CNoutput; + subplot(4,2,3) + case 'right' + CNoutputRight=CNoutput; + subplot(4,2,4) + end + plotInstructions=[]; + plotInstructions.axes=gca; + plotInstructions.displaydt=dtSpikes; + plotInstructions.title= ['CN spikes ' ear{1}]; + plotInstructions.rasterDotSize=2; + if sum(sum(CNoutput))<100 + plotInstructions.rasterDotSize=3; + end + UTIL_plotMatrix(CNoutput, plotInstructions); + + end % left/ right ear + + %% MSO + % run MSO model using left and right CN spikes + MSOspikes=MSO(CNoutputLeft,CNoutputRight, dtSpikes, MSOParams); + + sumspikes=sum(sum(MSOspikes)); + disp(['ITD/ MSO spikes count= ' num2str([ITD sumspikes])]) + MSOcounts(ITDcount)=sumspikes; + figure(98), subplot(4,2, 8), cla, hold off, plot(ITDs*1e6, MSOcounts) + + %% IC chopper + % run IC model using all MSO spikes as input to a single IC cell + ICMSOspikes=ICchopper(MSOspikes, dtSpikes, ICchopperParams); + + sumspikes=sum(sum(ICMSOspikes)); + disp(['ITD/ ICMSO spikes count= ' num2str([ITD sumspikes])]) + ICcounts(ITDcount)=sumspikes; + figure(98), subplot(4,2,8),hold on, plot(ITDs*1e6, ICcounts,'r') + xlabel('ITD'), ylabel(' spike count') + title('MSO (blue)/ IC (red) spike counts') + legend({'MSO','IC'}) + +end % ITDs + +path(restorePath) + + +function MSOspikes=MSO(CNoutputLeft,CNoutputRight, dtSpikes, MSOparams) +%% +[nMSOcells nEpochs]=size(CNoutputLeft); +inputCurrent=zeros(nMSOcells, nEpochs); +MSOmembranePotential=inputCurrent; + +MSO_tauM=MSOparams.tauM; +MSO_tauGk=MSOparams.tauGk; +MSO_tauTh=MSOparams.tauTh; +MSO_cap=MSOparams.Cap; +MSO_c=MSOparams.c; +MSO_b=MSOparams.dGkSpike; +MSO_Th0=MSOparams.Th0; +MSO_Ek=MSOparams.Ek; +MSO_Eb= MSOparams.Eb; +MSO_Er=MSOparams.Er; + +MSO_E=zeros(nMSOcells,1); +MSO_Gk=zeros(nMSOcells,1); +MSO_Th=MSO_Th0*ones(nMSOcells,1); + +% Dendritic filtering, all spikes are replaced by CNalphaFunction functions +MSOdendriteLPfreq= MSOparams.dendriteLPfreq; +MSOcurrentPerSpike=MSOparams.currentPerSpike; +MSOspikeToCurrentTau=1/(2*pi*MSOdendriteLPfreq); +t=dtSpikes:dtSpikes:5*MSOspikeToCurrentTau; +MSO_CNalphaFunction= (MSOcurrentPerSpike / ... + MSOspikeToCurrentTau)*t.*exp(-t / MSOspikeToCurrentTau); +% show alpha function +% figure(84), subplot(4,2,2), plot(t,MSO_CNalphaFunction) +% title(['LP cutoff ' num2str(MSOdendriteLPfreq)]) + +% convert CN spikes to post-dendritic current +CN_spikes=CNoutputLeft+CNoutputRight; +for i=1:nMSOcells + x= conv2(CN_spikes(i,:), MSO_CNalphaFunction); + inputCurrent(i,:)=x(1:nEpochs); +end + +if MSO_c==0 + % faster computation when threshold is stable (c==0) + for t=1:nEpochs + s=MSO_E>MSO_Th0; + dE = (-MSO_E/MSO_tauM + inputCurrent(:,t)/MSO_cap +... + (MSO_Gk/MSO_cap).*(MSO_Ek-MSO_E))*dtSpikes; + dGk=-MSO_Gk*dtSpikes/MSO_tauGk +MSO_b*s; + MSO_E=MSO_E+dE; + MSO_Gk=MSO_Gk+dGk; + MSOmembranePotential(:,t)=MSO_E+s.*(MSO_Eb-MSO_E)+MSO_Er; + end +else + % threshold is changing (MSO_c>0; e.g. bushy cell) + for t=1:nEpochs + dE = (-MSO_E/MSO_tauM + ... + inputCurrent(:,t)/MSO_cap + (MSO_Gk/MSO_cap)... + .*(MSO_Ek-MSO_E))*dtSpikes; + MSO_E=MSO_E+dE; + s=MSO_E>MSO_Th; + MSOmembranePotential(:,t)=MSO_E+s.*(MSO_Eb-MSO_E)+MSO_Er; + dGk=-MSO_Gk*dtSpikes/MSO_tauGk +MSO_b*s; + MSO_Gk=MSO_Gk+dGk; + + % After a spike, the threshold is raised + % otherwise it settles to its baseline + dTh=-(MSO_Th-MSO_Th0)*dtSpikes/MSO_tauTh +s*MSO_c; + MSO_Th=MSO_Th+dTh; + end +end + +figure(98),subplot(4,1,3) +hold off, imagesc(MSOmembranePotential) +title ('MSO (V)') + +MSOspikes=MSOmembranePotential> -0.01; +% Remove any spike that is immediately followed by a spike +% NB 'find' works on columns (whence the transposing) +MSOspikes=MSOspikes'; +idx=find(MSOspikes); +idx=idx(1:end-1); +MSOspikes(idx+1)=0; +MSOspikes=MSOspikes'; + + +function ICMSOspikes=ICchopper(ICMSOspikes, dtSpikes, ICMSOParams) +%% +ICMSOspikes=sum(ICMSOspikes); +[nICMSOcells nEpochs]=size(ICMSOspikes); +inputCurrent=zeros(nICMSOcells, nEpochs); +ICMSOmembranePotential=inputCurrent; + +ICMSO_tauM=ICMSOParams.tauM; +ICMSO_tauGk=ICMSOParams.tauGk; +ICMSO_tauTh=ICMSOParams.tauTh; +ICMSO_cap=ICMSOParams.Cap; +ICMSO_c=ICMSOParams.c; +ICMSO_b=ICMSOParams.dGkSpike; +ICMSO_Th0=ICMSOParams.Th0; +ICMSO_Ek=ICMSOParams.Ek; +ICMSO_Eb= ICMSOParams.Eb; +ICMSO_Er=ICMSOParams.Er; + +ICMSO_E=zeros(nICMSOcells,1); +ICMSO_Gk=zeros(nICMSOcells,1); +ICMSO_Th=ICMSO_Th0*ones(nICMSOcells,1); + +% Dendritic filtering, all spikes are replaced by CNalphaFunction functions +ICMSOdendriteLPfreq= ICMSOParams.dendriteLPfreq; +ICMSOcurrentPerSpike=ICMSOParams.currentPerSpike; +ICMSOspikeToCurrentTau=1/(2*pi*ICMSOdendriteLPfreq); +t=dtSpikes:dtSpikes:5*ICMSOspikeToCurrentTau; +ICMSOalphaFunction= (ICMSOcurrentPerSpike / ... + ICMSOspikeToCurrentTau)*t.*exp(-t / ICMSOspikeToCurrentTau); +% show alpha function +% figure(84), subplot(4,2,5), plot(t,ICMSOalphaFunction) +% title(['IC MSO LP cutoff ' num2str(ICMSOdendriteLPfreq)]) + +% post-dendritic current +for i=1:nICMSOcells + x= conv2(1*ICMSOspikes(i,:), ICMSOalphaFunction); + inputCurrent(i,:)=x(1:nEpochs); +end + +if ICMSO_c==0 + % faster computation when threshold is stable (c==0) + for t=1:nEpochs + s=ICMSO_E>ICMSO_Th0; + dE = (-ICMSO_E/ICMSO_tauM + inputCurrent(:,t)/ICMSO_cap +... + (ICMSO_Gk/ICMSO_cap).*(ICMSO_Ek-ICMSO_E))*dtSpikes; + dGk=-ICMSO_Gk*dtSpikes/ICMSO_tauGk +ICMSO_b*s; + ICMSO_E=ICMSO_E+dE; + ICMSO_Gk=ICMSO_Gk+dGk; + ICMSOmembranePotential(:,t)=ICMSO_E+s.*(ICMSO_Eb-ICMSO_E)+ICMSO_Er; + end +else + % threshold is changing (ICMSO_c>0; e.g. bushy cell) + for t=1:nEpochs + dE = (-ICMSO_E/ICMSO_tauM + ... + inputCurrent(:,t)/ICMSO_cap + (ICMSO_Gk/ICMSO_cap)... + .*(ICMSO_Ek-ICMSO_E))*dtSpikes; + ICMSO_E=ICMSO_E+dE; + s=ICMSO_E>ICMSO_Th; + ICMSOmembranePotential(:,t)=ICMSO_E+s.*(ICMSO_Eb-ICMSO_E)+ICMSO_Er; + dGk=-ICMSO_Gk*dtSpikes/ICMSO_tauGk +ICMSO_b*s; + ICMSO_Gk=ICMSO_Gk+dGk; + + % After a spike, the threshold is raised + % otherwise it settles to its baseline + dTh=-(ICMSO_Th-ICMSO_Th0)*dtSpikes/ICMSO_tauTh +s*ICMSO_c; + ICMSO_Th=ICMSO_Th+dTh; + end +end + +t=dtSpikes:dtSpikes:dtSpikes*length(ICMSOmembranePotential); +figure(98),subplot(4,2,7) +plot(t, ICMSOmembranePotential) +ylim([-0.07 0]), xlim([0 max(t)]) +title('IC (V)') + +ICMSOspikes=ICMSOmembranePotential> -0.01; +% now remove any spike that is immediately followed by a spike +% NB 'find' works on columns (whence the transposing) +ICMSOspikes=ICMSOspikes'; +idx=find(ICMSOspikes); +idx=idx(1:end-1); +ICMSOspikes(idx+1)=0; +ICMSOspikes=ICMSOspikes'; +