Revision 31:c54a34161e4a multithreshold 1.46
| multithreshold 1.46/MAPmodel.m | ||
|---|---|---|
| 1 |
function [modelResponse, MacGregorResponse]=MAPmodel( MAPplot, method) |
|
| 2 |
|
|
| 3 |
global experiment stimulusParameters audio withinRuns |
|
| 4 |
global outerMiddleEarParams DRNLParams AN_IHCsynapseParams |
|
| 5 |
|
|
| 6 |
savePath=path; |
|
| 7 |
addpath(['..' filesep 'MAP'], ['..' filesep 'utilities']) |
|
| 8 |
modelResponse=[]; |
|
| 9 |
MacGregorResponse=[]; |
|
| 10 |
|
|
| 11 |
% mono only (column vector) |
|
| 12 |
audio=audio(:,1)'; |
|
| 13 |
|
|
| 14 |
% if stop button pressed earlier |
|
| 15 |
if experiment.stop, return, end |
|
| 16 |
|
|
| 17 |
% -------------------------------------------------------------- run Model |
|
| 18 |
MAPparamsName=experiment.name; |
|
| 19 |
showPlotsAndDetails=experiment.MAPplot; |
|
| 20 |
AN_spikesOrProbability='spikes'; |
|
| 21 |
|
|
| 22 |
% [response, method]=MAPsequenceSeg(audio, method, 1:8); |
|
| 23 |
global ICoutput ANdt |
|
| 24 |
MAP1_14(audio, 1/method.dt, method.nonlinCF,... |
|
| 25 |
MAPparamsName, AN_spikesOrProbability); |
|
| 26 |
|
|
| 27 |
if showPlotsAndDetails |
|
| 28 |
options.printModelParameters=0; |
|
| 29 |
options.showModelOutput=1; |
|
| 30 |
options.printFiringRates=1; |
|
| 31 |
options.showACF=0; |
|
| 32 |
options.showEfferent=1; |
|
| 33 |
UTIL_showMAP(options) |
|
| 34 |
end |
|
| 35 |
|
|
| 36 |
% No response, probably caused by hitting 'stop' button |
|
| 37 |
if isempty(ICoutput), return, end |
|
| 38 |
|
|
| 39 |
% MacGregor response is the sum total of all final stage spiking |
|
| 40 |
MacGregorResponse= sum(ICoutput,1); % use IC |
|
| 41 |
|
|
| 42 |
% ---------------------------------------------------------- end model run |
|
| 43 |
|
|
| 44 |
dt=ANdt; |
|
| 45 |
time=dt:dt:dt*length(MacGregorResponse); |
|
| 46 |
|
|
| 47 |
% group delay on unit response |
|
| 48 |
MacGonsetDelay= 0.004; |
|
| 49 |
MacGoffsetDelay= 0.022; |
|
| 50 |
|
|
| 51 |
% now find the response of the MacGregor model during the target presentation + group delay |
|
| 52 |
switch experiment.threshEstMethod |
|
| 53 |
case {'2I2AFC++', '2I2AFC+++'}
|
|
| 54 |
idx= time>stimulusParameters.testTargetBegins+MacGonsetDelay ... |
|
| 55 |
& time<stimulusParameters.testTargetEnds+MacGoffsetDelay; |
|
| 56 |
nSpikesTrueWindow=sum(MacGregorResponse(:,idx)); |
|
| 57 |
idx=find(time>stimulusParameters.testNonTargetBegins+MacGonsetDelay ... |
|
| 58 |
& time<stimulusParameters.testNonTargetEnds+MacGoffsetDelay); |
|
| 59 |
nSpikesFalseWindow=sum(MacGregorResponse(:,idx)); |
|
| 60 |
% nSpikesDuringTarget is +ve when more spikes are found |
|
| 61 |
% in the target window |
|
| 62 |
difference= nSpikesTrueWindow-nSpikesFalseWindow; |
|
| 63 |
|
|
| 64 |
if difference>0 |
|
| 65 |
% hit |
|
| 66 |
nSpikesDuringTarget=experiment.MacGThreshold+1; |
|
| 67 |
elseif difference<0 |
|
| 68 |
% miss (wrong choice) |
|
| 69 |
nSpikesDuringTarget=experiment.MacGThreshold-1; |
|
| 70 |
else |
|
| 71 |
if rand>0.5 |
|
| 72 |
% hit (random choice) |
|
| 73 |
nSpikesDuringTarget=experiment.MacGThreshold+1; |
|
| 74 |
else |
|
| 75 |
% miss (random choice) |
|
| 76 |
nSpikesDuringTarget=experiment.MacGThreshold-1; |
|
| 77 |
end |
|
| 78 |
end |
|
| 79 |
disp(['level target dummy decision: ' ... |
|
| 80 |
num2str([withinRuns.variableValue nSpikesTrueWindow ... |
|
| 81 |
nSpikesFalseWindow nSpikesDuringTarget], '%4.0f') ] ) |
|
| 82 |
|
|
| 83 |
otherwise |
|
| 84 |
% idx=find(time>stimulusParameters.testTargetBegins+MacGonsetDelay ... |
|
| 85 |
% & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); |
|
| 86 |
% no delay at onset |
|
| 87 |
idx=find(time>stimulusParameters.testTargetBegins +MacGonsetDelay... |
|
| 88 |
& time<stimulusParameters.testTargetEnds+MacGoffsetDelay); |
|
| 89 |
nSpikesDuringTarget=sum(MacGregorResponse(:,idx)); |
|
| 90 |
|
|
| 91 |
% find(MacGregorResponse)*dt-stimulusParameters.stimulusDelay |
|
| 92 |
timeX=time(idx); |
|
| 93 |
end |
|
| 94 |
|
|
| 95 |
% now find the response of the MacGregor model at the end of the masker |
|
| 96 |
idx2=find(time>stimulusParameters.testTargetBegins-0.02 ... |
|
| 97 |
& time<stimulusParameters.testTargetBegins); |
|
| 98 |
if ~isempty(idx2) |
|
| 99 |
maskerRate=mean(mean(MacGregorResponse(idx2))); |
|
| 100 |
else |
|
| 101 |
%e.g. no masker |
|
| 102 |
maskerRate=0; |
|
| 103 |
end |
|
| 104 |
|
|
| 105 |
if experiment.MAPplot |
|
| 106 |
% add vertical lines to indicate target region |
|
| 107 |
figure(99), subplot(6,1,6) |
|
| 108 |
hold on |
|
| 109 |
yL=get(gca,'YLim'); |
|
| 110 |
plot([stimulusParameters.testTargetBegins + MacGonsetDelay ... |
|
| 111 |
stimulusParameters.testTargetBegins + MacGonsetDelay],yL,'r') |
|
| 112 |
plot([stimulusParameters.testTargetEnds + MacGoffsetDelay ... |
|
| 113 |
stimulusParameters.testTargetEnds + MacGoffsetDelay],yL,'r') |
|
| 114 |
end |
|
| 115 |
|
|
| 116 |
% specify unambiguous response |
|
| 117 |
switch experiment.paradigm |
|
| 118 |
case 'gapDetection' |
|
| 119 |
gapResponse=(maskerRate-nSpikesDuringTarget)/maskerRate; |
|
| 120 |
if gapResponse>0.2 |
|
| 121 |
modelResponse=2; % gap detected |
|
| 122 |
else |
|
| 123 |
modelResponse=1; % gap not detected |
|
| 124 |
end |
|
| 125 |
[nSpikesDuringTarget maskerRate gapResponse modelResponse] |
|
| 126 |
figure(22), plot(timeX,earObject(idx)) |
|
| 127 |
otherwise |
|
| 128 |
if nSpikesDuringTarget>experiment.MacGThreshold |
|
| 129 |
modelResponse=2; % stimulus detected |
|
| 130 |
else |
|
| 131 |
modelResponse=1; % nothing heard (default) |
|
| 132 |
end |
|
| 133 |
end |
|
| 134 |
|
|
| 135 |
|
|
| 136 |
path(savePath) |
|
| multithreshold 1.46/UTIL_testPhysiology.m | ||
|---|---|---|
| 1 |
function UTIL_testPhysiology(BF) |
|
| 2 |
testOME('Normal')
|
|
| 3 |
relativeFrequencies=[0.25 .5 .75 1 1.25 1.5 2]; |
|
| 4 |
testBM (BF, 'Normal',relativeFrequencies) |
|
| 5 |
testRP(BF,'Normal') |
|
| 6 |
testSynapse(BF,'Normal') |
|
| 7 |
testFM(BF,'Normal',1) |
|
| 8 |
testPhaseLocking |
|
| 9 |
testAN(BF,BF, 10:10:80); |
|
| 10 |
figure(14) |
|
| 11 |
figure(15) |
|
| multithreshold 1.46/paradigms/paradigm_IFMC_16ms.m | ||
|---|---|---|
| 1 |
function paradigm_IFMC_8ms(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
stimulusParameters.WRVname='maskerLevel'; |
|
| 7 |
stimulusParameters.WRVstartValues=50; |
|
| 8 |
stimulusParameters.WRVsteps= [-10 -2]; |
|
| 9 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 10 |
|
|
| 11 |
experiment.psyFunSlope = -1; |
|
| 12 |
withinRuns.direction='up'; |
|
| 13 |
|
|
| 14 |
betweenRuns.variableName1='maskerRelativeFrequency'; |
|
| 15 |
betweenRuns.variableList1=[1 0.5 1.6 .9 .7 1.1 1.3 ]; |
|
| 16 |
betweenRuns.variableName2='targetFrequency'; |
|
| 17 |
% keep old list of target frequencies |
|
| 18 |
betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); |
|
| 19 |
betweenRuns.randomizeSequence=1; % 'random sequence' |
|
| 20 |
|
|
| 21 |
stimulusParameters.maskerDuration=0.108; |
|
| 22 |
stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); |
|
| 23 |
stimulusParameters.maskerRelativeFrequency=betweenRuns.variableList1; |
|
| 24 |
|
|
| 25 |
stimulusParameters.gapDuration=0.01; |
|
| 26 |
|
|
| 27 |
stimulusParameters.targetType='tone'; |
|
| 28 |
stimulusParameters.targetPhase='sin'; |
|
| 29 |
stimulusParameters.targetFrequency=betweenRuns.variableList2(1); |
|
| 30 |
stimulusParameters.targetDuration=0.016; |
|
| 31 |
stimulusParameters.targetLevel=NaN; |
|
| 32 |
|
|
| 33 |
stimulusParameters.rampDuration=0.004; |
|
| 34 |
|
|
| 35 |
% instructions to user |
|
| 36 |
% single interval up/down no cue |
|
| 37 |
stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 38 |
% single interval up/down with cue |
|
| 39 |
stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},...
|
|
| 40 |
{'The clicks must be **clearly distinct** to count'}];
|
|
| 41 |
|
|
| multithreshold 1.46/paradigms/paradigm_TMC_16ms.m | ||
|---|---|---|
| 1 |
function paradigm_TMC_16ms(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
experiment.singleIntervalMaxTrials=20; |
|
| 7 |
|
|
| 8 |
stimulusParameters.WRVname='maskerLevel'; |
|
| 9 |
stimulusParameters.WRVstartValues=50; |
|
| 10 |
stimulusParameters.WRVsteps= [-10 -4]; |
|
| 11 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 12 |
|
|
| 13 |
stimulusParameters.cueTestDifference = 10; |
|
| 14 |
experiment.psyFunSlope = -1; |
|
| 15 |
withinRuns.direction='up'; |
|
| 16 |
|
|
| 17 |
betweenRuns.variableName1='gapDuration'; |
|
| 18 |
betweenRuns.variableList1=[.01 .09 .03 .05 .07]; |
|
| 19 |
betweenRuns.variableName2='targetFrequency'; |
|
| 20 |
% retain existing targetFrequencies |
|
| 21 |
betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); |
|
| 22 |
betweenRuns.randomizeSequence=1; % 'random sequence' |
|
| 23 |
|
|
| 24 |
stimulusParameters.maskerType='tone'; |
|
| 25 |
stimulusParameters.maskerPhase='sin'; |
|
| 26 |
stimulusParameters.maskerDuration=0.108; |
|
| 27 |
stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); |
|
| 28 |
stimulusParameters.maskerRelativeFrequency=1; |
|
| 29 |
|
|
| 30 |
stimulusParameters.gapDuration=betweenRuns.variableList1; |
|
| 31 |
|
|
| 32 |
stimulusParameters.targetType='tone'; |
|
| 33 |
stimulusParameters.targetPhase='sin'; |
|
| 34 |
stimulusParameters.targetFrequency=betweenRuns.variableList2(1); |
|
| 35 |
stimulusParameters.targetDuration=0.016; |
|
| 36 |
stimulusParameters.targetLevel=NaN; |
|
| 37 |
|
|
| 38 |
stimulusParameters.rampDuration=0.004; |
|
| 39 |
|
|
| 40 |
% instructions to user |
|
| 41 |
% single interval up/down no cue |
|
| 42 |
stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 43 |
% single interval up/down with cue |
|
| 44 |
stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},...
|
|
| 45 |
{'The clicks must be **clearly distinct** to count'}];
|
|
| 46 |
|
|
| multithreshold 1.46/paradigms/paradigm_TMCmodel.m | ||
|---|---|---|
| 1 |
function paradigm_TMCmodel(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
stimulusParameters.WRVname='maskerLevel'; |
|
| 7 |
stimulusParameters.WRVstartValues=30; |
|
| 8 |
stimulusParameters.WRVsteps= [-10 -4]; |
|
| 9 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 10 |
|
|
| 11 |
stimulusParameters.cueTestDifference = 10; |
|
| 12 |
experiment.psyFunSlope = -1; |
|
| 13 |
withinRuns.direction='up'; |
|
| 14 |
|
|
| 15 |
betweenRuns.variableName1='gapDuration'; |
|
| 16 |
betweenRuns.variableList1=[ 0.09 0.01:0.02:0.07 0.02:0.02:.08 0.005]; |
|
| 17 |
betweenRuns.variableName2='targetFrequency'; |
|
| 18 |
% retain existing targetFrequencies |
|
| 19 |
betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); |
|
| 20 |
betweenRuns.randomizeSequence=1; % 'random sequence' |
|
| 21 |
|
|
| 22 |
stimulusParameters.maskerType='tone'; |
|
| 23 |
stimulusParameters.maskerPhase='sin'; |
|
| 24 |
stimulusParameters.maskerDuration=0.108; |
|
| 25 |
stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); |
|
| 26 |
stimulusParameters.maskerRelativeFrequency=1; |
|
| 27 |
experiment.singleIntervalMaxTrials=10; |
|
| 28 |
|
|
| 29 |
stimulusParameters.gapDuration=betweenRuns.variableList1; |
|
| 30 |
|
|
| 31 |
stimulusParameters.targetType='tone'; |
|
| 32 |
stimulusParameters.targetPhase='sin'; |
|
| 33 |
stimulusParameters.targetFrequency=betweenRuns.variableList2(1); |
|
| 34 |
stimulusParameters.targetDuration=0.016; |
|
| 35 |
stimulusParameters.targetLevel=NaN; |
|
| 36 |
|
|
| 37 |
stimulusParameters.rampDuration=0.004; |
|
| 38 |
|
|
| 39 |
% instructions to user |
|
| 40 |
% single interval up/down no cue |
|
| 41 |
stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 42 |
% single interval up/down with cue |
|
| 43 |
stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},...
|
|
| 44 |
{'The clicks must be **clearly distinct** to count'}];
|
|
| 45 |
|
|
| multithreshold 1.46/paradigms/paradigm_absThreshold_8.m | ||
|---|---|---|
| 1 |
function paradigm_absThreshold_8(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
betweenRuns.variableName1='targetFrequency'; |
|
| 7 |
betweenRuns.variableList1=1000; |
|
| 8 |
betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); |
|
| 9 |
betweenRuns.variableName2='targetDuration'; |
|
| 10 |
betweenRuns.variableList2=0.008 ; |
|
| 11 |
betweenRuns.randomizeSequence=1; % 'random sequence' |
|
| 12 |
|
|
| 13 |
% delay > masker > gap > target |
|
| 14 |
|
|
| 15 |
|
|
| 16 |
stimulusParameters.targetType='tone'; |
|
| 17 |
stimulusParameters.targetPhase='sin'; |
|
| 18 |
stimulusParameters.targetFrequency=1000; |
|
| 19 |
stimulusParameters.targetDuration=0.008; |
|
| 20 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 21 |
|
|
| 22 |
stimulusParameters.rampDuration=0.004; |
|
| 23 |
|
|
| 24 |
% forced choice window interval |
|
| 25 |
stimulusParameters.AFCsilenceDuration=0.5; |
|
| 26 |
|
|
| 27 |
% instructions to user |
|
| 28 |
% single interval up/down no cue |
|
| 29 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 30 |
% single interval up/down with cue |
|
| 31 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| 32 |
|
|
| multithreshold 1.46/paradigms/paradigm_thr_IFMC.m | ||
|---|---|---|
| 1 |
function paradigm_thr_IFMC(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
betweenRuns.variableName1='targetFrequency'; |
|
| 7 |
betweenRuns.variableList1=1000; |
|
| 8 |
betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); |
|
| 9 |
betweenRuns.variableName2='targetDuration'; |
|
| 10 |
betweenRuns.variableList2=0.016; |
|
| 11 |
betweenRuns.randomizeSequence=1; % 'random sequence' |
|
| 12 |
|
|
| 13 |
% delay > masker > gap > target |
|
| 14 |
|
|
| 15 |
|
|
| 16 |
stimulusParameters.targetType='tone'; |
|
| 17 |
stimulusParameters.targetPhase='sin'; |
|
| 18 |
stimulusParameters.targetFrequency=1000; |
|
| 19 |
stimulusParameters.targetDuration=0.016; |
|
| 20 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 21 |
|
|
| 22 |
stimulusParameters.rampDuration=0.004; |
|
| 23 |
|
|
| 24 |
experiment.stopCriteria2IFC=[75 3 5]; |
|
| 25 |
experiment.singleIntervalMaxTrials=[20]; |
|
| 26 |
|
|
| 27 |
|
|
| 28 |
% forced choice window interval |
|
| 29 |
stimulusParameters.AFCsilenceDuration=0.5; |
|
| 30 |
|
|
| 31 |
% instructions to user |
|
| 32 |
% single interval up/down no cue |
|
| 33 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 34 |
% single interval up/down with cue |
|
| 35 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| 36 |
|
|
| multithreshold 1.46/paradigms/paradigm_thr_TMC.m | ||
|---|---|---|
| 1 |
function paradigm_thr_TMC(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
betweenRuns.variableName1='targetFrequency'; |
|
| 7 |
betweenRuns.variableList1=1000; |
|
| 8 |
betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); |
|
| 9 |
betweenRuns.variableName2='targetDuration'; |
|
| 10 |
betweenRuns.variableList2=0.016; |
|
| 11 |
betweenRuns.randomizeSequence=1; % 'random sequence' |
|
| 12 |
|
|
| 13 |
% delay > masker > gap > target |
|
| 14 |
|
|
| 15 |
|
|
| 16 |
stimulusParameters.targetType='tone'; |
|
| 17 |
stimulusParameters.targetPhase='sin'; |
|
| 18 |
stimulusParameters.targetFrequency=1000; |
|
| 19 |
stimulusParameters.targetDuration=0.016; |
|
| 20 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 21 |
|
|
| 22 |
stimulusParameters.rampDuration=0.004; |
|
| 23 |
|
|
| 24 |
experiment.stopCriteria2IFC=[75 3 5]; |
|
| 25 |
experiment.singleIntervalMaxTrials=[20]; |
|
| 26 |
|
|
| 27 |
|
|
| 28 |
% forced choice window interval |
|
| 29 |
stimulusParameters.AFCsilenceDuration=0.5; |
|
| 30 |
|
|
| 31 |
% instructions to user |
|
| 32 |
% single interval up/down no cue |
|
| 33 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 34 |
% single interval up/down with cue |
|
| 35 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| 36 |
|
|
| multithreshold 1.46/paradigms/reserve team/OHIOthresholds.m | ||
|---|---|---|
| 1 |
function experiment=OHIOthresholds(experiment) |
|
| 2 |
|
|
| 3 |
experiment.OHIOfrequencies=[494, 663, 870, 1125, 1442, 1838, 2338, 2957, 3725, 4680, 5866, 7334]; %Hz. |
|
| 4 |
% User must specify abs thresholds (dB SPL) of each tone frequency |
|
| 5 |
experiment.OHIOthresholds= [ |
|
| 6 |
9.1 8.6 8.1 7.9 9.8 10.5 13.5 15.0 17.4 19.4 22.6 25.2 |
|
| 7 |
]; |
|
| multithreshold 1.46/paradigms/reserve team/paradigm_OHIOabs.m | ||
|---|---|---|
| 1 |
function paradigm_OHIOabs(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones |
|
| 7 |
% whose frequencies are chosen at random from a list (OHIOfrequencies) |
|
| 8 |
% All tones are presented at the same level (SL) computed using absolute |
|
| 9 |
% threshols specified in OHIOthresholds; |
|
| 10 |
% The duration of the complex is increased across runs and the number of tones is |
|
| 11 |
% controlled by OHIOdurations, (for each 20 ms a further tone is added. |
|
| 12 |
% The frequency of the tones is changed on each trial |
|
| 13 |
|
|
| 14 |
experiment.OHIOfrequencies=[494, 663, 870, 1125, 1442, 1838, 2338, 2957, 3725, 4680, 5866, 7334]; %Hz. |
|
| 15 |
% User must specify abs thresholds (dB SPL) of each tone frequency |
|
| 16 |
% experiment.OHIOthresholds= [18 16 16 19 20 22 24 26 27 30 32 35]; |
|
| 17 |
|
|
| 18 |
% assessment method |
|
| 19 |
% {'oneIntervalUpDown', 'MaxLikelihood', '2I2AFC++', '2I2AFC+++'}
|
|
| 20 |
experiment.threshEstMethod='oneIntervalUpDown'; |
|
| 21 |
% {'cued', 'noCue'};
|
|
| 22 |
|
|
| 23 |
stimulusParameters.WRVname='targetLevel'; |
|
| 24 |
stimulusParameters.WRVstartValues=20 ; |
|
| 25 |
stimulusParameters.WRVsteps=[10 2]; |
|
| 26 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 27 |
|
|
| 28 |
betweenRuns.variableName1='numOHIOtones'; |
|
| 29 |
betweenRuns.variableList1= 1:12; % i.e. the frequency to be used |
|
| 30 |
betweenRuns.variableName2='stimulusDelay'; |
|
| 31 |
betweenRuns.variableList2=0.05; |
|
| 32 |
betweenRuns.randomizeSequence=2; % not random sequence |
|
| 33 |
|
|
| 34 |
stimulusParameters.targetType='OHIO'; |
|
| 35 |
stimulusParameters.targetPhase='sin'; |
|
| 36 |
stimulusParameters.targetFrequency=experiment.OHIOfrequencies; |
|
| 37 |
stimulusParameters.targetDuration=0.01; % overruled by OHIO program |
|
| 38 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 39 |
|
|
| 40 |
stimulusParameters.rampDuration=0.005; |
|
| 41 |
|
|
| 42 |
% instructions to user |
|
| 43 |
% single interval up/down no cue |
|
| 44 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 45 |
% single interval up/down with cue |
|
| 46 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| 47 |
|
|
| multithreshold 1.46/paradigms/reserve team/paradigm_OHIOrand.m | ||
|---|---|---|
| 1 |
function paradigm_OHIOrand(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones |
|
| 7 |
% whose frequencies are chosen at random from a list (OHIOfrequencies) |
|
| 8 |
% All tones are presented at the same level (SL) computed using absolute |
|
| 9 |
% threshols specified in OHIOthresholds; |
|
| 10 |
% The duration of the complex is increased across runs and the number of tones is |
|
| 11 |
% controlled by OHIOdurations, (for each 20 ms a further tone is added. |
|
| 12 |
% The frequency of the tones is changed on each trial |
|
| 13 |
|
|
| 14 |
% fetch thresholds and frequencies |
|
| 15 |
experiment=OHIOthresholds(experiment); |
|
| 16 |
|
|
| 17 |
stimulusParameters.WRVname='targetLevel'; |
|
| 18 |
stimulusParameters.WRVstartValues=0 ; |
|
| 19 |
stimulusParameters.WRVsteps=[10 2]; |
|
| 20 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 21 |
|
|
| 22 |
betweenRuns.variableName1='numOHIOtones'; |
|
| 23 |
betweenRuns.variableList1= [1 2 4 8 12]; |
|
| 24 |
betweenRuns.variableName2='stimulusDelay'; |
|
| 25 |
betweenRuns.variableList2=0.1; |
|
| 26 |
betweenRuns.randomizeSequence=2; % not random sequence |
|
| 27 |
|
|
| 28 |
stimulusParameters.targetType='OHIO'; |
|
| 29 |
stimulusParameters.targetPhase='sin'; |
|
| 30 |
stimulusParameters.targetFrequency=experiment.OHIOfrequencies; |
|
| 31 |
stimulusParameters.targetDuration=betweenRuns.variableList2; |
|
| 32 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 33 |
|
|
| 34 |
stimulusParameters.rampDuration=0.005; |
|
| 35 |
|
|
| 36 |
% instructions to user |
|
| 37 |
% single interval up/down no cue |
|
| 38 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 39 |
% single interval up/down with cue |
|
| 40 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| 41 |
|
|
| multithreshold 1.46/paradigms/reserve team/paradigm_OHIOspect.m | ||
|---|---|---|
| 1 |
function paradigm_OHIOspect(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones |
|
| 7 |
% whose frequencies are chosen at random from a list (OHIOfrequencies) |
|
| 8 |
% All tones are presented at the same level (SL) computed using absolute |
|
| 9 |
% threshols specified in OHIOthresholds; |
|
| 10 |
% The duration of the complex is increased across runs and the number of tones is |
|
| 11 |
% controlled by OHIOdurations, (for each 20 ms a further tone is added. |
|
| 12 |
% The frequency of the tones is changed on each trial |
|
| 13 |
|
|
| 14 |
% fetch thresholds and frequencies |
|
| 15 |
experiment=OHIOthresholds(experiment); |
|
| 16 |
|
|
| 17 |
stimulusParameters.WRVname='targetLevel'; |
|
| 18 |
stimulusParameters.WRVstartValues=0 ; |
|
| 19 |
stimulusParameters.WRVsteps=[10 2]; |
|
| 20 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 21 |
|
|
| 22 |
betweenRuns.variableName1='numOHIOtones'; |
|
| 23 |
betweenRuns.variableList1= [1 2 4 8 12]; |
|
| 24 |
betweenRuns.variableName2='stimulusDelay'; |
|
| 25 |
betweenRuns.variableList2=0.1; |
|
| 26 |
betweenRuns.randomizeSequence=2; % not random sequence |
|
| 27 |
|
|
| 28 |
stimulusParameters.targetType='OHIO'; |
|
| 29 |
stimulusParameters.targetPhase='sin'; |
|
| 30 |
stimulusParameters.targetFrequency=experiment.OHIOfrequencies; |
|
| 31 |
stimulusParameters.targetDuration=betweenRuns.variableList2; |
|
| 32 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 33 |
|
|
| 34 |
stimulusParameters.rampDuration=0.005; |
|
| 35 |
|
|
| 36 |
% instructions to user |
|
| 37 |
% single interval up/down no cue |
|
| 38 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 39 |
% single interval up/down with cue |
|
| 40 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| 41 |
|
|
| multithreshold 1.46/paradigms/reserve team/paradigm_OHIOspectemp.m | ||
|---|---|---|
| 1 |
function paradigm_OHIOspectemp(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones |
|
| 7 |
% whose frequencies are chosen at random from a list (OHIOfrequencies) |
|
| 8 |
% All tones are presented at the same level (SL) computed using absolute |
|
| 9 |
% threshols specified in OHIOthresholds; |
|
| 10 |
% The duration of the complex is increased across runs and the number of tones is |
|
| 11 |
% controlled by OHIOdurations, (for each 20 ms a further tone is added. |
|
| 12 |
% The frequency of the tones is changed on each trial |
|
| 13 |
|
|
| 14 |
% fetch thresholds and frequencies |
|
| 15 |
experiment=OHIOthresholds(experiment); |
|
| 16 |
|
|
| 17 |
stimulusParameters.WRVname='targetLevel'; |
|
| 18 |
stimulusParameters.WRVstartValues=0 ; |
|
| 19 |
stimulusParameters.WRVsteps=[10 2]; |
|
| 20 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 21 |
|
|
| 22 |
betweenRuns.variableName1='numOHIOtones'; |
|
| 23 |
betweenRuns.variableList1= [1 2 4 8 12]; |
|
| 24 |
betweenRuns.variableName2='stimulusDelay'; |
|
| 25 |
betweenRuns.variableList2=0.1; |
|
| 26 |
betweenRuns.randomizeSequence=2; % not random sequence |
|
| 27 |
|
|
| 28 |
stimulusParameters.targetType='OHIO'; |
|
| 29 |
stimulusParameters.targetPhase='sin'; |
|
| 30 |
stimulusParameters.targetFrequency=experiment.OHIOfrequencies; |
|
| 31 |
stimulusParameters.targetDuration=betweenRuns.variableList2; |
|
| 32 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 33 |
|
|
| 34 |
stimulusParameters.rampDuration=0.005; |
|
| 35 |
|
|
| 36 |
% instructions to user |
|
| 37 |
% single interval up/down no cue |
|
| 38 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 39 |
% single interval up/down with cue |
|
| 40 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| multithreshold 1.46/paradigms/reserve team/paradigm_OHIOtemp.m | ||
|---|---|---|
| 1 |
function paradigm_OHIOtemp(handles) |
|
| 2 |
global stimulusParameters experiment betweenRuns |
|
| 3 |
|
|
| 4 |
paradigm_training(handles) % default |
|
| 5 |
|
|
| 6 |
% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones |
|
| 7 |
% whose frequencies are chosen at random from a list (OHIOfrequencies) |
|
| 8 |
% All tones are presented at the same level (SL) computed using absolute |
|
| 9 |
% threshols specified in OHIOthresholds; |
|
| 10 |
% The duration of the complex is increased across runs and the number of tones is |
|
| 11 |
% controlled by OHIOdurations, (for each 20 ms a further tone is added. |
|
| 12 |
% The frequency of the tones is changed on each trial |
|
| 13 |
|
|
| 14 |
% fetch thresholds and frequencies |
|
| 15 |
experiment=OHIOthresholds(experiment); |
|
| 16 |
|
|
| 17 |
stimulusParameters.WRVname='targetLevel'; |
|
| 18 |
stimulusParameters.WRVstartValues=0 ; |
|
| 19 |
stimulusParameters.WRVsteps=[10 2]; |
|
| 20 |
stimulusParameters.WRVlimits=[-30 110]; |
|
| 21 |
% target variable: slope=1, start going down. |
|
| 22 |
stimulusParameters.cueTestDifference=10; |
|
| 23 |
experiment.psyFunSlope= 1; |
|
| 24 |
withinRuns.direction='down'; |
|
| 25 |
|
|
| 26 |
betweenRuns.variableName1='numOHIOtones'; |
|
| 27 |
betweenRuns.variableList1= [1 2 4 8 12]; |
|
| 28 |
betweenRuns.variableName2='stimulusDelay'; |
|
| 29 |
betweenRuns.variableList2=0.1; |
|
| 30 |
betweenRuns.randomizeSequence=2; % not random sequence |
|
| 31 |
|
|
| 32 |
stimulusParameters.targetType='OHIO'; |
|
| 33 |
stimulusParameters.targetPhase='sin'; |
|
| 34 |
stimulusParameters.targetFrequency=experiment.OHIOfrequencies; |
|
| 35 |
stimulusParameters.targetDuration=betweenRuns.variableList2; |
|
| 36 |
stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); |
|
| 37 |
|
|
| 38 |
stimulusParameters.rampDuration=0.005; |
|
| 39 |
|
|
| 40 |
% instructions to user |
|
| 41 |
% single interval up/down no cue |
|
| 42 |
stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}];
|
|
| 43 |
% single interval up/down with cue |
|
| 44 |
stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
|
|
| multithreshold 1.46/testAN.m | ||
|---|---|---|
| 1 |
function vectorStrength=testAN(targetFrequency,BFlist, levels) |
|
| 2 |
% testIHC used either for IHC I/O function ... |
|
| 3 |
% or receptive field (doReceptiveFields=1) |
|
| 4 |
|
|
| 5 |
global experiment method stimulusParameters |
|
| 6 |
global IHC_VResp_VivoParams IHC_cilia_RPParams IHCpreSynapseParams |
|
| 7 |
global AN_IHCsynapseParams |
|
| 8 |
|
|
| 9 |
global ANoutput ANdt CNoutput ICoutput ICmembraneOutput tauCas |
|
| 10 |
global ARattenuation MOCattenuation |
|
| 11 |
|
|
| 12 |
dbstop if error |
|
| 13 |
|
|
| 14 |
addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... |
|
| 15 |
['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... |
|
| 16 |
['..' filesep 'testPrograms']) |
|
| 17 |
|
|
| 18 |
if nargin<3 |
|
| 19 |
levels=-10:10:80; |
|
| 20 |
% levels=80:10:90; |
|
| 21 |
end |
|
| 22 |
|
|
| 23 |
nLevels=length(levels); |
|
| 24 |
|
|
| 25 |
toneDuration=.2; |
|
| 26 |
rampDuration=0.002; |
|
| 27 |
silenceDuration=.02; |
|
| 28 |
localPSTHbinwidth=0.001; |
|
| 29 |
|
|
| 30 |
% Use only the first frequency in the GUI targetFrequency box to defineBF |
|
| 31 |
% targetFrequency=stimulusParameters.targetFrequency(1); |
|
| 32 |
% BFlist=targetFrequency; |
|
| 33 |
|
|
| 34 |
AN_HSRonset=zeros(nLevels,1); |
|
| 35 |
AN_HSRsaturated=zeros(nLevels,1); |
|
| 36 |
AN_LSRonset=zeros(nLevels,1); |
|
| 37 |
AN_LSRsaturated=zeros(nLevels,1); |
|
| 38 |
CNLSRrate=zeros(nLevels,1); |
|
| 39 |
CNHSRsaturated=zeros(nLevels,1); |
|
| 40 |
ICHSRsaturated=zeros(nLevels,1); |
|
| 41 |
ICLSRsaturated=zeros(nLevels,1); |
|
| 42 |
vectorStrength=zeros(nLevels,1); |
|
| 43 |
|
|
| 44 |
AR=zeros(nLevels,1); |
|
| 45 |
MOC=zeros(nLevels,1); |
|
| 46 |
|
|
| 47 |
% ANoutput=zeros(200,200); |
|
| 48 |
|
|
| 49 |
figure(15), clf |
|
| 50 |
set(gcf,'position',[980 356 401 321]) |
|
| 51 |
figure(5), clf |
|
| 52 |
set(gcf,'position', [980 34 400 295]) |
|
| 53 |
drawnow |
|
| 54 |
|
|
| 55 |
%% guarantee that the sample rate is at least 10 times the frequency |
|
| 56 |
sampleRate=50000; |
|
| 57 |
while sampleRate< 10* targetFrequency |
|
| 58 |
sampleRate=sampleRate+10000; |
|
| 59 |
end |
|
| 60 |
|
|
| 61 |
%% adjust sample rate so that the pure tone stimulus has an integer |
|
| 62 |
%% numver of epochs in a period |
|
| 63 |
dt=1/sampleRate; |
|
| 64 |
period=1/targetFrequency; |
|
| 65 |
ANspeedUpFactor=5; %anticipating MAP (needs clearing up) |
|
| 66 |
ANdt=dt*ANspeedUpFactor; |
|
| 67 |
ANdt=period/round(period/ANdt); |
|
| 68 |
dt=ANdt/ANspeedUpFactor; |
|
| 69 |
sampleRate=1/dt; |
|
| 70 |
epochsPerPeriod=sampleRate*period; |
|
| 71 |
|
|
| 72 |
%% main computational loop (vary level) |
|
| 73 |
levelNo=0; |
|
| 74 |
for leveldB=levels |
|
| 75 |
levelNo=levelNo+1; |
|
| 76 |
|
|
| 77 |
fprintf('%4.0f\t', leveldB)
|
|
| 78 |
amp=28e-6*10^(leveldB/20); |
|
| 79 |
|
|
| 80 |
time=dt:dt:toneDuration; |
|
| 81 |
rampTime=dt:dt:rampDuration; |
|
| 82 |
ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... |
|
| 83 |
ones(1,length(time)-length(rampTime))]; |
|
| 84 |
ramp=ramp.*fliplr(ramp); |
|
| 85 |
|
|
| 86 |
silence=zeros(1,round(silenceDuration/dt)); |
|
| 87 |
|
|
| 88 |
% create signal (leveldB/ targetFrequency) |
|
| 89 |
inputSignal=amp*sin(2*pi*targetFrequency'*time); |
|
| 90 |
inputSignal= ramp.*inputSignal; |
|
| 91 |
inputSignal=[silence inputSignal]; |
|
| 92 |
|
|
| 93 |
%% run the model |
|
| 94 |
AN_spikesOrProbability='spikes'; |
|
| 95 |
MAPparamsName=experiment.name; |
|
| 96 |
showPlotsAndDetails=0; |
|
| 97 |
|
|
| 98 |
|
|
| 99 |
MAP1_14(inputSignal, 1/dt, BFlist, ... |
|
| 100 |
MAPparamsName, AN_spikesOrProbability); |
|
| 101 |
|
|
| 102 |
nTaus=length(tauCas); |
|
| 103 |
|
|
| 104 |
%LSR (same as HSR if no LSR fibers present) |
|
| 105 |
[nANFibers nTimePoints]=size(ANoutput); |
|
| 106 |
|
|
| 107 |
numLSRfibers=nANFibers/nTaus; |
|
| 108 |
numHSRfibers=numLSRfibers; |
|
| 109 |
|
|
| 110 |
LSRspikes=ANoutput(1:numLSRfibers,:); |
|
| 111 |
PSTH=UTIL_PSTHmaker(LSRspikes, ANdt, localPSTHbinwidth); |
|
| 112 |
PSTHLSR=mean(PSTH,1)/localPSTHbinwidth; % across fibers rates |
|
| 113 |
PSTHtime=localPSTHbinwidth:localPSTHbinwidth:... |
|
| 114 |
localPSTHbinwidth*length(PSTH); |
|
| 115 |
AN_LSRonset(levelNo)= max(PSTHLSR); % peak in 5 ms window |
|
| 116 |
AN_LSRsaturated(levelNo)= mean(PSTHLSR(round(length(PSTH)/2):end)); |
|
| 117 |
|
|
| 118 |
% HSR |
|
| 119 |
HSRspikes= ANoutput(end- numHSRfibers+1:end, :); |
|
| 120 |
PSTH=UTIL_PSTHmaker(HSRspikes, ANdt, localPSTHbinwidth); |
|
| 121 |
PSTH=mean(PSTH,1)/localPSTHbinwidth; % sum across fibers (HSR only) |
|
| 122 |
AN_HSRonset(levelNo)= max(PSTH); |
|
| 123 |
AN_HSRsaturated(levelNo)= mean(PSTH(round(length(PSTH)/2): end)); |
|
| 124 |
|
|
| 125 |
figure(5), subplot(2,2,2) |
|
| 126 |
hold off, bar(PSTHtime,PSTH, 'b') |
|
| 127 |
hold on, bar(PSTHtime,PSTHLSR,'r') |
|
| 128 |
ylim([0 1000]) |
|
| 129 |
xlim([0 length(PSTH)*localPSTHbinwidth]) |
|
| 130 |
set(gcf,'name',[num2str(BFlist), ' Hz: ' num2str(leveldB) ' dB']); |
|
| 131 |
|
|
| 132 |
% AN - CV |
|
| 133 |
% CV is computed 5 times. Use the middle one (3) as most typical |
|
| 134 |
cvANHSR= UTIL_CV(HSRspikes, ANdt); |
|
| 135 |
|
|
| 136 |
% AN - vector strength |
|
| 137 |
PSTH=sum(HSRspikes); |
|
| 138 |
[PH, binTimes]=UTIL_periodHistogram... |
|
| 139 |
(PSTH, ANdt, targetFrequency); |
|
| 140 |
VS=UTIL_vectorStrength(PH); |
|
| 141 |
vectorStrength(levelNo)=VS; |
|
| 142 |
disp(['sat rate= ' num2str(AN_HSRsaturated(levelNo)) ... |
|
| 143 |
'; phase-locking VS = ' num2str(VS)]) |
|
| 144 |
title(['AN HSR: CV=' num2str(cvANHSR(3),'%5.2f') ... |
|
| 145 |
'VS=' num2str(VS,'%5.2f')]) |
|
| 146 |
|
|
| 147 |
% CN - first-order neurons |
|
| 148 |
|
|
| 149 |
% CN LSR |
|
| 150 |
[nCNneurons c]=size(CNoutput); |
|
| 151 |
nLSRneurons=round(nCNneurons/nTaus); |
|
| 152 |
CNLSRspikes=CNoutput(1:nLSRneurons,:); |
|
| 153 |
PSTH=UTIL_PSTHmaker(CNLSRspikes, ANdt, localPSTHbinwidth); |
|
| 154 |
PSTH=sum(PSTH)/nLSRneurons; |
|
| 155 |
CNLSRrate(levelNo)=mean(PSTH(round(length(PSTH)/2):end))/localPSTHbinwidth; |
|
| 156 |
|
|
| 157 |
%CN HSR |
|
| 158 |
MacGregorMultiHSRspikes=... |
|
| 159 |
CNoutput(end-nLSRneurons:end,:); |
|
| 160 |
PSTH=UTIL_PSTHmaker(MacGregorMultiHSRspikes, ANdt, localPSTHbinwidth); |
|
| 161 |
PSTH=sum(PSTH)/nLSRneurons; |
|
| 162 |
PSTH=mean(PSTH,1)/localPSTHbinwidth; % sum across fibers (HSR only) |
|
| 163 |
|
|
| 164 |
CNHSRsaturated(levelNo)=mean(PSTH(length(PSTH)/2:end)); |
|
| 165 |
|
|
| 166 |
figure(5), subplot(2,2,3) |
|
| 167 |
bar(PSTHtime,PSTH) |
|
| 168 |
ylim([0 1000]) |
|
| 169 |
xlim([0 length(PSTH)*localPSTHbinwidth]) |
|
| 170 |
cvMMHSR= UTIL_CV(MacGregorMultiHSRspikes, ANdt); |
|
| 171 |
title(['CN CV= ' num2str(cvMMHSR(3),'%5.2f')]) |
|
| 172 |
|
|
| 173 |
% IC LSR |
|
| 174 |
[nICneurons c]=size(ICoutput); |
|
| 175 |
nLSRneurons=round(nICneurons/nTaus); |
|
| 176 |
ICLSRspikes=ICoutput(1:nLSRneurons,:); |
|
| 177 |
PSTH=UTIL_PSTHmaker(ICLSRspikes, ANdt, localPSTHbinwidth); |
|
| 178 |
ICLSRsaturated(levelNo)=mean(PSTH(round(length(PSTH)/2):end))/localPSTHbinwidth; |
|
| 179 |
|
|
| 180 |
%IC HSR |
|
| 181 |
MacGregorMultiHSRspikes=... |
|
| 182 |
ICoutput(end-nLSRneurons:end,:); |
|
| 183 |
PSTH=UTIL_PSTHmaker(MacGregorMultiHSRspikes, ANdt, localPSTHbinwidth); |
|
| 184 |
PSTH=sum(PSTH)/nLSRneurons; |
|
| 185 |
PSTH=mean(PSTH,1)/localPSTHbinwidth; % sum across fibers (HSR only) |
|
| 186 |
|
|
| 187 |
ICHSRsaturated(levelNo)=mean(PSTH(length(PSTH)/2:end)); |
|
| 188 |
|
|
| 189 |
AR(levelNo)=min(ARattenuation); |
|
| 190 |
MOC(levelNo)=min(MOCattenuation(length(MOCattenuation)/2:end)); |
|
| 191 |
|
|
| 192 |
time=dt:dt:dt*size(ICmembraneOutput,2); |
|
| 193 |
figure(5), subplot(2,2,4) |
|
| 194 |
plot(time,ICmembraneOutput(2, 1:end),'k') |
|
| 195 |
ylim([-0.07 0]) |
|
| 196 |
xlim([0 max(time)]) |
|
| 197 |
title(['IC ' num2str(leveldB,'%4.0f') 'dB']) |
|
| 198 |
drawnow |
|
| 199 |
|
|
| 200 |
figure(5), subplot(2,2,1) |
|
| 201 |
plot(20*log10(MOC), 'k'), |
|
| 202 |
title(' MOC'), ylabel('dB attenuation')
|
|
| 203 |
ylim([-30 0]) |
|
| 204 |
|
|
| 205 |
|
|
| 206 |
end % level |
|
| 207 |
figure(5), subplot(2,2,1) |
|
| 208 |
plot(levels,20*log10(MOC), 'k'), |
|
| 209 |
title(' MOC'), ylabel('dB attenuation')
|
|
| 210 |
ylim([-30 0]) |
|
| 211 |
xlim([0 max(levels)]) |
|
| 212 |
|
|
| 213 |
fprintf('\n')
|
|
| 214 |
toneDuration=2; |
|
| 215 |
rampDuration=0.004; |
|
| 216 |
silenceDuration=.02; |
|
| 217 |
nRepeats=200; % no. of AN fibers |
|
| 218 |
fprintf('toneDuration %6.3f\n', toneDuration)
|
|
| 219 |
fprintf(' %6.0f AN fibers (repeats)\n', nRepeats)
|
|
| 220 |
fprintf('levels')
|
|
| 221 |
fprintf('%6.2f\t', levels)
|
|
| 222 |
fprintf('\n')
|
|
| 223 |
|
|
| 224 |
|
|
| 225 |
% ---------------------------------------------------- display parameters |
|
| 226 |
|
|
| 227 |
figure(15), clf |
|
| 228 |
nRows=2; nCols=2; |
|
| 229 |
|
|
| 230 |
% AN rate - level ONSET functions |
|
| 231 |
subplot(nRows,nCols,1) |
|
| 232 |
plot(levels,AN_LSRonset,'ro'), hold on |
|
| 233 |
plot(levels,AN_HSRonset,'ko'), hold off |
|
| 234 |
ylim([0 1000]), xlim([min(levels) max(levels)]) |
|
| 235 |
ttl=['tauCa= ' num2str(IHCpreSynapseParams.tauCa)]; |
|
| 236 |
title( ttl) |
|
| 237 |
xlabel('level dB SPL'), ylabel('peak rate (sp/s)'), grid on
|
|
| 238 |
text(0, 800, 'AN onset', 'fontsize', 16) |
|
| 239 |
|
|
| 240 |
% AN rate - level ADAPTED function |
|
| 241 |
subplot(nRows,nCols,2) |
|
| 242 |
plot(levels,AN_LSRsaturated, 'ro'), hold on |
|
| 243 |
plot(levels,AN_HSRsaturated, 'ko'), hold off |
|
| 244 |
ylim([0 400]) |
|
| 245 |
set(gca,'ytick',0:50:300) |
|
| 246 |
xlim([min(levels) max(levels)]) |
|
| 247 |
set(gca,'xtick',[levels(1):20:levels(end)]) |
|
| 248 |
% grid on |
|
| 249 |
ttl=[ 'spont=' num2str(mean(AN_HSRsaturated(1,:)),'%4.0f')... |
|
| 250 |
' sat=' num2str(mean(AN_HSRsaturated(end,1)),'%4.0f')]; |
|
| 251 |
title( ttl) |
|
| 252 |
xlabel('level dB SPL'), ylabel ('adapted rate (sp/s)')
|
|
| 253 |
text(0, 340, 'AN adapted', 'fontsize', 16), grid on |
|
| 254 |
|
|
| 255 |
% CN rate - level ADAPTED function |
|
| 256 |
subplot(nRows,nCols,3) |
|
| 257 |
plot(levels,CNLSRrate, 'ro'), hold on |
|
| 258 |
plot(levels,CNHSRsaturated, 'ko'), hold off |
|
| 259 |
ylim([0 400]) |
|
| 260 |
set(gca,'ytick',0:50:300) |
|
| 261 |
xlim([min(levels) max(levels)]) |
|
| 262 |
set(gca,'xtick',[levels(1):20:levels(end)]) |
|
| 263 |
% grid on |
|
| 264 |
ttl=[ 'spont=' num2str(mean(CNHSRsaturated(1,:)),'%4.0f') ' sat=' ... |
|
| 265 |
num2str(mean(CNHSRsaturated(end,1)),'%4.0f')]; |
|
| 266 |
title( ttl) |
|
| 267 |
xlabel('level dB SPL'), ylabel ('adapted rate (sp/s)')
|
|
| 268 |
text(0, 350, 'CN', 'fontsize', 16), grid on |
|
| 269 |
|
|
| 270 |
% IC rate - level ADAPTED function |
|
| 271 |
subplot(nRows,nCols,4) |
|
| 272 |
plot(levels,ICLSRsaturated, 'ro'), hold on |
|
| 273 |
plot(levels,ICHSRsaturated, 'ko'), hold off |
|
| 274 |
ylim([0 400]) |
|
| 275 |
set(gca,'ytick',0:50:300) |
|
| 276 |
xlim([min(levels) max(levels)]) |
|
| 277 |
set(gca,'xtick',[levels(1):20:levels(end)]), grid on |
|
| 278 |
|
|
| 279 |
|
|
| 280 |
ttl=['spont=' num2str(mean(ICHSRsaturated(1,:)),'%4.0f') ... |
|
| 281 |
' sat=' num2str(mean(ICHSRsaturated(end,1)),'%4.0f')]; |
|
| 282 |
title( ttl) |
|
| 283 |
xlabel('level dB SPL'), ylabel ('adapted rate (sp/s)')
|
|
| 284 |
text(0, 350, 'IC', 'fontsize', 16) |
|
| 285 |
set(gcf,'name',' AN CN IC rate/level') |
|
| 286 |
|
|
| 287 |
peakVectorStrength=max(vectorStrength); |
|
| 288 |
|
|
| 289 |
fprintf('\n')
|
|
| 290 |
disp('levels vectorStrength')
|
|
| 291 |
fprintf('%3.0f \t %6.4f \n', [levels; vectorStrength'])
|
|
| 292 |
fprintf('\n')
|
|
| 293 |
fprintf('Phase locking, max vector strength=\t %6.4f\n\n',...
|
|
| 294 |
max(vectorStrength)) |
|
| 295 |
|
|
| 296 |
allData=[ levels' AN_HSRonset AN_HSRsaturated... |
|
| 297 |
AN_LSRonset AN_LSRsaturated ... |
|
| 298 |
CNHSRsaturated CNLSRrate... |
|
| 299 |
ICHSRsaturated ICLSRsaturated]; |
|
| 300 |
fprintf('\n levels \tANHSR Onset \tANHSR adapted\tANLSR Onset \tANLSR adapted\tCNHSR\tCNLSR\tICHSR \tICLSR \n');
|
|
| 301 |
UTIL_printTabTable(round(allData)) |
|
| 302 |
fprintf('VS (phase locking)= \t%6.4f\n\n',...
|
|
| 303 |
max(vectorStrength)) |
|
| 304 |
|
|
| 305 |
UTIL_showStruct(IHC_cilia_RPParams, 'IHC_cilia_RPParams') |
|
| 306 |
UTIL_showStruct(IHCpreSynapseParams, 'IHCpreSynapseParams') |
|
| 307 |
UTIL_showStruct(AN_IHCsynapseParams, 'AN_IHCsynapseParams') |
|
| 308 |
|
|
| 309 |
fprintf('\n')
|
|
| 310 |
disp('levels vectorStrength')
|
|
| 311 |
fprintf('%3.0f \t %6.4f \n', [levels; vectorStrength'])
|
|
| 312 |
fprintf('\n')
|
|
| 313 |
fprintf('Phase locking, max vector strength= \t%6.4f\n\n',...
|
|
| 314 |
max(vectorStrength)) |
|
| 315 |
|
|
| 316 |
allData=[ levels' AN_HSRonset AN_HSRsaturated... |
|
| 317 |
AN_LSRonset AN_LSRsaturated ... |
|
| 318 |
CNHSRsaturated CNLSRrate... |
|
| 319 |
ICHSRsaturated ICLSRsaturated]; |
|
| 320 |
fprintf('\n levels \tANHSR Onset \tANHSR adapted\tANLSR Onset \tANLSR adapted\tCNHSR\tCNLSR\tICHSR \tICLSR \n');
|
|
| 321 |
UTIL_printTabTable(round(allData)) |
|
| 322 |
fprintf('VS (phase locking)= \t%6.4f\n\n',...
|
|
| 323 |
max(vectorStrength)) |
|
| 324 |
|
|
| multithreshold 1.46/testBM.m | ||
|---|---|---|
| 1 |
function testBM (BMlocations, paramsName,relativeFrequencies) |
|
| 2 |
% testBM generates input output functions for DRNL model for any number |
|
| 3 |
% of locations. |
|
| 4 |
% Computations are bast on a single channel model (channelBFs=BF) |
|
| 5 |
% peak displacement (peakAmp) is measured. |
|
| 6 |
% if DRNLParams.useMOC is chosen, the full model is run (slow) |
|
| 7 |
% otherwise only DRNL is computed. |
|
| 8 |
% Tuning curves are generated based on a range of frequencies reletove to |
|
| 9 |
% the BF of the location. |
|
| 10 |
% |
|
| 11 |
|
|
| 12 |
global DRNLParams |
|
| 13 |
|
|
| 14 |
savePath=path; |
|
| 15 |
|
|
| 16 |
addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) |
|
| 17 |
|
|
| 18 |
levels=-10:10:90; nLevels=length(levels); |
|
| 19 |
% levels= 50; nLevels=length(levels); |
|
| 20 |
|
|
| 21 |
% refBMdisplacement is the displacement of the BM at threshold |
|
| 22 |
% 1 nm disp at threshold (9 kHz, Ruggero) |
|
| 23 |
refBMdisplacement= 1e-8; % adjusted for 10 nm at 1 kHz |
|
| 24 |
|
|
| 25 |
toneDuration=.200; |
|
| 26 |
rampDuration=0.01; |
|
| 27 |
silenceDuration=0.01; |
|
| 28 |
|
|
| 29 |
sampleRate=30000; |
|
| 30 |
|
|
| 31 |
dbstop if error |
|
| 32 |
figure(3), clf |
|
| 33 |
set(gcf,'position',[280 350 327 326]) |
|
| 34 |
set(gcf,'name','DRNL - BM') |
|
| 35 |
pause(0.1) |
|
| 36 |
|
|
| 37 |
finalSummary=[]; |
|
| 38 |
nBFs=length(BMlocations); |
|
| 39 |
BFno=0; plotCount=0; |
|
| 40 |
for BF=BMlocations |
|
| 41 |
BFno=BFno+1; |
|
| 42 |
plotCount=plotCount+nBFs; |
|
| 43 |
stimulusFrequencies=BF* relativeFrequencies; |
|
| 44 |
nFrequencies=length(stimulusFrequencies); |
|
| 45 |
|
|
| 46 |
peakAmpBM=zeros(nLevels,nFrequencies); |
|
| 47 |
peakAmpBMdB=NaN(nLevels,nFrequencies); |
|
| 48 |
peakEfferent=NaN(nLevels,nFrequencies); |
|
| 49 |
peakAREfferent=NaN(nLevels,nFrequencies); |
|
| 50 |
|
|
| 51 |
|
|
| 52 |
levelNo=0; |
|
| 53 |
for leveldB=levels |
|
| 54 |
disp(['level= ' num2str(leveldB)]) |
|
| 55 |
levelNo=levelNo+1; |
|
| 56 |
|
|
| 57 |
freqNo=0; |
|
| 58 |
for frequency=stimulusFrequencies |
|
| 59 |
freqNo=freqNo+1; |
|
| 60 |
|
|
| 61 |
% Generate stimuli |
|
| 62 |
globalStimParams.FS=sampleRate; |
|
| 63 |
globalStimParams.overallDuration=... |
|
| 64 |
toneDuration+silenceDuration; % s |
|
| 65 |
stim.phases='sin'; |
|
| 66 |
stim.type='tone'; |
|
| 67 |
stim.toneDuration=toneDuration; |
|
| 68 |
stim.frequencies=frequency; |
|
| 69 |
stim.amplitudesdB=leveldB; |
|
| 70 |
stim.beginSilence=silenceDuration; |
|
| 71 |
stim.rampOnDur=rampDuration; |
|
| 72 |
% no offset ramp |
|
| 73 |
stim.rampOffDur=rampDuration; |
|
| 74 |
doPlot=0; |
|
| 75 |
inputSignal=stimulusCreate(globalStimParams, stim, doPlot); |
|
| 76 |
inputSignal=inputSignal(:,1)'; |
|
| 77 |
|
|
| 78 |
%% run the model |
|
| 79 |
MAPparamsName=paramsName; |
|
| 80 |
AN_spikesOrProbability='probability'; |
|
| 81 |
% AN_spikesOrProbability='spikes'; |
|
| 82 |
|
|
| 83 |
global DRNLoutput MOCattenuation ARattenuation |
|
| 84 |
MAP1_14(inputSignal, sampleRate, BF, ... |
|
| 85 |
MAPparamsName, AN_spikesOrProbability); |
|
| 86 |
|
|
| 87 |
DRNLresponse=DRNLoutput; |
|
| 88 |
peakAmp=max(max(... |
|
| 89 |
DRNLresponse(:, end-round(length(DRNLresponse)/2):end))); |
|
| 90 |
peakAmpBM(levelNo,freqNo)=peakAmp; |
|
| 91 |
peakAmpBMdB(levelNo,freqNo)=... |
|
| 92 |
20*log10(peakAmp/refBMdisplacement); |
|
| 93 |
peakEfferent(levelNo,freqNo)=min(min(MOCattenuation)); |
|
| 94 |
peakAREfferent(levelNo,freqNo)=min(min(ARattenuation)); |
|
| 95 |
|
|
| 96 |
end % tone frequency |
|
| 97 |
end % level |
|
| 98 |
|
|
| 99 |
%% analyses results and plot |
|
| 100 |
|
|
| 101 |
% BM I/O plot (top panel) |
|
| 102 |
figure(3) |
|
| 103 |
subplot(3,nBFs,BFno), cla |
|
| 104 |
plot(levels,peakAmpBMdB, 'linewidth',2) |
|
| 105 |
hold on, plot(levels, repmat(refBMdisplacement,1,length(levels))) |
|
| 106 |
hold off |
|
| 107 |
title(['BF=' num2str(BF,'%5.0f') ' - ' paramsName]) |
|
| 108 |
xlabel('level')
|
|
| 109 |
% set(gca,'xtick',levels), grid on |
|
| 110 |
if length(levels)>1,xlim([min(levels) max(levels)]), end |
|
| 111 |
ylabel(['dB re:' num2str(refBMdisplacement,'%6.1e') 'm']) |
|
| 112 |
ylim([-20 50]) |
|
| 113 |
set(gca,'ytick',[-10 0 10 20 40]) |
|
| 114 |
grid on |
|
| 115 |
% legend({num2str(stimulusFrequencies')}, 'location', 'EastOutside')
|
|
| 116 |
UTIL_printTabTable([levels' peakAmpBMdB], ... |
|
| 117 |
num2str([0 stimulusFrequencies]','%5.0f'), '%5.0f') |
|
| 118 |
finalSummary=[finalSummary peakAmpBMdB]; |
|
| 119 |
|
|
| 120 |
% Tuning curve |
|
| 121 |
if length(relativeFrequencies)>2 |
|
| 122 |
figure(3), subplot(3,nBFs, 2*nBFs+BFno) |
|
| 123 |
% contour(stimulusFrequencies,levels,peakAmpBM,... |
|
| 124 |
% [refBMdisplacement refBMdisplacement],'r') |
|
| 125 |
contour(stimulusFrequencies,levels,peakAmpBM,... |
|
| 126 |
refBMdisplacement.*[1 5 10 50 100]) |
|
| 127 |
title(['tuning curve at ' num2str(refBMdisplacement) 'm']); |
|
| 128 |
ylabel('level (dB) at reference')
|
|
| 129 |
xlim([100 10000]) |
|
| 130 |
grid on |
|
| 131 |
hold on |
|
| 132 |
set(gca,'xscale','log') |
|
| 133 |
end |
|
| 134 |
|
|
| 135 |
|
|
| 136 |
% MOC contribution |
|
| 137 |
figure(3) |
|
| 138 |
subplot(3,nBFs,nBFs+BFno), cla |
|
| 139 |
plot(levels,20*log10(peakEfferent), 'linewidth',2) |
|
| 140 |
ylabel('MOC (dB attenuation)'), xlabel('level')
|
|
| 141 |
title(['peak MOC: model= ' AN_spikesOrProbability]) |
|
| 142 |
grid on |
|
| 143 |
if length(levels)>1, xlim([min(levels) max(levels)]), end |
|
| 144 |
|
|
| 145 |
% AR contribution |
|
| 146 |
hold on |
|
| 147 |
plot(levels,20*log10(peakAREfferent), 'r') |
|
| 148 |
hold off |
|
| 149 |
|
|
| 150 |
end % best frequency |
|
| 151 |
|
|
| 152 |
UTIL_showStructureSummary(DRNLParams, 'DRNLParams', 10) |
|
| 153 |
|
|
| 154 |
UTIL_printTabTable([levels' finalSummary], ... |
|
| 155 |
num2str([0 stimulusFrequencies]','%5.0f'), '%5.0f') |
|
| 156 |
|
|
| 157 |
path(savePath); |
|
| multithreshold 1.46/testFM.m | ||
|---|---|---|
| 1 |
function testFM(BFlist,paramsName,showPSTHs) |
|
| 2 |
% specify whether you want AN 'probability' or 'spikes' |
|
| 3 |
% spikes is more realistic but takes longer |
|
| 4 |
% refractory effect is included only for spikes |
|
| 5 |
% |
|
| 6 |
|
|
| 7 |
% specify the AN ANresponse bin width (normally 1 ms). |
|
| 8 |
% This can influence the measure of the AN onset rate based on the |
|
| 9 |
% largest bin in the ANresponse |
|
| 10 |
% |
|
| 11 |
% Demonstration is based on Harris and Dallos |
|
| 12 |
|
|
| 13 |
global inputStimulusParams outerMiddleEarParams DRNLParams |
|
| 14 |
global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams |
|
| 15 |
|
|
| 16 |
dbstop if error |
|
| 17 |
% masker and probe levels are relative to this threshold |
|
| 18 |
thresholdAtCF=10; % dB SPL |
|
| 19 |
thresholdAtCF=5; % dB SPL |
|
| 20 |
|
|
| 21 |
if nargin<1, showPSTHs=1;end |
|
| 22 |
|
|
| 23 |
sampleRate=50000; |
|
| 24 |
|
|
| 25 |
% fetch BF from GUI: use only the first target frequency |
|
| 26 |
maskerFrequency=BFlist; |
|
| 27 |
maskerDuration=.1; |
|
| 28 |
|
|
| 29 |
targetFrequency=maskerFrequency; |
|
| 30 |
probeLeveldB=20+thresholdAtCF; % H&D use 20 dB SL/ TMC uses 10 dB SL |
|
| 31 |
probeDuration=0.008; % HD use 15 ms probe (fig 3). |
|
| 32 |
probeDuration=0.015; % HD use 15 ms probe (fig 3). |
|
| 33 |
|
|
| 34 |
rampDuration=.001; % HD use 1 ms linear ramp |
|
| 35 |
initialSilenceDuration=0.02; |
|
| 36 |
finalSilenceDuration=0.05; % useful for showing recovery |
|
| 37 |
|
|
| 38 |
maskerLevels=[-80 10 20 30 40 60 ] + thresholdAtCF; |
|
| 39 |
% maskerLevels=[-80 40 60 ] + thresholdAtCF; |
|
| 40 |
|
|
| 41 |
dt=1/sampleRate; |
|
| 42 |
|
|
| 43 |
figure(7), clf |
|
| 44 |
set(gcf,'position',[613 36 360 247]) |
|
| 45 |
set(gcf,'name', ['forward masking: thresholdAtCF=' num2str(thresholdAtCF)]) |
|
| 46 |
|
|
| 47 |
if showPSTHs |
|
| 48 |
figure(8), clf |
|
| 49 |
set(gcf,'name', 'Harris and Dallos simulation') |
|
| 50 |
set(gcf,'position',[980 36 380 249]) |
|
| 51 |
end |
|
| 52 |
|
|
| 53 |
% Plot Harris and Dallos result for comparison |
|
| 54 |
gapDurations=[0.001 0.002 0.005 0.01 0.02 0.05 0.1 0.3]; |
|
| 55 |
HDmaskerLevels=[+10 +20 +30 +40 +60]; |
|
| 56 |
HDresponse=[ |
|
| 57 |
1 1 1 1 1 1 1 1; |
|
| 58 |
0.8 0.82 0.81 0.83 0.87 0.95 1 1; |
|
| 59 |
0.48 0.5 0.54 0.58 0.7 0.85 0.95 1; |
|
| 60 |
0.3 0.31 0.35 0.4 0.5 0.68 0.82 0.94; |
|
| 61 |
0.2 0.27 0.27 0.29 0.42 0.64 0.75 0.92; |
|
| 62 |
0.15 0.17 0.18 0.23 0.3 0.5 0.6 0.82]; |
|
| 63 |
|
|
| 64 |
figure(7) |
|
| 65 |
semilogx(gapDurations,HDresponse,'o'), hold on |
|
| 66 |
legend(strvcat(num2str(maskerLevels')),'location','southeast') |
|
| 67 |
title([ 'masker dB: ' num2str(HDmaskerLevels)]) |
|
| 68 |
|
|
| 69 |
%% Run the trials |
|
| 70 |
maxProbeResponse=0; |
|
| 71 |
levelNo=0; |
|
| 72 |
resultsMatrix=zeros(length(maskerLevels), length(gapDurations)); |
|
| 73 |
summaryFiringRates=[]; |
|
| 74 |
|
|
| 75 |
% initial silence |
|
| 76 |
time=dt: dt: initialSilenceDuration; |
|
| 77 |
initialSilence=zeros(1,length(time)); |
|
| 78 |
|
|
| 79 |
% probe |
|
| 80 |
time=dt: dt: probeDuration; |
|
| 81 |
amp=28e-6*10^(probeLeveldB/20); |
|
| 82 |
probe=amp*sin(2*pi.*targetFrequency*time); |
|
| 83 |
% ramps |
|
| 84 |
% catch rampTime error |
|
| 85 |
if rampDuration>0.5*probeDuration, rampDuration=probeDuration/2; end |
|
| 86 |
rampTime=dt:dt:rampDuration; |
|
| 87 |
% raised cosine ramp |
|
| 88 |
ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... |
|
| 89 |
ones(1,length(time)-length(rampTime))]; |
|
| 90 |
% onset ramp |
|
| 91 |
probe=probe.*ramp; |
|
| 92 |
% offset ramp makes complete ramp for probe |
|
| 93 |
ramp=fliplr(ramp); |
|
| 94 |
% apply ramp mask to probe. Probe does not change below |
|
| 95 |
probe=probe.*ramp; |
|
| 96 |
|
|
| 97 |
% final silence |
|
| 98 |
time=dt: dt: finalSilenceDuration; |
|
| 99 |
finalSilence=zeros(1,length(time)); |
|
| 100 |
|
|
| 101 |
PSTHplotCount=0; |
|
| 102 |
longestSignalDuration=initialSilenceDuration + maskerDuration +... |
|
| 103 |
max(gapDurations) + probeDuration + finalSilenceDuration ; |
|
| 104 |
for maskerLeveldB=maskerLevels |
|
| 105 |
levelNo=levelNo+1; |
|
| 106 |
allDurations=[]; |
|
| 107 |
allFiringRates=[]; |
|
| 108 |
|
|
| 109 |
%masker |
|
| 110 |
time=dt: dt: maskerDuration; |
|
| 111 |
masker=sin(2*pi.*maskerFrequency*time); |
|
| 112 |
% masker ramps |
|
| 113 |
if rampDuration>0.5*maskerDuration |
|
| 114 |
% catch ramp duration error |
|
| 115 |
rampDuration=maskerDuration/2; |
|
| 116 |
end |
|
| 117 |
% NB masker ramp (not probe ramp) |
|
| 118 |
rampTime=dt:dt:rampDuration; |
|
| 119 |
% raised cosine ramp |
|
| 120 |
ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi))... |
|
| 121 |
ones(1,length(time)-length(rampTime))]; |
|
| 122 |
% onset ramp |
|
| 123 |
masker=masker.*ramp; |
|
| 124 |
% offset ramp |
|
| 125 |
ramp=fliplr(ramp); |
|
| 126 |
% apply ramp |
|
| 127 |
masker=masker.*ramp; |
|
| 128 |
amp=28e-6*10^(maskerLeveldB/20); |
|
| 129 |
maskerPa=amp*masker; |
|
| 130 |
|
|
| 131 |
for gapDuration=gapDurations |
|
| 132 |
time=dt: dt: gapDuration; |
|
| 133 |
gap=zeros(1,length(time)); |
|
| 134 |
|
|
| 135 |
inputSignal=... |
|
| 136 |
[initialSilence maskerPa gap probe finalSilence]; |
|
| 137 |
|
|
| 138 |
% ********************************** run MAP model |
|
| 139 |
|
|
| 140 |
global ANprobRateOutput tauCas ... |
|
| 141 |
|
|
| 142 |
showPlotsAndDetails=0; |
|
| 143 |
|
|
| 144 |
AN_spikesOrProbability='probability'; |
|
| 145 |
|
|
| 146 |
MAP1_14(inputSignal, 1/dt, targetFrequency, ... |
|
| 147 |
paramsName, AN_spikesOrProbability); |
|
| 148 |
|
|
| 149 |
[nFibers c]=size(ANprobRateOutput); |
|
| 150 |
nLSRfibers=nFibers/length(tauCas); |
|
| 151 |
ANresponse=ANprobRateOutput(end-nLSRfibers:end,:); |
|
| 152 |
ANresponse=sum(ANresponse)/nLSRfibers; |
|
| 153 |
|
|
| 154 |
% analyse results |
|
| 155 |
probeStart=initialSilenceDuration+maskerDuration+gapDuration; |
|
| 156 |
PSTHbinWidth=dt; |
|
| 157 |
responseDelay=0.005; |
|
| 158 |
probeTimes=probeStart+responseDelay:... |
|
| 159 |
PSTHbinWidth:probeStart+probeDuration+responseDelay; |
|
| 160 |
probeIDX=round(probeTimes/PSTHbinWidth); |
|
| 161 |
probePSTH=ANresponse(probeIDX); |
|
| 162 |
firingRate=mean(probePSTH); |
|
| 163 |
% NB this only works if you start with the lowest level masker |
|
| 164 |
maxProbeResponse=max([maxProbeResponse firingRate]); |
|
| 165 |
allDurations=[allDurations gapDuration]; |
|
| 166 |
allFiringRates=[allFiringRates firingRate]; |
|
| 167 |
|
|
| 168 |
%% show PSTHs |
|
| 169 |
if showPSTHs |
|
| 170 |
nLevels=length(maskerLevels); |
|
| 171 |
nDurations=length(gapDurations); |
|
| 172 |
figure(8) |
|
| 173 |
PSTHbinWidth=1e-3; |
|
| 174 |
PSTH=UTIL_PSTHmaker(ANresponse, dt, PSTHbinWidth); |
|
| 175 |
PSTH=PSTH*dt/PSTHbinWidth; |
|
| 176 |
PSTHplotCount=PSTHplotCount+1; |
|
| 177 |
subplot(nLevels,nDurations,PSTHplotCount) |
|
| 178 |
probeTime=PSTHbinWidth:PSTHbinWidth:... |
|
| 179 |
PSTHbinWidth*length(PSTH); |
|
| 180 |
bar(probeTime, PSTH) |
|
| 181 |
if strcmp(AN_spikesOrProbability, 'spikes') |
|
| 182 |
ylim([0 500]) |
|
| 183 |
else |
|
| 184 |
ylim([0 500]) |
|
| 185 |
end |
|
| 186 |
xlim([0 longestSignalDuration]) |
|
| 187 |
grid on |
|
| 188 |
|
|
| 189 |
if PSTHplotCount< (nLevels-1) * nDurations+1 |
|
| 190 |
set(gca,'xticklabel',[]) |
|
| 191 |
end |
|
| 192 |
|
|
| 193 |
if ~isequal(mod(PSTHplotCount,nDurations),1) |
|
| 194 |
set(gca,'yticklabel',[]) |
|
| 195 |
else |
|
| 196 |
ylabel([num2str(maskerLevels... |
|
| 197 |
(round(PSTHplotCount/nDurations) +1))]) |
|
| 198 |
end |
|
| 199 |
|
|
| 200 |
if PSTHplotCount<=nDurations |
|
| 201 |
title([num2str(1000*gapDurations(PSTHplotCount)) 'ms']) |
|
| 202 |
end |
|
| 203 |
end % showPSTHs |
|
| 204 |
|
|
| 205 |
end % gapDurations duration |
|
| 206 |
summaryFiringRates=[summaryFiringRates allFiringRates']; |
|
| 207 |
|
|
| 208 |
figure(7), hold on |
|
| 209 |
semilogx(allDurations, allFiringRates/maxProbeResponse) |
|
| 210 |
ylim([0 1]), hold on |
|
| 211 |
ylim([0 inf]), xlim([min(gapDurations) max(gapDurations)]) |
|
| 212 |
xlim([0.001 1]) |
|
| 213 |
pause(0.1) % to allow for CTRL/C interrupts |
|
| 214 |
resultsMatrix(levelNo,:)=allFiringRates; |
|
| 215 |
end % maskerLevel |
|
| 216 |
|
|
| 217 |
disp('delay/ rates')
|
|
| 218 |
disp(num2str(round( [1000*allDurations' summaryFiringRates]))) |
|
| 219 |
|
|
| 220 |
% replot with best adjustment |
|
| 221 |
% figure(34), clf% use for separate plot |
|
| 222 |
figure(7), clf |
|
| 223 |
peakProbe=max(max(resultsMatrix)); |
|
| 224 |
resultsMatrix=resultsMatrix/peakProbe; |
|
| 225 |
semilogx(gapDurations,HDresponse,'o'), hold on |
|
| 226 |
title(['FrMsk: probe ' num2str(probeLeveldB)... |
|
| 227 |
'dB SL: peakProbe=' num2str(peakProbe,'%5.0f') ' sp/s']) |
|
| 228 |
xlabel('gap duration (s)'), ylabel ('probe response')
|
|
| 229 |
semilogx(allDurations, resultsMatrix'), ylim([0 1]) |
|
| 230 |
ylim([0 inf]), |
|
| 231 |
xlim([0.001 1]) |
|
| 232 |
legend(strvcat(num2str(maskerLevels'-thresholdAtCF)), -1) |
|
| 233 |
|
|
| 234 |
% ------------------------------------------------- display parameters |
|
| 235 |
disp(['parameter file was: ' paramsName]) |
|
| 236 |
fprintf('\n')
|
|
| 237 |
% UTIL_showStruct(inputStimulusParams, 'inputStimulusParams') |
|
| 238 |
% UTIL_showStruct(outerMiddleEarParams, 'outerMiddleEarParams') |
|
| 239 |
% UTIL_showStruct(DRNLParams, 'DRNLParams') |
|
| 240 |
% UTIL_showStruct(IHC_VResp_VivoParams, 'IHC_VResp_VivoParams') |
|
| 241 |
UTIL_showStruct(IHCpreSynapseParams, 'IHCpreSynapseParams') |
|
| 242 |
UTIL_showStruct(AN_IHCsynapseParams, 'AN_IHCsynapseParams') |
|
| 243 |
|
|
| 244 |
|
|
| multithreshold 1.46/testOME.m | ||
|---|---|---|
| 1 |
function testOME(paramsName) |
|
| 2 |
|
|
| 3 |
savePath=path; |
|
| 4 |
addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) |
|
| 5 |
|
|
| 6 |
sampleRate=50000; |
|
| 7 |
|
|
| 8 |
dt=1/sampleRate; |
|
| 9 |
leveldBSPL=80; % dB SPL as used by Huber (may trigger AR) |
|
| 10 |
amp=10^(leveldBSPL/20)*28e-6; |
|
| 11 |
duration=.05; |
|
| 12 |
time=dt: dt: duration; |
|
| 13 |
|
|
| 14 |
%% Comparison data (human) |
|
| 15 |
% These data are taken directly from Huber 2001 (Fig. 4) |
|
| 16 |
HuberFrequencies=[600 800 1000 2000 3000 4000 6000 8000]; |
|
| 17 |
HuberDisplacementAt80dBSPL=[1.5E-9 1.5E-09 1.5E-09 1.0E-09 7.0E-10 ... |
|
| 18 |
3.0E-10 2.0E-10 1.0E-10]; % m; |
|
| 19 |
% HuberVelocityAt80dBSPL= 2*pi*HuberFrequencies.*HuberDisplacementAt80dBSPL; |
|
| 20 |
|
|
| 21 |
figure(2), clf, subplot(2,1,1) |
|
| 22 |
set(2,'position',[5 349 268 327]) |
|
| 23 |
semilogx(HuberFrequencies, 20*log10(HuberDisplacementAt80dBSPL/1e-10),... |
|
| 24 |
'ko', 'MarkerFaceColor','k', 'Marker','o', 'markerSize',6) |
|
| 25 |
hold on |
|
| 26 |
|
|
| 27 |
%% Generate test stimulus ................................................................. |
|
| 28 |
|
|
| 29 |
% independent test using discrete frequencies |
|
| 30 |
peakResponses=[]; |
|
| 31 |
peakTMpressure=[]; |
|
| 32 |
frequencies=[200 400 HuberFrequencies 10000]; |
|
| 33 |
for toneFrequency=frequencies |
|
| 34 |
inputSignal=amp*sin(2*pi*toneFrequency*time); |
|
| 35 |
|
|
| 36 |
showPlotsAndDetails=0; |
|
| 37 |
AN_spikesOrProbability='probability'; |
|
| 38 |
% switch off AR & MOC (Huber's patients were deaf) |
|
| 39 |
paramChanges{1}='OMEParams.rateToAttenuationFactorProb=0;';
|
|
| 40 |
paramChanges{2}='DRNLParams.rateToAttenuationFactorProb = 0;';
|
|
| 41 |
|
|
| 42 |
global OMEoutput OMEextEarPressure TMoutput ARattenuation |
|
| 43 |
% BF is irrelevant |
|
| 44 |
MAP1_14(inputSignal, sampleRate, -1, ... |
|
| 45 |
paramsName, AN_spikesOrProbability, paramChanges); |
|
| 46 |
|
|
| 47 |
peakDisplacement=max(OMEoutput(floor(end/2):end)); |
|
| 48 |
peakResponses=[peakResponses peakDisplacement]; |
|
| 49 |
|
|
| 50 |
peakTMpressure=[peakTMpressure max(OMEextEarPressure)]; |
|
| 51 |
disp([' AR attenuation (dB): ' num2str(20*log10(min(ARattenuation)))]) |
|
| 52 |
end |
|
| 53 |
|
|
| 54 |
%% Report |
|
| 55 |
disp('frequency displacement(m)')
|
|
| 56 |
% disp(num2str([frequencies' peakResponses'])) |
|
| 57 |
fprintf('%6.0f \t%10.3e\n',[frequencies' peakResponses']')
|
|
| 58 |
|
|
| 59 |
% stapes peak displacement |
|
| 60 |
figure(2), subplot(2,1,1), hold on |
|
| 61 |
semilogx(frequencies, 20*log10(peakResponses/1e-10), 'r', 'linewidth',4) |
|
| 62 |
set(gca,'xScale','log') |
|
| 63 |
% ylim([1e-11 1e-8]) |
|
| 64 |
xlim([100 10000]), ylim([0 30]) |
|
| 65 |
grid on |
|
| 66 |
title(['stapes at ' num2str(leveldBSPL) ' (NB deaf)']) |
|
| 67 |
ylabel('disp: dB re 1e-10m')
|
|
| 68 |
xlabel('stimulus frequency (Hz)')
|
|
| 69 |
legend({'Huber et al','model'},'location','southWest')
|
|
| 70 |
set(gcf,'name','OME') |
|
| 71 |
|
|
| 72 |
% external ear resonance |
|
| 73 |
figure(2), subplot(2,1,2),hold off |
|
| 74 |
semilogx(frequencies, 20*log10(peakTMpressure/28e-6)-leveldBSPL,... |
|
| 75 |
'k', 'linewidth',2) |
|
| 76 |
xlim([100 10000]) %, ylim([-10 30]) |
|
| 77 |
grid on |
|
| 78 |
title(['External ear resonances' ]) |
|
| 79 |
ylabel('dB')
|
|
| 80 |
xlabel('frequency')
|
|
| 81 |
set(gcf,'name','OME: external resonances') |
|
| 82 |
% ---------------------------------------------------------- display parameters |
|
| 83 |
disp(['parameter file was: ' paramsName]) |
|
| 84 |
fprintf('\n')
|
|
| 85 |
|
|
| 86 |
path(savePath); |
|
| multithreshold 1.46/testPeriphery.m | ||
|---|---|---|
| 1 |
function testPeriphery (BMlocations, paramsName) |
|
| 2 |
% testBM generates input output functions for DRNL model for any number |
|
Also available in: Unified diff