annotate MAP/MAP1_14parallel.m @ 28:02aa9826efe0

mainly multiThreshold
author Ray Meddis <rmeddis@essex.ac.uk>
date Fri, 01 Jul 2011 12:59:47 +0100
parents b03ef38fe497
children
rev   line source
rmeddis@9 1
rmeddis@9 2 function MAP1_14parallel(inputSignal, sampleRate, BFlist, MAPparamsName, ...
rmeddis@9 3 AN_spikesOrProbability, paramChanges)
rmeddis@9 4 % To test this function use test_MAP1_14 in this folder
rmeddis@9 5 %
rmeddis@9 6 % All arguments are mandatory.
rmeddis@9 7 %
rmeddis@9 8 % BFlist is a list of BFs but can be '-1' to allow MAPparams to choose
rmeddis@9 9 %
rmeddis@9 10
rmeddis@9 11 % MAPparamsName='Normal'; % source of model parameters
rmeddis@9 12 % AN_spikesOrProbability='spikes'; % or 'probability'
rmeddis@9 13 % paramChanges is a cell array of strings that can be used to make last
rmeddis@9 14 % minute parameter changes, e.g., to simulate OHC loss
rmeddis@9 15 % paramChanges{1}= 'DRNLParams.a=0;';
rmeddis@9 16
rmeddis@9 17 % The model parameters are established in the MAPparams<***> file
rmeddis@9 18 % and stored as global
rmeddis@9 19
rmeddis@9 20 restorePath=path;
rmeddis@9 21 addpath (['..' filesep 'parameterStore'])
rmeddis@9 22
rmeddis@9 23 global OMEParams DRNLParams IHC_cilia_RPParams IHCpreSynapseParams
rmeddis@9 24 global AN_IHCsynapseParams MacGregorParams MacGregorMultiParams
rmeddis@9 25
rmeddis@9 26 % All of the results of this function are stored as global
rmeddis@9 27 global dt ANdt savedBFlist saveAN_spikesOrProbability saveMAPparamsName...
rmeddis@9 28 savedInputSignal OMEextEarPressure TMoutput OMEoutput ARattenuation ...
rmeddis@9 29 DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV...
rmeddis@9 30 IHCoutput ANprobRateOutput ANoutput savePavailable tauCas ...
rmeddis@9 31 CNoutput ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation
rmeddis@9 32
rmeddis@9 33 % Normally only ICoutput(logical spike matrix) or ANprobRateOutput will be
rmeddis@9 34 % needed by the user; so the following will suffice
rmeddis@9 35 % global ANdt ICoutput ANprobRateOutput
rmeddis@9 36
rmeddis@9 37 % Note that sampleRate has not changed from the original function call and
rmeddis@9 38 % ANprobRateOutput is sampled at this rate
rmeddis@9 39 % However ANoutput, CNoutput and IC output are stored as logical
rmeddis@9 40 % 'spike' matrices using a lower sample rate (see ANdt).
rmeddis@9 41
rmeddis@9 42 % When AN_spikesOrProbability is set to probability,
rmeddis@9 43 % no spike matrices are computed.
rmeddis@9 44 % When AN_spikesOrProbability is set to 'spikes',
rmeddis@9 45 % no probability output is computed
rmeddis@9 46
rmeddis@9 47 % Efferent control variables are ARattenuation and MOCattenuation
rmeddis@9 48 % These are scalars between 1 (no attenuation) and 0.
rmeddis@9 49 % They are represented with dt=1/sampleRate (not ANdt)
rmeddis@9 50 % They are computed using either AN probability rate output
rmeddis@9 51 % or IC (spikes) output as approrpriate.
rmeddis@9 52 % AR is computed using across channel activity
rmeddis@9 53 % MOC is computed on a within-channel basis.
rmeddis@9 54
rmeddis@9 55
rmeddis@9 56 % save as global for later plotting if required
rmeddis@9 57 savedBFlist=BFlist;
rmeddis@9 58 saveAN_spikesOrProbability=AN_spikesOrProbability;
rmeddis@9 59 saveMAPparamsName=MAPparamsName;
rmeddis@9 60
rmeddis@9 61 % Read parameters from MAPparams<***> file in 'parameterStore' folder
rmeddis@9 62 cmd=['method=MAPparams' MAPparamsName ...
rmeddis@9 63 '(BFlist, sampleRate, 0);'];
rmeddis@9 64 eval(cmd);
rmeddis@9 65
rmeddis@9 66 % Beware, 'BFlist=-1' is a legitimate argument for MAPparams<>
rmeddis@9 67 % if the calling program allows MAPparams to specify the list
rmeddis@9 68 BFlist=DRNLParams.nonlinCFs;
rmeddis@9 69
rmeddis@9 70 % now accept last mintue parameter changes required by the calling program
rmeddis@9 71 if nargin>5 && ~isempty(paramChanges)
rmeddis@9 72 nChanges=length(paramChanges);
rmeddis@9 73 for idx=1:nChanges
rmeddis@9 74 eval(paramChanges{idx})
rmeddis@9 75 end
rmeddis@9 76 end
rmeddis@9 77
rmeddis@9 78 dt=1/sampleRate;
rmeddis@9 79 duration=length(inputSignal)/sampleRate;
rmeddis@9 80 % segmentDuration is specified in parameter file (must be >efferent delay)
rmeddis@9 81 segmentDuration=method.segmentDuration;
rmeddis@9 82 segmentLength=round(segmentDuration/ dt);
rmeddis@9 83 segmentTime=dt*(1:segmentLength); % used in debugging plots
rmeddis@9 84
rmeddis@9 85 % all spiking activity is computed using longer epochs
rmeddis@9 86 ANspeedUpFactor=5; % 5 times longer
rmeddis@9 87
rmeddis@9 88 % inputSignal must be row vector
rmeddis@9 89 [r c]=size(inputSignal);
rmeddis@9 90 if r>c, inputSignal=inputSignal'; end % transpose
rmeddis@9 91 % ignore stereo signals
rmeddis@9 92 inputSignal=inputSignal(1,:); % drop any second channel
rmeddis@9 93 savedInputSignal=inputSignal;
rmeddis@9 94
rmeddis@9 95 % Segment the signal
rmeddis@9 96 % The sgment length is given but the signal length must be adjusted to be a
rmeddis@9 97 % multiple of both the segment length and the reduced segmentlength
rmeddis@9 98 [nSignalRows signalLength]=size(inputSignal);
rmeddis@9 99 segmentLength=ceil(segmentLength/ANspeedUpFactor)*ANspeedUpFactor;
rmeddis@9 100 % Make the signal length a whole multiple of the segment length
rmeddis@9 101 nSignalSegments=ceil(signalLength/segmentLength);
rmeddis@9 102 padSize=nSignalSegments*segmentLength-signalLength;
rmeddis@9 103 pad=zeros(nSignalRows,padSize);
rmeddis@9 104 inputSignal=[inputSignal pad];
rmeddis@9 105 [ignore signalLength]=size(inputSignal);
rmeddis@9 106
rmeddis@9 107 % AN (spikes) is computed at a lower sample rate when spikes required
rmeddis@9 108 % so it has a reduced segment length (see 'ANspeeUpFactor' above)
rmeddis@9 109 % AN CN and IC all use this sample interval
rmeddis@9 110 ANdt=dt*ANspeedUpFactor;
rmeddis@9 111 reducedSegmentLength=round(segmentLength/ANspeedUpFactor);
rmeddis@9 112 reducedSignalLength= round(signalLength/ANspeedUpFactor);
rmeddis@9 113
rmeddis@9 114 %% Initialise with respect to each stage before computing
rmeddis@9 115 % by allocating memory,
rmeddis@9 116 % by computing constants
rmeddis@9 117 % by establishing easy to read variable names
rmeddis@9 118 % The computations are made in segments and boundary conditions must
rmeddis@9 119 % be established and stored. These are found in variables with
rmeddis@9 120 % 'boundary' or 'bndry' in the name
rmeddis@9 121
rmeddis@9 122 %% OME ---
rmeddis@9 123 % external ear resonances
rmeddis@9 124 OMEexternalResonanceFilters=OMEParams.externalResonanceFilters;
rmeddis@9 125 [nOMEExtFilters c]=size(OMEexternalResonanceFilters);
rmeddis@9 126 % details of external (outer ear) resonances
rmeddis@9 127 OMEgaindBs=OMEexternalResonanceFilters(:,1);
rmeddis@9 128 OMEgainScalars=10.^(OMEgaindBs/20);
rmeddis@9 129 OMEfilterOrder=OMEexternalResonanceFilters(:,2);
rmeddis@9 130 OMElowerCutOff=OMEexternalResonanceFilters(:,3);
rmeddis@9 131 OMEupperCutOff=OMEexternalResonanceFilters(:,4);
rmeddis@9 132 % external resonance coefficients
rmeddis@9 133 ExtFilter_b=cell(nOMEExtFilters,1);
rmeddis@9 134 ExtFilter_a=cell(nOMEExtFilters,1);
rmeddis@9 135 for idx=1:nOMEExtFilters
rmeddis@9 136 Nyquist=sampleRate/2;
rmeddis@9 137 [b, a] = butter(OMEfilterOrder(idx), ...
rmeddis@9 138 [OMElowerCutOff(idx) OMEupperCutOff(idx)]...
rmeddis@9 139 /Nyquist);
rmeddis@9 140 ExtFilter_b{idx}=b;
rmeddis@9 141 ExtFilter_a{idx}=a;
rmeddis@9 142 end
rmeddis@9 143 OMEExtFilterBndry=cell(2,1);
rmeddis@9 144 OMEextEarPressure=zeros(1,signalLength); % pressure at tympanic membrane
rmeddis@9 145
rmeddis@9 146 % pressure to velocity conversion using smoothing filter (50 Hz cutoff)
rmeddis@9 147 tau=1/(2*pi*50);
rmeddis@9 148 a1=dt/tau-1; a0=1;
rmeddis@9 149 b0=1+ a1;
rmeddis@9 150 TMdisp_b=b0; TMdisp_a=[a0 a1];
rmeddis@9 151 % figure(9), freqz(TMdisp_b, TMdisp_a)
rmeddis@9 152 OME_TMdisplacementBndry=[];
rmeddis@9 153
rmeddis@9 154 % OME high pass (simulates poor low frequency stapes response)
rmeddis@9 155 OMEhighPassHighCutOff=OMEParams.OMEstapesLPcutoff;
rmeddis@9 156 Nyquist=sampleRate/2;
rmeddis@9 157 [stapesDisp_b,stapesDisp_a] = butter(1, OMEhighPassHighCutOff/Nyquist, 'high');
rmeddis@9 158 % figure(10), freqz(stapesDisp_b, stapesDisp_a)
rmeddis@9 159
rmeddis@9 160 OMEhighPassBndry=[];
rmeddis@9 161
rmeddis@9 162 % OMEampStapes might be reducdant (use OMEParams.stapesScalar)
rmeddis@9 163 stapesScalar= OMEParams.stapesScalar;
rmeddis@9 164
rmeddis@9 165 % Acoustic reflex
rmeddis@9 166 efferentDelayPts=round(OMEParams.ARdelay/dt);
rmeddis@9 167 % smoothing filter
rmeddis@9 168 % Nyquist=(1/ANdt)/2;
rmeddis@9 169 % [ARfilt_b,ARfilt_a] = butter(1, (1/(2*pi*OMEParams.ARtau))/Nyquist, 'low');
rmeddis@9 170 a1=dt/OMEParams.ARtau-1; a0=1;
rmeddis@9 171 b0=1+ a1;
rmeddis@9 172 ARfilt_b=b0; ARfilt_a=[a0 a1];
rmeddis@9 173
rmeddis@9 174 ARattenuation=ones(1,signalLength);
rmeddis@9 175 ARrateThreshold=OMEParams.ARrateThreshold; % may not be used
rmeddis@9 176 ARrateToAttenuationFactor=OMEParams.rateToAttenuationFactor;
rmeddis@9 177 ARrateToAttenuationFactorProb=OMEParams.rateToAttenuationFactorProb;
rmeddis@9 178 ARboundary=[];
rmeddis@9 179 ARboundaryProb=0;
rmeddis@9 180
rmeddis@9 181 % save complete OME record (stapes displacement)
rmeddis@9 182 OMEoutput=zeros(1,signalLength);
rmeddis@9 183 TMoutput=zeros(1,signalLength);
rmeddis@9 184
rmeddis@9 185 %% BM ---
rmeddis@9 186 % BM is represented as a list of locations identified by BF
rmeddis@9 187 DRNL_BFs=BFlist;
rmeddis@9 188 nBFs= length(DRNL_BFs);
rmeddis@9 189
rmeddis@9 190 % DRNLchannelParameters=DRNLParams.channelParameters;
rmeddis@9 191 DRNLresponse= zeros(nBFs, segmentLength);
rmeddis@9 192
rmeddis@9 193 MOCrateToAttenuationFactor=DRNLParams.rateToAttenuationFactor;
rmeddis@9 194 rateToAttenuationFactorProb=DRNLParams.rateToAttenuationFactorProb;
rmeddis@26 195 MOCrateThresholdProb=DRNLParams.MOCrateThresholdProb;
rmeddis@9 196
rmeddis@9 197 % smoothing filter for MOC
rmeddis@9 198 % Nyquist=(1/ANdt)/2;
rmeddis@9 199 % [MOCfilt_b,MOCfilt_a] = ...
rmeddis@9 200 % butter(1, (1/(2*pi*DRNLParams.MOCtau))/Nyquist, 'low');
rmeddis@9 201 % figure(10), freqz(stapesDisp_b, stapesDisp_a)
rmeddis@9 202 a1=dt/DRNLParams.MOCtau-1; a0=1;
rmeddis@9 203 b0=1+ a1;
rmeddis@9 204 MOCfilt_b=b0; MOCfilt_a=[a0 a1];
rmeddis@9 205 % figure(9), freqz(stapesDisp_b, stapesDisp_a)
rmeddis@9 206 MOCboundary=cell(nBFs,1);
rmeddis@9 207 MOCprobBoundary=cell(nBFs,1);
rmeddis@9 208
rmeddis@9 209 MOCattSegment=zeros(nBFs,reducedSegmentLength);
rmeddis@9 210 MOCattenuation=ones(nBFs,signalLength);
rmeddis@9 211
rmeddis@9 212 if DRNLParams.a>0
rmeddis@9 213 DRNLcompressionThreshold=10^((1/(1-DRNLParams.c))* ...
rmeddis@9 214 log10(DRNLParams.b/DRNLParams.a));
rmeddis@9 215 else
rmeddis@9 216 DRNLcompressionThreshold=inf;
rmeddis@9 217 end
rmeddis@9 218
rmeddis@9 219 DRNLlinearOrder= DRNLParams.linOrder;
rmeddis@9 220 DRNLnonlinearOrder= DRNLParams.nonlinOrder;
rmeddis@9 221
rmeddis@9 222 DRNLa=DRNLParams.a;
rmeddis@9 223 DRNLb=DRNLParams.b;
rmeddis@9 224 DRNLc=DRNLParams.c;
rmeddis@9 225 linGAIN=DRNLParams.g;
rmeddis@9 226 %
rmeddis@9 227 % gammatone filter coefficients for linear pathway
rmeddis@9 228 bw=DRNLParams.linBWs';
rmeddis@9 229 phi = 2 * pi * bw * dt;
rmeddis@9 230 cf=DRNLParams.linCFs';
rmeddis@9 231 theta = 2 * pi * cf * dt;
rmeddis@9 232 cos_theta = cos(theta);
rmeddis@9 233 sin_theta = sin(theta);
rmeddis@9 234 alpha = -exp(-phi).* cos_theta;
rmeddis@9 235 b0 = ones(nBFs,1);
rmeddis@9 236 b1 = 2 * alpha;
rmeddis@9 237 b2 = exp(-2 * phi);
rmeddis@9 238 z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i;
rmeddis@9 239 z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i;
rmeddis@9 240 z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i;
rmeddis@9 241 tf = (z2 + z3) ./ z1;
rmeddis@9 242 a0 = abs(tf);
rmeddis@9 243 a1 = alpha .* a0;
rmeddis@9 244 GTlin_a = [b0, b1, b2];
rmeddis@9 245 GTlin_b = [a0, a1];
rmeddis@9 246 GTlinOrder=DRNLlinearOrder;
rmeddis@9 247 GTlinBdry1=cell(nBFs);
rmeddis@9 248 GTlinBdry2=cell(nBFs);
rmeddis@9 249 GTlinBdry3=cell(nBFs);
rmeddis@9 250 GTlinBdry1out=cell(nBFs);
rmeddis@9 251 GTlinBdry2out=cell(nBFs);
rmeddis@9 252 GTlinBdry3out=cell(nBFs);
rmeddis@9 253
rmeddis@9 254 % nonlinear gammatone filter coefficients
rmeddis@9 255 bw=DRNLParams.nlBWs';
rmeddis@9 256 phi = 2 * pi * bw * dt;
rmeddis@9 257 cf=DRNLParams.nonlinCFs';
rmeddis@9 258 theta = 2 * pi * cf * dt;
rmeddis@9 259 cos_theta = cos(theta);
rmeddis@9 260 sin_theta = sin(theta);
rmeddis@9 261 alpha = -exp(-phi).* cos_theta;
rmeddis@9 262 b0 = ones(nBFs,1);
rmeddis@9 263 b1 = 2 * alpha;
rmeddis@9 264 b2 = exp(-2 * phi);
rmeddis@9 265 z1 = (1 + alpha .* cos_theta) - (alpha .* sin_theta) * i;
rmeddis@9 266 z2 = (1 + b1 .* cos_theta) - (b1 .* sin_theta) * i;
rmeddis@9 267 z3 = (b2 .* cos(2 * theta)) - (b2 .* sin(2 * theta)) * i;
rmeddis@9 268 tf = (z2 + z3) ./ z1;
rmeddis@9 269 a0 = abs(tf);
rmeddis@9 270 a1 = alpha .* a0;
rmeddis@9 271 GTnonlin_a = [b0, b1, b2];
rmeddis@9 272 GTnonlin_b = [a0, a1];
rmeddis@9 273 GTnonlinOrder=DRNLnonlinearOrder;
rmeddis@9 274 firstGTnonlinBdry1=cell(nBFs);
rmeddis@9 275 firstGTnonlinBdry2=cell(nBFs);
rmeddis@9 276 firstGTnonlinBdry3=cell(nBFs);
rmeddis@9 277 firstGTnonlinBdry1out=cell(nBFs);
rmeddis@9 278 firstGTnonlinBdry2out=cell(nBFs);
rmeddis@9 279 firstGTnonlinBdry3out=cell(nBFs);
rmeddis@9 280
rmeddis@9 281 secondGTnonlinBdry1=cell(nBFs);
rmeddis@9 282 secondGTnonlinBdry2=cell(nBFs);
rmeddis@9 283 secondGTnonlinBdry3=cell(nBFs);
rmeddis@9 284 secondGTnonlinBdry1out=cell(nBFs);
rmeddis@9 285 secondGTnonlinBdry2out=cell(nBFs);
rmeddis@9 286 secondGTnonlinBdry3out=cell(nBFs);
rmeddis@9 287
rmeddis@9 288 % complete BM record (BM displacement)
rmeddis@9 289 DRNLoutput=zeros(nBFs, signalLength);
rmeddis@9 290
rmeddis@9 291
rmeddis@9 292 %% IHC ---
rmeddis@9 293 % IHC cilia activity and receptor potential
rmeddis@9 294 % viscous coupling between BM and stereocilia displacement
rmeddis@9 295 % Nyquist=sampleRate/2;
rmeddis@9 296 % IHCcutoff=1/(2*pi*IHC_cilia_RPParams.tc);
rmeddis@9 297 % [IHCciliaFilter_b,IHCciliaFilter_a]=...
rmeddis@9 298 % butter(1, IHCcutoff/Nyquist, 'high');
rmeddis@9 299 a1=dt/IHC_cilia_RPParams.tc-1; a0=1;
rmeddis@9 300 b0=1+ a1;
rmeddis@9 301 % high pass (i.e. low pass reversed)
rmeddis@9 302 IHCciliaFilter_b=[a0 a1]; IHCciliaFilter_a=b0;
rmeddis@9 303 % figure(9), freqz(IHCciliaFilter_b, IHCciliaFilter_a)
rmeddis@9 304
rmeddis@9 305 IHCciliaBndry=cell(nBFs,1);
rmeddis@9 306
rmeddis@9 307 % IHC apical conductance (Boltzman function)
rmeddis@9 308 IHC_C= IHC_cilia_RPParams.C;
rmeddis@9 309 IHCu0= IHC_cilia_RPParams.u0;
rmeddis@9 310 IHCu1= IHC_cilia_RPParams.u1;
rmeddis@9 311 IHCs0= IHC_cilia_RPParams.s0;
rmeddis@9 312 IHCs1= IHC_cilia_RPParams.s1;
rmeddis@9 313 IHCGmax= IHC_cilia_RPParams.Gmax;
rmeddis@9 314 IHCGa= IHC_cilia_RPParams.Ga; % (leakage)
rmeddis@9 315
rmeddis@9 316 IHCGu0 = IHCGa+IHCGmax./(1+exp(IHCu0/IHCs0).*(1+exp(IHCu1/IHCs1)));
rmeddis@9 317
rmeddis@9 318 % Receptor potential
rmeddis@9 319 IHC_Cab= IHC_cilia_RPParams.Cab;
rmeddis@9 320 IHC_Gk= IHC_cilia_RPParams.Gk;
rmeddis@9 321 IHC_Et= IHC_cilia_RPParams.Et;
rmeddis@9 322 IHC_Ek= IHC_cilia_RPParams.Ek;
rmeddis@9 323 IHC_Ekp= IHC_Ek+IHC_Et*IHC_cilia_RPParams.Rpc;
rmeddis@9 324
rmeddis@9 325 IHCrestingV= (IHC_Gk*IHC_Ekp+IHCGu0*IHC_Et)/(IHCGu0+IHC_Gk);
rmeddis@9 326
rmeddis@9 327 IHC_Vnow= IHCrestingV*ones(nBFs,1); % initial voltage
rmeddis@9 328 IHC_RP= zeros(nBFs,segmentLength);
rmeddis@9 329
rmeddis@9 330 % complete record of IHC receptor potential (V)
rmeddis@9 331 IHCciliaDisplacement= zeros(nBFs,segmentLength);
rmeddis@9 332 IHCoutput= zeros(nBFs,signalLength);
rmeddis@9 333 IHC_cilia_output= zeros(nBFs,signalLength);
rmeddis@9 334
rmeddis@9 335
rmeddis@9 336 %% pre-synapse ---
rmeddis@9 337 % Each BF is replicated using a different fiber type to make a 'channel'
rmeddis@9 338 % The number of channels is nBFs x nANfiberTypes
rmeddis@9 339 % Fiber types are specified in terms of tauCa
rmeddis@9 340 nANfiberTypes= length(IHCpreSynapseParams.tauCa);
rmeddis@9 341 tauCas= IHCpreSynapseParams.tauCa;
rmeddis@9 342 nChannels= nANfiberTypes*nBFs;
rmeddis@9 343 synapticCa= zeros(nChannels,segmentLength);
rmeddis@9 344
rmeddis@9 345 % Calcium control (more calcium, greater release rate)
rmeddis@9 346 ECa=IHCpreSynapseParams.ECa;
rmeddis@9 347 gamma=IHCpreSynapseParams.gamma;
rmeddis@9 348 beta=IHCpreSynapseParams.beta;
rmeddis@9 349 tauM=IHCpreSynapseParams.tauM;
rmeddis@9 350 mICa=zeros(nChannels,segmentLength);
rmeddis@9 351 GmaxCa=IHCpreSynapseParams.GmaxCa;
rmeddis@9 352 synapse_z= IHCpreSynapseParams.z;
rmeddis@9 353 synapse_power=IHCpreSynapseParams.power;
rmeddis@9 354
rmeddis@9 355 % tauCa vector is established across channels to allow vectorization
rmeddis@9 356 % (one tauCa per channel). Do not confuse with tauCas (one pre fiber type)
rmeddis@9 357 tauCa=repmat(tauCas, nBFs,1);
rmeddis@9 358 tauCa=reshape(tauCa, nChannels, 1);
rmeddis@9 359
rmeddis@9 360 % presynapse startup values (vectors, length:nChannels)
rmeddis@9 361 % proportion (0 - 1) of Ca channels open at IHCrestingV
rmeddis@9 362 mICaCurrent=((1+beta^-1 * exp(-gamma*IHCrestingV))^-1)...
rmeddis@9 363 *ones(nBFs*nANfiberTypes,1);
rmeddis@9 364 % corresponding startup currents
rmeddis@9 365 ICaCurrent= (GmaxCa*mICaCurrent.^3) * (IHCrestingV-ECa);
rmeddis@9 366 CaCurrent= ICaCurrent.*tauCa;
rmeddis@9 367
rmeddis@9 368 % vesicle release rate at startup (one per channel)
rmeddis@9 369 % kt0 is used only at initialisation
rmeddis@9 370 kt0= -synapse_z * CaCurrent.^synapse_power;
rmeddis@9 371
rmeddis@9 372
rmeddis@9 373 %% AN ---
rmeddis@9 374 % each row of the AN matrices represents one AN fiber
rmeddis@9 375 % The results computed either for probabiities *or* for spikes (not both)
rmeddis@9 376 % Spikes are necessary if CN and IC are to be computed
rmeddis@9 377 nFibersPerChannel= AN_IHCsynapseParams.numFibers;
rmeddis@9 378 nANfibers= nChannels*nFibersPerChannel;
rmeddis@9 379
rmeddis@9 380 y=AN_IHCsynapseParams.y;
rmeddis@9 381 l=AN_IHCsynapseParams.l;
rmeddis@9 382 x=AN_IHCsynapseParams.x;
rmeddis@9 383 r=AN_IHCsynapseParams.r;
rmeddis@9 384 M=round(AN_IHCsynapseParams.M);
rmeddis@9 385
rmeddis@9 386 % probability (NB initial 'P' on everything)
rmeddis@9 387 PAN_ydt = repmat(AN_IHCsynapseParams.y*dt, nChannels,1);
rmeddis@9 388 PAN_ldt = repmat(AN_IHCsynapseParams.l*dt, nChannels,1);
rmeddis@9 389 PAN_xdt = repmat(AN_IHCsynapseParams.x*dt, nChannels,1);
rmeddis@9 390 PAN_rdt = repmat(AN_IHCsynapseParams.r*dt, nChannels,1);
rmeddis@9 391 PAN_rdt_plus_ldt = PAN_rdt + PAN_ldt;
rmeddis@9 392 PAN_M=round(AN_IHCsynapseParams.M);
rmeddis@9 393
rmeddis@9 394 % compute starting values
rmeddis@9 395 Pcleft = kt0* y* M ./ (y*(l+r)+ kt0* l);
rmeddis@9 396 Pavailable = Pcleft*(l+r)./kt0;
rmeddis@9 397 Preprocess = Pcleft*r/x; % canbe fractional
rmeddis@9 398
rmeddis@9 399 ANprobability=zeros(nChannels,segmentLength);
rmeddis@9 400 ANprobRateOutput=zeros(nChannels,signalLength);
rmeddis@9 401 % special variables for monitoring synaptic cleft (specialists only)
rmeddis@9 402 savePavailableSeg=zeros(nChannels,segmentLength);
rmeddis@9 403 savePavailable=zeros(nChannels,signalLength);
rmeddis@9 404
rmeddis@9 405 % spikes % ! ! ! ! ! ! ! !
rmeddis@9 406 AN_refractory_period= AN_IHCsynapseParams.refractory_period;
rmeddis@9 407 lengthAbsRefractory= round(AN_refractory_period/ANdt);
rmeddis@9 408
rmeddis@9 409 AN_ydt= repmat(AN_IHCsynapseParams.y*ANdt, nANfibers,1);
rmeddis@9 410 AN_ldt= repmat(AN_IHCsynapseParams.l*ANdt, nANfibers,1);
rmeddis@9 411 AN_xdt= repmat(AN_IHCsynapseParams.x*ANdt, nANfibers,1);
rmeddis@9 412 AN_rdt= repmat(AN_IHCsynapseParams.r*ANdt, nANfibers,1);
rmeddis@9 413 AN_rdt_plus_ldt= AN_rdt + AN_ldt;
rmeddis@9 414 AN_M= round(AN_IHCsynapseParams.M);
rmeddis@9 415
rmeddis@9 416 % kt0 is initial release rate
rmeddis@9 417 % Establish as a vector (length=channel x number of fibers)
rmeddis@9 418 kt0= repmat(kt0', nFibersPerChannel, 1);
rmeddis@9 419 kt0=reshape(kt0, nANfibers,1);
rmeddis@9 420
rmeddis@9 421 % starting values for reservoirs
rmeddis@9 422 AN_cleft = kt0* y* M ./ (y*(l+r)+ kt0* l);
rmeddis@9 423 AN_available = round(AN_cleft*(l+r)./kt0); %must be integer
rmeddis@9 424 AN_reprocess = AN_cleft*r/x;
rmeddis@9 425
rmeddis@9 426 % output is in a logical array spikes = 1/ 0.
rmeddis@9 427 ANspikes= false(nANfibers,reducedSegmentLength);
rmeddis@9 428 ANoutput= false(nANfibers,reducedSignalLength);
rmeddis@9 429
rmeddis@9 430
rmeddis@9 431 %% CN (first brain stem nucleus - could be any subdivision of CN)
rmeddis@9 432 % Input to a CN neuorn is a random selection of AN fibers within a channel
rmeddis@9 433 % The number of AN fibers used is ANfibersFanInToCN
rmeddis@9 434 ANfibersFanInToCN=MacGregorMultiParams.fibersPerNeuron;
rmeddis@9 435 nCNneuronsPerChannel=MacGregorMultiParams.nNeuronsPerBF;
rmeddis@9 436 % CNtauGk (Potassium time constant) determines the rate of firing of
rmeddis@9 437 % the unit when driven hard by a DC input (not normally >350 sp/s)
rmeddis@9 438 CNtauGk=MacGregorMultiParams.tauGk;
rmeddis@9 439 ANavailableFibersPerChan=AN_IHCsynapseParams.numFibers;
rmeddis@9 440 nCNneurons=nCNneuronsPerChannel*nChannels;
rmeddis@9 441 % nCNneuronsPerFiberType= nCNneurons/nANfiberTypes;
rmeddis@9 442
rmeddis@9 443 CNmembranePotential=zeros(nCNneurons,reducedSegmentLength);
rmeddis@9 444
rmeddis@9 445 % establish which ANfibers (by name) feed into which CN nuerons
rmeddis@9 446 CNinputfiberLists=zeros(nChannels*nCNneuronsPerChannel, ANfibersFanInToCN);
rmeddis@9 447 unitNo=1;
rmeddis@9 448 for ch=1:nChannels
rmeddis@9 449 % Each channel contains a number of units =length(listOfFanInValues)
rmeddis@9 450 for idx=1:nCNneuronsPerChannel
rmeddis@9 451 fibersUsed=(ch-1)*ANavailableFibersPerChan + ...
rmeddis@9 452 ceil(rand(1,ANfibersFanInToCN)* ANavailableFibersPerChan);
rmeddis@9 453 CNinputfiberLists(unitNo,:)=fibersUsed;
rmeddis@9 454 unitNo=unitNo+1;
rmeddis@9 455 end
rmeddis@9 456 end
rmeddis@9 457
rmeddis@9 458 % input to CN units
rmeddis@9 459 AN_PSTH=zeros(nCNneurons,reducedSegmentLength);
rmeddis@9 460
rmeddis@9 461 % Generate CNalphaFunction function
rmeddis@9 462 % by which spikes are converted to post-synaptic currents
rmeddis@9 463 CNdendriteLPfreq= MacGregorMultiParams.dendriteLPfreq;
rmeddis@9 464 CNcurrentPerSpike=MacGregorMultiParams.currentPerSpike;
rmeddis@9 465 CNspikeToCurrentTau=1/(2*pi*CNdendriteLPfreq);
rmeddis@9 466 t=ANdt:ANdt:5*CNspikeToCurrentTau;
rmeddis@9 467 CNalphaFunction=...
rmeddis@9 468 (CNcurrentPerSpike/CNspikeToCurrentTau)*t.*exp(-t/CNspikeToCurrentTau);
rmeddis@9 469 % figure(98), plot(t,CNalphaFunction)
rmeddis@9 470 % working memory for implementing convolution
rmeddis@9 471 CNcurrentTemp=...
rmeddis@9 472 zeros(nCNneurons,reducedSegmentLength+length(CNalphaFunction)-1);
rmeddis@9 473 % trailing alphas are parts of humps carried forward to the next segment
rmeddis@9 474 CNtrailingAlphas=zeros(nCNneurons,length(CNalphaFunction));
rmeddis@9 475
rmeddis@9 476 CN_tauM=MacGregorMultiParams.tauM;
rmeddis@9 477 CN_tauTh=MacGregorMultiParams.tauTh;
rmeddis@9 478 CN_cap=MacGregorMultiParams.Cap;
rmeddis@9 479 CN_c=MacGregorMultiParams.c;
rmeddis@9 480 CN_b=MacGregorMultiParams.dGkSpike;
rmeddis@9 481 CN_Ek=MacGregorMultiParams.Ek;
rmeddis@9 482 CN_Eb= MacGregorMultiParams.Eb;
rmeddis@9 483 CN_Er=MacGregorMultiParams.Er;
rmeddis@9 484 CN_Th0= MacGregorMultiParams.Th0;
rmeddis@9 485 CN_E= zeros(nCNneurons,1);
rmeddis@9 486 CN_Gk= zeros(nCNneurons,1);
rmeddis@9 487 CN_Th= MacGregorMultiParams.Th0*ones(nCNneurons,1);
rmeddis@9 488 CN_Eb=CN_Eb.*ones(nCNneurons,1);
rmeddis@9 489 CN_Er=CN_Er.*ones(nCNneurons,1);
rmeddis@9 490 CNtimeSinceLastSpike=zeros(nCNneurons,1);
rmeddis@9 491 % tauGk is the main distinction between neurons
rmeddis@9 492 % in fact they are all the same in the standard model
rmeddis@9 493 tauGk=repmat(CNtauGk,nChannels*nCNneuronsPerChannel,1);
rmeddis@9 494
rmeddis@9 495 CN_PSTH=zeros(nChannels,reducedSegmentLength);
rmeddis@9 496 CNoutput=false(nCNneurons,reducedSignalLength);
rmeddis@9 497
rmeddis@9 498
rmeddis@9 499 %% MacGregor (IC - second nucleus) --------
rmeddis@9 500 nICcells=nChannels; % one cell per channel
rmeddis@9 501
rmeddis@9 502 ICspikeWidth=0.00015; % this may need revisiting
rmeddis@9 503 epochsPerSpike=round(ICspikeWidth/ANdt);
rmeddis@9 504 if epochsPerSpike<1
rmeddis@9 505 error(['MacGregorMulti: sample rate too low to support ' ...
rmeddis@9 506 num2str(ICspikeWidth*1e6) ' microsec spikes']);
rmeddis@9 507 end
rmeddis@9 508
rmeddis@9 509 % short names
rmeddis@9 510 IC_tauM=MacGregorParams.tauM;
rmeddis@9 511 IC_tauGk=MacGregorParams.tauGk;
rmeddis@9 512 IC_tauTh=MacGregorParams.tauTh;
rmeddis@9 513 IC_cap=MacGregorParams.Cap;
rmeddis@9 514 IC_c=MacGregorParams.c;
rmeddis@9 515 IC_b=MacGregorParams.dGkSpike;
rmeddis@9 516 IC_Th0=MacGregorParams.Th0;
rmeddis@9 517 IC_Ek=MacGregorParams.Ek;
rmeddis@9 518 IC_Eb= MacGregorParams.Eb;
rmeddis@9 519 IC_Er=MacGregorParams.Er;
rmeddis@9 520
rmeddis@9 521 IC_E=zeros(nICcells,1);
rmeddis@9 522 IC_Gk=zeros(nICcells,1);
rmeddis@9 523 IC_Th=IC_Th0*ones(nICcells,1);
rmeddis@9 524
rmeddis@9 525 % Dendritic filtering, all spikes are replaced by CNalphaFunction functions
rmeddis@9 526 ICdendriteLPfreq= MacGregorParams.dendriteLPfreq;
rmeddis@9 527 ICcurrentPerSpike=MacGregorParams.currentPerSpike;
rmeddis@9 528 ICspikeToCurrentTau=1/(2*pi*ICdendriteLPfreq);
rmeddis@9 529 t=ANdt:ANdt:3*ICspikeToCurrentTau;
rmeddis@9 530 IC_CNalphaFunction= (ICcurrentPerSpike / ...
rmeddis@9 531 ICspikeToCurrentTau)*t.*exp(-t / ICspikeToCurrentTau);
rmeddis@9 532 % figure(98), plot(t,IC_CNalphaFunction)
rmeddis@9 533
rmeddis@9 534 % working space for implementing alpha function
rmeddis@9 535 ICcurrentTemp=...
rmeddis@9 536 zeros(nICcells,reducedSegmentLength+length(IC_CNalphaFunction)-1);
rmeddis@9 537 ICtrailingAlphas=zeros(nICcells, length(IC_CNalphaFunction));
rmeddis@9 538
rmeddis@9 539 ICfiberTypeRates=zeros(nANfiberTypes,reducedSignalLength);
rmeddis@9 540 ICoutput=false(nChannels,reducedSignalLength);
rmeddis@9 541
rmeddis@9 542 ICmembranePotential=zeros(nICcells,reducedSegmentLength);
rmeddis@9 543 ICmembraneOutput=zeros(nICcells,signalLength);
rmeddis@9 544
rmeddis@9 545
rmeddis@9 546 %% Main program %% %% %% %% %% %% %% %% %% %% %% %% %% %%
rmeddis@9 547
rmeddis@9 548 % Compute the entire model for each segment
rmeddis@9 549 segmentStartPTR=1;
rmeddis@9 550 reducedSegmentPTR=1; % when sampling rate is reduced
rmeddis@9 551 while segmentStartPTR<signalLength
rmeddis@9 552 segmentEndPTR=segmentStartPTR+segmentLength-1;
rmeddis@9 553 % shorter segments after speed up.
rmeddis@9 554 shorterSegmentEndPTR=reducedSegmentPTR+reducedSegmentLength-1;
rmeddis@9 555
rmeddis@9 556 iputPressureSegment=inputSignal...
rmeddis@9 557 (:,segmentStartPTR:segmentStartPTR+segmentLength-1);
rmeddis@9 558
rmeddis@9 559 % segment debugging plots
rmeddis@9 560 % figure(98)
rmeddis@9 561 % plot(segmentTime,iputPressureSegment), title('signalSegment')
rmeddis@9 562
rmeddis@9 563
rmeddis@9 564 % OME ----------------------
rmeddis@9 565
rmeddis@9 566 % OME Stage 1: external resonances. Add to inputSignal pressure wave
rmeddis@9 567 y=iputPressureSegment;
rmeddis@9 568 for n=1:nOMEExtFilters
rmeddis@9 569 % any number of resonances can be used
rmeddis@9 570 [x OMEExtFilterBndry{n}] = ...
rmeddis@9 571 filter(ExtFilter_b{n},ExtFilter_a{n},...
rmeddis@9 572 iputPressureSegment, OMEExtFilterBndry{n});
rmeddis@9 573 x= x* OMEgainScalars(n);
rmeddis@9 574 % This is a parallel resonance so add it
rmeddis@9 575 y=y+x;
rmeddis@9 576 end
rmeddis@9 577 iputPressureSegment=y;
rmeddis@9 578 OMEextEarPressure(segmentStartPTR:segmentEndPTR)= iputPressureSegment;
rmeddis@9 579
rmeddis@9 580 % OME stage 2: convert input pressure (velocity) to
rmeddis@9 581 % tympanic membrane(TM) displacement using low pass filter
rmeddis@9 582 [TMdisplacementSegment OME_TMdisplacementBndry] = ...
rmeddis@9 583 filter(TMdisp_b,TMdisp_a,iputPressureSegment, ...
rmeddis@9 584 OME_TMdisplacementBndry);
rmeddis@9 585 % and save it
rmeddis@9 586 TMoutput(segmentStartPTR:segmentEndPTR)= TMdisplacementSegment;
rmeddis@9 587
rmeddis@9 588 % OME stage 3: middle ear high pass effect to simulate stapes inertia
rmeddis@9 589 [stapesDisplacement OMEhighPassBndry] = ...
rmeddis@9 590 filter(stapesDisp_b,stapesDisp_a,TMdisplacementSegment, ...
rmeddis@9 591 OMEhighPassBndry);
rmeddis@9 592
rmeddis@9 593 % OME stage 4: apply stapes scalar
rmeddis@9 594 stapesDisplacement=stapesDisplacement*stapesScalar;
rmeddis@9 595
rmeddis@9 596 % OME stage 5: acoustic reflex stapes attenuation
rmeddis@9 597 % Attenuate the TM response using feedback from LSR fiber activity
rmeddis@9 598 if segmentStartPTR>efferentDelayPts
rmeddis@9 599 stapesDisplacement= stapesDisplacement.*...
rmeddis@9 600 ARattenuation(segmentStartPTR-efferentDelayPts:...
rmeddis@9 601 segmentEndPTR-efferentDelayPts);
rmeddis@9 602 end
rmeddis@9 603
rmeddis@9 604 % segment debugging plots
rmeddis@9 605 % figure(98)
rmeddis@9 606 % plot(segmentTime, stapesDisplacement), title ('stapesDisplacement')
rmeddis@9 607
rmeddis@9 608 % and save
rmeddis@9 609 OMEoutput(segmentStartPTR:segmentEndPTR)= stapesDisplacement;
rmeddis@9 610
rmeddis@9 611 % needed for parallel processing
rmeddis@9 612 if segmentStartPTR>efferentDelayPts
rmeddis@9 613 MOCatt=MOCattenuation(:, segmentStartPTR-efferentDelayPts:...
rmeddis@9 614 segmentEndPTR-efferentDelayPts);
rmeddis@9 615 else % no MOC available yet
rmeddis@9 616 MOCatt=ones(nBFs, segmentLength);
rmeddis@9 617 end
rmeddis@9 618 %% BM ------------------------------
rmeddis@9 619 % Each BM location is computed separately
rmeddis@9 620 parfor BFno=1:nBFs
rmeddis@9 621
rmeddis@9 622 % *linear* path
rmeddis@9 623 % repeats used to avoid parallel processin problems
rmeddis@9 624 linOutput = stapesDisplacement * linGAIN; % linear gain
rmeddis@9 625 [linOutput GTlinBdry1out{BFno}] = ...
rmeddis@9 626 filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry1{BFno});
rmeddis@9 627 [linOutput GTlinBdry2out{BFno}] = ...
rmeddis@9 628 filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry2{BFno});
rmeddis@9 629 [linOutput GTlinBdry3out{BFno}] = ...
rmeddis@9 630 filter(GTlin_b(BFno,:), GTlin_a(BFno,:), linOutput, GTlinBdry3{BFno});
rmeddis@9 631
rmeddis@9 632 % *nonLinear* path
rmeddis@9 633 % efferent attenuation (0 <> 1)
rmeddis@9 634 MOC=MOCatt(BFno);
rmeddis@9 635
rmeddis@9 636
rmeddis@9 637 % first gammatone filter
rmeddis@9 638 [nonlinOutput firstGTnonlinBdry1out{BFno}] = ...
rmeddis@9 639 filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
rmeddis@9 640 stapesDisplacement, firstGTnonlinBdry1{BFno});
rmeddis@9 641
rmeddis@9 642 [nonlinOutput firstGTnonlinBdry2out{BFno}] = ...
rmeddis@9 643 filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
rmeddis@9 644 stapesDisplacement, firstGTnonlinBdry2{BFno});
rmeddis@9 645
rmeddis@9 646 [nonlinOutput firstGTnonlinBdry3out{BFno}] = ...
rmeddis@9 647 filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
rmeddis@9 648 stapesDisplacement, firstGTnonlinBdry3{BFno});
rmeddis@9 649
rmeddis@9 650 % broken stick instantaneous compression
rmeddis@9 651 % nonlinear gain is weakend by MOC before applied to BM response
rmeddis@9 652 y= nonlinOutput.*(MOC* DRNLa); % linear section.
rmeddis@9 653 % compress those parts of the signal above the compression
rmeddis@9 654 % threshold
rmeddis@9 655 abs_x = abs(nonlinOutput);
rmeddis@9 656 idx=find(abs_x>DRNLcompressionThreshold);
rmeddis@9 657 if ~isempty(idx)>0
rmeddis@9 658 y(idx)=sign(nonlinOutput(idx)).*...
rmeddis@9 659 (DRNLb*abs_x(idx).^DRNLc);
rmeddis@9 660 end
rmeddis@9 661 nonlinOutput=y;
rmeddis@9 662
rmeddis@9 663 % second filter removes distortion products
rmeddis@9 664 [nonlinOutput secondGTnonlinBdry1out{BFno}] = ...
rmeddis@9 665 filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
rmeddis@9 666 nonlinOutput, secondGTnonlinBdry1{BFno});
rmeddis@9 667
rmeddis@9 668 [nonlinOutput secondGTnonlinBdry2out{BFno}] = ...
rmeddis@9 669 filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
rmeddis@9 670 nonlinOutput, secondGTnonlinBdry2{BFno});
rmeddis@9 671
rmeddis@9 672 [nonlinOutput secondGTnonlinBdry3out{BFno}] = ...
rmeddis@9 673 filter(GTnonlin_b(BFno,:), GTnonlin_a(BFno,:), ...
rmeddis@9 674 nonlinOutput, secondGTnonlinBdry3{BFno});
rmeddis@9 675
rmeddis@9 676
rmeddis@9 677 % combine the two paths to give the DRNL displacement
rmeddis@9 678 DRNLresponse(BFno,:)=linOutput+nonlinOutput;
rmeddis@9 679 end % BF
rmeddis@9 680 GTlinBdry1=GTlinBdry1out;
rmeddis@9 681 GTlinBdry2=GTlinBdry2out;
rmeddis@9 682 GTlinBdry3=GTlinBdry3out;
rmeddis@9 683 firstGTnonlinBdry1=firstGTnonlinBdry1out;
rmeddis@9 684 firstGTnonlinBdry2=firstGTnonlinBdry2out;
rmeddis@9 685 firstGTnonlinBdry3=firstGTnonlinBdry3out;
rmeddis@9 686 secondGTnonlinBdry1=secondGTnonlinBdry1out;
rmeddis@9 687 secondGTnonlinBdry2=secondGTnonlinBdry2out;
rmeddis@9 688 secondGTnonlinBdry3=secondGTnonlinBdry3out;
rmeddis@9 689 % segment debugging plots
rmeddis@9 690 % figure(98)
rmeddis@9 691 % if size(DRNLresponse,1)>3
rmeddis@9 692 % imagesc(DRNLresponse) % matrix display
rmeddis@9 693 % title('DRNLresponse'); % single or double channel response
rmeddis@9 694 % else
rmeddis@9 695 % plot(segmentTime, DRNLresponse)
rmeddis@9 696 % end
rmeddis@9 697
rmeddis@9 698 % and save it
rmeddis@9 699 DRNLoutput(:, segmentStartPTR:segmentEndPTR)= DRNLresponse;
rmeddis@9 700
rmeddis@9 701
rmeddis@9 702 %% IHC ------------------------------------
rmeddis@9 703 % BM displacement to IHCciliaDisplacement is a high-pass filter
rmeddis@9 704 % because of viscous coupling
rmeddis@9 705 for idx=1:nBFs
rmeddis@9 706 [IHCciliaDisplacement(idx,:) IHCciliaBndry{idx}] = ...
rmeddis@9 707 filter(IHCciliaFilter_b,IHCciliaFilter_a, ...
rmeddis@9 708 DRNLresponse(idx,:), IHCciliaBndry{idx});
rmeddis@9 709 end
rmeddis@9 710
rmeddis@9 711 % apply scalar
rmeddis@9 712 IHCciliaDisplacement=IHCciliaDisplacement* IHC_C;
rmeddis@9 713
rmeddis@9 714 % and save it
rmeddis@9 715 IHC_cilia_output(:,segmentStartPTR:segmentStartPTR+segmentLength-1)=...
rmeddis@9 716 IHCciliaDisplacement;
rmeddis@9 717
rmeddis@9 718 % compute apical conductance
rmeddis@9 719 G=IHCGmax./(1+exp(-(IHCciliaDisplacement-IHCu0)/IHCs0).*...
rmeddis@9 720 (1+exp(-(IHCciliaDisplacement-IHCu1)/IHCs1)));
rmeddis@9 721 Gu=G + IHCGa;
rmeddis@9 722
rmeddis@9 723 % Compute receptor potential
rmeddis@9 724 for idx=1:segmentLength
rmeddis@9 725 IHC_Vnow=IHC_Vnow+ (-Gu(:, idx).*(IHC_Vnow-IHC_Et)-...
rmeddis@9 726 IHC_Gk*(IHC_Vnow-IHC_Ekp))* dt/IHC_Cab;
rmeddis@9 727 IHC_RP(:,idx)=IHC_Vnow;
rmeddis@9 728 end
rmeddis@9 729
rmeddis@9 730 % segment debugging plots
rmeddis@9 731 % if size(IHC_RP,1)>3
rmeddis@9 732 % surf(IHC_RP), shading interp, title('IHC_RP')
rmeddis@9 733 % else
rmeddis@9 734 % plot(segmentTime, IHC_RP)
rmeddis@9 735 % end
rmeddis@9 736
rmeddis@9 737 % and save it
rmeddis@9 738 IHCoutput(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=IHC_RP;
rmeddis@9 739
rmeddis@9 740
rmeddis@9 741 %% synapse -----------------------------
rmeddis@9 742 % Compute the vesicle release rate for each fiber type at each BF
rmeddis@9 743 % replicate IHC_RP for each fiber type
rmeddis@9 744 Vsynapse=repmat(IHC_RP, nANfiberTypes,1);
rmeddis@9 745
rmeddis@9 746 % look-up table of target fraction channels open for a given IHC_RP
rmeddis@9 747 mICaINF= 1./( 1 + exp(-gamma * Vsynapse) /beta);
rmeddis@9 748 % fraction of channel open - apply time constant
rmeddis@9 749 for idx=1:segmentLength
rmeddis@9 750 % mICaINF is the current 'target' value of mICa
rmeddis@9 751 mICaCurrent=mICaCurrent+(mICaINF(:,idx)-mICaCurrent)*dt./tauM;
rmeddis@9 752 mICa(:,idx)=mICaCurrent;
rmeddis@9 753 end
rmeddis@9 754
rmeddis@9 755 ICa= (GmaxCa* mICa.^3) .* (Vsynapse- ECa);
rmeddis@9 756
rmeddis@9 757 for idx=1:segmentLength
rmeddis@9 758 CaCurrent=CaCurrent + ICa(:,idx)*dt - CaCurrent*dt./tauCa;
rmeddis@9 759 synapticCa(:,idx)=CaCurrent;
rmeddis@9 760 end
rmeddis@9 761 synapticCa=-synapticCa; % treat IHCpreSynapseParams as positive substance
rmeddis@9 762
rmeddis@9 763 % NB vesicleReleaseRate is /s and is independent of dt
rmeddis@9 764 vesicleReleaseRate = synapse_z * synapticCa.^synapse_power; % rate
rmeddis@9 765
rmeddis@9 766 % segment debugging plots
rmeddis@9 767 % if size(vesicleReleaseRate,1)>3
rmeddis@9 768 % surf(vesicleReleaseRate), shading interp, title('vesicleReleaseRate')
rmeddis@9 769 % else
rmeddis@9 770 % plot(segmentTime, vesicleReleaseRate)
rmeddis@9 771 % end
rmeddis@9 772
rmeddis@9 773
rmeddis@9 774 %% AN
rmeddis@9 775 switch AN_spikesOrProbability
rmeddis@9 776 case 'probability'
rmeddis@9 777 % No refractory effect is applied
rmeddis@9 778 for t = 1:segmentLength;
rmeddis@9 779 M_Pq=PAN_M-Pavailable;
rmeddis@9 780 M_Pq(M_Pq<0)=0;
rmeddis@9 781 Preplenish = M_Pq .* PAN_ydt;
rmeddis@9 782 Pejected = Pavailable.* vesicleReleaseRate(:,t)*dt;
rmeddis@9 783 Preprocessed = M_Pq.*Preprocess.* PAN_xdt;
rmeddis@9 784
rmeddis@9 785 ANprobability(:,t)= min(Pejected,1);
rmeddis@9 786 reuptakeandlost= PAN_rdt_plus_ldt .* Pcleft;
rmeddis@9 787 reuptake= PAN_rdt.* Pcleft;
rmeddis@9 788
rmeddis@9 789 Pavailable= Pavailable+ Preplenish- Pejected+ Preprocessed;
rmeddis@9 790 Pcleft= Pcleft + Pejected - reuptakeandlost;
rmeddis@9 791 Preprocess= Preprocess + reuptake - Preprocessed;
rmeddis@9 792 Pavailable(Pavailable<0)=0;
rmeddis@9 793 savePavailableSeg(:,t)=Pavailable; % synapse tracking
rmeddis@9 794 end
rmeddis@9 795 % and save it as *rate*
rmeddis@9 796 ANrate=ANprobability/dt;
rmeddis@9 797 ANprobRateOutput(:, segmentStartPTR:...
rmeddis@9 798 segmentStartPTR+segmentLength-1)= ANrate;
rmeddis@9 799 % monitor synapse contents (only sometimes used)
rmeddis@9 800 savePavailable(:, segmentStartPTR:segmentStartPTR+segmentLength-1)=...
rmeddis@9 801 savePavailableSeg;
rmeddis@9 802
rmeddis@9 803 % Estimate efferent effects. ARattenuation (0 <> 1)
rmeddis@9 804 % acoustic reflex
rmeddis@9 805 ARAttSeg=mean(ANrate(1:nBFs,:),1); %LSR channels are 1:nBF
rmeddis@9 806 % smooth
rmeddis@9 807 [ARAttSeg, ARboundaryProb] = ...
rmeddis@9 808 filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundaryProb);
rmeddis@9 809 ARAttSeg=ARAttSeg-ARrateThreshold;
rmeddis@9 810 ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths
rmeddis@9 811 ARattenuation(segmentStartPTR:segmentEndPTR)=...
rmeddis@9 812 (1-ARrateToAttenuationFactorProb.* ARAttSeg);
rmeddis@9 813
rmeddis@9 814 % MOC attenuation
rmeddis@9 815 % within-channel HSR response only
rmeddis@9 816 HSRbegins=nBFs*(nANfiberTypes-1)+1;
rmeddis@9 817 rates=ANrate(HSRbegins:end,:);
rmeddis@9 818 for idx=1:nBFs
rmeddis@9 819 [smoothedRates, MOCprobBoundary{idx}] = ...
rmeddis@9 820 filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ...
rmeddis@9 821 MOCprobBoundary{idx});
rmeddis@26 822 smoothedRates=smoothedRates-MOCrateThresholdProb;
rmeddis@9 823 smoothedRates(smoothedRates<0)=0;
rmeddis@9 824 MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ...
rmeddis@9 825 (1- smoothedRates* rateToAttenuationFactorProb);
rmeddis@9 826 end
rmeddis@9 827 MOCattenuation(MOCattenuation<0)=0.001;
rmeddis@9 828
rmeddis@9 829
rmeddis@9 830 case 'spikes'
rmeddis@9 831 ANtimeCount=0;
rmeddis@9 832 % implement speed upt
rmeddis@9 833 for t = ANspeedUpFactor:ANspeedUpFactor:segmentLength;
rmeddis@9 834 ANtimeCount=ANtimeCount+1;
rmeddis@9 835 % convert release rate to probabilities
rmeddis@9 836 releaseProb=vesicleReleaseRate(:,t)*ANdt;
rmeddis@9 837 % releaseProb is the release probability per channel
rmeddis@9 838 % but each channel has many synapses
rmeddis@9 839 releaseProb=repmat(releaseProb',nFibersPerChannel,1);
rmeddis@9 840 releaseProb=reshape(releaseProb, nFibersPerChannel*nChannels,1);
rmeddis@9 841
rmeddis@9 842 % AN_available=round(AN_available); % vesicles must be integer, (?needed)
rmeddis@9 843 M_q=AN_M- AN_available; % number of missing vesicles
rmeddis@9 844 M_q(M_q<0)= 0; % cannot be less than 0
rmeddis@9 845
rmeddis@9 846 % AN_N1 converts probability to discrete events
rmeddis@9 847 % it considers each event that might occur
rmeddis@9 848 % (how many vesicles might be released)
rmeddis@9 849 % and returns a count of how many were released
rmeddis@9 850
rmeddis@9 851 % slow line
rmeddis@9 852 % probabilities= 1-(1-releaseProb).^AN_available;
rmeddis@9 853 probabilities= 1-intpow((1-releaseProb), AN_available);
rmeddis@9 854 ejected= probabilities> rand(length(AN_available),1);
rmeddis@9 855
rmeddis@9 856 reuptakeandlost = AN_rdt_plus_ldt .* AN_cleft;
rmeddis@9 857 reuptake = AN_rdt.* AN_cleft;
rmeddis@9 858
rmeddis@9 859 % slow line
rmeddis@9 860 % probabilities= 1-(1-AN_reprocess.*AN_xdt).^M_q;
rmeddis@9 861 probabilities= 1-intpow((1-AN_reprocess.*AN_xdt), M_q);
rmeddis@9 862 reprocessed= probabilities>rand(length(M_q),1);
rmeddis@9 863
rmeddis@9 864 % slow line
rmeddis@9 865 % probabilities= 1-(1-AN_ydt).^M_q;
rmeddis@9 866 probabilities= 1-intpow((1-AN_ydt), M_q);
rmeddis@9 867
rmeddis@9 868 replenish= probabilities>rand(length(M_q),1);
rmeddis@9 869
rmeddis@9 870 AN_available = AN_available + replenish - ejected ...
rmeddis@9 871 + reprocessed;
rmeddis@9 872 AN_cleft = AN_cleft + ejected - reuptakeandlost;
rmeddis@9 873 AN_reprocess = AN_reprocess + reuptake - reprocessed;
rmeddis@9 874
rmeddis@9 875 % ANspikes is logical record of vesicle release events>0
rmeddis@9 876 ANspikes(:, ANtimeCount)= ejected;
rmeddis@9 877 end % t
rmeddis@9 878
rmeddis@9 879 % zero any events that are preceded by release events ...
rmeddis@9 880 % within the refractory period
rmeddis@9 881 % The refractory period consist of two periods
rmeddis@9 882 % 1) the absolute period where no spikes occur
rmeddis@9 883 % 2) a relative period where a spike may occur. This relative
rmeddis@9 884 % period is realised as a variable length interval
rmeddis@9 885 % where the length is chosen at random
rmeddis@9 886 % (esentially a linear ramp up)
rmeddis@9 887
rmeddis@9 888 % Andreas has a fix for this
rmeddis@9 889 for t = 1:ANtimeCount-2*lengthAbsRefractory;
rmeddis@9 890 % identify all spikes across fiber array at time (t)
rmeddis@9 891 % idx is a list of channels where spikes occurred
rmeddis@9 892 % ?? try sparse matrices?
rmeddis@9 893 idx=find(ANspikes(:,t));
rmeddis@9 894 for j=idx % consider each spike
rmeddis@9 895 % specify variable refractory period
rmeddis@9 896 % between abs and 2*abs refractory period
rmeddis@9 897 nPointsRefractory=lengthAbsRefractory+...
rmeddis@9 898 round(rand*lengthAbsRefractory);
rmeddis@9 899 % disable spike potential for refractory period
rmeddis@9 900 % set all values in this range to 0
rmeddis@9 901 ANspikes(j,t+1:t+nPointsRefractory)=0;
rmeddis@9 902 end
rmeddis@9 903 end %t
rmeddis@9 904
rmeddis@9 905 % segment debugging
rmeddis@9 906 % plotInstructions.figureNo=98;
rmeddis@9 907 % plotInstructions.displaydt=ANdt;
rmeddis@9 908 % plotInstructions.numPlots=1;
rmeddis@9 909 % plotInstructions.subPlotNo=1;
rmeddis@9 910 % UTIL_plotMatrix(ANspikes, plotInstructions);
rmeddis@9 911
rmeddis@9 912 % and save it. NB, AN is now on 'speedUp' time
rmeddis@9 913 ANoutput(:, reducedSegmentPTR: shorterSegmentEndPTR)=ANspikes;
rmeddis@9 914
rmeddis@9 915
rmeddis@9 916 %% CN Macgregor first neucleus -------------------------------
rmeddis@9 917 % input is from AN so ANdt is used throughout
rmeddis@9 918 % Each CNneuron has a unique set of input fibers selected
rmeddis@9 919 % at random from the available AN fibers (CNinputfiberLists)
rmeddis@9 920
rmeddis@9 921 % Create the dendritic current for that neuron
rmeddis@9 922 % First get input spikes to this neuron
rmeddis@9 923 synapseNo=1;
rmeddis@9 924 for ch=1:nChannels
rmeddis@9 925 for idx=1:nCNneuronsPerChannel
rmeddis@9 926 % determine candidate fibers for this unit
rmeddis@9 927 fibersUsed=CNinputfiberLists(synapseNo,:);
rmeddis@9 928 % ANpsth has a bin width of dt
rmeddis@9 929 % (just a simple sum across fibers)
rmeddis@9 930 AN_PSTH(synapseNo,:) = ...
rmeddis@9 931 sum(ANspikes(fibersUsed,:), 1);
rmeddis@9 932 synapseNo=synapseNo+1;
rmeddis@9 933 end
rmeddis@9 934 end
rmeddis@9 935
rmeddis@9 936 % One alpha function per spike
rmeddis@9 937 [alphaRows alphaCols]=size(CNtrailingAlphas);
rmeddis@9 938
rmeddis@9 939 for unitNo=1:nCNneurons
rmeddis@9 940 CNcurrentTemp(unitNo,:)= ...
rmeddis@9 941 conv(AN_PSTH(unitNo,:),CNalphaFunction);
rmeddis@9 942 end
rmeddis@9 943 % add post-synaptic current left over from previous segment
rmeddis@9 944 CNcurrentTemp(:,1:alphaCols)=...
rmeddis@9 945 CNcurrentTemp(:,1:alphaCols)+ CNtrailingAlphas;
rmeddis@9 946
rmeddis@9 947 % take post-synaptic current for this segment
rmeddis@9 948 CNcurrentInput= CNcurrentTemp(:, 1:reducedSegmentLength);
rmeddis@9 949
rmeddis@9 950 % trailingalphas are the ends of the alpha functions that
rmeddis@9 951 % spill over into the next segment
rmeddis@9 952 CNtrailingAlphas= ...
rmeddis@9 953 CNcurrentTemp(:, reducedSegmentLength+1:end);
rmeddis@9 954
rmeddis@9 955 if CN_c>0
rmeddis@9 956 % variable threshold condition (slow)
rmeddis@9 957 for t=1:reducedSegmentLength
rmeddis@9 958 CNtimeSinceLastSpike=CNtimeSinceLastSpike-dts;
rmeddis@9 959 s=CN_E>CN_Th & CNtimeSinceLastSpike<0 ;
rmeddis@9 960 CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike
rmeddis@9 961 dE =(-CN_E/CN_tauM + ...
rmeddis@9 962 CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt;
rmeddis@9 963 dGk=-CN_Gk*dt./tauGk + CN_b*s;
rmeddis@9 964 dTh=-(CN_Th-CN_Th0)*dt/CN_tauTh + CN_c*s;
rmeddis@9 965 CN_E=CN_E+dE;
rmeddis@9 966 CN_Gk=CN_Gk+dGk;
rmeddis@9 967 CN_Th=CN_Th+dTh;
rmeddis@9 968 CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er;
rmeddis@9 969 end
rmeddis@9 970 else
rmeddis@9 971 % static threshold (faster)
rmeddis@9 972 for t=1:reducedSegmentLength
rmeddis@9 973 CNtimeSinceLastSpike=CNtimeSinceLastSpike-dt;
rmeddis@9 974 s=CN_E>CN_Th0 & CNtimeSinceLastSpike<0 ; % =1 if both conditions met
rmeddis@9 975 CNtimeSinceLastSpike(s)=0.0005; % 0.5 ms for sodium spike
rmeddis@9 976 dE = (-CN_E/CN_tauM + ...
rmeddis@9 977 CNcurrentInput(:,t)/CN_cap+(CN_Gk/CN_cap).*(CN_Ek-CN_E))*dt;
rmeddis@9 978 dGk=-CN_Gk*dt./tauGk +CN_b*s;
rmeddis@9 979 CN_E=CN_E+dE;
rmeddis@9 980 CN_Gk=CN_Gk+dGk;
rmeddis@9 981 % add spike to CN_E and add resting potential (-60 mV)
rmeddis@9 982 CNmembranePotential(:,t)=CN_E+s.*(CN_Eb-CN_E)+CN_Er;
rmeddis@9 983 end
rmeddis@9 984 end
rmeddis@9 985
rmeddis@9 986 % extract spikes. A spike is a substantial upswing in voltage
rmeddis@9 987 CN_spikes=CNmembranePotential> -0.01;
rmeddis@9 988
rmeddis@9 989 % now remove any spike that is immediately followed by a spike
rmeddis@9 990 % NB 'find' works on columns (whence the transposing)
rmeddis@9 991 CN_spikes=CN_spikes';
rmeddis@9 992 idx=find(CN_spikes);
rmeddis@9 993 idx=idx(1:end-1);
rmeddis@9 994 CN_spikes(idx+1)=0;
rmeddis@9 995 CN_spikes=CN_spikes';
rmeddis@9 996
rmeddis@9 997 % segment debugging
rmeddis@9 998 % plotInstructions.figureNo=98;
rmeddis@9 999 % plotInstructions.displaydt=ANdt;
rmeddis@9 1000 % plotInstructions.numPlots=1;
rmeddis@9 1001 % plotInstructions.subPlotNo=1;
rmeddis@9 1002 % UTIL_plotMatrix(CN_spikes, plotInstructions);
rmeddis@9 1003
rmeddis@9 1004 % and save it
rmeddis@9 1005 CNoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=...
rmeddis@9 1006 CN_spikes;
rmeddis@9 1007
rmeddis@9 1008
rmeddis@9 1009 %% IC ----------------------------------------------
rmeddis@9 1010 % MacGregor or some other second order neurons
rmeddis@9 1011
rmeddis@9 1012 % combine CN neurons in same channel, i.e. same BF & same tauCa
rmeddis@9 1013 % to generate inputs to single IC unit
rmeddis@9 1014 channelNo=0;
rmeddis@9 1015 for idx=1:nCNneuronsPerChannel:nCNneurons-nCNneuronsPerChannel+1;
rmeddis@9 1016 channelNo=channelNo+1;
rmeddis@9 1017 CN_PSTH(channelNo,:)=...
rmeddis@9 1018 sum(CN_spikes(idx:idx+nCNneuronsPerChannel-1,:));
rmeddis@9 1019 end
rmeddis@9 1020
rmeddis@9 1021 [alphaRows alphaCols]=size(ICtrailingAlphas);
rmeddis@9 1022 for ICneuronNo=1:nICcells
rmeddis@9 1023 ICcurrentTemp(ICneuronNo,:)= ...
rmeddis@9 1024 conv(CN_PSTH(ICneuronNo,:), IC_CNalphaFunction);
rmeddis@9 1025 end
rmeddis@9 1026
rmeddis@9 1027 % add the unused current from the previous convolution
rmeddis@9 1028 ICcurrentTemp(:,1:alphaCols)=ICcurrentTemp(:,1:alphaCols)...
rmeddis@9 1029 + ICtrailingAlphas;
rmeddis@9 1030 % take what is required and keep the trailing part for next time
rmeddis@9 1031 inputCurrent=ICcurrentTemp(:, 1:reducedSegmentLength);
rmeddis@9 1032 ICtrailingAlphas=ICcurrentTemp(:, reducedSegmentLength+1:end);
rmeddis@9 1033
rmeddis@9 1034 if IC_c==0
rmeddis@9 1035 % faster computation when threshold is stable (C==0)
rmeddis@9 1036 for t=1:reducedSegmentLength
rmeddis@9 1037 s=IC_E>IC_Th0;
rmeddis@9 1038 dE = (-IC_E/IC_tauM + inputCurrent(:,t)/IC_cap +...
rmeddis@9 1039 (IC_Gk/IC_cap).*(IC_Ek-IC_E))*dt;
rmeddis@9 1040 dGk=-IC_Gk*dt/IC_tauGk +IC_b*s;
rmeddis@9 1041 IC_E=IC_E+dE;
rmeddis@9 1042 IC_Gk=IC_Gk+dGk;
rmeddis@9 1043 ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er;
rmeddis@9 1044 end
rmeddis@9 1045 else
rmeddis@9 1046 % threshold is changing (IC_c>0; e.g. bushy cell)
rmeddis@9 1047 for t=1:reducedSegmentLength
rmeddis@9 1048 dE = (-IC_E/IC_tauM + ...
rmeddis@9 1049 inputCurrent(:,t)/IC_cap + (IC_Gk/IC_cap)...
rmeddis@9 1050 .*(IC_Ek-IC_E))*dt;
rmeddis@9 1051 IC_E=IC_E+dE;
rmeddis@9 1052 s=IC_E>IC_Th;
rmeddis@9 1053 ICmembranePotential(:,t)=IC_E+s.*(IC_Eb-IC_E)+IC_Er;
rmeddis@9 1054 dGk=-IC_Gk*dt/IC_tauGk +IC_b*s;
rmeddis@9 1055 IC_Gk=IC_Gk+dGk;
rmeddis@9 1056
rmeddis@9 1057 % After a spike, the threshold is raised
rmeddis@9 1058 % otherwise it settles to its baseline
rmeddis@9 1059 dTh=-(IC_Th-Th0)*dt/IC_tauTh +s*IC_c;
rmeddis@9 1060 IC_Th=IC_Th+dTh;
rmeddis@9 1061 end
rmeddis@9 1062 end
rmeddis@9 1063
rmeddis@9 1064 ICspikes=ICmembranePotential> -0.01;
rmeddis@9 1065 % now remove any spike that is immediately followed by a spike
rmeddis@9 1066 % NB 'find' works on columns (whence the transposing)
rmeddis@9 1067 ICspikes=ICspikes';
rmeddis@9 1068 idx=find(ICspikes);
rmeddis@9 1069 idx=idx(1:end-1);
rmeddis@9 1070 ICspikes(idx+1)=0;
rmeddis@9 1071 ICspikes=ICspikes';
rmeddis@9 1072
rmeddis@9 1073 nCellsPerTau= nICcells/nANfiberTypes;
rmeddis@9 1074 firstCell=1;
rmeddis@9 1075 lastCell=nCellsPerTau;
rmeddis@9 1076 for tauCount=1:nANfiberTypes
rmeddis@9 1077 % separate rates according to fiber types
rmeddis@9 1078 ICfiberTypeRates(tauCount, ...
rmeddis@9 1079 reducedSegmentPTR:shorterSegmentEndPTR)=...
rmeddis@9 1080 sum(ICspikes(firstCell:lastCell, :))...
rmeddis@9 1081 /(nCellsPerTau*ANdt);
rmeddis@9 1082 firstCell=firstCell+nCellsPerTau;
rmeddis@9 1083 lastCell=lastCell+nCellsPerTau;
rmeddis@9 1084 end
rmeddis@9 1085 ICoutput(:, reducedSegmentPTR:shorterSegmentEndPTR)=ICspikes;
rmeddis@9 1086
rmeddis@9 1087 if nBFs==1 % single channel
rmeddis@9 1088 x= repmat(ICmembranePotential(1,:), ANspeedUpFactor,1);
rmeddis@9 1089 x= reshape(x,1,segmentLength);
rmeddis@9 1090 if nANfiberTypes>1 % save HSR and LSR
rmeddis@9 1091 y= repmat(ICmembranePotential(end,:), ANspeedUpFactor,1);
rmeddis@9 1092 y= reshape(y,1,segmentLength);
rmeddis@9 1093 x=[x; y];
rmeddis@9 1094 end
rmeddis@9 1095 ICmembraneOutput(:, segmentStartPTR:segmentEndPTR)= x;
rmeddis@9 1096 end
rmeddis@9 1097
rmeddis@9 1098 % estimate efferent effects.
rmeddis@9 1099 % ARis based on LSR units. LSR channels are 1:nBF
rmeddis@9 1100 if nANfiberTypes>1 % AR is multi-channel only
rmeddis@9 1101 ARAttSeg=sum(ICspikes(1:nBFs,:),1)/ANdt;
rmeddis@9 1102 [ARAttSeg, ARboundary] = ...
rmeddis@9 1103 filter(ARfilt_b, ARfilt_a, ARAttSeg, ARboundary);
rmeddis@9 1104 ARAttSeg=ARAttSeg-ARrateThreshold;
rmeddis@9 1105 ARAttSeg(ARAttSeg<0)=0; % prevent negative strengths
rmeddis@9 1106 % scale up to dt from ANdt
rmeddis@9 1107 x= repmat(ARAttSeg, ANspeedUpFactor,1);
rmeddis@9 1108 x=reshape(x,1,segmentLength);
rmeddis@9 1109 ARattenuation(segmentStartPTR:segmentEndPTR)=...
rmeddis@9 1110 (1-ARrateToAttenuationFactor* x);
rmeddis@9 1111 ARattenuation(ARattenuation<0)=0.001;
rmeddis@9 1112 else
rmeddis@9 1113 % single channel model; disable AR
rmeddis@9 1114 ARattenuation(segmentStartPTR:segmentEndPTR)=...
rmeddis@9 1115 ones(1,segmentLength);
rmeddis@9 1116 end
rmeddis@9 1117
rmeddis@9 1118 % MOC attenuation using HSR response only
rmeddis@9 1119 % Separate MOC effect for each BF
rmeddis@9 1120 HSRbegins=nBFs*(nANfiberTypes-1)+1;
rmeddis@9 1121 rates=ICspikes(HSRbegins:end,:)/ANdt;
rmeddis@9 1122 for idx=1:nBFs
rmeddis@9 1123 [smoothedRates, MOCboundary{idx}] = ...
rmeddis@9 1124 filter(MOCfilt_b, MOCfilt_a, rates(idx,:), ...
rmeddis@9 1125 MOCboundary{idx});
rmeddis@9 1126 MOCattSegment(idx,:)=smoothedRates;
rmeddis@9 1127 % expand timescale back to model dt from ANdt
rmeddis@9 1128 x= repmat(MOCattSegment(idx,:), ANspeedUpFactor,1);
rmeddis@9 1129 x= reshape(x,1,segmentLength);
rmeddis@9 1130 MOCattenuation(idx,segmentStartPTR:segmentEndPTR)= ...
rmeddis@9 1131 (1- MOCrateToAttenuationFactor* x);
rmeddis@9 1132 end
rmeddis@9 1133 MOCattenuation(MOCattenuation<0)=0.04;
rmeddis@9 1134 % segment debugging
rmeddis@9 1135 % plotInstructions.figureNo=98;
rmeddis@9 1136 % plotInstructions.displaydt=ANdt;
rmeddis@9 1137 % plotInstructions.numPlots=1;
rmeddis@9 1138 % plotInstructions.subPlotNo=1;
rmeddis@9 1139 % UTIL_plotMatrix(ICspikes, plotInstructions);
rmeddis@9 1140
rmeddis@9 1141 end % AN_spikesOrProbability
rmeddis@9 1142 segmentStartPTR=segmentStartPTR+segmentLength;
rmeddis@9 1143 reducedSegmentPTR=reducedSegmentPTR+reducedSegmentLength;
rmeddis@9 1144
rmeddis@9 1145
rmeddis@9 1146 end % segment
rmeddis@9 1147
rmeddis@9 1148 path(restorePath)