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