Mercurial > hg > map
changeset 28:02aa9826efe0
mainly multiThreshold
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/Levitt2.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,145 @@ +function [nextStep, msg]=Levitt2 (decision, currentValue) +global LevittControl withinRuns +% descision is a string: 'hit' or 'miss' +% current value is the value of the variable parameter (e.g. level) +% msg: +% msg='' indicates trial progressing successfully +% msg='done' indicates that a threshold estimate has been found +% msg='maximum level exceeded' +% msg='maximum no of trials exceeded' + +% Initialize by running Levitt2 without arguments +% later LevittControl will be set in aReadAndCheckParameterBoxes in expGUI_MT +if nargin==0 + + LevittControl.peakTroughValues=[]; + LevittControl.trialRunning=0; + LevittControl.sequence='****'; + LevittControl.LevittValuesUsed=[NaN NaN NaN NaN]; + LevittControl.TurnsToSmallSteps=4; % 2 peaks and 2 troughs + LevittControl.direction='same'; + LevittControl.prevDirection='easier'; + LevittControl.Nreversals=0; + + LevittControl.trialRunning=1; + LevittControl.meanPeakTrough=NaN; + LevittControl.sd=NaN; + msg=''; + return +end + +% apply Levitt rules to find next stimulus value +rule=LevittControl.rule; +sequence=LevittControl.sequence; +meanPT=LevittControl.meanPeakTrough; +sdPT=LevittControl.sd; + +% response sequence: '+' is a hit and '-' is a miss. +if strcmp(decision,'hit') + sequence=[sequence '+']; +else + sequence=[sequence '-']; +end +LevittControl.LevittValuesUsed=[LevittControl.LevittValuesUsed withinRuns.levelList(end)]; + +switch rule + case '++' + peakCriterion='-++'; + troughCriteria={'++ -', '++ +-'}; + case '+++' + peakCriterion='-+++'; + troughCriteria={'+++ -', '+++ +-', '+++ ++-'}; + otherwise + error('Levitt:') +end + +troughs=[]; allTroughPtrs=[]; +for i=1:length(troughCriteria) % do all trough criteria + troughCriterion=char(troughCriteria(i));% one criterion at a time + % identify the location of a trough + troughPtrs=findstr(sequence, troughCriterion) + length(troughCriterion)-1; + % identify the level at which it occurred + troughLevels=LevittControl.LevittValuesUsed(troughPtrs); + % archive the list + withinRuns.troughs=troughLevels; + troughs=[troughs troughLevels]; + allTroughPtrs=[allTroughPtrs troughPtrs]; +end +% only one peak criterion used +withinRuns.troughs=troughs; +peakPtrs=findstr(sequence,peakCriterion)+length(peakCriterion)-1; +peakLevels=LevittControl.LevittValuesUsed(peakPtrs); +withinRuns.peaks=peakLevels; + +% almagamate and sort into date order +peakTroughList=[peakLevels troughs]; +peakTroughPtrs=[peakPtrs allTroughPtrs]; +[peakTroughPtrs idx]=sort(peakTroughPtrs); +% it needs to be sequenced so that the algorithm can take the last peaks +% and troughs +peakTroughList=peakTroughList(idx); + +% adjust step size as the trial progresses +% a positive step size indicates the 'harder' direction +if length(peakTroughList)>=LevittControl.TurnsToSmallSteps + currentStep=LevittControl.steadyLevittStep; +else + currentStep=LevittControl.startLevelStep; +end + +% base next stimulus on the basis of the sequence +% any miss requires an 'easier' stimulus next time. +if strcmp(sequence(end),'-') + nextStep= -currentStep; + + % success requires 2 or more successive hits +elseif strcmp(sequence(end-length(rule)+1:end),rule) + sequence=[sequence ' ']; % add space to prevent success on successive trials + LevittControl.LevittValuesUsed=[LevittControl.LevittValuesUsed NaN]; + nextStep=currentStep; + + % not enough hits to provoke a change +else + nextStep=0; +end + +LevittControl.sequence=sequence; + +LevittControl.Nreversals=length(peakTroughList); +% compute threshold estimate +% only if minReversals exceeded and even number of peaks and troughs +if LevittControl.Nreversals>=LevittControl.minReversals && rem(length(peakTroughList),2)==0 + % use only the peaks and troughs at the end of the sequence + peaksAndTroughs=peakTroughList(end-LevittControl.useLastNturns+1:end); + disp(['peak/trough sequence= ' num2str(peaksAndTroughs, '%6.0f') ] ) + + meanPT=mean(peaksAndTroughs); + sdPT=std(peaksAndTroughs); + LevittControl.meanPeakTrough=meanPT; + LevittControl.sd=sdPT; + fprintf('Levitt, mean, sd= %6.1f,%6.1f\n', meanPT, sdPT) + % final check that the sd is low enough + if sdPT<LevittControl.targetsdPT + nextValue=currentValue; + msg='done'; + return + end +end + +nextValue=currentValue + nextStep; +if nextValue>LevittControl.maxLevittValue + msg='maximum level exceeded' + return +end + +% required for later use +LevittControl.trialRunning=LevittControl.trialRunning+1; +LevittControl.peakTroughValues=peakTroughList; + +if LevittControl.trialRunning>LevittControl.maxTrials + msg='maximum no of trials exceeded' + return +end + +% Trial continues +msg='';
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/MAPmodel.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,136 @@ +function [modelResponse, MacGregorResponse]=MAPmodel( MAPplot, method) + +global experiment stimulusParameters audio withinRuns +global outerMiddleEarParams DRNLParams AN_IHCsynapseParams + +savePath=path; +addpath(['..' filesep 'MAP'], ['..' filesep 'utilities']) +modelResponse=[]; +MacGregorResponse=[]; + +% mono only (column vector) +audio=audio(:,1)'; + +% if stop button pressed earlier +if experiment.stop, return, end + +% -------------------------------------------------------------- run Model +MAPparamsName=experiment.name; +showPlotsAndDetails=experiment.MAPplot; +AN_spikesOrProbability='spikes'; + +% [response, method]=MAPsequenceSeg(audio, method, 1:8); +global ICoutput ANdt + MAP1_14(audio, 1/method.dt, method.nonlinCF,... + MAPparamsName, AN_spikesOrProbability); + +if showPlotsAndDetails + options.printModelParameters=0; + options.showModelOutput=1; + options.printFiringRates=1; + options.showACF=0; + options.showEfferent=1; + UTIL_showMAP(options) +end + +% No response, probably caused by hitting 'stop' button +if isempty(ICoutput), return, end + +% MacGregor response is the sum total of all final stage spiking +MacGregorResponse= sum(ICoutput,1); % use IC + +% ---------------------------------------------------------- end model run + +dt=ANdt; +time=dt:dt:dt*length(MacGregorResponse); + +% group delay on unit response +MacGonsetDelay= 0.004; +MacGoffsetDelay= 0.022; + +% now find the response of the MacGregor model during the target presentation + group delay +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + idx= time>stimulusParameters.testTargetBegins+MacGonsetDelay ... + & time<stimulusParameters.testTargetEnds+MacGoffsetDelay; + nSpikesTrueWindow=sum(MacGregorResponse(:,idx)); + idx=find(time>stimulusParameters.testNonTargetBegins+MacGonsetDelay ... + & time<stimulusParameters.testNonTargetEnds+MacGoffsetDelay); + nSpikesFalseWindow=sum(MacGregorResponse(:,idx)); + % nSpikesDuringTarget is +ve when more spikes are found + % in the target window + difference= nSpikesTrueWindow-nSpikesFalseWindow; + + if difference>0 + % hit + nSpikesDuringTarget=experiment.MacGThreshold+1; + elseif difference<0 + % miss (wrong choice) + nSpikesDuringTarget=experiment.MacGThreshold-1; + else + if rand>0.5 + % hit (random choice) + nSpikesDuringTarget=experiment.MacGThreshold+1; + else + % miss (random choice) + nSpikesDuringTarget=experiment.MacGThreshold-1; + end + end + disp(['level target dummy decision: ' ... + num2str([withinRuns.variableValue nSpikesTrueWindow ... + nSpikesFalseWindow nSpikesDuringTarget], '%4.0f') ] ) + + otherwise + % idx=find(time>stimulusParameters.testTargetBegins+MacGonsetDelay ... + % & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); + % no delay at onset + idx=find(time>stimulusParameters.testTargetBegins +MacGonsetDelay... + & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); + nSpikesDuringTarget=sum(MacGregorResponse(:,idx)); + + % find(MacGregorResponse)*dt-stimulusParameters.stimulusDelay + timeX=time(idx); +end + +% now find the response of the MacGregor model at the end of the masker +idx2=find(time>stimulusParameters.testTargetBegins-0.02 ... + & time<stimulusParameters.testTargetBegins); +if ~isempty(idx2) + maskerRate=mean(mean(MacGregorResponse(idx2))); +else + %e.g. no masker + maskerRate=0; +end + +if experiment.MAPplot + % add vertical lines to indicate target region + figure(99), subplot(6,1,6) + hold on + yL=get(gca,'YLim'); + plot([stimulusParameters.testTargetBegins + MacGonsetDelay ... + stimulusParameters.testTargetBegins + MacGonsetDelay],yL,'r') + plot([stimulusParameters.testTargetEnds + MacGoffsetDelay ... + stimulusParameters.testTargetEnds + MacGoffsetDelay],yL,'r') +end + +% specify unambiguous response +switch experiment.paradigm + case 'gapDetection' + gapResponse=(maskerRate-nSpikesDuringTarget)/maskerRate; + if gapResponse>0.2 + modelResponse=2; % gap detected + else + modelResponse=1; % gap not detected + end + [nSpikesDuringTarget maskerRate gapResponse modelResponse] + figure(22), plot(timeX,earObject(idx)) + otherwise + if nSpikesDuringTarget>experiment.MacGThreshold + modelResponse=2; % stimulus detected + else + modelResponse=1; % nothing heard (default) + end +end + + +path(savePath)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/addToMsg.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,35 @@ +% ---------------------------------------------------------- addToMsg +function addToMsg(message,append, warning) +% 'message' is posted to the message board +% if append==1, message is appended to the current message +global experiment expGUIhandles + +if nargin<3 + % this is not a warning screen + warning=0; +end + +if append +msg=get(expGUIhandles.textMSG,'string'); +[r c]=size(msg); + if length(message)<=c + y=[message blanks(c-length(message))]; + msg(r+1,:)=y; + else + msg=message; + end +else + msg=message; +end + +try + set(expGUIhandles.textMSG,'string', msg,'fontSize', experiment.msgFontSize) + if warning + % flash red to signal a warning + set(expGUIhandles.textMSG,'backgroundcolor','r', 'ForegroundColor', 'w' ) + else + set(expGUIhandles.textMSG,'backgroundcolor','w', 'ForegroundColor', 'b') + end +catch + error(message) +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/bestFitPsychometicFunctions.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,314 @@ +% ------------------------------------------------------- bestFitPsychometicFunctions +function [psy, levelsPhaseTwoBinVector, logistic, rareEvent]= bestFitPsychometicFunctions (levelsPhaseTwo, responsesPhaseTwo) +% bestFitPsychometicFunctions computes a psychometric function from a matrix of levels and responses +%output +% psy is the empirical probabbility of a detection associated with levels in levelsPhaseTwoBinVector +% logistic is a structure with results for fitting the logistic function +% the logistic fit depends on whether maximum likelihood is used or least squares +% rareEvent is a structure with results for fitting the rareEvent function +% this is always calculated and lest squares is always used + +global experiment stimulusParameters binFrequencies + +% Generate a psychometic function by binning the levelsPhaseTwo +% x is a vector of [levelsPhaseTwo; responsesPhaseTwo] +% experiment.psyBinWidth defines the width of the bin +[psy, levelsPhaseTwoBinVector, binFrequencies,yesResponses, noResponses]= ... + psychometricFunction(levelsPhaseTwo, responsesPhaseTwo, experiment.psyBinWidth); +% [levelsPhaseTwoBinVector; binFrequencies; psy]; + +% undefined slope - return +if isempty(psy) + % slope is undefined + psy=[]; levelsPhaseTwoBinVector=[]; + logistic.bestThreshold=NaN; logistic.bestK=NaN; logistic.predictionsLOG=[]; logistic.predictionLevels=[]; + rareEvent.bestGain=NaN; rareEvent.bestVMin=NaN; rareEvent.predictionsRE=[]; rareEvent.predictionLevels=[]; + rareEvent.thresholddB= NaN; rareEvent.bestPaMindB=NaN; + return +end + +% find best fit rare event function +switch experiment.paradigm + case 'gapDuration' + % i.e. don't attempt this but visit the function to set null results + rareEvent=fitRareEvent([], responsesPhaseTwo, stimulusParameters.targetDuration); + otherwise + rareEvent=fitRareEvent(levelsPhaseTwo, responsesPhaseTwo, stimulusParameters.targetDuration); +end + +% find best logistic fit +logisticFunc=' 1./(1+exp(-a2.*(x-a1)));'; +switch experiment.functionEstMethod + % least squares estimate + case {'logisticLS', 'rareEvent','peaksAndTroughs'} + [a1, a2, Euclid]=fitFunctionUsingLeastSquares(levelsPhaseTwo, responsesPhaseTwo, ... + logisticFunc, experiment.possLogSlopes, experiment.meanSearchStep); +% [a1, a2, Euclid]=fitLogisticUsingLS(psy, levelsPhaseTwoBinVector); %! does not give same result + logistic.bestThreshold=a1; + logistic.bestK=a2; + logistic.predictionsLOG= ... + 1./(1+exp(-logistic.bestK.*(experiment.predictionLevels-logistic.bestThreshold))); + logistic.predictionLevels=experiment.predictionLevels; + logistic.Euclid = Euclid; + % predResponses=1./(1+exp(-logistic.bestK.*(levelsPhaseTwo-logistic.bestThreshold))); + % [levelsPhaseTwo' responsesPhaseTwo' predResponses' responsesPhaseTwo'-predResponses' ] + + % maximum likelihood fitting + case 'logisticML' + [a1, a2, Euclid]=fitFunctionUsingMaxLikelihood (levelsPhaseTwoBinVector,... + psy, yesResponses, noResponses, logisticFunc, experiment.possLogSlopes,experiment.meanSearchStep); + logistic.bestThreshold=a1; + logistic.bestK=a2; + logistic.predictionsLOG= ... + 1./(1+exp(-logistic.bestK.*(experiment.predictionLevels-logistic.bestThreshold))); + logistic.predictionLevels=experiment.predictionLevels; + logistic.Euclid = Euclid; +end + +% disp(num2str([logistic.bestThreshold logistic.bestK logistic.Euclid])) +% disp(num2str([ rareEvent.thresholddB rareEvent.bestGain rareEvent.bestVMin rareEvent.Euclid])) + +% --------------------------------------------- fitLogisticUsingLS +function [mean, slope, Euclid]=fitLogisticUsingLS(p,L) + +%!! each bin needs to be weighted by its size + +idx1=find(p>0); +p=p(idx1); +L=L(idx1); +idx1=find(p<1); +p=p(idx1); +L=L(idx1); + +if length(L)<2 + mean=NaN; + slope=NaN; + Euclid=NaN; + return +end + +y=L; +x=log(1./p -1); +a =polyfit(x, y, 1); +mean=a(2); +slope=-1/a(1); + +% euclid +predy=polyval(a,x); +Euclid=sum((predy-y).^2); +[mean slope Euclid]; + +% --------------------------------------------- fitFunctionUsingLeastSquares +function [a1, a2, Euclid]=fitFunctionUsingLeastSquares(levelsPhaseTwo, responsesPhaseTwo, func, possSlopes, meanSearchStep) + +% nResponses= yesResponses+noResponses; +% idx=find(not(nResponses==0)); +% levelsPhaseTwo=levelsPhaseTwo(idx); +% yesResponses=yesResponses(idx); +% noResponses=noResponses(idx); +% nResponses=nResponses(idx); + +% psy=yesResponses./nResponses; + +possThresholds=min(levelsPhaseTwo):meanSearchStep:max(levelsPhaseTwo); + + +% create vectors representing all combinations of a1 and a2 +nPossThresh=length(possThresholds); +nPossSlopes=length(possSlopes); +a1=repmat(possThresholds',nPossSlopes,1); +a2=repmat(possSlopes,nPossThresh,1); +a2=reshape(a2,nPossThresh*nPossSlopes,1); + +% each response is predicted by every possible threshold and slope +LS=ones(size(a1)); +for i=1:length(levelsPhaseTwo) + x=levelsPhaseTwo(i); + eval(['y=' func]); + actual=responsesPhaseTwo(i); + error= (actual - y).^2; + LS=LS+error; +end + +[Euclid, idx]=min(LS); + +a1=a1(idx); +a2=a2(idx); + +% x=levelsPhaseTwo; +% eval(['y=' func]); +% Euclid= sum((psy-y).^2); + +% plot(levelsPhaseTwo,y,'r') +% hold on +% plot(levelsPhaseTwo,psy,'o') + +% --------------------------------------------- fitFunctionUsingMaxLikelihood +function [a1, a2, Euclid]=fitFunctionUsingMaxLikelihood... + (levelsPhaseTwo,psy, yesResponses, noResponses, func, possible_a2, meanSearchStep) + +% fitFunctionUsingMaxLikelihood fits the function in 'func' to binned yes-no data. +% levelsPhaseTwo specifies the bin centers +% yesResponses and noResponses are the niumber of yes and no responsesPhaseTwo in each bin +% 'func' is a function of a1, b1, x; e.g. func='1./(1+exp(-a2.*(x-a1)));'; +% and a2, a1 are parameters to be discovered. +% If bins are empty (i.e. neither yes or no), these are eliminated +% + +nResponses=yesResponses+noResponses; +possible_a1=min(levelsPhaseTwo):meanSearchStep:max(levelsPhaseTwo); + +% if nargin<6 +% possible_a2=-2:.05:4; +% end + +% create vectors representing all combinations of a1 and a2 +nPossThresh=length(possible_a1); +nPossSlopes=length(possible_a2); +a1=repmat(possible_a1',nPossSlopes,1); +a2=repmat(possible_a2,nPossThresh,1); +a2=reshape(a2,nPossThresh*nPossSlopes,1); + +cumulativeProbability=ones(1, length(a2)); +cumulativeProbability=cumulativeProbability'; + +for i=1:length(levelsPhaseTwo) + x=levelsPhaseTwo(i); + eval(['y=' func]); + funcVal=(1-y).^yesResponses(i); + cumulativeProbability= cumulativeProbability.*funcVal; + funcVal=y.^noResponses(i); + cumulativeProbability= cumulativeProbability.*funcVal; +end + +[maxProb idx]=max(cumulativeProbability); +a1=a1(idx); +a2=a2(idx); + +% x=levelsPhaseTwo; +eval(['y=' func]); +Euclid= sum(nResponses.*(psy-y).^2); + +% figure(1), clf +% plot(levelsPhaseTwo,y) +% hold on +% plot(levelsPhaseTwo,psy,'o') + + + +% --------------------------------------------------- fitRareEvent +function rareEvent=fitRareEvent(stimulusLevels, responsesPhaseTwo, duration, gains, Vmins) +% least squares estimate of *rare event* function +% model is: r = g P – A ... g=events/s/Pa, A= events/s, P= pressure (Pa) +% psy=1- exp(d(gP –A )) ... d=duration +% p(event)=gain*levelmPa -Vmin +% 'responsesPhaseTwo' is a binary vector of subject's decision. +% 'stimulusLevels' are the corresponding signal levesl (values) +% duration is required to compute the expectation of an event occurring +% gains is an optional list of gains to be tried +% Vmins is an optional list of Vmins to be tried + +global experiment +if nargin<5 + minVmin=.1; maxVmin=10; nVmins=100; + Vmins=[0 logspace(log10(minVmin),log10(maxVmin),nVmins)]; + % disp(Vmins) + gainMin=0.0001; gainMax=1; nGains=100; + gains=[1e-5 logspace(log10(gainMin),log10(gainMax),nGains)]; +end + +rareEvent.bestGain=NaN; +rareEvent.bestVMin=NaN; +rareEvent.thresholddB=0; +rareEvent.bestPaMindB=NaN; +rareEvent.predictionLevels=[]; +rareEvent.predictionsRE=[]; +rareEvent.Euclid=NaN; + +if isempty(stimulusLevels), return, end + +% expected slope is negative, rareEvent can not be used +if experiment.psyFunSlope<0 + return +end + +% NB calculations in microPascals! +stimulusLevelsAsPressure=28 * 10.^(stimulusLevels/20); + +% allGains=reshape(repmat(gains,nVmins,1), 1, nVmins*nGains); +% allVmins=repmat(Vmins, 1, nGains); + + predictions=NaN*zeros(1,length(stimulusLevels)); + gainCount=0; + Euclid=inf; bestVmin=0; bestGain=0; + for gain= gains + gainCount=gainCount+1; + VminCount=0; + + % 1 – exp(-d (g P – A)) + for Vmin=Vmins + VminCount=VminCount+1; + % all levelsPhaseTwo are simultaneously assessed + + % original linear function +% gP_Vmin=gain*stimulusLevelsAsPressure-Vmin; +% idx=(gP_Vmin>0); + % predictions(idx)= 1-exp(-duration*(gP_Vmin(idx))); + % new log function log(r) =gP-A + + % log function + gP_Vmin=gain*stimulusLevelsAsPressure-Vmin; + idx=(gP_Vmin>0); + predictions(idx)= 1-exp(-duration*exp(gP_Vmin(idx))); + predictions(~idx)=0; + +% % square function +% P_Vmin=stimulusLevelsAsPressure-Vmin; +% idx=(P_Vmin)>0; +% predictions(idx)= 1-exp(-duration*gain*(P_Vmin(idx)).^2); +% predictions(~idx)=0; + + + % NB the error is equally weighted for each stimulus/response pair + % this is not the same as equal weighting for each distinct level + error=(predictions - responsesPhaseTwo).^2; + error=mean(error(~isnan(error))); + if error<Euclid + Euclid=error; + bestVmin=Vmin; + bestVminCount=VminCount; + % bestGainCount=gainCount; + bestGain=gain; + end + end + end + % disp(Vmins) + +% if bestGainCount==1 | bestGainCount==nGains +% disp(['gain estimate ' num2str(gains(bestGainCount)) ' may be out of range']) +% end + +[rareEvent.Euclid idx]=min(Euclid); +rareEvent.bestGain=bestGain; +rareEvent.bestVMin=bestVmin; +rareEvent.thresholdPa=(-log(0.5)/duration + rareEvent.bestVMin)/rareEvent.bestGain; +rareEvent.thresholddB=20*log10(rareEvent.thresholdPa/28); +rareEvent.bestPaMindB=20*log10((rareEvent.bestVMin/rareEvent.bestGain)/28); + +predictionLevels= -50:1:120; +rareEvent.predictionLevels=predictionLevels; +stimulusLevelsAsPressure=28*10.^(predictionLevels/20); + +% gP_Vmin=rareEvent.bestGain*stimulusLevelsAsPressure-rareEvent.bestVMin; +% rareEvent.predictionsRE= 1-exp(-duration*(gP_Vmin)); + +gP_Vmin=rareEvent.bestGain*stimulusLevelsAsPressure-rareEvent.bestVMin; +rareEvent.predictionsRE= 1-exp(-duration*exp(gP_Vmin)); + +% P_Vmin=stimulusLevelsAsPressure-Vmin; +% predictions= 1-exp(-duration*gain*P_Vmin.^2); +% predictions(predictions<0)=0; +% rareEvent.predictionsRE=predictions; + +% rareEvent +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/compare.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,36 @@ +f=[100 200 500 1000 2000 5000 10000]; +levels=-10:10:90; + +without=[ +1.44E-10 8.24E-10 1.15E-09 1.43E-09 1.08E-09 4.75E-10 1.43E-09 +4.56E-10 2.61E-09 3.63E-09 4.52E-09 3.37E-09 1.50E-09 4.52E-09 +1.44E-09 8.24E-09 1.15E-08 1.44E-08 1.06E-08 4.75E-09 1.44E-08 +4.56E-09 2.61E-08 4.45E-08 5.16E-08 3.73E-08 1.15E-08 5.16E-08 +1.44E-08 7.05E-08 9.57E-08 9.34E-08 7.44E-08 1.98E-08 9.34E-08 +4.56E-08 1.28E-07 1.46E-07 1.34E-07 1.04E-07 4.35E-08 1.34E-07 +1.06E-07 1.76E-07 2.29E-07 1.99E-07 1.47E-07 5.80E-08 1.99E-07 +1.72E-07 2.48E-07 3.65E-07 3.94E-07 3.39E-07 1.31E-07 3.94E-07 +2.54E-07 3.59E-07 7.88E-07 9.97E-07 9.07E-07 3.51E-07 9.97E-07 +3.82E-07 6.00E-07 2.13E-06 2.85E-06 2.66E-06 1.03E-06 2.85E-06 +5.81E-07 1.37E-06 6.30E-06 8.65E-06 8.17E-06 3.30E-06 8.65E-06 +]; +with=[ +2.60E-11 1.48E-10 2.09E-10 2.61E-10 1.93E-10 8.54E-11 2.61E-10 +8.21E-11 4.69E-10 6.61E-10 8.25E-10 6.10E-10 2.70E-10 8.25E-10 +2.60E-10 1.48E-09 2.09E-09 2.61E-09 1.93E-09 8.54E-10 2.61E-09 +8.21E-10 4.69E-09 6.61E-09 8.25E-09 6.10E-09 2.70E-09 8.25E-09 +2.60E-09 1.48E-08 2.35E-08 3.10E-08 1.96E-08 8.54E-09 3.10E-08 +8.21E-09 4.56E-08 7.17E-08 7.64E-08 5.59E-08 1.33E-08 7.64E-08 +2.60E-08 1.02E-07 1.20E-07 1.16E-07 9.13E-08 3.13E-08 1.16E-07 +7.49E-08 1.51E-07 1.79E-07 1.70E-07 1.25E-07 4.88E-08 1.70E-07 +1.38E-07 2.10E-07 2.90E-07 2.70E-07 2.24E-07 8.63E-08 2.70E-07 +2.10E-07 3.02E-07 5.08E-07 6.24E-07 5.58E-07 2.15E-07 6.24E-07 +3.13E-07 4.33E-07 1.29E-06 1.70E-06 1.57E-06 6.05E-07 1.70E-06 +]; +figure(7), clf +criterion = 1e-7; +c1=contour(f, levels, with,[criterion criterion]) +hold on +c2=contour(f, levels, without,[criterion criterion]) +title(['criterion= ' num2str(criterion)]) +set(gca,'Xscale','log')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/compareMicrophonic.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,43 @@ +% these data are generated by the testBM program + + +f=[250 500 1000 2000 4000 8000]; +levels=-10:10:90; + +with=[ +3.00036e-010 2.9476e-010 3.67369e-010 2.69424e-010 2.61262e-010 7.18365e-011 +9.48796e-010 9.32111e-010 1.16172e-009 8.51994e-010 8.26184e-010 2.27167e-010 +3.00036e-009 2.9476e-009 3.67369e-009 2.69424e-009 2.61262e-009 7.18365e-010 +9.48796e-009 9.32126e-009 1.16172e-008 8.51994e-009 8.26184e-009 2.27167e-009 +2.98964e-008 3.30801e-008 4.3799e-008 2.85983e-008 2.12715e-008 7.18365e-009 +8.08142e-008 1.0005e-007 1.0854e-007 8.23884e-008 6.41103e-008 1.57936e-008 +1.4489e-007 1.70294e-007 1.67989e-007 1.37031e-007 9.77912e-008 3.74565e-008 +1.9871e-007 2.56245e-007 2.50429e-007 1.82704e-007 1.2266e-007 5.73054e-008 +2.80266e-007 4.15464e-007 4.42073e-007 3.65116e-007 3.24109e-007 6.7619e-008 +4.49308e-007 8.26643e-007 1.0501e-006 9.22625e-007 9.46576e-007 2.13766e-007 +8.73737e-007 2.1498e-006 2.9006e-006 2.61691e-006 2.90337e-006 6.36048e-007 +]; + +without=[ +1.85179e-009 1.84842e-009 2.29365e-009 1.68885e-009 1.64802e-009 4.53194e-010 +5.85587e-009 5.84521e-009 7.25317e-009 5.34061e-009 5.2115e-009 1.43313e-009 +1.85179e-008 1.84842e-008 2.39525e-008 1.67348e-008 1.41015e-008 4.53194e-009 +5.70059e-008 6.97074e-008 8.049e-008 5.93827e-008 4.75289e-008 1.43313e-008 +1.21363e-007 1.42557e-007 1.42791e-007 1.14796e-007 8.59727e-008 2.31062e-008 +1.7631e-007 2.1607e-007 2.05558e-007 1.61584e-007 1.09552e-007 5.05732e-008 +2.41242e-007 3.44485e-007 3.25688e-007 2.57527e-007 2.17035e-007 6.31655e-008 +3.64591e-007 5.90911e-007 7.23077e-007 6.17822e-007 6.09472e-007 1.38217e-007 +6.52753e-007 1.44434e-006 1.89854e-006 1.69908e-006 1.84634e-006 4.09033e-007 +1.43691e-006 4.03513e-006 5.54045e-006 5.04855e-006 5.73398e-006 1.24307e-006 +3.75649e-006 1.20961e-005 1.69372e-005 1.55783e-005 1.7989e-005 3.87293e-006 +]; + + +figure(7), clf +criterion = 1e-7; +c1=contour(f, levels, with,[criterion criterion]) + +hold on +c2=contour(f, levels, without,[criterion criterion]) +title(['criterion= ' num2str(criterion)]) +set(gca,'Xscale','log')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/expGUI_MT.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,1705 @@ +% expGUI_MT = 'experimenter GUI for multiThreshold +% allows the experimenter to design experiments. +% The *running* of experiments is left to subjGUI.m +% +% There are three kinds of experiments known as 'earOptions': +% 1. Measurements using real listeners +% 'left', 'right', 'diotic', 'dichoticLeft', 'dichoticRight' +% 2. Measurements using the MAP model as the subject +% 'MAPmodelListen', 'MAPmodelMultiCh', 'MAPmodelSingleCh' +% 3. Monte Carlo simulations +% 'statsModelLogistic','statsModelRareEvent' +% +% There are many stimulus configurations relating to different measurement +% requirements. These configurations are defined in paradigm files located +% in the 'paradigms' folder with names of the form paradigm_<name>.m. These +% files specify values in the stimulusParameter and experiment structures. +% Some minor parameters are specified in the intialiseGUI function below. +% Each configuration is only a start up arrangement and the user can modify +% the parameters on the GUI itself. +% +% the 'RUN' button initiates the measurements and hands control over to the +% subjGUI program. When the measurements are complete control is handed +% back and the stack unwinds without any further action + +function varargout = expGUI_MT(varargin) +%EXPGUI_MT M-file for expGUI_MT.fig +% EXPGUI_MT, by itself, creates a new EXPGUI_MT or raises the existing +% singleton*. +% +% H = EXPGUI_MT returns the handle to a new EXPGUI_MT or the handle to +% the existing singleton*. +% +% EXPGUI_MT('Property','Value',...) creates a new EXPGUI_MT using the +% given property value pairs. Unrecognized properties are passed via +% varargin to expGUI_MT_OpeningFcn. This calling syntax produces a +% warning when there is an existing singleton*. +% +% EXPGUI_MT('CALLBACK') and EXPGUI_MT('CALLBACK',hObject,...) call the +% local function named CALLBACK in EXPGUI_MT.M with the given input +% arguments. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help expGUI_MT + +% Last Modified by GUIDE v2.5 29-May-2011 16:02:02 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @expGUI_MT_OpeningFcn, ... + 'gui_OutputFcn', @expGUI_MT_OutputFcn, ... + 'gui_LayoutFcn', [], ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +% -------------------------------------------------- expGUI_MT_OpeningFcn +function expGUI_MT_OpeningFcn(hObject, eventdata, handles, varargin) + +% Choose default command line output for expGUI_MT +handles.output = hObject; + +cla(handles.axes1) +cla(handles.axes2) +cla(handles.axes4) +cla(handles.axes5) + +% Update handles structure +guidata(hObject, handles); + +function varargout = expGUI_MT_OutputFcn(hObject, eventdata, handles) +% Get default command line output from handles structure +initializeGUI(handles) +varargout{1} = handles.output; +setLocationOfGUIs(handles) + +function setLocationOfGUIs(handles) +global checkForPreviousGUI % holds screen positioning across repeated calls +scrnsize=get(0,'screensize'); +checkForPreviousGUI=[]; +% if isstruct(checkForPreviousGUI)... +% && checkForPreviousGUI.GUIalreadyStarted==1 ... +% && isfield(checkForPreviousGUI,'GUIposition') +% set(handles.figure1,'position',checkForPreviousGUI.GUIposition) +% else +% % relocate the GUI only if this is the first time of use +% set(0, 'units','pixels') +% % occupies top to bottom of screen but only 60% width +% % [left bottom width height] +% firstPos=[0.01*scrnsize(4) 0.03*scrnsize(3) 0.6*scrnsize(3) 0.92*scrnsize(4)]; +% firstPos=[4 0.045*scrnsize(4) 0.6*scrnsize(3) 0.93*scrnsize(4)]; +% set(handles.figure1, 'units','pixels') +% set(handles.figure1,'position',firstPos) +% checkForPreviousGUI.GUIalreadyStarted=1; +% checkForPreviousGUI.GUIposition=firstPos; +% end +set(handles.figure1,'color',[.871 .961 .996]) +set(handles.figure1,'name', pwd) + +% MAP model figure; sits alongside GUI if requested +figure(99) +% [left bottom width height] +MAPpos=[0.615*scrnsize(3) 0.05*scrnsize(4) 0.15*scrnsize(3) 0.85*scrnsize(4)]; +% visible only on request. +set(gcf,'position',MAPpos , 'visible','off') + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% -----------------------------------------------------initializeGUI +function initializeGUI(handles) +% Populate the edit boxes and popup menus on the GUI +% Then wait for user action +global stimulusParameters experiment betweenRuns +global targetTypes maskerTypes backgroundTypes +global variableNames paradigmNames threshEstNames cueNames + +% dbstop if error % allow for debugging and user error reporting +% dbstop if warning + +% specify structure fields for pretty automatic printing +% It also initialises some simple variables +orderGlobals + +addpath ('paradigms') % preset paradigm informations is stored here +% filesep is usd to be compatible with other operating systems +% addpath (['..' filesep 'modules'], ['..' filesep 'utilities'], ... +% ['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... +% ['..' filesep 'testPrograms']) + +% specify all variables that need to be set on the GUI +variableNames={'stimulusDelay','maskerDuration','maskerLevel',... + 'maskerRelativeFrequency', 'targetFrequency', 'gapDuration',... + 'targetDuration','targetLevel','rampDuration',... + 'cueTestDifference', 'WRVstartValues', 'WRVsteps', 'WRVlimits'}; + +% Variable variables +% (specifies paradigm paramaters that can changed on a 'between runs' basis) +% make them options in the two between runs variable menus +% NB 'numOHIOtones' is used only to solve a problem; it should not be +% selected manually +betweenRunsVariables={'stimulusDelay','maskerDuration','maskerLevel',... + 'maskerRelativeFrequency','targetFrequency', 'gapDuration',... + 'targetDuration','targetLevel','numOHIOtones'}; +set(handles.popupmenuVaryParameter1,'string',betweenRunsVariables) +set(handles.popupmenuVaryParameter2,'string',betweenRunsVariables) + +% NB 'Warning: popupmenu control requires a scalar Value' +% indicates that an inappropriate 'value' is being set. +% when testing for this, always clear the GUI before running + +% Trial presentation order - randomize at startup +presentationOrderNames={'randomize within blocks', 'fixed sequence', ... + 'randomize across blocks'}; +set(handles.popupmenuRandomize,'string', presentationOrderNames) + +% targetType- value must be set in paradigm +targetTypes={'tone','noise', 'pinkNoise','whiteNoise','24TalkerBabble',... + 'speech', 'Twister','digitStrings'}; +set(handles.popupmenuTargetType, 'string', targetTypes); + +% maskerType - value must be set in paradigm +maskerTypes={'tone','noise', 'pinkNoise','TEN','whiteNoise','24TalkerBabble', ... + 'speech'}; +set(handles.popupmenuMaskerType, 'string', maskerTypes); + +% background Type- value must be set in paradigm (default = 1, 'none') +backgroundTypes={'none','noise', 'pinkNoise', 'TEN','noiseDich',... + 'pinkNoiseDich','whiteNoise','24TalkerBabble',... + '16TalkerBabble','8TalkerBabble','4TalkerBabble',... + '4TalkerReversedBabble','2TalkerBabble','1TalkerBabble'}; +set(handles.popupmenuBackgroundType, 'string', backgroundTypes); +set(handles.editBackgroundLevel,'string',... + num2str(stimulusParameters.backgroundLevel)) + +% Establish available paradigms by scanning paradigms folder +paradigmNames= what('paradigms'); +paradigmNames=paradigmNames.m; % m files only +for i=1:length(paradigmNames), paradigmNames{i}=paradigmNames{i}(10:end-2); end +set(handles.popupmenuParadigm,'string', paradigmNames) + +% startup paradigm, 'training' (could be anywhere on the list) +startupParadigm='training'; +idx= find(strcmp(paradigmNames,startupParadigm)); +if ~isempty(idx) + set(handles.popupmenuParadigm,'value', idx) +else + % training paradigm is always the startup paradigm + error(['expGUI_MT\initializeGUI: No ' startupParadigm... + ' paradigm found in paradigms folder']) +end + +earOptions={'left', 'right', 'diotic', 'dichoticLeft', 'dichoticRight',... + 'MAPmodelListen', 'MAPmodelMultiCh', 'MAPmodelSingleCh'... + 'statsModelLogistic','statsModelRareEvent'}; +set(handles.popupmenuEar,'string', earOptions) +defaultOption=1; +experiment.ear=earOptions{defaultOption}; +set(handles.popupmenuEar,'value', defaultOption) % 'left' is deafult +set(handles.pushbuttonSingleShot, 'visible', 'off') % use only for MAP + +% masker phase box- value must be set in paradigm +phaseOptions={'sin','cos','alt','rand'}; +set(handles.popupmenuPhase,'string', phaseOptions) + +% Cue +cueNames={'cued', 'noCue'}; +set(handles.popupmenuCueNoCue, 'string', cueNames); + +% threshold assessment method - value must be set in paradigm +threshEstNames={'oneIntervalUpDown', 'MaxLikelihood', ... + '2I2AFC++', '2I2AFC+++'}; +set(handles.popupmenuThreshEst, 'string', threshEstNames); +experiment.stopCriteria2IFC=[75 3 5]; +experiment.stopCriteriaSI=[20]; + +% ** editBoxes that are only set by hand +% music (relative) level, 'tada!' (manual setting only) +% increase for the hard of hearing +set(handles.editMusicLevel,'string','0') + +% Catch Trial Rate +set(handles.editCatchTrialRate,'string','0.2 0.1 2 '); + +% calibration +stimulusParameters.restoreCalibration=7; +set(handles.editcalibrationdB,'string',... + stimulusParameters.restoreCalibration) + +% a MAPplot +experiment.MAPplot=0; %default +set(handles.editMAPplot,'string',num2str(experiment.MAPplot)) + +% saveData +experiment.saveData=1; +set(handles.editSaveData,'string',num2str(experiment.saveData)) + +% printTracks +experiment.printTracks=0; +set(handles.editPrintTracks,'string',num2str(experiment.printTracks)) + +% standard delay between button press and initiation of next stimulus +experiment.clickToStimulusPause=1; + +% buttonBoxType: NB no problem if mouse is used instead +experiment.buttonBoxType='square'; + +% estimation of the mean +% {'logisticLS', 'logisticML', 'rareEvent'} +experiment.functionEstMethod='logisticLS'; + +% message box +set(handles.textMSG,'backgroundcolor', 'w', 'ForegroundColor', 'b', 'string', '') +set(handles.editMsgFont,'string','7') +set(handles.editSubjectFont,'string','14') + +% default psychometric bin size and logistic slopes +experiment.psyBinWidth=1; % dB +maxLogisticK=2; % steepest slope contemplated +experiment.maxLogisticK=maxLogisticK; +experiment.numPossLogisticK=100; +experiment.possLogSlopes= ... + 0.01: maxLogisticK/experiment.numPossLogisticK: maxLogisticK; +experiment.meanSearchStep=0.25; % dB + +% indicate that this is the first run and the GUI should be located in +% default location. +experiment.justInitialized=1; + +% set up GUI based on training paradigm +aParadigmSelection(handles); +earSetUp(handles) +aThresholdAssessmentMethod(handles) +aShowRelevantObjects(handles) + +% Done. Now wait for action + +% -------------------------------------------- popupmenuMaskerType_Callback +function popupmenuMaskerType_Callback(hObject, eventdata, handles) +% show or remove masker frequency box +aShowRelevantObjects(handles) + +% -------------------------------------------- popupmenuTargetType_Callback +function popupmenuTargetType_Callback(hObject, eventdata, handles) +% show or remove target frequency box +aShowRelevantObjects(handles) + +% -------------------------------------------- popupmenuParadigm_Callback +function popupmenuParadigm_Callback(hObject, eventdata, handles) +% Any change to the paradigm selection causes all boxes to be shown +% showParameters(handles) +aParadigmSelection(handles); + +% -------------------------------------------- aParadigmSelection +function aParadigmSelection(handles) +global experiment stimulusParameters betweenRuns paradigmNames +global variableNames + +% identify paradigm selected +chosenOption=get(handles.popupmenuParadigm,'value'); +paradigm=paradigmNames{chosenOption}; +experiment.paradigm=paradigm; + + %Paradigm: read in all relevant parameters +% a file must exist with this name 'paradigm_<paradigm>' +% 'handles' are only occasionally used +addpath ('paradigms') +cmd=['paradigm_' paradigm '(handles);']; +try + eval(cmd) +catch + error(['ExpGUI\aParadigmSelection:'... + 'paradigm file not found or error in file']) +end +rmpath ('paradigms') + +switch experiment.paradigm + % identify masker free paradigms + case {'training', 'discomfort','absThreshold', 'absThreshold_8',... + 'absThreshold_16','TENtest', 'threshold_duration','SRT'... + 'paradigm_thr_IFMC'} + experiment.maskerInUse=0; + otherwise + experiment.maskerInUse=1; +end + +% if a variable is subject to change, specify list of values here +% eg. stimulusParameters.targetFrequency=betweenRuns.variableList1; +cmd=['stimulusParameters.' ... + betweenRuns.variableName1 '=betweenRuns.variableList1;']; +eval (cmd); +cmd=['stimulusParameters.' ... + betweenRuns.variableName2 '=betweenRuns.variableList2;']; +eval (cmd); + +% establish popup menus on the basis of the paradigm file +set(handles.popupmenuRandomize,'value', betweenRuns.randomizeSequence) +set(handles.popupmenuPhase,'string', stimulusParameters.maskerPhase) +if stimulusParameters.includeCue + set(handles.popupmenuCueNoCue,'value', 1) +else + set(handles.popupmenuCueNoCue,'value', 2) +end + +set(handles.text34, 'string', stimulusParameters.WRVname) + +% Put the new data values into the edit boxes on the GUI +for i=1:length(variableNames) + cmd=(['set(handles.edit' variableNames{i} ... + ',''string'', num2str(stimulusParameters.' ... + variableNames{i} '));']); + eval(cmd); +end +% backgroundLevel is not a variableName (?!) +set(handles.editBackgroundLevel,'string', num2str... + (stimulusParameters.backgroundLevel)) + +% on RUN the sample rate will be picked from the text box +% However, MAP overrules the sample rate and sets its own +aSetSampleRate(stimulusParameters.subjectSampleRate, handles); + + +% used for plotting functions (NB affected by paradigm settings) +experiment.predictionLevels=stimulusParameters.WRVlimits(1):... + experiment.meanSearchStep:stimulusParameters.WRVlimits(2); +experiment.possLogSlopes=abs(experiment.possLogSlopes)*... + sign(experiment.psyFunSlope); + +aResetPopupMenus(handles) + +% ------------------------------------------------------ aResetPopupMenus +function aResetPopupMenus(handles) +global stimulusParameters betweenRuns variableNames +global targetTypes maskerTypes experiment backgroundTypes + +switch experiment.threshEstMethod + case {'MaxLikelihood','oneIntervalUpDown'} + set(handles.editstopCriteriaBox, 'string', ... + num2str(experiment.singleIntervalMaxTrials)) + + case {'2I2AFC++','2I2AFC+++'} + set(handles.editstopCriteriaBox, 'string', ... + num2str(experiment.stopCriteria2IFC)) + otherwise + error([' aResetPopupMenus: threshEstMethod not recognised -> ' ... + experiment.threshEstMethod]) +end + +% forced noCue +switch experiment.paradigm + case 'discomfort' + set(handles.popupmenuCueNoCue,'value', 2) +end + +%set variables popupmenus as specified in betweenRuns +variableParameter1ID=0; variableParameter2ID=0; +for i=1:length(variableNames) + if strcmp(variableNames{i},betweenRuns.variableName1) + variableParameter1ID=i; + end + if strcmp(variableNames{i},betweenRuns.variableName2) + variableParameter2ID=i; + end +end +if variableParameter1ID==0 || variableParameter2ID==0; + Error('a ResetPopMenu: variableParameter not identified') +end + +% display popupmenus +set(handles.popupmenuVaryParameter1, 'value',round(variableParameter1ID)) +set(handles.popupmenuVaryParameter2, 'value',round(variableParameter2ID)) + +% targetType +idx= find(strcmp(stimulusParameters.targetType, targetTypes)); +set(handles.popupmenuTargetType,'value', idx) + +% paradigm selection may alter the maskerType +idx= find(strcmp(stimulusParameters.maskerType, maskerTypes)); +set(handles.popupmenuMaskerType,'value', idx) + +aShowRelevantObjects(handles) + +% % backgroundType popup +idx= find(strcmp(stimulusParameters.backgroundType, backgroundTypes)); +set(handles.popupmenuBackgroundType,'value', idx) +set(handles.editBackgroundLevel,'string', ... + num2str(stimulusParameters.backgroundLevel)) + +% ---------------------------------------------- aShowRelevantObjects +function aShowRelevantObjects(handles) +global experiment stimulusParameters +% called from aShowRelevantObjects +% always on +set(handles.edittargetLevel, 'visible', 'on') +set(handles.edittargetDuration, 'visible', 'on') +set(handles.edittargetFrequency, 'visible', 'on') + +switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent'} + set(handles.editStatsModel, 'visible', 'on') + set(handles.textStatsModel, 'visible', 'on') + set(handles.pushbuttonStop, 'visible', 'on') +showModelPushButtons(handles, 0) + set(handles.editCatchTrialRate, 'visible', 'off') + set(handles.textCatchTrials, 'visible', 'off') + set(handles.editcalibrationdB, 'visible', 'off') + set(handles.textcalibration, 'visible', 'off') + set(handles.popupmenuCueNoCue, 'visible', 'off') + set(handles.textCue, 'visible', 'off') + set(handles.editMusicLevel,'visible', 'off') + set(handles.textMusicLevel,'visible', 'off') + + case {'MAPmodel', 'MAPmodelListen', 'MAPmodelMultiCh', 'MAPmodelSingleCh'} + set(handles.popupmenuCueNoCue, 'visible', 'off') + set(handles.editStatsModel, 'visible', 'off') + set(handles.textStatsModel, 'visible', 'off') + set(handles.pushbuttonStop, 'visible', 'on') +showModelPushButtons(handles, 1) + set(handles.editcalibrationdB, 'visible', 'off') + set(handles.textcalibration, 'visible', 'off') + set(handles.textCue, 'visible', 'off') + set(handles.editMusicLevel,'visible', 'off') + set(handles.textMusicLevel,'visible', 'off') + + otherwise + % i.e. using real subjects (left, right, diotic, dichotic) + set(handles.editStatsModel, 'visible', 'off') + set(handles.textStatsModel, 'visible', 'off') + set(handles.pushbuttonStop, 'visible', 'off') +showModelPushButtons(handles, 0) + set(handles.editCatchTrialRate, 'visible', 'on') + set(handles.textCatchTrials, 'visible', 'on') + set(handles.editcalibrationdB, 'visible', 'on') + set(handles.textcalibration, 'visible', 'on') + set(handles.popupmenuCueNoCue, 'visible', 'on') + set(handles.textCue, 'visible', 'on') + set(handles.editMusicLevel,'visible', 'on') + set(handles.textMusicLevel,'visible', 'on') +end + +switch experiment.threshEstMethod + case {'MaxLikelihood','oneIntervalUpDown'} + set(handles.popupmenuCueNoCue,'visible', 'on') + set(handles.textCue,'visible', 'on') + set(handles.editstopCriteriaBox, 'string', ... + num2str(experiment.singleIntervalMaxTrials)) + + if stimulusParameters.includeCue==0 + set(handles.editcueTestDifference,'visible', 'off') + set(handles.textcueTestDifference,'visible', 'off') + else + set(handles.editcueTestDifference,'visible', 'on') + set(handles.textcueTestDifference,'visible', 'on') + end + + case {'2I2AFC++','2I2AFC+++'} + set(handles.editCatchTrialRate, 'visible', 'off') + set(handles.textCatchTrials, 'visible', 'off') + set(handles.popupmenuCueNoCue,'visible', 'off') + set(handles.textCue,'visible', 'off') + set(handles.editcueTestDifference,'visible', 'off') + set(handles.textcueTestDifference,'visible', 'off') +end + +% show/ remove masker related boxes +if ~experiment.maskerInUse + set(handles.editmaskerDuration,'visible', 'off') + set(handles.editmaskerLevel,'visible', 'off') + set(handles.editmaskerRelativeFrequency,'visible', 'off') + set(handles.editgapDuration,'visible', 'off') + set(handles.textmaskerDuration,'visible', 'off') + set(handles.textmaskerLevel,'visible', 'off') + set(handles.textmaskerRelativeFrequency,'visible', 'off') + set(handles.textgapDuration,'visible', 'off') + set(handles.popupmenuMaskerType,'visible', 'off') + set(handles.textMaskerType,'visible', 'off') + + % paradigms with maskers +else + set(handles.editmaskerDuration,'visible', 'on') + set(handles.editmaskerLevel,'visible', 'on') + set(handles.editmaskerRelativeFrequency,'visible', 'on') + set(handles.editgapDuration,'visible', 'on') + set(handles.popupmenuMaskerType,'visible', 'on') + set(handles.textmaskerDuration,'visible', 'on') + set(handles.textmaskerLevel,'visible', 'on') + set(handles.textmaskerRelativeFrequency,'visible', 'on') + set(handles.textgapDuration,'visible', 'on') + set(handles.popupmenuMaskerType,'visible', 'on') + set(handles.textMaskerType,'visible', 'on') + % masker relative frequency /type + chosenOption=get(handles.popupmenuMaskerType,'value'); + maskerTypes=get(handles.popupmenuMaskerType,'string'); + maskerType=maskerTypes{chosenOption}; + switch maskerType + case 'tone' + set(handles.editmaskerRelativeFrequency,'visible', 'on') + otherwise + set(handles.editmaskerRelativeFrequency,'visible', 'off') + end +end + +eval(['set(handles.edit' stimulusParameters.WRVname ... + ',''visible'',''off'' )']) + +% target type +chosenOption=get(handles.popupmenuTargetType,'value'); +targetTypes=get(handles.popupmenuTargetType,'string'); +targetType=targetTypes{chosenOption}; +switch targetType + case 'tone' + set(handles.edittargetFrequency,'visible', 'on') + otherwise + set(handles.edittargetFrequency,'visible', 'off') +end + +if strcmp(stimulusParameters.backgroundType,'none') + set(handles.popupmenuBackgroundType, 'visible', 'on'); + set(handles.editBackgroundLevel,'visible','off') + set(handles.textBGlevel,'visible','off') +else + set(handles.popupmenuBackgroundType, 'visible', 'on'); + set(handles.editBackgroundLevel,'visible','on') + set(handles.textBGlevel,'visible','on') +end + +% ------------------------------------------------ showModelPushButtons +function showModelPushButtons(handles,on) +if on + set(handles.pushbuttonOME, 'visible', 'on') + set(handles.pushbuttonBM, 'visible', 'on') + set(handles.pushbuttonRP, 'visible', 'on') + set(handles.pushbuttonAN, 'visible', 'on') + set(handles.pushbuttonPhLk, 'visible', 'on') + set(handles.pushbuttonSYN, 'visible', 'on') + set(handles.pushbuttonFM, 'visible', 'on') + set(handles.pushbuttonParams, 'visible', 'on') + set(handles.pushbuttonSingleShot, 'visible', 'on') + set(handles.editMAPplot,'visible', 'on') + set(handles.textMAPplot,'visible', 'on') + +else + set(handles.pushbuttonOME, 'visible', 'off') + set(handles.pushbuttonBM, 'visible', 'off') + set(handles.pushbuttonRP, 'visible', 'off') + set(handles.pushbuttonAN, 'visible', 'off') + set(handles.pushbuttonPhLk, 'visible', 'off') + set(handles.pushbuttonSYN, 'visible', 'off') + set(handles.pushbuttonFM, 'visible', 'off') + set(handles.pushbuttonParams, 'visible', 'off') + set(handles.pushbuttonSingleShot, 'visible', 'off') + set(handles.editMAPplot,'visible', 'off') + set(handles.textMAPplot,'visible', 'off') + +end + +% ------------------------------------------------ pushbuttonRun_Callback +function pushbuttonRun_Callback(hObject, eventdata, handles) +global checkForPreviousGUI % holds screen positioning across repeated calls +global experiment betweenRuns paradigmNames +checkForPreviousGUI.GUIposition=get(handles.figure1,'position'); +experiment.singleShot=0; +switch experiment.paradigm + case 'thr_IFMC' + %% special option for two successive and linked measurements + clc + experiment.paradigm='threshold_16ms'; + set(handles.editstopCriteriaBox,'string','30') % nTrials + run (handles) + + % use these threshold for IFMC + thresholds16ms=betweenRuns.thresholds; + optionNo=strmatch('IFMC_16ms',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + aParadigmSelection(handles) + set(handles.edittargetLevel,'string', thresholds16ms+10); + set(handles.editstopCriteriaBox,'string','30') % nTrials + pause(.1) + run (handles) + + % reset original paradigm + optionNo=strmatch('thr_IFMC',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + aParadigmSelection(handles) + + case 'thr_TMC' + %% special option for two successive and linked measurements + clc + experiment.paradigm='threshold_16ms'; + set(handles.edittargetDuration,'string', num2str(0.25)) + set(handles.editstopCriteriaBox,'string','30') % nTrials + run (handles) + + set(handles.edittargetDuration,'string', num2str(0.016)) + set(handles.editstopCriteriaBox,'string','30') % nTrials + run (handles) + + % use these threshold for TMC + thresholds16ms=betweenRuns.thresholds; + optionNo=strmatch('TMC_16ms',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + aParadigmSelection(handles) + set(handles.edittargetLevel,'string', thresholds16ms+10); + set(handles.editstopCriteriaBox,'string','30') % nTrials + pause(.1) + run (handles) + + % reset original paradigm + optionNo=strmatch('thr_TMC',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + aParadigmSelection(handles) + + otherwise + run (handles) + experiment.stop=0; +end + +function run (handles) +global experiment expGUIhandles stimulusParameters +tic +expGUIhandles=handles; +set(handles.pushbuttonStop, 'backgroundColor', [.941 .941 .941]) + +% message box white (removes any previous error message) +set(handles.textMSG,... + 'backgroundcolor', 'w', 'ForegroundColor', 'b', 'string', '') + +errorMsg=aReadAndCheckParameterBoxes(handles); +if ~isempty(errorMsg) + append=0; + warning=1; + addToMsg(['error message:' errorMsg], append, warning) + return +end + +if isnan(stimulusParameters.targetLevel) + addToMsg('Error: targetlevel not set', 1) + error('Error: targetlevel not set') +end + +set(handles.textMSG,'backgroundcolor', 'w') +set(handles.textMSG,'string', ' ') + +% leave the program and start up multiThreshold +subjGUI_MT % leave the program and start up multiThreshold +experiment.justInitialized=0;% prevents moving subjectGUI +toc + +% --- Executes on button press in pushbuttonSingleShot. +function pushbuttonSingleShot_Callback(hObject, eventdata, handles) +global experiment +experiment.singleShot=1; + +% special test for spontaneous activity +x=get(handles.editWRVstartValues, 'string'); +y=get(handles.edittargetDuration, 'string'); +set(handles.editWRVstartValues, 'string', '-20') +set(handles.edittargetDuration, 'string', '1') + +MAPplot=get(handles.editMAPplot, 'string'); +set(handles.editMAPplot, 'string', '1') +drawnow + +run (handles) + +set(handles.editMAPplot, 'string', MAPplot) +set(handles.editWRVstartValues, 'string', x) +set(handles.edittargetDuration, 'string', y) + +% ------------------------------------------aReadAndCheckParameterBoxes +function errorMsg=aReadAndCheckParameterBoxes(handles) +global experiment stimulusParameters betweenRuns statsModel +global variableNames LevittControl +% When the program sets the parameters all should be well +% But when the user changes them... + +errorMsg=''; + +% name +experiment.name=get(handles.editName,'string'); + +% ear/models +option=get(handles.popupmenuEar,'value'); +strings=get(handles.popupmenuEar,'string'); +experiment.ear=strings{option}; + +switch experiment.ear + case { 'MAPmodel', 'MAPmodelMultiCh', ... + 'MAPmodelSingleCh', 'MAPmodelListen'} + % MAPmodel writes forced parameter settings to the screen + % so that they can be read from there + set(handles.popupmenuRandomize,'value',2) % fixed sequence + set(handles.editstimulusDelay,'string','0.01') % no stimulus delay + stimulusParameters.includeCue=0; % no cue for MAP +end + +% find tone type +option=get(handles.popupmenuTargetType,'value'); +strings=get(handles.popupmenuTargetType,'string'); +stimulusParameters.targetType=strings{option}; + +% find masker type +option=get(handles.popupmenuMaskerType,'value'); +strings=get(handles.popupmenuMaskerType,'string'); +stimulusParameters.maskerType=strings{option}; + +% find background type and level +option=get(handles.popupmenuBackgroundType,'value'); +strings=get(handles.popupmenuBackgroundType,'string'); +stimulusParameters.backgroundTypeValue=option; +stimulusParameters.backgroundLevel=... + str2num(get(handles.editBackgroundLevel,'string')); +stimulusParameters.backgroundType=strings{option}; + +% Read all stimulus parameter boxes +for i=1:length(variableNames) + cmd=['stimulusParameters.' variableNames{i} ... + '= str2num(get(handles.edit' variableNames{i} ',''string'' ));']; + eval(cmd); +end +% for multiple levels +stimulusParameters.targetLevels=stimulusParameters.targetLevel; + +% check that all required values are in the edit boxes +for i=1:length(variableNames)-3 % do not include 'level limits' + eval([ 'variableValues=stimulusParameters.' variableNames{i} ';']) + if isempty(variableValues), errorMsg=[ variableNames{i} ... + ' is an empty box']; return, end +end + +chosenOption=get(handles.popupmenuVaryParameter1,'value'); +betweenRuns.variableName1=variableNames{chosenOption}; +eval(['betweenRuns.variableList1 = stimulusParameters.' ... + betweenRuns.variableName1 ';']); + +chosenOption=get(handles.popupmenuVaryParameter2,'value'); +betweenRuns.variableName2=variableNames{chosenOption}; +eval(['betweenRuns.variableList2 = stimulusParameters.' ... + betweenRuns.variableName2 ';']); + +% Check that variable parameters 1 & 2 have different names +if strcmp(betweenRuns.variableName1,betweenRuns.variableName2) ... + && ~strcmp(betweenRuns.variableName1,'none') + errorMsg='variable parameters have the same name'; + return +end + +% calibration +% this is used to *reduce* the output signal from what it otherwise +% would be +% signal values are between 1 - 2^23 +% these are interpreted as microPascals between -29 dB and 128 dB SPL +% calibrationdB adjusts these values to compensate for equipment +% characteristics +% this will change the range. e.g. a 7 dB calibration will yield +% a range of -36 to 121 dB SPL +% Calibration is not used when modelling. Values are treated as dB SPL +stimulusParameters.calibrationdB=... + str2num(get(handles.editcalibrationdB,'string')); + +% check on cue +cueSetUp(handles) + +stimulusParameters.WRVinitialStep=stimulusParameters.WRVsteps(1); +stimulusParameters.WRVsmallStep=stimulusParameters.WRVsteps(2); + +% jitter start value set after reading in new parameters +switch experiment.paradigm + case 'discomfort' + stimulusParameters.jitterStartdB=0; + otherwise + stimulusParameters.jitterStartdB=abs(stimulusParameters.WRVsteps(1)); +end + + +% stats model mean and slope +statsModelParameters= str2num(get(handles.editStatsModel,'string')); +switch experiment.ear + case {'statsModelLogistic'} + statsModel.logisticMean=statsModelParameters(1) ; + statsModel.logisticSlope=statsModelParameters(2); + statsModel.rareEvenGain=NaN ; + statsModel.rareEventVmin=NaN; + case 'statsModelRareEvent' + statsModel.logisticMean=NaN ; + statsModel.logisticSlope=NaN; + statsModel.rareEvenGain=statsModelParameters(2) ; + statsModel.rareEventVmin=statsModelParameters(1); +end + +% MAP plotting +experiment.MAPplot=str2num(get(handles.editMAPplot,'string')); +% if ~isequal(experiment.MAPplot, 0), +% % any other character will do it +% experiment.MAPplot=1; +% end + +% save data +experiment.saveData=str2num(get(handles.editSaveData,'string')); +if ~isequal(experiment.saveData, 0), + % any other character will do it + experiment.saveData=1; +end + +% print tracks +experiment.printTracks=str2num(get(handles.editPrintTracks,'string')); +if ~isequal(experiment.printTracks, 0), + % any other character will do it + experiment.printTracks=1; +end + +% catch trial rate +% (1)= start rate, (2)= base rate, (3)= time constant (trials) +stimulusParameters.catchTrialRates=... + str2num(get(handles.editCatchTrialRate,'string')); +if stimulusParameters.catchTrialRates(1) ... + < stimulusParameters.catchTrialRates(2) + errorMsg=... + 'catch trial base rates must be less than catch trial start rate'; + return, +end + +% sample rate +% The sample rate is set in the paradigm file. +% Normally this is set in the startUp paradigm file and then left +% When the model is used, the multiThreshold sample rate +% overrules anything in the model +stimulusParameters.sampleRate=... + str2num(get(handles.textsampleRate,'string')); + +% music level +stimulusParameters.musicLeveldB=... + str2num(get(handles.editMusicLevel,'string')); + +% set message box font size +experiment.msgFontSize=str2num(get(handles.editMsgFont,'string')); +experiment.subjGUIfontSize=str2num(get(handles.editSubjectFont,'string')); + +% stop criteria +experiment.singleIntervalMaxTrials=... + str2num(get(handles.editstopCriteriaBox,'string')); +experiment.maxTrials=experiment.singleIntervalMaxTrials(1); + +% set up 2IFC is required (? better in atrhesholdAssessmentMethod) +switch experiment.threshEstMethod + case {'2I2AFC++', '2A2AIFC+++'} + experiment.peaksUsed=experiment.singleIntervalMaxTrials(2); + experiment.PeakTroughCriterionSD=... + experiment.singleIntervalMaxTrials(3); + experiment.trialsToBeUsed= 5; + LevittControl.maxTrials=experiment.singleIntervalMaxTrials(1); + % start value for step until reduced + LevittControl.startLevelStep= stimulusParameters.WRVsteps(1); + % reduced step size + LevittControl.steadyLevittStep= stimulusParameters.WRVsteps(2); + LevittControl.TurnsToSmallSteps= 2; + LevittControl.useLastNturns= 2*experiment.peaksUsed; + LevittControl.minReversals= ... + LevittControl.TurnsToSmallSteps+2*experiment.peaksUsed; + LevittControl.targetsdPT = experiment.PeakTroughCriterionSD; + LevittControl.maxLevittValue= stimulusParameters.WRVlimits(2); + Levitt2; +end + +% What kind of randomisation is required? +idx=get(handles.popupmenuRandomize,'value'); +s=get(handles.popupmenuRandomize,'string'); +betweenRuns.randomizeSequence=s{idx}; + +% Make small adjustments to variable values +% to keep values unique against later sorting +x=betweenRuns.variableList1; +[y idx]= sort(x); +for i=1:length(y)-1, if y(i+1)==y(i); y(i+1)=y(i)*1.001; end, end +x(idx)=y; +betweenRuns.variableList1=x; + +x=betweenRuns.variableList2; +[y idx]= sort(x); +for i=1:length(y)-1, if y(i+1)==y(i); y(i+1)=y(i)*1.001; end, end +x(idx)=y; +betweenRuns.variableList2=x; + +% Checks: after reading and setting parameters ------------------------------------------ +% check for finger trouble (more checks possible +if stimulusParameters.maskerDuration>10 + errorMsg='maskerDuration is too long'; return, end +if stimulusParameters.gapDuration>10 + errorMsg='gapDuration is too long'; return, end +if stimulusParameters.targetDuration>10 + errorMsg='targetDuration is too long'; return, end + +% rare event slope check +if experiment.psyFunSlope<0 ... + && strcmp(experiment.functionEstMethod,'rareEvent') + errorMsg='cannot use rareEvent option for negative psychometr slopes'; + return +end + +% check ramps +if stimulusParameters.rampDuration*2> stimulusParameters.targetDuration + errorMsg=' ramp duration is too long for the target'; + return +end + +if max(stimulusParameters.maskerDuration)>0 ... + && max(stimulusParameters.rampDuration... + *2> stimulusParameters.maskerDuration) + errorMsg=' ramp duration is too long for the masker'; + return +end + +% Check WRVstartValues for length and compatibility with randomization +% only one start value supplied so all start values are the same +if length(stimulusParameters.WRVstartValues)==1 + stimulusParameters.WRVstartValues= ... + repmat(stimulusParameters.WRVstartValues, 1, ... + length(betweenRuns.variableList1)... + *length(betweenRuns.variableList2)); +elseif ~isequal(length(stimulusParameters.WRVstartValues), ... + length(betweenRuns.variableList1)... + *length(betweenRuns.variableList2)) + % otherwise we need one value for each combination of var1/ var2 + errorMsg='WRVstartValues not the same length as number of runs'; + return +elseif strcmp(betweenRuns.randomizeSequence, 'randomize within blocks')... + && length(stimulusParameters.WRVstartValues)>1 + errorMsg='multiple WRVstartValues inappropriate'; + return +end + +% set the target level in advance for every wnticipated run +switch experiment.paradigm + case {'trainingIFMC', 'TMC','TMC_16ms', 'TMC - ELP', ... + 'IFMC', 'IFMC_16ms'} + % For TMC and IFMC multiple target levels can be set + if length(stimulusParameters.targetLevel)==1 + betweenRuns.targetLevels=... + repmat(stimulusParameters.targetLevel, 1, ... + length(betweenRuns.variableList1)... + *length(betweenRuns.variableList2)); + elseif length(stimulusParameters.targetLevel)==... + length(betweenRuns.variableList2) + % only one level specified, so use this throughout + x=stimulusParameters.targetLevel; + x=repmat(x,length(betweenRuns.variableList1),1); + x=reshape(x,1,length(betweenRuns.variableList1)*length(betweenRuns.variableList2)); + betweenRuns.targetLevels=x; + else + errorMsg='targetLevels not the same length as number of targetFrequencies'; + end +end + +switch experiment.paradigm + case {'gapDetection', 'frequencyDiscrimination'} + if ~isequal(stimulusParameters.targetDuration, ... + stimulusParameters.maskerDuration) + addToMsg(... + 'Warning: masker and target duration not the same.',1,1) + end + if ~isequal(stimulusParameters.maskerLevel, ... + stimulusParameters.targetLevel) + addToMsg(['Warning: masker and target level different.'... + 'They will be changed to be equal',1,1]); + end +end + +% -------------------------------------------- aSetSampleRate +function aSetSampleRate(sampleRate, handles) +global stimulusParameters +stimulusParameters.sampleRate=sampleRate; +set(handles.textsampleRate,'string',num2str(stimulusParameters.sampleRate)) + +% -------------------------------------------- popupmenuEar_Callback +function popupmenuEar_Callback(hObject, eventdata, handles) +global experiment +option=get(handles.popupmenuEar,'value'); +options=get(handles.popupmenuEar,'string'); % left/right/model +experiment.ear=options{option}; +switch experiment.ear + case 'statsModelLogistic' + set(handles.editStatsModel,'string', '15, 0.5') + case 'statsModelRareEvent' + set(handles.editStatsModel,'string', '20 1') +end +earSetUp(handles) + +% -------------------------------------------- earSetUp +function earSetUp(handles) +global experiment stimulusParameters +% option=get(handles.popupmenuEar,'value'); +% options=get(handles.popupmenuEar,'string'); % left/right/model +% experiment.ear=options{option}; + +switch experiment.ear + case {'statsModelLogistic'} + statsModel.logisticSlope=0.5; + statsModel.logisticMean=15; + set(handles.editStatsModel,'string', ... + num2str([statsModel.logisticMean statsModel.logisticSlope])) + set(handles.textStatsModel,... + 'string', {'statsModel',' logistic threshold\ slope'}) + case 'statsModelRareEvent' + set(handles.textStatsModel,'string', ... + {'statsModel',' rareEvent Vmin\ gain'}) +end + +switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent'} + set(handles.editStatsModel, 'visible', 'off') + set(handles.textStatsModel, 'visible', 'off') + + % default psychometric bin size and logistic slopes + set(handles.popupmenuRandomize,'value',2) % fixed sequence + set(handles.editName,'string', 'statsModel') + % experiment.headphonesUsed=0; + + case {'MAPmodelListen', 'MAPmodelMultiCh', 'MAPmodelSingleCh'} + stimulusParameters.includeCue=0; % no cue + set(handles.popupmenuCueNoCue,'value', 2) + + set(handles.editCatchTrialRate,'string','0 0 2 ');%no catch trials + set(handles.editName,'string', 'Normal') % force name + experiment.name=get(handles.editName,'string'); % read name back + set(handles.editcalibrationdB,'string','0') + + set(handles.popupmenuRandomize,'value',2) % fixed sequence + set(handles.editstimulusDelay,'string','0') + + set(handles.editSaveData,'string', '0') + set(handles.editSubjectFont,'string', '10'); + experiment.MacGThreshold=0; % num MacG spikes to exceed threshold +end +aResetPopupMenus(handles) + +% --------------------------------------------- popupmenuCueNoCue_Callback +function popupmenuCueNoCue_Callback(hObject, eventdata, handles) +cueSetUp(handles) + +% ------------------------------------------------------------- cueSetUp +function cueSetUp(handles) +global stimulusParameters + +chosenOption=get(handles.popupmenuCueNoCue,'value'); +if chosenOption==1 + stimulusParameters.includeCue=1; + set(handles.editcueTestDifference,'visible', 'on') + set(handles.textcueTestDifference,'visible', 'on') + stimulusParameters.subjectText=stimulusParameters.instructions{2}; +else + stimulusParameters.includeCue=0; + set(handles.editcueTestDifference,'visible', 'off') + set(handles.textcueTestDifference,'visible', 'off') + stimulusParameters.subjectText= stimulusParameters.instructions{1}; +end + +% -------------------------------------------- popupmenuThreshEst_Callback +function popupmenuThreshEst_Callback(hObject, eventdata, handles) +aThresholdAssessmentMethod(handles); + +% --------------------------------------------- aThresholdAssessmentMethod +function aThresholdAssessmentMethod(handles) +% identify the threshold assessment method +% and set various parameters on the GUI appropriately +global stimulusParameters experiment threshEstNames LevittControl + +chosenOption=get(handles.popupmenuThreshEst,'value'); +experiment.threshEstMethod=threshEstNames{chosenOption}; +set(handles.editCatchTrialRate, 'visible', 'on') +set(handles.textCatchTrials, 'visible', 'on') + +% establish appropriate stop criterion and post on GUI +switch experiment.threshEstMethod + case 'MaxLikelihood' + experiment.functionEstMethod='logisticML'; + stimulusParameters.WRVsteps=10*experiment.psyFunSlope; % ??? + set(handles.textstopCriteria,'string', 'stop criteria \ maxTrials') + experiment.singleIntervalMaxTrials=experiment.stopCriteriaSI; + experiment.allowCatchTrials= 1; + switch experiment.paradigm + case 'training' + experiment.possLogSlopes=0.5; + end + + case 'oneIntervalUpDown' + experiment.functionEstMethod='logisticLS'; + set(handles.textstopCriteria,'string', 'stop criteria \ maxTrials') + experiment.singleIntervalMaxTrials=experiment.stopCriteriaSI; + switch experiment.paradigm + case 'discomfort' + experiment.allowCatchTrials= 0; + otherwise + experiment.allowCatchTrials= 1; + end + + case {'2I2AFC++', '2I2AFC+++'} + LevittControl.rule='++'; % e.g. '++' or '+++' + experiment.singleIntervalMaxTrials=experiment.stopCriteria2IFC; + experiment.functionEstMethod='peaksAndTroughs'; + LevittControl.maxTrials=experiment.singleIntervalMaxTrials(1); + set(handles.editWRVsteps,'string', ... + num2str(stimulusParameters.WRVsteps)) + set(handles.textstopCriteria,'string', {'trials peaks sdCrit'}) + experiment.allowCatchTrials= 0; +end + +set(handles.textstopCriteria,'fontSize',8) +set(handles.editstopCriteriaBox,'string',... + num2str(experiment.singleIntervalMaxTrials)) + +% establish the appropriate instructions to the subject +% NB responsibility for this is now transferred to the paradigm file +switch experiment.threshEstMethod + % only one value required for level change + case {'2I2AFC++', '2A2AIFC+++'} + stimulusParameters.subjectText=... + 'did the tone occur in window 1 or 2?'; + case {'MaxLikelihood', 'oneIntervalUpDown'}; + switch stimulusParameters.includeCue + case 0 + stimulusParameters.subjectText=... + stimulusParameters.instructions{1}; + case 1 + stimulusParameters.subjectText= ... + stimulusParameters.instructions{2}; + end +end +stimulusParameters.messageString={'training'}; + +aResetPopupMenus(handles) +% -------------------------------------------------- function orderGlobals +function orderGlobals +global stimulusParameters experiment betweenRuns withinRuns + +stimulusParameters=[]; +stimulusParameters.sampleRate= []; +stimulusParameters.targetType= ''; +stimulusParameters.targetFrequency= []; +stimulusParameters.targetDuration= []; +stimulusParameters.targetLevel= []; +stimulusParameters.gapDuration= []; +stimulusParameters.maskerType= ''; +stimulusParameters.maskerRelativeFrequency= []; +stimulusParameters.maskerDuration= []; +stimulusParameters.maskerLevel= []; +stimulusParameters.backgroundType= ''; +stimulusParameters.backgroundTypeValue= []; +stimulusParameters.backgroundLevel= []; +stimulusParameters.includeCue= []; +experiment.clickToStimulusPause=[]; +stimulusParameters.stimulusDelay= []; +stimulusParameters.rampDuration= []; +stimulusParameters.absThresholds= []; +stimulusParameters.numOHIOtones= []; + +stimulusParameters.WRVname= ''; +stimulusParameters.WRVstartValues= []; +stimulusParameters.WRVsteps= []; +stimulusParameters.WRVlimits= []; +stimulusParameters.WRVinitialStep= []; +stimulusParameters.WRVsmallStep= []; +experiment.singleIntervalMaxTrials= []; +stimulusParameters.calibrationdB= []; + +stimulusParameters.catchTrialRates= []; +stimulusParameters.catchTrialBaseRate= []; +stimulusParameters.catchTrialRate= []; +stimulusParameters.catchTrialTimeConstant= []; + +stimulusParameters.dt= []; + +stimulusParameters.jitterStartdB= []; +stimulusParameters.restoreCalibration= []; +stimulusParameters.messageString= []; +stimulusParameters.cueTestDifference= []; +stimulusParameters.subjectText= ''; +stimulusParameters.testTargetBegins= []; +stimulusParameters.testTargetEnds= []; +stimulusParameters.musicLeveldB= []; + +stimulusParameters.subjectSampleRate=[]; +stimulusParameters.MAPSampleRate=[]; + +experiment=[]; +experiment.name= ''; +experiment.date= ''; +experiment.paradigm= ''; +experiment.ear= ''; +experiment.headphonesUsed=[]; +experiment.singleShot= []; +experiment.randomize= ''; +experiment.maxTrials= []; +experiment.MacGThreshold= []; +experiment.resetCriterion= []; +experiment.runResetCriterion= []; + +experiment.comparisonData= []; +experiment.absThresholds= []; +experiment.threshEstMethod= ''; +experiment.functionEstMethod= ''; +experiment.psyBinWidth= []; +experiment.maxLogisticK=2; +experiment.numPossLogisticK=100; +experiment.possLogSlopes= []; +experiment.meanSearchStep= []; +experiment.psyFunSlope= []; +experiment.predictionLevels=[]; + +experiment.buttonBoxType= ''; +experiment.buttonBoxStatus= ''; +experiment.status= ''; +experiment.stop= 0; +experiment.pleaseRepeat= []; +experiment.justInitialized=[]; + +experiment.MAPplot= []; +experiment.saveData= []; +experiment.printTracks= []; +experiment.msgFontSize= []; +experiment.subjGUIfontSize= []; + +experiment.timeAtStart= ''; +experiment.minElapsed= []; + +betweenRuns=[]; +betweenRuns.variableName1= ''; +betweenRuns.variableList1= []; +betweenRuns.variableName2= ''; +betweenRuns.variableList2= []; +betweenRuns.var1Sequence= []; +betweenRuns.var2Sequence= []; +betweenRuns.randomizeSequence=[]; +betweenRuns.timeNow= []; +betweenRuns.runNumber= []; +% betweenRuns.variableCount1= []; +% betweenRuns.variableCount2= []; +betweenRuns.thresholds= []; +betweenRuns.forceThresholds= []; +betweenRuns.observationCount= []; +betweenRuns.timesOfFirstReversals= []; +betweenRuns.bestThresholdTracks=''; +betweenRuns.levelTracks=''; +betweenRuns.responseTracks=''; +betweenRuns.slopeKTracks= []; +betweenRuns.gainTracks= []; +betweenRuns.VminTracks= []; +betweenRuns.bestGain= []; +betweenRuns.bestVMin= []; +betweenRuns.bestPaMin= []; +betweenRuns.bestLogisticM= []; +betweenRuns.bestLogisticK= []; +betweenRuns.psychometicFunction=''; +betweenRuns.catchTrials= []; +betweenRuns.caughtOut= []; + +withinRuns=[]; +withinRuns.trialNumber=[]; +withinRuns.nowInPhase2=0; +withinRuns.beginningOfPhase2=0; +withinRuns.variableValue=[]; +withinRuns.direction=''; +withinRuns.peaks=[]; +withinRuns.troughs= []; +withinRuns.levelList= []; +withinRuns.responseList= []; +withinRuns.meanEstTrack= []; +withinRuns.meanLogisticEstTrack=[]; +withinRuns.bestSlopeK= []; +withinRuns.bestGain= []; +withinRuns.bestVMin= []; +withinRuns.forceThreshold=[]; +withinRuns.catchTrial= []; +withinRuns.caughtOut=[]; +withinRuns.catchTrialCount=[]; +withinRuns.wrongButton= []; +withinRuns.babblePlaying=0; + +% --- Executes on selection change in popupmenuBackgroundType. +function popupmenuBackgroundType_Callback(hObject, eventdata, handles) +global backgroundTypes +option=get(handles.popupmenuBackgroundType,'value'); +selectedBackground=backgroundTypes{option}; +stimulusParameters.backgroundType=selectedBackground; + +switch selectedBackground + case 'none' + set(handles.editBackgroundLevel,'visible','off') + set(handles.textBGlevel,'visible','off') + otherwise + set(handles.editBackgroundLevel,'visible','on') + set(handles.textBGlevel,'visible','on') +end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function pushbuttonStop_Callback(hObject, eventdata, handles) +global experiment +experiment.stop=1; +disp('stop!') +set(handles.pushbuttonStop, 'backgroundColor','r') +pause(.1) +drawnow + +function pushbuttonOME_Callback(hObject, eventdata, handles) +aReadAndCheckParameterBoxes(handles); +testOME + +function pushbuttonBM_Callback(hObject, eventdata, handles) +global stimulusParameters experiment +aReadAndCheckParameterBoxes(handles); +testBM(stimulusParameters.targetFrequency, experiment.name); + +function pushbuttonAN_Callback(hObject, eventdata, handles) +global stimulusParameters +aReadAndCheckParameterBoxes(handles); +% now carry out tests +showPSTHs=0; +targetFrequency=stimulusParameters.targetFrequency(1); +BFlist=targetFrequency; + +testAN(targetFrequency,BFlist); + +function pushbuttonPhLk_Callback(hObject, eventdata, handles) +aReadAndCheckParameterBoxes(handles); +testPhaseLocking + +function pushbuttonSYN_Callback(hObject, eventdata, handles) +aReadAndCheckParameterBoxes(handles); +testSynapse + +function pushbuttonFM_Callback(hObject, eventdata, handles) +aReadAndCheckParameterBoxes(handles); +testFM + +function popupmenuPhase_Callback(hObject, eventdata, handles) +global stimulusParameters + +optionNo=get(handles.popupmenuPhase,'value'); +options=get(handles.popupmenuPhase,'string'); +phase=options{optionNo}; +stimulusParameters.maskerPhase=phase; +stimulusParameters.targetPhase=phase; + +function pushbuttonParams_Callback(hObject, eventdata, handles) +global experiment stimulusParameters +aReadAndCheckParameterBoxes(handles); +% print model parameters using the 'name' box (e.g. CTa -> MAPparamsCTa) +showParams=1; BFlist=-1; +paramFunctionName=['method=MAPparams' experiment.name ... + '(BFlist, stimulusParameters.sampleRate, showParams);']; +eval(paramFunctionName) % go and fetch the parameters requesting parameter printout + + +% --- Executes on button press in pushbuttonRP. +function pushbuttonRP_Callback(hObject, eventdata, handles) +global experiment stimulusParameters +aReadAndCheckParameterBoxes(handles); +% now carry out test +testRP(stimulusParameters.targetFrequency,experiment.name) + +% function handles % ?? + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function editmaskerDuration_Callback(hObject, eventdata, handles) + +function editmaskerDuration_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editmaskerLevel_Callback(hObject, eventdata, handles) + +function editmaskerLevel_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editmaskerRelativeFrequency_Callback(hObject, eventdata, handles) + +function editmaskerRelativeFrequency_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editWRVstartValues_Callback(hObject, eventdata, handles) + +function editWRVstartValues_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editgapDuration_Callback(hObject, eventdata, handles) + +function editgapDuration_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function edittargetDuration_Callback(hObject, eventdata, handles) + +function edittargetDuration_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function edittargetLevel_Callback(hObject, eventdata, handles) + +function edittargetLevel_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editrampDuration_Callback(hObject, eventdata, handles) + +function editrampDuration_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editcueTestDifference_Callback(hObject, eventdata, handles) + +function editcueTestDifference_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function editWRVsteps_Callback(hObject, eventdata, handles) + +function editWRVsteps_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editWRVlimits_Callback(hObject, eventdata, handles) + +function editWRVlimits_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function edittargetFrequency_Callback(hObject, eventdata, handles) + +function edittargetFrequency_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editName_Callback(hObject, eventdata, handles) + +function editName_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editcalibrationdB_Callback(hObject, eventdata, handles) + +function editcalibrationdB_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editMAPplot_Callback(hObject, eventdata, handles) + +function editMAPplot_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editMsgFont_Callback(hObject, eventdata, handles) + +function editMsgFont_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editCatchTrialRate_Callback(hObject, eventdata, handles) + +function editCatchTrialRate_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function editSaveData_Callback(hObject, eventdata, handles) + +function editSaveData_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editStatsModel_Callback(hObject, eventdata, handles) + +function editStatsModel_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editBackgroundLevel_Callback(hObject, eventdata, handles) + +function editBackgroundLevel_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editPrintTracks_Callback(hObject, eventdata, handles) + +function editPrintTracks_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editstopCriteriaBox_Callback(hObject, eventdata, handles) + +function editstopCriteriaBox_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editstimulusDelay_Callback(hObject, eventdata, handles) + +function editstimulusDelay_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function popupmenuCueNoCue_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function popupmenuEar_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','red'); +end + +function popupmenuVaryParameter1_Callback(hObject, eventdata, handles) + +function popupmenuVaryParameter1_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function popupmenuVaryParameter2_Callback(hObject, eventdata, handles) + +function popupmenuVaryParameter2_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function popupmenuRandomize_Callback(hObject, eventdata, handles) + +function popupmenuRandomize_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function popupmenuParadigm_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function popupmenuMaskerType_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function popupmenuThreshEst_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function popupmenuBackgroundType_CreateFcn(hObject, eventdata, handles) + +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function popupmenuTargetType_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editSubjectFont_Callback(hObject, eventdata, handles) + +function editSubjectFont_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editMusicLevel_Callback(hObject, eventdata, handles) + +function editMusicLevel_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function figure1_ButtonDownFcn(hObject, eventdata, handles) + + +function edit33_Callback(hObject, eventdata, handles) + +function edit33_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function popupmenuPhase_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +function editsegSize_Callback(hObject, eventdata, handles) + +function editsegSize_CreateFcn(hObject, eventdata, handles) +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +function editnumOHIOtones_Callback(hObject, eventdata, handles) +% hObject handle to editnumOHIOtones (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of editnumOHIOtones as text +% str2double(get(hObject,'String')) returns contents of editnumOHIOtones as a double + + +% --- Executes during object creation, after setting all properties. +function editnumOHIOtones_CreateFcn(hObject, eventdata, handles) +% hObject handle to editnumOHIOtones (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/hs_err_pid6084.log Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,258 @@ +# +# An unexpected error has been detected by Java Runtime Environment: +# +# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000002e47250, pid=6084, tid=5820 +# +# Java VM: Java HotSpot(TM) 64-Bit Server VM (1.6.0-b105 mixed mode) +# Problematic frame: +# C [libmwgui.dll+0x77250] +# +# If you would like to submit a bug report, please visit: +# http://java.sun.com/webapps/bugreport/crash.jsp +# + +--------------- T H R E A D --------------- + +Current thread (0x0000000003d2fc00): JavaThread "main" [_thread_in_native, id=5820] + +siginfo: ExceptionCode=0xc0000005, reading address 0x0000000000000000 + +Registers: +EAX=0x0000000000000000, EBX=0x0000000000000000, ECX=0x0000000000000000, EDX=0x0000000000000000 +ESP=0x00000000010296f8, EBP=0x0000000000000001, ESI=0x0000000000000000, EDI=0x0000000000000000 +EIP=0x0000000002e47250, EFLAGS=0x0000000000010206 + +Top of Stack: (sp=0x00000000010296f8) +0x00000000010296f8: 0000000002fb728f 4010002000000000 +0x0000000001029708: 0000000000000000 0000000035937370 +0x0000000001029718: 0000000002e596dd 0000000008a3cf00 +0x0000000001029728: 0000000002f7fb49 4010000000000000 +0x0000000001029738: 4008000000000000 0000000000000000 +0x0000000001029748: 0000000000000000 0000000008a3cf60 +0x0000000001029758: 0000000002fb72be 0000000008a3cf00 +0x0000000001029768: 0000000000000001 4010000000000000 +0x0000000001029778: 0000000000000000 0000000000000000 +0x0000000001029788: 0000000002f8d1de 0000000000000000 +0x0000000001029798: 0000000008a3cf60 0000000000000001 +0x00000000010297a8: 000000001176d320 0000000009e522a0 +0x00000000010297b8: 000000000319bd9e 0000000008a3cf60 +0x00000000010297c8: 0000000000000020 0000000000000002 +0x00000000010297d8: 00000000013b7338 0000000008a3cf50 +0x00000000010297e8: 00000000359f17a0 000000003c19ca80 + +Instructions: (pc=0x0000000002e47250) +0x0000000002e47240: 89 11 c3 cc cc cc cc cc cc cc cc cc cc cc cc cc +0x0000000002e47250: 8b 01 c3 cc cc cc cc cc cc cc cc cc cc cc cc cc + + +Stack: [0x0000000000030000,0x0000000001030000), sp=0x00000000010296f8, free space=16357k +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +C [libmwgui.dll+0x77250] + +Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) +j com.mathworks.jmi.NativeMatlab.SendMatlabMessage(Ljava/lang/Object;)Ljava/lang/Object;+0 +j com.mathworks.jmi.NativeMatlab.sendMatlabMessage(Ljava/lang/Object;)Ljava/lang/Object;+22 +j com.mathworks.jmi.MatlabLooper.sendMatlabMessage(Lcom/mathworks/services/message/MWMessage;)Ljava/lang/Object;+20 +j com.mathworks.jmi.Matlab.mtFevalConsoleOutput(Ljava/lang/String;[Ljava/lang/Object;I)Ljava/lang/Object;+58 +j com.mathworks.mde.desk.MLDesktop$5.run()V+14 +j com.mathworks.jmi.NativeMatlab.dispatchMTRequests(Z)V+50 +v ~StubRoutines::call_stub + +--------------- P R O C E S S --------------- + +Java Threads: ( => current thread ) + 0x0000000011b68400 JavaThread "Thread-168" [_thread_blocked, id=3544] + 0x0000000011b68c00 JavaThread "Prefs Updater" [_thread_blocked, id=6864] + 0x0000000011b67000 JavaThread "Thread-8" [_thread_blocked, id=6900] + 0x0000000011b66800 JavaThread "Thread-7" [_thread_blocked, id=6792] + 0x0000000011b66000 JavaThread "Thread-6" [_thread_blocked, id=868] + 0x0000000011b65800 JavaThread "Thread-5" [_thread_blocked, id=6628] + 0x0000000030e0a000 JavaThread "Active Reference Queue Daemon" daemon [_thread_blocked, id=1428] + 0x0000000011b97800 JavaThread "Timer-2" daemon [_thread_blocked, id=3276] + 0x0000000030ded400 JavaThread "Timer-1" daemon [_thread_blocked, id=6912] + 0x0000000011a81000 JavaThread "TimerQueue" daemon [_thread_blocked, id=5220] + 0x00000000117fd400 JavaThread "AWT-EventQueue-0" [_thread_blocked, id=120] + 0x00000000114dec00 JavaThread "AWT-Windows" daemon [_thread_in_native, id=3212] + 0x00000000114de400 JavaThread "AWT-Shutdown" [_thread_blocked, id=6512] + 0x00000000114ddc00 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=4896] + 0x0000000011244c00 JavaThread "Timer-0" [_thread_blocked, id=3172] + 0x000000000fb42400 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=2312] + 0x000000000fb40000 JavaThread "CompilerThread1" daemon [_thread_blocked, id=3556] + 0x000000000fb3b800 JavaThread "CompilerThread0" daemon [_thread_blocked, id=2260] + 0x000000000fb37400 JavaThread "Attach Listener" daemon [_thread_blocked, id=6760] + 0x000000000fb1f400 JavaThread "Finalizer" daemon [_thread_blocked, id=5488] + 0x000000000fb19800 JavaThread "Reference Handler" daemon [_thread_blocked, id=6300] +=>0x0000000003d2fc00 JavaThread "main" [_thread_in_native, id=5820] + +Other Threads: + 0x000000000fb16000 VMThread [id=7068] + 0x000000000fb47800 WatcherThread [id=4288] + +VM state:not at safepoint (normal execution) + +VM Mutex/Monitor currently owned by a thread: None + +Heap + PSYoungGen total 7104K, used 6681K [0x00000000265a0000, 0x0000000026d80000, 0x00000000296a0000) + eden space 6400K, 97% used [0x00000000265a0000,0x0000000026bb6710,0x0000000026be0000) + from space 704K, 63% used [0x0000000026cd0000,0x0000000026d40000,0x0000000026d80000) + to space 832K, 0% used [0x0000000026be0000,0x0000000026be0000,0x0000000026cb0000) + PSOldGen total 47616K, used 41927K [0x000000001d2a0000, 0x0000000020120000, 0x00000000265a0000) + object space 47616K, 88% used [0x000000001d2a0000,0x000000001fb91f18,0x0000000020120000) + PSPermGen total 80384K, used 43275K [0x00000000152a0000, 0x000000001a120000, 0x000000001d2a0000) + object space 80384K, 53% used [0x00000000152a0000,0x0000000017ce2c78,0x000000001a120000) + +Dynamic libraries: +0x0000000140000000 - 0x0000000140138000 C:\Program Files\MATLAB\R2008a\bin\win64\MATLAB.exe +0x0000000077420000 - 0x00000000775c9000 C:\Windows\SYSTEM32\ntdll.dll +0x0000000077300000 - 0x000000007741f000 C:\Windows\system32\kernel32.dll +0x000007fefd440000 - 0x000007fefd4ab000 C:\Windows\system32\KERNELBASE.dll +0x0000000180000000 - 0x0000000180401000 C:\Program Files\MATLAB\R2008a\bin\win64\libut.dll +0x000007fefee00000 - 0x000007fefee17000 C:\Windows\system32\imagehlp.dll +0x000007fefd7c0000 - 0x000007fefd85f000 C:\Windows\system32\msvcrt.dll +0x00000000775f0000 - 0x00000000775f7000 C:\Windows\system32\PSAPI.DLL +0x00000000011e0000 - 0x0000000001208000 C:\Program Files\MATLAB\R2008a\bin\win64\LIBEXPAT.dll +0x0000000073a30000 - 0x0000000073af9000 C:\Windows\WinSxS\amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.5592_none_88e45feb2faab9ce\MSVCR80.dll +0x000000004a800000 - 0x000000004a917000 C:\Program Files\MATLAB\R2008a\bin\win64\icuuc36.dll +0x000007fefea70000 - 0x000007fefeb4b000 C:\Windows\system32\ADVAPI32.dll +0x000007feff180000 - 0x000007feff19f000 C:\Windows\SYSTEM32\sechost.dll +0x000007feff2d0000 - 0x000007feff3fd000 C:\Windows\system32\RPCRT4.dll +0x0000000001220000 - 0x0000000001223000 C:\Program Files\MATLAB\R2008a\bin\win64\icudt36.dll +0x000000004ab00000 - 0x000000004ab0f000 C:\Program Files\MATLAB\R2008a\bin\win64\icuio36.dll +0x0000000001250000 - 0x0000000001356000 C:\Program Files\MATLAB\R2008a\bin\win64\icuin36.dll +0x0000000072330000 - 0x0000000072439000 C:\Windows\WinSxS\amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.5592_none_88e45feb2faab9ce\MSVCP80.dll +0x0000000077200000 - 0x00000000772fa000 C:\Windows\system32\USER32.dll +0x000007fefd750000 - 0x000007fefd7b7000 C:\Windows\system32\GDI32.dll +0x000007fefea60000 - 0x000007fefea6e000 C:\Windows\system32\LPK.dll +0x000007feff030000 - 0x000007feff0f9000 C:\Windows\system32\USP10.dll +0x0000000001370000 - 0x00000000014e4000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwservices.dll +0x0000000001500000 - 0x0000000001570000 C:\Program Files\MATLAB\R2008a\bin\win64\libmx.dll +0x0000000001580000 - 0x0000000001597000 C:\Program Files\MATLAB\R2008a\bin\win64\zlib1.dll +0x00000000015a0000 - 0x0000000001648000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwmathutil.dll +0x0000000001660000 - 0x00000000016b5000 C:\Program Files\MATLAB\R2008a\bin\win64\mpath.dll +0x00000000016d0000 - 0x00000000016f1000 C:\Program Files\MATLAB\R2008a\bin\win64\mlutil.dll +0x000007fef9870000 - 0x000007fef9910000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7601.17514_none_a4d6a923711520a9\COMCTL32.dll +0x000007fefec90000 - 0x000007fefed27000 C:\Windows\system32\comdlg32.dll +0x000007fefed80000 - 0x000007fefedf1000 C:\Windows\system32\SHLWAPI.dll +0x000007fefd970000 - 0x000007fefe6f8000 C:\Windows\system32\SHELL32.dll +0x000007fefc840000 - 0x000007fefc856000 C:\Windows\system32\NETAPI32.dll +0x000007fefc830000 - 0x000007fefc83c000 C:\Windows\system32\netutils.dll +0x000007fefcee0000 - 0x000007fefcf03000 C:\Windows\system32\srvcli.dll +0x000007fefc810000 - 0x000007fefc825000 C:\Windows\system32\wkscli.dll +0x000007fefed30000 - 0x000007fefed7d000 C:\Windows\system32\WS2_32.dll +0x000007fefd740000 - 0x000007fefd748000 C:\Windows\system32\NSI.dll +0x0000000001710000 - 0x0000000001765000 C:\Program Files\MATLAB\R2008a\bin\win64\mcr.dll +0x0000000001780000 - 0x00000000017a5000 C:\Program Files\MATLAB\R2008a\bin\win64\iqm.dll +0x00000000017c0000 - 0x00000000017e1000 C:\Program Files\MATLAB\R2008a\bin\win64\bridge.dll +0x0000000001800000 - 0x0000000001811000 C:\Program Files\MATLAB\R2008a\bin\win64\libmex.dll +0x0000000001830000 - 0x00000000018bc000 C:\Program Files\MATLAB\R2008a\bin\win64\m_dispatcher.dll +0x00000000018d0000 - 0x00000000018f5000 C:\Program Files\MATLAB\R2008a\bin\win64\datasvcs.dll +0x0000000012000000 - 0x0000000012295000 C:\Program Files\MATLAB\R2008a\bin\win64\xerces-c_2_7.dll +0x0000000001920000 - 0x00000000021b1000 C:\Program Files\MATLAB\R2008a\bin\win64\m_interpreter.dll +0x00000000021d0000 - 0x0000000002201000 C:\Program Files\MATLAB\R2008a\bin\win64\libmat.dll +0x0000000002220000 - 0x0000000002325000 C:\Program Files\MATLAB\R2008a\bin\win64\libhdf5.dll +0x0000000002330000 - 0x000000000239f000 C:\Program Files\MATLAB\R2008a\bin\win64\profiler.dll +0x00000000023b0000 - 0x00000000023ba000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwmathrng.dll +0x00000000023d0000 - 0x00000000023ea000 C:\Program Files\MATLAB\R2008a\bin\win64\m_pcodeio.dll +0x0000000002400000 - 0x000000000244a000 C:\Program Files\MATLAB\R2008a\bin\win64\m_ir.dll +0x0000000002460000 - 0x0000000002a1b000 C:\Program Files\MATLAB\R2008a\bin\win64\m_parser.dll +0x0000000002a30000 - 0x0000000002a42000 C:\Program Files\MATLAB\R2008a\bin\win64\ir_xfmr.dll +0x0000000002a60000 - 0x0000000002c7b000 C:\Program Files\MATLAB\R2008a\bin\win64\mcos.dll +0x0000000002c90000 - 0x0000000002c9c000 C:\Program Files\MATLAB\R2008a\bin\win64\mtok.dll +0x0000000002cb0000 - 0x0000000002cd0000 C:\Program Files\MATLAB\R2008a\bin\win64\m_pcodegen.dll +0x000007fef4b20000 - 0x000007fef4c45000 C:\Windows\system32\dbghelp.dll +0x0000000002ce0000 - 0x0000000002cf0000 C:\Program Files\MATLAB\R2008a\bin\win64\boost_thread-vc80-mt-1_34_1.dll +0x0000000002d00000 - 0x0000000002dc0000 C:\Program Files\MATLAB\R2008a\bin\win64\udd.dll +0x0000000002dd0000 - 0x0000000002f12000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwgui.dll +0x0000000002f30000 - 0x000000000316a000 C:\Program Files\MATLAB\R2008a\bin\win64\hg.dll +0x0000000003180000 - 0x00000000031d6000 C:\Program Files\MATLAB\R2008a\bin\win64\jmi.dll +0x00000000031f0000 - 0x000000000322e000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwhardcopy.dll +0x0000000003240000 - 0x000000000329c000 C:\Program Files\MATLAB\R2008a\bin\win64\libuij.dll +0x00000000032b0000 - 0x000000000353c000 C:\Program Files\MATLAB\R2008a\bin\win64\numerics.dll +0x0000000003550000 - 0x000000000355c000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwblas.dll +0x0000000003570000 - 0x000000000357f000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwbinder.dll +0x0000000003590000 - 0x00000000035b4000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwlapack.dll +0x00000000035d0000 - 0x00000000035db000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwfftw.dll +0x00000000035f0000 - 0x0000000003625000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwrookfastbp.dll +0x0000000003640000 - 0x000000000366e000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwma57.dll +0x0000000010000000 - 0x00000000100d3000 C:\Program Files\MATLAB\R2008a\bin\win64\libifcoremd.dll +0x0000000003680000 - 0x000000000389d000 C:\Program Files\MATLAB\R2008a\bin\win64\libmmd.dll +0x00000000038a0000 - 0x00000000038a9000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwcsparse.dll +0x00000000038c0000 - 0x000000000398a000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwumfpack.dll +0x00000000039a0000 - 0x00000000039ad000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwamd.dll +0x00000000039c0000 - 0x0000000003a52000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwcholmod.dll +0x0000000003a70000 - 0x0000000003a7c000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwcolamd.dll +0x0000000003a90000 - 0x0000000003b49000 C:\Program Files\MATLAB\R2008a\bin\win64\uiw.dll +0x0000000003b60000 - 0x0000000003b6a000 C:\Program Files\MATLAB\R2008a\bin\win64\uinone.dll +0x0000000068a70000 - 0x0000000068c0c000 C:\Windows\WinSxS\amd64_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.5592_none_8448f49f328da8c3\MFC80.DLL +0x000007fefb690000 - 0x000007fefb701000 C:\Windows\system32\WINSPOOL.DRV +0x000007fefee20000 - 0x000007feff023000 C:\Windows\system32\ole32.dll +0x000007fefebb0000 - 0x000007fefec87000 C:\Windows\system32\OLEAUT32.dll +0x0000000003b80000 - 0x0000000003c10000 C:\Program Files\MATLAB\R2008a\bin\win64\udd_mi.dll +0x0000000003c20000 - 0x0000000003c38000 C:\Program Files\MATLAB\R2008a\bin\win64\mwoles05.DLL +0x0000000003c50000 - 0x0000000003cb9000 C:\Program Files\MATLAB\R2008a\bin\win64\comcli.dll +0x0000000072310000 - 0x0000000072330000 C:\Windows\WinSxS\amd64_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.5592_none_8a1e1b372ed7b012\ATL80.DLL +0x0000000003cd0000 - 0x0000000003cde000 C:\Program Files\MATLAB\R2008a\bin\win64\mlautoregister.dll +0x000007feff4a0000 - 0x000007feff4ce000 C:\Windows\system32\IMM32.DLL +0x000007fefd860000 - 0x000007fefd969000 C:\Windows\system32\MSCTF.dll +0x000000006fa00000 - 0x000000006fa3f000 C:\PROGRA~2\Sophos\SOPHOS~1\SOPHOS~2.DLL +0x00000000076c0000 - 0x000000000808e000 C:\Program Files\MATLAB\R2008a\bin\win64\mkl.dll +0x00000000068d0000 - 0x000000000691b000 C:\Program Files\MATLAB\R2008a\bin\win64\libguide40.dll +0x0000000003e70000 - 0x0000000003e78000 C:\Program Files\MATLAB\R2008a\bin\win64\mklcompat.dll +0x0000000008090000 - 0x0000000008637000 C:\Program Files\MATLAB\R2008a\bin\win64\mllapack.dll +0x00000000070b0000 - 0x00000000071a4000 C:\Program Files\MATLAB\R2008a\bin\win64\libfftw3i.dll +0x0000000007260000 - 0x000000000734e000 C:\Program Files\MATLAB\R2008a\bin\win64\libfftw3f.dll +0x000007fefd370000 - 0x000007fefd37f000 C:\Windows\system32\profapi.dll +0x000007fefd240000 - 0x000007fefd24f000 C:\Windows\system32\CRYPTBASE.dll +0x000007fefbe90000 - 0x000007fefc084000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_fa396087175ac9ac\comctl32.dll +0x000007fefe700000 - 0x000007fefe8d7000 C:\Windows\system32\SETUPAPI.dll +0x000007fefd4b0000 - 0x000007fefd4e6000 C:\Windows\system32\CFGMGR32.dll +0x000007fefd420000 - 0x000007fefd43a000 C:\Windows\system32\DEVOBJ.dll +0x000007feff400000 - 0x000007feff499000 C:\Windows\system32\CLBCatQ.DLL +0x000007fefb8f0000 - 0x000007fefba1c000 C:\Windows\system32\propsys.dll +0x000007fefaea0000 - 0x000007fefaecd000 C:\Windows\system32\ntmarta.dll +0x000007fefeb50000 - 0x000007fefeba2000 C:\Windows\system32\WLDAP32.dll +0x000007fefa500000 - 0x000007fefa527000 C:\Windows\system32\iphlpapi.dll +0x000007fefa4f0000 - 0x000007fefa4fb000 C:\Windows\system32\WINNSI.DLL +0x000007fefca60000 - 0x000007fefcabb000 C:\Windows\system32\DNSAPI.dll +0x000007fefa0b0000 - 0x000007fefa0c8000 C:\Windows\system32\dhcpcsvc.DLL +0x000007fefa0d0000 - 0x000007fefa0e1000 C:\Windows\system32\dhcpcsvc6.DLL +0x000007fefd210000 - 0x000007fefd235000 C:\Windows\system32\SspiCli.dll +0x0000000074aa0000 - 0x0000000074aa3000 C:\Windows\system32\icmp.Dll +0x000000000edf0000 - 0x000000000f341000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\server\jvm.dll +0x000007fefaed0000 - 0x000007fefaf0b000 C:\Windows\system32\WINMM.dll +0x0000000007450000 - 0x00000000074b5000 C:\Program Files\WIDCOMM\Bluetooth Software\btmmhook.dll +0x0000000007230000 - 0x000000000723a000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\hpi.dll +0x0000000008740000 - 0x000000000874e000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\verify.dll +0x0000000008750000 - 0x0000000008777000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\java.dll +0x0000000008780000 - 0x0000000008792000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\zip.dll +0x00000000087a0000 - 0x00000000087b6000 C:\Program Files\MATLAB\R2008a\bin\win64\nativejava.dll +0x00000000088a0000 - 0x00000000088b6000 C:\Program Files\MATLAB\R2008a\bin\win64\nativejmi.dll +0x000000000f850000 - 0x000000000f857000 C:\Program Files\MATLAB\R2008a\bin\win64\nativeservices.dll +0x0000000011ce0000 - 0x0000000011f30000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\awt.dll +0x00000000306a0000 - 0x0000000030709000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\fontmanager.dll + +VM Arguments: +jvm_args: -Xss512k -XX:PermSize=32M -Xms64m -XX:NewRatio=3 -XX:MaxPermSize=128M -Xmx196m -XX:MaxDirectMemorySize=2147400000 -Dsun.java2d.noddraw=true -Dsun.awt.nopixfmt=true -Xshare:off -Xrs -Djava.library.path=C:\Program Files\MATLAB\R2008a\bin\win64 vfprintf abort +java_command: <unknown> +Launcher Type: generic + +Environment Variables: +CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip +PATH=C:\Program Files (x86)\Nokia\PC Connectivity Solution\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\DMIX;C:\Program Files (x86)\NTRU Cryptosystems\NTRU TCG Software Stack\bin\;C:\Program Files\NTRU Cryptosystems\NTRU TCG Software Stack\bin\;C:\Program Files\Wave Systems Corp\Gemalto\Access Client\v5\;c:\Program Files\WIDCOMM\Bluetooth Software\;c:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Program Files (x86)\Common Files\Roxio Shared\DLLShared\;C:\Program Files (x86)\Common Files\Roxio Shared\10.0\DLLShared\;C:\Program Files (x86)\Common Files\Adobe\AGL;C:\Program Files\MATLAB\R2010b\bin;C:\Program Files\MATLAB\R2010a\bin;C:\Program Files\MATLAB\R2008a\bin;C:\Program Files\MATLAB\R2008a\bin\win64;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files\Microsoft Windows Performance Toolkit\ +USERNAME=rmeddis +OS=Windows_NT +PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 37 Stepping 2, GenuineIntel + + + +--------------- S Y S T E M --------------- + +OS: Windows NT 6.1 Build 7601 Service Pack 1 + +CPU:total 4 em64t ht + +Memory: 4k page, physical 8181592k(6037968k free), swap 16361336k(14041736k free) + +vm_info: Java HotSpot(TM) 64-Bit Server VM (1.6.0-b105) for windows-amd64, built on Nov 29 2006 00:38:01 by "java_re" with unknown MS VC++:1400 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/hs_err_pid6852.log Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,288 @@ +# +# An unexpected error has been detected by Java Runtime Environment: +# +# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000011cc5110, pid=6852, tid=5540 +# +# Java VM: Java HotSpot(TM) 64-Bit Server VM (1.6.0-b105 mixed mode) +# Problematic frame: +# C [awt.dll+0x185110] +# +# If you would like to submit a bug report, please visit: +# http://java.sun.com/webapps/bugreport/crash.jsp +# + +--------------- T H R E A D --------------- + +Current thread (0x0000000011841800): JavaThread "AWT-EventQueue-0" [_thread_in_native, id=5540] + +siginfo: ExceptionCode=0xc0000005, reading address 0xffffffffffffffff + +Registers: +EAX=0x800000b26e4dd767, EBX=0x0000000000000001, ECX=0x0000000030776480, EDX=0x0000000011a012d0 +ESP=0x000000003126e600, EBP=0x000000001183a360, ESI=0x0000000011841990, EDI=0x0000000000000000 +EIP=0x0000000011cc5110, EFLAGS=0x0000000000010206 + +Top of Stack: (sp=0x000000003126e600) +0x000000003126e600: 0000000011841800 0000000000000000 +0x000000003126e610: 000000003126e750 0000000015e00818 +0x000000003126e620: 0000000000000001 0000000011cc6dd3 +0x000000003126e630: 0000000000000001 000000001183a360 +0x000000003126e640: 0000000011841990 0000000000000000 +0x000000003126e650: 0000000011a012d0 00000000169f4028 +0x000000003126e660: 0000000000000004 00000000152cd810 +0x000000003126e670: 0000000000000000 0000000000000000 +0x000000003126e680: 0000000000000001 0000000000000102 +0x000000003126e690: 00000000122a308e 0000000000000001 +0x000000003126e6a0: 000000003126e728 00000000122afc24 +0x000000003126e6b0: 0000000000000000 0000000026630e70 +0x000000003126e6c0: 0000000000000000 0000000015e00818 +0x000000003126e6d0: 0000000000000001 0000000000000000 +0x000000003126e6e0: 000000003126e6d0 000000003126e6e8 +0x000000003126e6f0: 0000000000000000 000000003126e750 + +Instructions: (pc=0x0000000011cc5110) +0x0000000011cc5100: e8 5b 72 f9 ff 48 8b 0d 04 9a 08 00 48 8b 04 d8 +0x0000000011cc5110: 48 8b 58 30 e8 67 72 f9 ff 48 8b c3 48 83 c4 20 + + +Stack: [0x00000000311f0000,0x0000000031270000), sp=0x000000003126e600, free space=505k +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +C [awt.dll+0x185110] + +Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) +j sun.awt.Win32GraphicsConfig.getBounds(I)Ljava/awt/Rectangle;+0 +j sun.awt.Win32GraphicsConfig.getBounds()Ljava/awt/Rectangle;+8 +j com.mathworks.mwswing.WindowUtils.getVirtualScreenBounds()Ljava/awt/Rectangle;+98 +j com.mathworks.mwswing.MJUtilities.getVirtualScreenBounds()Ljava/awt/Rectangle;+0 +j com.mathworks.mwswing.desk.DTSingleClientFrame.refineLocation(Lcom/mathworks/mwswing/desk/DTLocation;)Lcom/mathworks/mwswing/desk/DTFloatingLocation;+495 +j com.mathworks.mwswing.desk.DTSingleClientFrame.addClient(Lcom/mathworks/mwswing/desk/DTClient;Lcom/mathworks/mwswing/desk/DTLocation;)V+297 +j com.mathworks.mwswing.desk.Desktop.setClientShowing(Lcom/mathworks/mwswing/desk/DTClient;ZLcom/mathworks/mwswing/desk/DTLocation;ZZ)V+956 +j com.mathworks.mwswing.desk.Desktop.setClientShowing(Lcom/mathworks/mwswing/desk/DTClient;ZLcom/mathworks/mwswing/desk/DTLocation;Z)V+7 +j com.mathworks.mwswing.desk.Desktop.setClientDocked(Lcom/mathworks/mwswing/desk/DTClient;Z)V+296 +j com.mathworks.mwswing.desk.DTClient$ClientUndockAction.actionPerformed(Ljava/awt/event/ActionEvent;)V+12 +j javax.swing.AbstractButton.fireActionPerformed(Ljava/awt/event/ActionEvent;)V+84 +j javax.swing.AbstractButton$Handler.actionPerformed(Ljava/awt/event/ActionEvent;)V+5 +j javax.swing.DefaultButtonModel.fireActionPerformed(Ljava/awt/event/ActionEvent;)V+35 +j javax.swing.DefaultButtonModel.setPressed(Z)V+117 +j javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Ljava/awt/event/MouseEvent;)V+35 +j java.awt.AWTEventMulticaster.mouseReleased(Ljava/awt/event/MouseEvent;)V+8 +j java.awt.AWTEventMulticaster.mouseReleased(Ljava/awt/event/MouseEvent;)V+8 +j java.awt.Component.processMouseEvent(Ljava/awt/event/MouseEvent;)V+64 +j javax.swing.JComponent.processMouseEvent(Ljava/awt/event/MouseEvent;)V+23 +j com.mathworks.mwswing.MJButton.processMouseEvent(Ljava/awt/event/MouseEvent;)V+37 +j java.awt.Component.processEvent(Ljava/awt/AWTEvent;)V+81 +j java.awt.Container.processEvent(Ljava/awt/AWTEvent;)V+18 +J java.awt.Component.dispatchEventImpl(Ljava/awt/AWTEvent;)V +J java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V +J java.awt.LightweightDispatcher.retargetMouseEvent(Ljava/awt/Component;ILjava/awt/event/MouseEvent;)V +J java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V +j java.awt.Window.dispatchEventImpl(Ljava/awt/AWTEvent;)V+19 +J java.awt.EventDispatchThread.pumpOneEventForFilters(I)Z +J java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V +j java.awt.EventDispatchThread.pumpEventsForHierarchy(ILjava/awt/Conditional;Ljava/awt/Component;)V+11 +j java.awt.EventDispatchThread.pumpEvents(ILjava/awt/Conditional;)V+4 +j java.awt.EventDispatchThread.pumpEvents(Ljava/awt/Conditional;)V+3 +j java.awt.EventDispatchThread.run()V+9 +v ~StubRoutines::call_stub + +--------------- P R O C E S S --------------- + +Java Threads: ( => current thread ) + 0x0000000031567800 JavaThread "Timer-7" [_thread_blocked, id=4716] + 0x0000000031568000 JavaThread "Image Fetcher 0" daemon [_thread_blocked, id=6432] + 0x0000000031566c00 JavaThread "Inactive RequestProcessor thread [Was:TimedSoftReference/org.openide.util.TimedSoftReference]" daemon [_thread_blocked, id=7912] + 0x0000000031565000 JavaThread "Thread-237" [_thread_blocked, id=5244] + 0x0000000031568800 JavaThread "Thread-230" [_thread_blocked, id=5112] + 0x0000000031567400 JavaThread "Prefs Updater" [_thread_blocked, id=6764] + 0x0000000031566400 JavaThread "Thread-10" [_thread_blocked, id=7204] + 0x0000000031565c00 JavaThread "Thread-9" [_thread_blocked, id=6880] + 0x0000000031565800 JavaThread "Thread-8" [_thread_blocked, id=6964] + 0x0000000031564800 JavaThread "Active Reference Queue Daemon" daemon [_thread_blocked, id=7260] + 0x0000000031564000 JavaThread "Timer-3" daemon [_thread_blocked, id=4892] + 0x000000003155d000 JavaThread "Timer-2" daemon [_thread_blocked, id=6948] + 0x0000000030c13000 JavaThread "TimerQueue" daemon [_thread_blocked, id=5596] +=>0x0000000011841800 JavaThread "AWT-EventQueue-0" [_thread_in_native, id=5540] + 0x00000000307b0800 JavaThread "AWT-Windows" daemon [_thread_in_native, id=5832] + 0x00000000307afc00 JavaThread "AWT-Shutdown" [_thread_blocked, id=4548] + 0x00000000307af400 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=5040] + 0x0000000011779000 JavaThread "Timer-0" [_thread_blocked, id=6884] + 0x00000000111f1c00 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=4740] + 0x00000000111ef800 JavaThread "CompilerThread1" daemon [_thread_blocked, id=7472] + 0x00000000111e7c00 JavaThread "CompilerThread0" daemon [_thread_blocked, id=6800] + 0x00000000111e6800 JavaThread "Attach Listener" daemon [_thread_blocked, id=7688] + 0x00000000111c7400 JavaThread "Finalizer" daemon [_thread_blocked, id=7524] + 0x0000000003def400 JavaThread "Reference Handler" daemon [_thread_blocked, id=2228] + 0x0000000003d2fc00 JavaThread "main" [_thread_in_native, id=5124] + +Other Threads: + 0x0000000003dee400 VMThread [id=7268] + 0x00000000111f7400 WatcherThread [id=7276] + +VM state:not at safepoint (normal execution) + +VM Mutex/Monitor currently owned by a thread: None + +Heap + PSYoungGen total 11392K, used 691K [0x00000000265a0000, 0x00000000273a0000, 0x00000000296a0000) + eden space 10624K, 6% used [0x00000000265a0000,0x000000002664cc98,0x0000000027000000) + from space 768K, 0% used [0x0000000027040000,0x0000000027040000,0x0000000027100000) + to space 1856K, 0% used [0x00000000271d0000,0x00000000271d0000,0x00000000273a0000) + PSOldGen total 50944K, used 35225K [0x000000001d2a0000, 0x0000000020460000, 0x00000000265a0000) + object space 50944K, 69% used [0x000000001d2a0000,0x000000001f5066a8,0x0000000020460000) + PSPermGen total 58624K, used 44603K [0x00000000152a0000, 0x0000000018be0000, 0x000000001d2a0000) + object space 58624K, 76% used [0x00000000152a0000,0x0000000017e2ef18,0x0000000018be0000) + +Dynamic libraries: +0x0000000140000000 - 0x0000000140138000 C:\Program Files\MATLAB\R2008a\bin\win64\MATLAB.exe +0x0000000077a60000 - 0x0000000077c09000 C:\Windows\SYSTEM32\ntdll.dll +0x0000000077940000 - 0x0000000077a5f000 C:\Windows\system32\kernel32.dll +0x000007fefdbd0000 - 0x000007fefdc3b000 C:\Windows\system32\KERNELBASE.dll +0x0000000180000000 - 0x0000000180401000 C:\Program Files\MATLAB\R2008a\bin\win64\libut.dll +0x000007fefe1b0000 - 0x000007fefe1c7000 C:\Windows\system32\imagehlp.dll +0x000007fefdf80000 - 0x000007fefe01f000 C:\Windows\system32\msvcrt.dll +0x0000000077c30000 - 0x0000000077c37000 C:\Windows\system32\PSAPI.DLL +0x00000000010d0000 - 0x00000000010f8000 C:\Program Files\MATLAB\R2008a\bin\win64\LIBEXPAT.dll +0x0000000073fa0000 - 0x0000000074069000 C:\Windows\WinSxS\amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.5592_none_88e45feb2faab9ce\MSVCR80.dll +0x000000004a800000 - 0x000000004a917000 C:\Program Files\MATLAB\R2008a\bin\win64\icuuc36.dll +0x000007feffc30000 - 0x000007feffd0b000 C:\Windows\system32\ADVAPI32.dll +0x000007feff4e0000 - 0x000007feff4ff000 C:\Windows\SYSTEM32\sechost.dll +0x000007feff140000 - 0x000007feff26d000 C:\Windows\system32\RPCRT4.dll +0x0000000001120000 - 0x0000000001123000 C:\Program Files\MATLAB\R2008a\bin\win64\icudt36.dll +0x000000004ab00000 - 0x000000004ab0f000 C:\Program Files\MATLAB\R2008a\bin\win64\icuio36.dll +0x00000000012b0000 - 0x00000000013b6000 C:\Program Files\MATLAB\R2008a\bin\win64\icuin36.dll +0x0000000072920000 - 0x0000000072a29000 C:\Windows\WinSxS\amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.5592_none_88e45feb2faab9ce\MSVCP80.dll +0x0000000077840000 - 0x000000007793a000 C:\Windows\system32\USER32.dll +0x000007feff5a0000 - 0x000007feff607000 C:\Windows\system32\GDI32.dll +0x000007fefe1a0000 - 0x000007fefe1ae000 C:\Windows\system32\LPK.dll +0x000007feffb60000 - 0x000007feffc29000 C:\Windows\system32\USP10.dll +0x00000000013c0000 - 0x0000000001534000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwservices.dll +0x0000000001540000 - 0x00000000015b0000 C:\Program Files\MATLAB\R2008a\bin\win64\libmx.dll +0x0000000001180000 - 0x0000000001197000 C:\Program Files\MATLAB\R2008a\bin\win64\zlib1.dll +0x00000000015b0000 - 0x0000000001658000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwmathutil.dll +0x0000000001660000 - 0x00000000016b5000 C:\Program Files\MATLAB\R2008a\bin\win64\mpath.dll +0x00000000016d0000 - 0x00000000016f1000 C:\Program Files\MATLAB\R2008a\bin\win64\mlutil.dll +0x000007fef9630000 - 0x000007fef96d0000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7601.17514_none_a4d6a923711520a9\COMCTL32.dll +0x000007fefdd80000 - 0x000007fefde17000 C:\Windows\system32\comdlg32.dll +0x000007feff660000 - 0x000007feff6d1000 C:\Windows\system32\SHLWAPI.dll +0x000007fefe1d0000 - 0x000007fefef58000 C:\Windows\system32\SHELL32.dll +0x000007fefce80000 - 0x000007fefce96000 C:\Windows\system32\NETAPI32.dll +0x000007fefce70000 - 0x000007fefce7c000 C:\Windows\system32\netutils.dll +0x000007fefd500000 - 0x000007fefd523000 C:\Windows\system32\srvcli.dll +0x000007fefce50000 - 0x000007fefce65000 C:\Windows\system32\wkscli.dll +0x000007feff610000 - 0x000007feff65d000 C:\Windows\system32\WS2_32.dll +0x000007feff6e0000 - 0x000007feff6e8000 C:\Windows\system32\NSI.dll +0x0000000001710000 - 0x0000000001765000 C:\Program Files\MATLAB\R2008a\bin\win64\mcr.dll +0x0000000001780000 - 0x00000000017a5000 C:\Program Files\MATLAB\R2008a\bin\win64\iqm.dll +0x00000000017c0000 - 0x00000000017e1000 C:\Program Files\MATLAB\R2008a\bin\win64\bridge.dll +0x0000000001800000 - 0x0000000001811000 C:\Program Files\MATLAB\R2008a\bin\win64\libmex.dll +0x0000000001830000 - 0x00000000018bc000 C:\Program Files\MATLAB\R2008a\bin\win64\m_dispatcher.dll +0x00000000018d0000 - 0x00000000018f5000 C:\Program Files\MATLAB\R2008a\bin\win64\datasvcs.dll +0x0000000012000000 - 0x0000000012295000 C:\Program Files\MATLAB\R2008a\bin\win64\xerces-c_2_7.dll +0x0000000001920000 - 0x00000000021b1000 C:\Program Files\MATLAB\R2008a\bin\win64\m_interpreter.dll +0x00000000021d0000 - 0x0000000002201000 C:\Program Files\MATLAB\R2008a\bin\win64\libmat.dll +0x0000000002220000 - 0x0000000002325000 C:\Program Files\MATLAB\R2008a\bin\win64\libhdf5.dll +0x0000000002330000 - 0x000000000239f000 C:\Program Files\MATLAB\R2008a\bin\win64\profiler.dll +0x00000000023b0000 - 0x00000000023ba000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwmathrng.dll +0x00000000023d0000 - 0x00000000023ea000 C:\Program Files\MATLAB\R2008a\bin\win64\m_pcodeio.dll +0x0000000002400000 - 0x000000000244a000 C:\Program Files\MATLAB\R2008a\bin\win64\m_ir.dll +0x0000000002460000 - 0x0000000002a1b000 C:\Program Files\MATLAB\R2008a\bin\win64\m_parser.dll +0x0000000002a30000 - 0x0000000002a42000 C:\Program Files\MATLAB\R2008a\bin\win64\ir_xfmr.dll +0x0000000002a60000 - 0x0000000002c7b000 C:\Program Files\MATLAB\R2008a\bin\win64\mcos.dll +0x0000000002c90000 - 0x0000000002c9c000 C:\Program Files\MATLAB\R2008a\bin\win64\mtok.dll +0x0000000002cb0000 - 0x0000000002cd0000 C:\Program Files\MATLAB\R2008a\bin\win64\m_pcodegen.dll +0x000007fefad70000 - 0x000007fefae95000 C:\Windows\system32\dbghelp.dll +0x0000000002ce0000 - 0x0000000002cf0000 C:\Program Files\MATLAB\R2008a\bin\win64\boost_thread-vc80-mt-1_34_1.dll +0x0000000002d00000 - 0x0000000002dc0000 C:\Program Files\MATLAB\R2008a\bin\win64\udd.dll +0x0000000002dd0000 - 0x0000000002f12000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwgui.dll +0x0000000002f30000 - 0x000000000316a000 C:\Program Files\MATLAB\R2008a\bin\win64\hg.dll +0x0000000003180000 - 0x00000000031d6000 C:\Program Files\MATLAB\R2008a\bin\win64\jmi.dll +0x00000000031f0000 - 0x000000000322e000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwhardcopy.dll +0x0000000003240000 - 0x000000000329c000 C:\Program Files\MATLAB\R2008a\bin\win64\libuij.dll +0x00000000032b0000 - 0x000000000353c000 C:\Program Files\MATLAB\R2008a\bin\win64\numerics.dll +0x0000000003550000 - 0x000000000355c000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwblas.dll +0x0000000003570000 - 0x000000000357f000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwbinder.dll +0x0000000003590000 - 0x00000000035b4000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwlapack.dll +0x00000000035d0000 - 0x00000000035db000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwfftw.dll +0x00000000035f0000 - 0x0000000003625000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwrookfastbp.dll +0x0000000003640000 - 0x000000000366e000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwma57.dll +0x0000000010000000 - 0x00000000100d3000 C:\Program Files\MATLAB\R2008a\bin\win64\libifcoremd.dll +0x0000000003680000 - 0x000000000389d000 C:\Program Files\MATLAB\R2008a\bin\win64\libmmd.dll +0x00000000038a0000 - 0x00000000038a9000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwcsparse.dll +0x00000000038c0000 - 0x000000000398a000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwumfpack.dll +0x00000000039a0000 - 0x00000000039ad000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwamd.dll +0x00000000039c0000 - 0x0000000003a52000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwcholmod.dll +0x0000000003a70000 - 0x0000000003a7c000 C:\Program Files\MATLAB\R2008a\bin\win64\libmwcolamd.dll +0x0000000003a90000 - 0x0000000003b49000 C:\Program Files\MATLAB\R2008a\bin\win64\uiw.dll +0x0000000003b60000 - 0x0000000003b6a000 C:\Program Files\MATLAB\R2008a\bin\win64\uinone.dll +0x0000000071490000 - 0x000000007162c000 C:\Windows\WinSxS\amd64_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.5592_none_8448f49f328da8c3\MFC80.DLL +0x000007fefbcd0000 - 0x000007fefbd41000 C:\Windows\system32\WINSPOOL.DRV +0x000007feff6f0000 - 0x000007feff8f3000 C:\Windows\system32\ole32.dll +0x000007feff400000 - 0x000007feff4d7000 C:\Windows\system32\OLEAUT32.dll +0x0000000003b80000 - 0x0000000003c10000 C:\Program Files\MATLAB\R2008a\bin\win64\udd_mi.dll +0x0000000003c20000 - 0x0000000003c38000 C:\Program Files\MATLAB\R2008a\bin\win64\mwoles05.DLL +0x0000000003c50000 - 0x0000000003cb9000 C:\Program Files\MATLAB\R2008a\bin\win64\comcli.dll +0x0000000072900000 - 0x0000000072920000 C:\Windows\WinSxS\amd64_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.5592_none_8a1e1b372ed7b012\ATL80.DLL +0x0000000003cd0000 - 0x0000000003cde000 C:\Program Files\MATLAB\R2008a\bin\win64\mlautoregister.dll +0x000007fefde20000 - 0x000007fefde4e000 C:\Windows\system32\IMM32.DLL +0x000007feff2f0000 - 0x000007feff3f9000 C:\Windows\system32\MSCTF.dll +0x000000006fa00000 - 0x000000006fa3f000 C:\PROGRA~2\Sophos\SOPHOS~1\SOPHOS~2.DLL +0x0000000007240000 - 0x0000000007c0e000 C:\Program Files\MATLAB\R2008a\bin\win64\mkl.dll +0x0000000005810000 - 0x000000000585b000 C:\Program Files\MATLAB\R2008a\bin\win64\libguide40.dll +0x0000000005860000 - 0x0000000005868000 C:\Program Files\MATLAB\R2008a\bin\win64\mklcompat.dll +0x0000000007c10000 - 0x00000000081b7000 C:\Program Files\MATLAB\R2008a\bin\win64\mllapack.dll +0x0000000006c40000 - 0x0000000006d34000 C:\Program Files\MATLAB\R2008a\bin\win64\libfftw3i.dll +0x0000000006d40000 - 0x0000000006e2e000 C:\Program Files\MATLAB\R2008a\bin\win64\libfftw3f.dll +0x000007fefd9b0000 - 0x000007fefd9bf000 C:\Windows\system32\profapi.dll +0x000007fefd8e0000 - 0x000007fefd8ef000 C:\Windows\system32\CRYPTBASE.dll +0x000007fefc4d0000 - 0x000007fefc6c4000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_fa396087175ac9ac\comctl32.dll +0x000007fefef60000 - 0x000007feff137000 C:\Windows\system32\SETUPAPI.dll +0x000007fefdca0000 - 0x000007fefdcd6000 C:\Windows\system32\CFGMGR32.dll +0x000007fefdc80000 - 0x000007fefdc9a000 C:\Windows\system32\DEVOBJ.dll +0x000007feff500000 - 0x000007feff599000 C:\Windows\system32\CLBCatQ.DLL +0x000007fefbf30000 - 0x000007fefc05c000 C:\Windows\system32\propsys.dll +0x000007fefb4e0000 - 0x000007fefb50d000 C:\Windows\system32\ntmarta.dll +0x000007feffd10000 - 0x000007feffd62000 C:\Windows\system32\WLDAP32.dll +0x000007fefa3d0000 - 0x000007fefa3f7000 C:\Windows\system32\iphlpapi.dll +0x000007fefa3c0000 - 0x000007fefa3cb000 C:\Windows\system32\WINNSI.DLL +0x000007fefd0a0000 - 0x000007fefd0fb000 C:\Windows\system32\DNSAPI.dll +0x000007fef9e00000 - 0x000007fef9e11000 C:\Windows\system32\dhcpcsvc6.DLL +0x000007fef9db0000 - 0x000007fef9dc8000 C:\Windows\system32\dhcpcsvc.DLL +0x000007fefd850000 - 0x000007fefd875000 C:\Windows\system32\SspiCli.dll +0x0000000074fe0000 - 0x0000000074fe3000 C:\Windows\system32\icmp.Dll +0x000000000f820000 - 0x000000000fd71000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\server\jvm.dll +0x000007fefb5c0000 - 0x000007fefb5fb000 C:\Windows\system32\WINMM.dll +0x0000000006aa0000 - 0x0000000006aaa000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\hpi.dll +0x00000000082c0000 - 0x00000000082ce000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\verify.dll +0x00000000082d0000 - 0x00000000082f7000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\java.dll +0x0000000008300000 - 0x0000000008312000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\zip.dll +0x000000000ff40000 - 0x000000000ffa5000 C:\Program Files\WIDCOMM\Bluetooth Software\btmmhook.dll +0x000000000ffb0000 - 0x000000000ffc6000 C:\Program Files\MATLAB\R2008a\bin\win64\nativejava.dll +0x000000000ffe0000 - 0x000000000fff6000 C:\Program Files\MATLAB\R2008a\bin\win64\nativejmi.dll +0x00000000112f0000 - 0x00000000112f7000 C:\Program Files\MATLAB\R2008a\bin\win64\nativeservices.dll +0x0000000011b40000 - 0x0000000011d90000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\awt.dll +0x0000000011f10000 - 0x0000000011f79000 C:\Program Files\MATLAB\R2008a\sys\java\jre\win64\jre1.6.0\bin\fontmanager.dll + +VM Arguments: +jvm_args: -Xss512k -XX:PermSize=32M -Xms64m -XX:NewRatio=3 -XX:MaxPermSize=128M -Xmx196m -XX:MaxDirectMemorySize=2147400000 -Dsun.java2d.noddraw=true -Dsun.awt.nopixfmt=true -Xshare:off -Xrs -Djava.library.path=C:\Program Files\MATLAB\R2008a\bin\win64 vfprintf abort +java_command: <unknown> +Launcher Type: generic + +Environment Variables: +CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip +PATH=C:\Program Files (x86)\Nokia\PC Connectivity Solution\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\DMIX;C:\Program Files (x86)\NTRU Cryptosystems\NTRU TCG Software Stack\bin\;C:\Program Files\NTRU Cryptosystems\NTRU TCG Software Stack\bin\;C:\Program Files\Wave Systems Corp\Gemalto\Access Client\v5\;c:\Program Files\WIDCOMM\Bluetooth Software\;c:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Program Files (x86)\Common Files\Roxio Shared\DLLShared\;C:\Program Files (x86)\Common Files\Roxio Shared\10.0\DLLShared\;C:\Program Files (x86)\Common Files\Adobe\AGL;C:\Program Files\MATLAB\R2010b\bin;C:\Program Files\MATLAB\R2010a\bin;C:\Program Files\MATLAB\R2008a\bin;C:\Program Files\MATLAB\R2008a\bin\win64;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files\Microsoft Windows Performance Toolkit\ +USERNAME=rmeddis +OS=Windows_NT +PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 37 Stepping 2, GenuineIntel + + + +--------------- S Y S T E M --------------- + +OS: Windows NT 6.1 Build 7601 Service Pack 1 + +CPU:total 4 em64t ht + +Memory: 4k page, physical 8181592k(5194804k free), swap 16361336k(13377632k free) + +vm_info: Java HotSpot(TM) 64-Bit Server VM (1.6.0-b105) for windows-amd64, built on Nov 29 2006 00:38:01 by "java_re" with unknown MS VC++:1400 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/nextStimulus.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,870 @@ +function errormsg=nextStimulus(handles) +% Handles everything concerned with the stimulus presentation +% called from startNewRun in subjGUI + +global experiment stimulusParameters withinRuns betweenRuns +experiment.status='presentingStimulus'; +errormsg=''; + +% interrupt by 'stop' button +if experiment.stop + disp('******** experiment manually stopped *****************') + experiment.status= 'waitingForStart'; + addToMsg('manually stopped',1) + return +end + +% -----------------------------------------choose catch trials at random +% catch trials are for subject threshold measurements only +% this is the only place where withinRuns.catchTrial is set +if experiment.allowCatchTrials + if withinRuns.trialNumber==1; + % first trial is never a catch trial + withinRuns.catchTrial=0; + withinRuns.catchTrialCount=0; % reset count on first trial + elseif withinRuns.trialNumber==2 ... + && withinRuns.catchTrialCount==0 + % second trial is always a catch trial + withinRuns.catchTrial=1; + withinRuns.catchTrialCount=1; % this must be the first + elseif withinRuns.thisIsRepeatTrial + % for requested repeats do not change catch trial status + withinRuns.thisIsRepeatTrial=0; % reset toggle + else + % choose whether or not to have a catch trial + R=rand; + if R<stimulusParameters.catchTrialRate + % catch trial + withinRuns.catchTrial=1; + addToMsg('Catch Trial',1) + withinRuns.catchTrialCount=withinRuns.catchTrialCount+1; + else + % not a catch trial + withinRuns.catchTrial=0; + end + end +else + % no catch trials for statistical evaluations or 2AIFC or (poss) MAP + withinRuns.catchTrial=0; +end + +%------------ during stimulus presentation show appropriate button images +switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent',... + 'MAPmodel', 'MAPmodelMultiCh', 'MAPmodelSingleCh'} + % no buttons shown + otherwise + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + %Except for 2I2AFC + % For 2I2AFC the buttons on the screen ab initio + set(handles.frame1,'visible','off') + set(handles.pushbuttonGO,'visible','off') + set(handles.pushbuttoNotSure,'visible','off') + set(handles.pushbuttonWrongButton,'visible','off') + set(handles.pushbutton3,'visible','off') + set(handles.pushbutton0,'visible','off') + set(handles.pushbutton1,'visible','on') + set(handles.pushbutton2,'visible','on') + drawnow + otherwise + % i.e. single interval/ maxLikelihood + set(handles.frame1,'backgroundColor','w') + set(handles.frame1,'visible','off') + set(handles.pushbuttoNotSure,'visible','off') + set(handles.pushbuttonWrongButton,'visible','off') + set(handles.pushbutton3,'visible','off') + set(handles.pushbutton2,'visible','off') + set(handles.pushbutton1,'visible','off') + set(handles.pushbutton0,'visible','off') + pause(.1) + end +end + +set(handles.textMSG,'BackgroundColor','w', 'ForegroundColor', 'b') + +% Now the serious business of crafting and presenting the stimulus +errormsg= stimulusMakeAndPlay (handles); + +if ~isempty(errormsg) + % e.g. clipping. subjGUI will service the error + return +end + +% after playing the stimulus, reset the subjectGUI +switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent',... + 'MAPmodel', 'MAPmodelMultiCh', 'MAPmodelSingleCh'} + % no changes required if model used + % NB these changes do occur is 'MAPmodelListen' is selected + otherwise + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + % buttons already visible + otherwise + % single interval now make buttons visible + set(handles.frame1,'visible','on') + set(handles.pushbuttoNotSure,'visible','on') + % set(handles.pushbuttonWrongButton,'visible','on') + set(handles.pushbutton0,'visible','on') + set(handles.pushbutton1,'visible','on') + set(handles.pushbutton2,'visible','on') + set(handles.pushbutton3,'visible','on') + end +end + +switch experiment.paradigm + case 'SRT' + set(handles.frame1,'backgroundColor','w') + set(handles.frame1,'visible','off') + set(handles.pushbuttoNotSure,'visible','off') + set(handles.pushbuttonWrongButton,'visible','off') + set(handles.pushbutton3,'visible','off') + set(handles.pushbutton2,'visible','off') + set(handles.pushbutton1,'visible','off') + set(handles.pushbutton0,'visible','off') + set(handles.editdigitInput,'visible','on') + set(handles.editdigitInput,'string',[]) + pause(.2) + uicontrol(handles.editdigitInput) + + otherwise + set(handles.editdigitInput,'visible','off') +end + + +experiment.status='waitingForResponse'; +% home again + +% ------------------------------------------------------------------------------------------stimulusMakeAndPlay +function errormsg=stimulusMakeAndPlay (handles) +global experiment stimulusParameters betweenRuns withinRuns expGUIhandles audio +% creates the stimulus and plays it; there are two stimuli; cue and test +% called from nextStimulus + +errormsg=''; + +% first post the subjects instructions on subjGUI +set(handles.textMSG,'string', stimulusParameters.subjectText) + +% select the new levels of the between runs variables +num=betweenRuns.runNumber; +cmd=(['stimulusParameters.' betweenRuns.variableName1 '= ' ... + num2str(betweenRuns.var1Sequence(num)) ';']); +% e.g. stimulusParameters.targetFrequency= 1000; +eval(cmd); + +cmd=(['stimulusParameters.' betweenRuns.variableName2 '= ' ... + num2str(betweenRuns.var2Sequence(num)) ';']); +% e.g. stimulusParameters.targetDuration= 0.1; +eval(cmd); + +switch experiment.paradigm + % target level may vary between runs + case {'trainingIFMC', 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms','IFMC_16ms'} + idx=floor(num/length(betweenRuns.variableList1)-0.01)+1; + cmd=(['stimulusParameters.targetLevel = ' ... + num2str(stimulusParameters.targetLevels(idx)) ';']); + eval(cmd); + if withinRuns.trialNumber==1 + disp(['targetLevel=' num2str(stimulusParameters.targetLevel)]) + end +end + + +% for more readable code use shorter variable names; +% NB these may change below; these are only the starting values + +targetType= stimulusParameters.targetType; +targetDuration= stimulusParameters.targetDuration; +targetLevel= stimulusParameters.targetLevel; +targetFrequency= stimulusParameters.targetFrequency; + +maskerType= stimulusParameters.maskerType; +maskerDuration= stimulusParameters.maskerDuration; +maskerLevel= stimulusParameters.maskerLevel; +maskerRelativeFrequency= stimulusParameters.maskerRelativeFrequency; +maskerFrequency= maskerRelativeFrequency*targetFrequency; + +gapDuration= stimulusParameters.gapDuration; + +rampDuration= stimulusParameters.rampDuration; +AFCsilenceDuration=stimulusParameters.AFCsilenceDuration; % 2I2AFC gap +backgroundLevel= stimulusParameters.backgroundLevel; + +% Set level of within runs variable +% this is the first change to one of the values shown above +cmd=[stimulusParameters.WRVname '= withinRuns.variableValue;' ]; +% e.g.: maskerLevel= withinRuns.variableValue; +eval(cmd); + +% cue and test stimuli are identical except for a single difference +% depending on the paradigm +cueTestDifference= stimulusParameters.cueTestDifference; +% cue characteristics before adding cue differences +cueTargetLevel=targetLevel; +cueMaskerFrequency=maskerFrequency; +cueMaskerDuration=maskerDuration; +cueMaskerLevel=maskerLevel; +cueTargetFrequency=targetFrequency; +cueGapDuration=gapDuration; + +% ----------------------------paradigm sensitive cue and masker settings +% switch off unwanted components and base cue on target values +% for catch trials switch off the target +switch experiment.paradigm + % OHIO is a temporary special arrangement + case{'OHIOrand','OHIOspect','OHIOtemp','OHIOspectemp','OHIOabs'} + % these values must be set in MAPparamsOHIO + targetFrequency=experiment.OHIOfrequencies; + numOHIOtones=stimulusParameters.numOHIOtones; + maskerType='OHIO'; + targetType='OHIO'; + + % globalStimParams.beginSilences says when each tone begins + % targetFrequency specifies the frequency of each tone + % targetLevel is the level of each tone + switch experiment.paradigm + case 'OHIOabs' + % only one tone + targetFrequency=targetFrequency(numOHIOtones); + globalStimParams.beginSilences=0.01; + targetDuration=0.01; + case 'OHIOrand' + % select random frequencies from the list + x=rand(12,1); [x idx]=sort(x); + targetFrequency=targetFrequency(idx(1:numOHIOtones)); + thresholds=experiment.OHIOthresholds; + targetLevel=thresholds(idx(1:numOHIOtones))+targetLevel; + globalStimParams.beginSilences=0.01:0.02:... + 0.01+0.02*(numOHIOtones-1); + targetDuration=numOHIOtones*0.02; + case 'OHIOspect' + % only one tone with multiple frequencies + targetFrequency=fliplr(targetFrequency); + targetFrequency=targetFrequency(1:numOHIOtones); + thresholds=experiment.OHIOthresholds; + thresholds=fliplr(thresholds); + targetLevel=thresholds(1:numOHIOtones)+targetLevel; + globalStimParams.beginSilences=... + repmat(0.01, 1, numOHIOtones); + targetDuration=0.02; + case 'OHIOspectemp' + % only one tone with multiple frequencies + targetFrequency=fliplr(targetFrequency); + targetFrequency=targetFrequency(1:numOHIOtones); + thresholds=experiment.OHIOthresholds; + thresholds=fliplr(thresholds); + targetLevel=thresholds(1:numOHIOtones)+targetLevel; + globalStimParams.beginSilences=0.01:0.02:... + 0.01+0.02*(numOHIOtones-1); + targetDuration=numOHIOtones*0.02; + case 'OHIOtemp' + % use only one tone repeatedly + tonesToUse=10; + targetFrequency=targetFrequency(tonesToUse); + targetFrequency=repmat(targetFrequency,1,numOHIOtones); + thresholds=experiment.OHIOthresholds; + thresholds=thresholds(tonesToUse); + targetLevel=repmat(thresholds,1,numOHIOtones)+targetLevel; + globalStimParams.beginSilences=0.01:0.02:... + 0.01+0.02*(numOHIOtones-1); + targetDuration=numOHIOtones*0.02; + end + % still in OHIO + % Dummy values to make things work although no masker or cue used + % target values have changed and this affects the cue values + cueMaskerLevel=targetLevel; + cueTargetLevel=targetLevel; + cueTargetFrequency=targetFrequency; + cueMaskerFrequency=targetFrequency; + maskerFrequency=targetFrequency; + maskerLevel=targetLevel; + disp(['OHIO frequencies= ' num2str(targetFrequency)]) +end + +% --- set cueTarget level according to assessment method +% cue-test difference applies only with singleInterval +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + % For 2IFC the cue stimulus (masker + probe) is the 'no' window + % and the target stimulus (masker+probe) is the 'yes' window + % the order of presentation is decided at the last minute. + cueTargetLevel=-100; % the target is never in the 'no' window + cueMaskerLevel=maskerLevel; % masker level is the same in both + otherwise + % 'single interval' or max likelihood + switch experiment.paradigm + % cue target is more audible + case {'training','absThreshold', 'absThreshold_8', ... + 'TENtest', 'threshold_duration','discomfort',... + 'overShoot','overShootB','overShootMB1', ... + 'overShootMB2', 'OHIO','OHIOabs','OHIOspect'} + cueTargetLevel=targetLevel+cueTestDifference; + + case {'forwardMasking','forwardMaskingD','trainingIFMC', ... + 'TMC','TMC_16ms', 'TMC - ELP', 'IFMC','IFMC_8ms', 'FMreProbe'} + % cue masker is weaker to make target more audible + cueMaskerLevel=maskerLevel-cueTestDifference; + end +end + +% ----------------------------- catch trial +if withinRuns.catchTrial + targetLevel=-100; % no target +end + +% ----------------------------- calibration of sound output +calibrationCorrectiondB=stimulusParameters.calibrationdB; +if calibrationCorrectiondB<-50 + if maskerFrequency==targetFrequency + load 'calibrationFile' % calibrationFrequency calibrationAttenutation + idx=find(calibrationFrequency==targetFrequency); + if isempty(idx) + error('Calibration bty file; frequency not found') + else + calibrationCorrectiondB=calibrationAttenutation(idx) + end + else + error('calibration by file requested but masker frequency is not the same as target') + end +end + + +% -------------------------------------- Checks on excessive signal level + +% clipping is relevant only for soundcard use (not modelling) +switch experiment.ear + case {'left', 'right', 'diotic',... + 'dichotic', 'dioticLeft', 'dichoticRight'} + experiment.headphonesUsed=1; + otherwise + experiment.headphonesUsed=0; +end + +% NB calibration *reduces* the level of the soundCard output +switch experiment.ear + case {'left', 'right', 'diotic',... + 'dichotic', 'dioticLeft', 'dichoticRight'} + clippingLevel=91+calibrationCorrectiondB; + soundCardMinimum=clippingLevel-20*log10(2^24); + otherwise + clippingLevel=inf; + soundCardMinimum=-inf; +end + +% Check for extreme WRV values and abort if necessary +% WRVname specifies the value that changes from trial to trial +withinRuns.forceThreshold=[]; +switch stimulusParameters.WRVname + % check for extreme values. Note that one of the tones might be switched off + case 'maskerLevel' + upperLevel=stimulusParameters.WRVlimits(2); + lowerLevel=stimulusParameters.WRVlimits(1); + if max(maskerLevel, cueMaskerLevel)> upperLevel + errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ... + ') is too high ***']; + withinRuns.forceThreshold=upperLevel; + withinRuns.forceThreshold=NaN; + return + end + if max(maskerLevel, cueMaskerLevel)< lowerLevel + errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ... + ') is too low ***']; + withinRuns.forceThreshold=lowerLevel; + withinRuns.forceThreshold=NaN; + return + end + + if max(maskerLevel, cueMaskerLevel)> clippingLevel + errormsg=['Level(' num2str(max(maskerLevel,cueMaskerLevel)) ... + ') is clipping ***']; + withinRuns.forceThreshold=clippingLevel; + withinRuns.forceThreshold=NaN; + return + end + + case 'targetLevel' + upperLevel=stimulusParameters.WRVlimits(2); + lowerLevel=stimulusParameters.WRVlimits(1); + if ~withinRuns.catchTrial + if max(targetLevel, cueTargetLevel)> upperLevel + errormsg=['target level (' ... + num2str(max(targetLevel, cueTargetLevel)) ... + ') is too high ***']; + withinRuns.forceThreshold=upperLevel; + withinRuns.forceThreshold=NaN; + return + end + if max(targetLevel, cueTargetLevel)< lowerLevel + errormsg=['target level (' ... + num2str(max(targetLevel, cueTargetLevel)) ... + ') is too low ***']; + withinRuns.forceThreshold=lowerLevel; + withinRuns.forceThreshold=NaN; + return + end + if max(targetLevel, cueTargetLevel)> clippingLevel + errormsg=['target level (' ... + num2str(max(targetLevel, cueTargetLevel)) ... + ') is clipping ***']; + withinRuns.forceThreshold=upperLevel; + withinRuns.forceThreshold=NaN; + return + end + end + case 'maskerDuration' + % this is odd! but harmless + if max(maskerDuration, cueMaskerDuration)> ... + stimulusParameters.WRVlimits(2) + errormsg=['maskerDuration (' ... + num2str(max(maskerDuration, cueMaskerDuration))... + ') is too long ***']; + withinRuns.forceThreshold=stimulusParameters.WRVlimits(2); + withinRuns.forceThreshold=NaN; + return + end + + if min(maskerDuration, cueMaskerDuration)... + < stimulusParameters.WRVlimits(1) + errormsg=['maskerDuration (' num2str(maskerLevel) ... + ') too short ***']; + withinRuns.forceThreshold=stimulusParameters.WRVlimits(1); + withinRuns.forceThreshold=NaN; + return + end + + % legacy programming + case 'gapDuration' + if gapDuration<0 + errormsg=['gapDuration (' num2str(gapDuration) ... + ') is less than zero ***']; + return + end + + case 'maskerFrequency' + switch experiment.paradigm + case 'bandwidth' + frequency=maskerFrequency'; + if stimulusParameters.WRVstep<0 + lowerLevel=stimulusParameters.targetFrequency; + upperLevel=stimulusParameters.targetFrequency*2; + else + lowerLevel=stimulusParameters.targetFrequency/3; + upperLevel=stimulusParameters.targetFrequency; + end + + if frequency(1)>upperLevel || frequency(1)<lowerLevel + errormsg=['frequency out of range: ' ... + num2str(frequency)]; + withinRuns.forceThreshold=frequency; + return + end + otherwise + end + + case 'maskerRelativeFrequency' + if maskerRelativeFrequency<stimulusParameters.WRVlimits(1) + errormsg=['masker frequency (' ... + num2str(frequencyDifference) ... + ') is outside WRV limits ***']; + withinRuns.forceThreshold=stimulusParameters.WRVlimits(1) ; + return + end + if maskerRelativeFrequency>stimulusParameters.WRVlimits(2) + errormsg=['masker frequency (' ... + num2str(frequencyDifference) ... + ') is outside WRV limits ***']; + withinRuns.forceThreshold=stimulusParameters.WRVlimits(2) ; + return + end + +end + +% --------------------------------Ear ---------------------------------- +globalStimParams.ears='specified'; +% ear: 1=left, 2=right +switch experiment.ear + case 'left' + maskerEar=1; + targetEar=1; + case 'right' + maskerEar=2; + targetEar=2; + case 'dichoticLeft' + maskerEar=2; + targetEar=1; + case 'dichoticRight' + maskerEar=1; + targetEar=2; + case 'diotic' + maskerEar=1; + targetEar=1; + globalStimParams.ears='diotic'; + case {'MAPmodel', 'MAPmodelMultiCh', 'MAPmodelSingleCh', 'MAPmodelListen',... + 'statsModelLogistic', 'statsModelRareEvent'} + maskerEar=1; + targetEar=1; +end + +backgroundType=stimulusParameters.backgroundType; +switch stimulusParameters.backgroundType + case {'noiseDich', 'pinkNoiseDich'} + % case 'Dich' + % dich means put the background in the ear opposite to the target + backgroundType=backgroundType(1:end-4); + switch targetEar + case 1 + backgroundEar=2; + case 2 + backgroundEar=1; + end + otherwise + % case {'none','noise', 'pinkNoise', 'TEN','babble'} + backgroundEar=targetEar; +end + +% ------------------------------- Make Stimulus ------------------- +% single interval up/down plays cue then target stimulus +% 2IFC uses cue stimulus as interval with no target +globalStimParams.FS=stimulusParameters.sampleRate; +dt=1/stimulusParameters.sampleRate; +globalStimParams.dt=dt; +stimulusParameters.dt=dt; % for use later + + + +globalStimParams.audioOutCorrection=10^(calibrationCorrectiondB/20); +% the output will be reduced by this amount in stimulusCreate +% i.e. audio=audio/globalStimParams.audioOutCorrection +% A 91 dB level will yield a peak amp of 1 for calibration=0 +% A 91 dB level will yield a peak amp of 0.4467 for calibration=7 +% A 98 dB level will yield a peak amp of 1 for calibration=7 + +precedingSilence=stimulusParameters.stimulusDelay; +% all stimuli have 20 ms terminal silence. +% this is clearance for modelling late-ringing targets +terminalSilence=.03; + +% Now compute overall duration of the stimulus +% note that all endsilence values are set to -1 +% so that they will fill with terminal silence as required to make +% components equal in length +% We need to find the longest possible duration +duration(1)=precedingSilence+maskerDuration+cueGapDuration... + +targetDuration+terminalSilence; +duration(2)=precedingSilence+maskerDuration+gapDuration... + +targetDuration+ terminalSilence; +% If the gap is negative we need to ignore it when estimating total length +duration(3)=precedingSilence+maskerDuration+ terminalSilence; +globalStimParams.overallDuration=max(duration); +globalStimParams.nSignalPoints=... + round(globalStimParams.overallDuration/globalStimParams.dt); + +% ----------------------------------------------cue stimulus +% cue masker +componentNo=1; +precedingSilence=stimulusParameters.stimulusDelay; +stimComponents(maskerEar,componentNo).type=maskerType; +stimComponents(maskerEar,componentNo).toneDuration=cueMaskerDuration; +stimComponents(maskerEar,componentNo).frequencies=cueMaskerFrequency; +stimComponents(maskerEar,componentNo).amplitudesdB=cueMaskerLevel; +stimComponents(maskerEar,componentNo).beginSilence=precedingSilence; +stimComponents(maskerEar,componentNo).endSilence=-1; +stimComponents(maskerEar,componentNo).AMfrequency=0; +stimComponents(maskerEar,componentNo).AMdepth=0; +if rampDuration<maskerDuration + % ramps must be shorter than the signal + stimComponents(maskerEar,componentNo).rampOnDur=rampDuration; + stimComponents(maskerEar,componentNo).rampOffDur=rampDuration; +else + % or squeeze the ramp in + stimComponents(maskerEar,componentNo).rampOnDur=maskerDuration/2; + stimComponents(maskerEar,componentNo).rampOffDur=maskerDuration/2; +end +stimComponents(maskerEar,componentNo).phases=... + stimulusParameters.maskerPhase; +stimComponents(maskerEar,componentNo).niterations=0; % for IRN only +% stimComponents(targetEar,componentNo) + +% cue target +componentNo=2; +precedingSilence=precedingSilence + maskerDuration+cueGapDuration; +stimComponents(targetEar,componentNo).type=targetType; +stimComponents(targetEar,componentNo).toneDuration=targetDuration; +stimComponents(targetEar,componentNo).frequencies=cueTargetFrequency; +stimComponents(targetEar,componentNo).amplitudesdB=cueTargetLevel; +stimComponents(targetEar,componentNo).beginSilence=precedingSilence; +stimComponents(targetEar,componentNo).endSilence=-1; +stimComponents(targetEar,componentNo).AMfrequency=0; +stimComponents(targetEar,componentNo).AMdepth=0; +if rampDuration<targetDuration + % ramps must be shorter than the signal + stimComponents(targetEar,componentNo).rampOnDur=rampDuration; + stimComponents(targetEar,componentNo).rampOffDur=rampDuration; +else + stimComponents(targetEar,componentNo).rampOnDur=0; + stimComponents(targetEar,componentNo).rampOffDur=0; +end +stimComponents(targetEar,componentNo).phases=... + stimulusParameters.targetPhase; +% stimComponents(targetEar,componentNo) + +% background same ear as target +componentNo=3; +stimComponents(backgroundEar,componentNo).type=backgroundType; +switch backgroundType + case 'TEN' + fileName=['..' filesep '..' filesep ... + 'multithresholdResources' filesep ... + 'backgrounds and maskers'... + filesep 'ten.wav']; + [tenNoise, FS]=wavread(fileName); + tenNoise=resample(tenNoise, globalStimParams.FS, FS); + stimComponents(backgroundEar,componentNo).type='file'; + stimComponents(backgroundEar,componentNo).stimulus=tenNoise'; +end +stimComponents(backgroundEar,componentNo).toneDuration=... + globalStimParams.overallDuration; +stimComponents(backgroundEar,componentNo).amplitudesdB=backgroundLevel; +stimComponents(backgroundEar,componentNo).beginSilence=0; +stimComponents(backgroundEar,componentNo).endSilence=-1; +stimComponents(backgroundEar,componentNo).AMfrequency=0; +stimComponents(backgroundEar,componentNo).AMdepth=0; +stimComponents(backgroundEar,componentNo).rampOnDur=rampDuration; +stimComponents(backgroundEar,componentNo).rampOffDur=rampDuration; + +[cueStimulus, errormsg]=... + stimulusCreate(globalStimParams, stimComponents, 0); +if ~isempty(errormsg) % e.g. limits exceeded + errormsg + return +end + +% ------------------------------------------ test stimulus +% masker +componentNo=1; +precedingSilence=stimulusParameters.stimulusDelay; +stimComponents(maskerEar,componentNo).type=maskerType; +stimComponents(maskerEar,componentNo).toneDuration=maskerDuration; +stimComponents(maskerEar,componentNo).frequencies=maskerFrequency; +stimComponents(maskerEar,componentNo).amplitudesdB=maskerLevel; +stimComponents(maskerEar,componentNo).beginSilence=precedingSilence; +stimComponents(maskerEar,componentNo).endSilence=-1; +stimComponents(maskerEar,componentNo).AMfrequency=0; +stimComponents(maskerEar,componentNo).AMdepth=0; +if rampDuration<maskerDuration + % ramps must be shorter than the signal + stimComponents(maskerEar,componentNo).rampOnDur=rampDuration; + stimComponents(maskerEar,componentNo).rampOffDur=rampDuration; +else + stimComponents(maskerEar,componentNo).rampOnDur=maskerDuration/2; + stimComponents(maskerEar,componentNo).rampOffDur=maskerDuration/2; +end +stimComponents(maskerEar,componentNo).phases=... + stimulusParameters.maskerPhase; +stimComponents(maskerEar,componentNo).niterations=0; % for IRN only + +% target +componentNo=2; +targetDelay=precedingSilence+ maskerDuration+ gapDuration; +stimComponents(targetEar,componentNo).type=targetType; +stimComponents(targetEar,componentNo).toneDuration=targetDuration; +stimComponents(targetEar,componentNo).frequencies=targetFrequency; +stimComponents(targetEar,componentNo).amplitudesdB=targetLevel; +stimComponents(targetEar,componentNo).beginSilence=targetDelay; +stimComponents(targetEar,componentNo).endSilence=-1; +stimComponents(targetEar,componentNo).AMfrequency=0; +stimComponents(targetEar,componentNo).AMdepth=0; +if rampDuration<targetDuration + % ramps must be shorter than the signal + stimComponents(targetEar,componentNo).rampOnDur=rampDuration; + stimComponents(targetEar,componentNo).rampOffDur=rampDuration; +else + stimComponents(targetEar,componentNo).rampOnDur=0; + stimComponents(targetEar,componentNo).rampOffDur=0; +end +stimComponents(targetEar,componentNo).phases=stimulusParameters.targetPhase; +% stimComponents(targetEar,componentNo) + +% background same ear as target +componentNo=3; +stimComponents(backgroundEar,componentNo).type=backgroundType; +switch backgroundType + case 'TEN' + fileName=['..' filesep '..' filesep ... + 'multithresholdResources' filesep ... + 'backgrounds and maskers'... + filesep 'ten.wav']; + [tenNoise, FS]=wavread(fileName); + + tenNoise=resample(tenNoise, globalStimParams.FS, FS); + stimComponents(backgroundEar,componentNo).type='file'; + stimComponents(backgroundEar,componentNo).stimulus=tenNoise'; +end +stimComponents(backgroundEar,componentNo).toneDuration=... + globalStimParams.overallDuration; +stimComponents(backgroundEar,componentNo).amplitudesdB=backgroundLevel; +stimComponents(backgroundEar,componentNo).beginSilence=0; +stimComponents(backgroundEar,componentNo).endSilence=-1; +stimComponents(backgroundEar,componentNo).rampOnDur=rampDuration; +stimComponents(backgroundEar,componentNo).rampOffDur=rampDuration; +stimComponents(backgroundEar,componentNo).AMfrequency=0; +stimComponents(backgroundEar,componentNo).AMdepth=0; + +% timings used when evaluating MAP peripheral model +% this is the Slope during which spikes are counted +switch experiment.paradigm + case 'gapDetection' + % gap is the 'target' in this case + stimulusParameters.testTargetBegins=... + stimulusParameters.stimulusDelay... + +stimulusParameters.maskerDuration; + stimulusParameters.testTargetEnds=... + stimulusParameters.testTargetBegins+withinRuns.variableValue; + % case 'SRT' + % set(handles.editdigitInput,'visible','off') + otherwise + stimulusParameters.testTargetBegins=targetDelay; + stimulusParameters.testTargetEnds=targetDelay+targetDuration; +end + +% ------------------------------------------------------------- play! +% Create and play stimulus (as required by different paradigms) +switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent'} + audio=[0;0]; % no need to compute stimulus + + otherwise % create the stimulus + [targetStimulus, errormsg]= ... + stimulusCreate(globalStimParams, stimComponents, 0); + + if ~isempty(errormsg) % e.g. limits exceeded + errormsg + return + end + + switch experiment.ear + case {'MAPmodel' , 'MAPmodelMultiCh', 'MAPmodelSingleCh', 'MAPmodelListen'} + % model requires no calibration correction; + % signal is already in Pascals + globalStimParams.audioOutCorrection=1; + % use only the targetStimulus for the MAP model + audio=targetStimulus; + + otherwise % left, right diotic dichotic + if stimulusParameters.includeCue + audio= [cueStimulus; targetStimulus]; + else % no cue + audio=targetStimulus; + end + end + + % playtime + % order of the cue and test stimuli varies for 2AFC + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + % intervening silence (currently none; masking delay serves this purpose) + IAFCinterveningSilence=zeros(round(AFCsilenceDuration/dt),2); + if rand>0.5 % put test stimulus first + stimulusParameters.testTargetBegins=targetDelay ; + stimulusParameters.testTargetEnds= ... + targetDelay+targetDuration; + stimulusParameters.testNonTargetBegins=... + length(cueStimulus)*dt ... + + AFCsilenceDuration +targetDelay ; + stimulusParameters.testNonTargetEnds=... + length(cueStimulus)*dt ... + + AFCsilenceDuration+targetDelay+targetDuration; + + set(handles.pushbutton1,'backgroundcolor','r'), drawnow + y=audioplayer(targetStimulus, globalStimParams.FS, 24); + playblocking(y) + set(handles.pushbutton1,'backgroundcolor',... + get(0,'defaultUicontrolBackgroundColor')), drawnow + y=audioplayer(IAFCinterveningSilence, ... + globalStimParams.FS, 24); + playblocking(y) + set(handles.pushbutton2,'backgroundcolor','r'), drawnow + y=audioplayer(cueStimulus, globalStimParams.FS, 24); + playblocking(y) + set(handles.pushbutton2,'backgroundcolor',... + get(0,'defaultUicontrolBackgroundColor')), drawnow + withinRuns.stimulusOrder='targetFirst'; + audio= [targetStimulus; IAFCinterveningSilence; ... + cueStimulus]; % for plotting purposes later + + else % put test stimulus second + stimulusParameters.testTargetBegins=... + length(cueStimulus)*dt ... + + AFCsilenceDuration +targetDelay ; + stimulusParameters.testTargetEnds=... + length(cueStimulus)*dt ... + + AFCsilenceDuration+targetDelay+targetDuration; + stimulusParameters.testNonTargetBegins=targetDelay ; + stimulusParameters.testNonTargetEnds=... + targetDelay+targetDuration; + + set(handles.pushbutton1,'backgroundcolor','r'),drawnow + y=audioplayer(cueStimulus, globalStimParams.FS, 24); + playblocking(y) + set(handles.pushbutton1,'backgroundcolor',... + get(0,'defaultUicontrolBackgroundColor')), drawnow + y=audioplayer(IAFCinterveningSilence, ... + globalStimParams.FS, 24); + playblocking(y) + set(handles.pushbutton2,'backgroundcolor','r'), drawnow + y=audioplayer(targetStimulus, globalStimParams.FS, 24); + playblocking(y) + set(handles.pushbutton2,'backgroundcolor',... + get(0,'defaultUicontrolBackgroundColor')), drawnow + withinRuns.stimulusOrder='targetSecond'; + audio= [cueStimulus; IAFCinterveningSilence; ... + targetStimulus]; % for plotting purposes later + end + otherwise % singleInterval + if strcmp(experiment.ear,'MAPmodel') ... + || strcmp(experiment.ear,'MAPmodelMultiCh') ... + || strcmp(experiment.ear,'MAPmodelSingleCh') ... + ||strcmp(experiment.ear,'MAPmodelListen') + % don't play for MAPmodel + switch experiment.ear + % except on special request + case {'MAPmodelListen'} + y=audioplayer(audio, globalStimParams.FS, 24); + playblocking(y) % suspends operations until completed + end + else + y=audioplayer(audio, globalStimParams.FS, 24); + playblocking(y) + end % if experiment.ear + end % switch experiment.threshEstMethod +end % switch experiment.ear + + +% switch experiment.ear +% case {'MAPmodel', 'MAPmodelListen', 'MAPmodelMultiCh','MAPmodelSingleCh'} +% % save audio for later reference or for input to MAP model +% wavwrite(audio/max(audio), globalStimParams.FS,32,'stimulus') +% end + +% Panel 1 +% graphical presentation of the stimulus +% NB shown *after* the stimulus has been presented +axes(expGUIhandles.axes1), cla +% plot is HW rectified and plotted as dB re 28e-6 +% calibration is ignored +t=dt:dt:dt*length(audio); +plot(t,stimulusParameters.calibrationdB+20*log10((abs(audio)+1e-10)/28e-6)) +% set(gca,'xtick',[]) +ylim([-20 100]) +ylabel('stimulus (dB SPL)') +xlim([0 t(end)]) +grid on +header=[betweenRuns.variableName1 ': ' ... + num2str(betweenRuns.var1Sequence(betweenRuns.runNumber))]; +header=[header ' ' num2str(... + betweenRuns.var2Sequence(betweenRuns.runNumber)) ':' ... + betweenRuns.variableName2 ]; +title(header) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/old files/MAPmodel.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,136 @@ +function [modelResponse, MacGregorResponse]=MAPmodel( MAPplot, method) + +global experiment stimulusParameters audio withinRuns +global outerMiddleEarParams DRNLParams AN_IHCsynapseParams + +savePath=path; +addpath('..\MAP') +modelResponse=[]; +MacGregorResponse=[]; + +% mono only (column vector) +audio=audio(:,1)'; + +% if stop button pressed earlier +if experiment.stop, return, end + +% -------------------------------------------------------------- run Model +MAPparamsName=experiment.name; +showPlotsAndDetails=experiment.MAPplot; +AN_spikesOrProbability='spikes'; + +% [response, method]=MAPsequenceSeg(audio, method, 1:8); +global ICoutput ANdt + MAP1_14(audio, 1/method.dt, method.nonlinCF,... + MAPparamsName, AN_spikesOrProbability); + +if showPlotsAndDetails + options.showModelParameters=0; + options.showModelOutput=1; + options.printFiringRates=1; + options.showACF=0; + options.showEfferent=1; + UTIL_showMAP(options, paramChanges) +end + +% No response, probably caused by hitting 'stop' button +if isempty(ICoutput), return, end + +% MacGregor response is the sum total of all final stage spiking +MacGregorResponse= sum(ICoutput,1); % use IC + +% ---------------------------------------------------------- end model run + +dt=ANdt; +time=dt:dt:dt*length(MacGregorResponse); + +% group delay on unit response +MacGonsetDelay= 0.004; +MacGoffsetDelay= 0.022; + +% now find the response of the MacGregor model during the target presentation + group delay +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + idx= time>stimulusParameters.testTargetBegins+MacGonsetDelay ... + & time<stimulusParameters.testTargetEnds+MacGoffsetDelay; + nSpikesTrueWindow=sum(MacGregorResponse(:,idx)); + idx=find(time>stimulusParameters.testNonTargetBegins+MacGonsetDelay ... + & time<stimulusParameters.testNonTargetEnds+MacGoffsetDelay); + nSpikesFalseWindow=sum(MacGregorResponse(:,idx)); + % nSpikesDuringTarget is +ve when more spikes are found + % in the target window + difference= nSpikesTrueWindow-nSpikesFalseWindow; + + if difference>0 + % hit + nSpikesDuringTarget=experiment.MacGThreshold+1; + elseif difference<0 + % miss (wrong choice) + nSpikesDuringTarget=experiment.MacGThreshold-1; + else + if rand>0.5 + % hit (random choice) + nSpikesDuringTarget=experiment.MacGThreshold+1; + else + % miss (random choice) + nSpikesDuringTarget=experiment.MacGThreshold-1; + end + end + disp(['level target dummy decision: ' ... + num2str([withinRuns.variableValue nSpikesTrueWindow ... + nSpikesFalseWindow nSpikesDuringTarget], '%4.0f') ] ) + + otherwise + % idx=find(time>stimulusParameters.testTargetBegins+MacGonsetDelay ... + % & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); + % no delay at onset + idx=find(time>stimulusParameters.testTargetBegins +MacGonsetDelay... + & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); + nSpikesDuringTarget=sum(MacGregorResponse(:,idx)); + + % find(MacGregorResponse)*dt-stimulusParameters.stimulusDelay + timeX=time(idx); +end + +% now find the response of the MacGregor model at the end of the masker +idx2=find(time>stimulusParameters.testTargetBegins-0.02 ... + & time<stimulusParameters.testTargetBegins); +if ~isempty(idx2) + maskerRate=mean(mean(MacGregorResponse(idx2))); +else + %e.g. no masker + maskerRate=0; +end + +if experiment.MAPplot + % add vertical lines to indicate target region + figure(99), subplot(6,1,6) + hold on + yL=get(gca,'YLim'); + plot([stimulusParameters.testTargetBegins + MacGonsetDelay ... + stimulusParameters.testTargetBegins + MacGonsetDelay],yL,'r') + plot([stimulusParameters.testTargetEnds + MacGoffsetDelay ... + stimulusParameters.testTargetEnds + MacGoffsetDelay],yL,'r') +end + +% specify unambiguous response +switch experiment.paradigm + case 'gapDetection' + gapResponse=(maskerRate-nSpikesDuringTarget)/maskerRate; + if gapResponse>0.2 + modelResponse=2; % gap detected + else + modelResponse=1; % gap not detected + end + [nSpikesDuringTarget maskerRate gapResponse modelResponse] + figure(22), plot(timeX,earObject(idx)) + otherwise + if nSpikesDuringTarget>experiment.MacGThreshold + modelResponse=2; % stimulus detected + else + modelResponse=1; % nothing heard (default) + end +end + + +path(savePath)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_GOM.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,45 @@ +function paradigm_GOM(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='maskerLevel'; +stimulusParameters.WRVstartValues=20; +stimulusParameters.WRVsteps= [-10 -2]; +stimulusParameters.WRVlimits=[-30 110]; + +% target variable: slope=1, start going down. +withinRuns.direction='up'; +experiment.psyFunSlope=-1; + +betweenRuns.variableName1='targetLevel'; +betweenRuns.variableList1=25: 5: 70; +betweenRuns.variableName2='maskerRelativeFrequency'; +betweenRuns.variableList2=[1 0.5]; +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.104; +stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); +stimulusParameters.maskerRelativeFrequency=betweenRuns.variableList2; + +stimulusParameters.gapDuration=0.0002; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +% retain current target frequency +x=str2num(get(handles.edittargetFrequency,'string')); +stimulusParameters.targetFrequency=x(1); + +stimulusParameters.targetDuration=0.004; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.002; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_IFMC.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,41 @@ +function paradigm_IFMC(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='maskerLevel'; +stimulusParameters.WRVstartValues=-10; +stimulusParameters.WRVsteps= [-10 -2]; +stimulusParameters.WRVlimits=[-30 110]; + +experiment.psyFunSlope = -1; +withinRuns.direction='up'; + +betweenRuns.variableName1='maskerRelativeFrequency'; +betweenRuns.variableList1=[1 0.5 1.6 .9 .7 1.1 1.3 ]; +betweenRuns.variableName2='targetFrequency'; +% keep old list of target frequencies +betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerDuration=0.108; +stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); +stimulusParameters.maskerRelativeFrequency=betweenRuns.variableList1; + +stimulusParameters.gapDuration=0.01; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=betweenRuns.variableList2(1); +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=NaN; + +stimulusParameters.rampDuration=0.004; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_IFMC_16ms.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,41 @@ +function paradigm_IFMC_8ms(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='maskerLevel'; +stimulusParameters.WRVstartValues=50; +stimulusParameters.WRVsteps= [-10 -2]; +stimulusParameters.WRVlimits=[-30 110]; + +experiment.psyFunSlope = -1; +withinRuns.direction='up'; + +betweenRuns.variableName1='maskerRelativeFrequency'; +betweenRuns.variableList1=[1 0.5 1.6 .9 .7 1.1 1.3 ]; +betweenRuns.variableName2='targetFrequency'; +% keep old list of target frequencies +betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerDuration=0.108; +stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); +stimulusParameters.maskerRelativeFrequency=betweenRuns.variableList1; + +stimulusParameters.gapDuration=0.01; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=betweenRuns.variableList2(1); +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=NaN; + +stimulusParameters.rampDuration=0.004; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_SRT.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,72 @@ +function paradigm_SRT(handles) +global stimulusParameters experiment betweenRuns + +stimulusParameters.subjectSampleRate=44100; + +% assessment method +% {'oneIntervalUpDown', 'MaxLikelihood', '2I2AFC++', '2I2AFC+++'} +experiment.threshEstMethod='oneIntervalUpDown'; +% {'cued', 'noCue'}; +stimulusParameters.includeCue=0; +stimulusParameters.cueTestDifference=10; + +experiment.singleIntervalMaxTrials=10; +experiment.maxTrials=10; +experiment.allowCatchTrials= 0; + +% {'tone','noise', 'pinkNoise','whiteNoise','OHIO'} +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=60 ; +stimulusParameters.WRVsteps=[5 2]; +stimulusParameters.WRVlimits=[-30 110]; + +% target variable: slope=1, start going down. +experiment.psyFunSlope=1; +withinRuns.direction='down'; + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=1000; +betweenRuns.variableName2='maskerDuration'; +betweenRuns.variableList2=0.1 ; +% 1='fixed sequence', 2='randomize within blocks', 3='randomize across +% blocks' +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target + +stimulusParameters.stimulusDelay=0.3; + +% maskerTypes={'tone','noise', 'pinkNoise','TEN','whiteNoise'}; +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.0; +stimulusParameters.maskerLevel= -50; +stimulusParameters.maskerRelativeFrequency= 1 ; % not used + +stimulusParameters.gapDuration=0.0; + +% targetTypes={'tone','noise', 'pinkNoise','whiteNoise','OHIO'}; +stimulusParameters.targetType='digitStrings'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=2; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; +stimulusParameters.stimulusDelay=1; + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + +% {'none','noise', 'pinkNoise', 'TEN','noiseDich', 'pinkNoiseDich','whiteNoise'} +stimulusParameters.backgroundType='24TalkerBabble'; +stimulusParameters.backgroundLevel= 60; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= ... + [{'Type three digits in the box (top left)'}, { }, ... + {'then hit return'}]; + +stimulusParameters.numOHIOtones=1; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_TENtest.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,33 @@ +function paradigm_TENtest(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=40; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=[250 500 1000 2000 4000 8000 ]; +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2= 0.25; +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=betweenRuns.variableList1; +stimulusParameters.targetDuration=0.5; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +% {'none','noise', 'pinkNoise', 'TEN','noiseDich', 'pinkNoiseDich','whiteNoise'} +stimulusParameters.backgroundType='TEN'; +stimulusParameters.backgroundLevel=20; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_TMC.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,44 @@ +function paradigm_TMC(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='maskerLevel'; +stimulusParameters.WRVstartValues=-10; +stimulusParameters.WRVsteps= [-10 -4]; +stimulusParameters.WRVlimits=[-30 110]; + +stimulusParameters.cueTestDifference = 10; +experiment.psyFunSlope = -1; +withinRuns.direction='up'; + +betweenRuns.variableName1='gapDuration'; +betweenRuns.variableList1=[.05 .08 .02 .06 .04 ]; +betweenRuns.variableName2='targetFrequency'; +% retain existing targetFrequencies +betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.108; +stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); +stimulusParameters.maskerRelativeFrequency=1; + +stimulusParameters.gapDuration=betweenRuns.variableList1; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=betweenRuns.variableList2(1); +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=NaN; + +stimulusParameters.rampDuration=0.004; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_TMC_16ms.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,46 @@ +function paradigm_TMC_16ms(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +experiment.singleIntervalMaxTrials=20; + +stimulusParameters.WRVname='maskerLevel'; +stimulusParameters.WRVstartValues=50; +stimulusParameters.WRVsteps= [-10 -4]; +stimulusParameters.WRVlimits=[-30 110]; + +stimulusParameters.cueTestDifference = 10; +experiment.psyFunSlope = -1; +withinRuns.direction='up'; + +betweenRuns.variableName1='gapDuration'; +betweenRuns.variableList1=[.01 .09 .03 .05 .07]; +betweenRuns.variableName2='targetFrequency'; +% retain existing targetFrequencies +betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.108; +stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); +stimulusParameters.maskerRelativeFrequency=1; + +stimulusParameters.gapDuration=betweenRuns.variableList1; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=betweenRuns.variableList2(1); +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=NaN; + +stimulusParameters.rampDuration=0.004; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_TMCmodel.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,45 @@ +function paradigm_TMCmodel(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='maskerLevel'; +stimulusParameters.WRVstartValues=30; +stimulusParameters.WRVsteps= [-10 -4]; +stimulusParameters.WRVlimits=[-30 110]; + +stimulusParameters.cueTestDifference = 10; +experiment.psyFunSlope = -1; +withinRuns.direction='up'; + +betweenRuns.variableName1='gapDuration'; +betweenRuns.variableList1=[ 0.09 0.01:0.02:0.07 0.02:0.02:.08 0.005]; +betweenRuns.variableName2='targetFrequency'; +% retain existing targetFrequencies +betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.108; +stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); +stimulusParameters.maskerRelativeFrequency=1; +experiment.singleIntervalMaxTrials=10; + +stimulusParameters.gapDuration=betweenRuns.variableList1; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=betweenRuns.variableList2(1); +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=NaN; + +stimulusParameters.rampDuration=0.004; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_absThreshold.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,29 @@ +function paradigm_absThreshold(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=[250 500 1000 2000 4000 8000 ]; +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2= 0.25; + +stimulusParameters.targetFrequency=betweenRuns.variableList1; +stimulusParameters.targetDuration=betweenRuns.variableList2; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.WRVstartValues=30; + + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_absThreshold_16.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,36 @@ +function paradigm_absThreshold16(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=1000; +betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.016; +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target + + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; + +experiment.stopCriteria2IFC=[75 3 5]; +experiment.singleIntervalMaxTrials=[20]; + + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_absThreshold_8.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,32 @@ +function paradigm_absThreshold_8(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=1000; +betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.008 ; +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target + + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.008; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_discomfort.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,28 @@ +function paradigm_discomfort(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=75 ; +stimulusParameters.WRVsteps=[3 3]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=[1000]; +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.5 ; +betweenRuns.randomizeSequence=2; % 'fixed sequence' + +stimulusParameters.stimulusDelay=0; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.5; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.instructions{1}= ['Is the tone ''comfortable'', ''loud'' or ''uncomfortable''?']; +% single interval up/down with cue +stimulusParameters.instructions{2}= []; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_forwardMasking.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,44 @@ +function paradigm_forwardMasking(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=50; +stimulusParameters.WRVsteps= [10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='gapDuration'; +betweenRuns.variableList1=[.005 0.01 0.02 0.04]; +betweenRuns.variableName2='maskerLevel'; +betweenRuns.variableList2=[20 40 60 80]; +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.108; +stimulusParameters.maskerLevel=betweenRuns.variableList2; +stimulusParameters.maskerRelativeFrequency=1; + +stimulusParameters.gapDuration=betweenRuns.variableList1; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.02; +stimulusParameters.targetLevel=-stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.01; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; + +experiment.maxTrials=10; +% catchTrials +experiment.allowCatchTrials= 1; + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_overShoot.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,44 @@ +function paradigm_overShoot(handles) +global stimulusParameters betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=50; +stimulusParameters.WRVsteps= [10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='gapDuration'; +betweenRuns.variableList1=[-.399 -.2]; +% betweenRuns.variableList1=[-.288 -.218 -.2 -.190 -.170 -.130 -.070 -.030 -.010 .005 .020 .080]; +% betweenRuns.variableList1=[-.350 -.238 -.213 -.180 -.160 -.100 -.040 -.020 0 .010 .040 .140]; +betweenRuns.variableName2='maskerLevel'; +betweenRuns.variableList2=50; +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target +stimulusParameters.stimulusDelay=0.3; + +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.4; +stimulusParameters.maskerLevel=betweenRuns.variableList2; +stimulusParameters.maskerRelativeFrequency=1; + +stimulusParameters.gapDuration=betweenRuns.variableList1; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.01; +stimulusParameters.targetLevel=-stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.005; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_psychometric.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,32 @@ +function paradigm_psychometric(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +experiment.printTracks=1; +experiment.maxTrials=30; + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=30 ; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=1000.01:0.01:1000.05; +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.1 ; +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.1; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_thr_IFMC.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,36 @@ +function paradigm_thr_IFMC(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=1000; +betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.016; +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target + + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; + +experiment.stopCriteria2IFC=[75 3 5]; +experiment.singleIntervalMaxTrials=[20]; + + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_thr_TMC.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,36 @@ +function paradigm_thr_TMC(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=1000; +betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.016; +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target + + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; + +experiment.stopCriteria2IFC=[75 3 5]; +experiment.singleIntervalMaxTrials=[20]; + + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_threshold_duration.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,33 @@ +function paradigm_threshold_duration(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=40; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='targetDuration'; +betweenRuns.variableList1=[ .016 .032 .064 .128 .256 .512]; +betweenRuns.variableName2='targetFrequency'; +betweenRuns.variableList2=1000; +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +% retain current target frequency +x=str2num(get(handles.edittargetFrequency,'string')); +stimulusParameters.targetFrequency=x(1); +stimulusParameters.targetDuration=betweenRuns.variableList2; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_training.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,73 @@ +function paradigm_training(handles) +global stimulusParameters experiment betweenRuns + +stimulusParameters.subjectSampleRate=44100; % compatible with file input +% stimulusParameters.subjectSampleRate=64000; % compatible with file input +% stimulusParameters.subjectSampleRate=128000; % compatible with file input + +% assessment method +% {'oneIntervalUpDown', 'MaxLikelihood', '2I2AFC++', '2I2AFC+++'} +experiment.threshEstMethod='oneIntervalUpDown'; +% {'cued', 'noCue'}; +stimulusParameters.includeCue=1; +stimulusParameters.cueTestDifference=10; + +experiment.singleIntervalMaxTrials=10; +experiment.maxTrials=10; +experiment.allowCatchTrials= 1; + +% {'tone','noise', 'pinkNoise','whiteNoise','OHIO'} +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=20 ; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +% target variable: slope=1, start going down. +experiment.psyFunSlope=1; +withinRuns.direction='down'; + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=1000; +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.1 ; +% 1='fixed sequence', 2='randomize within blocks', 3='randomize across +% blocks' +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target + +stimulusParameters.stimulusDelay=0.3; + +% maskerTypes={'tone','noise', 'pinkNoise','TEN','whiteNoise'}; +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.0; +stimulusParameters.maskerLevel= -50; +stimulusParameters.maskerRelativeFrequency= 1 ; % not used + +stimulusParameters.gapDuration=0.0; + +% targetTypes={'tone','noise', 'pinkNoise','whiteNoise','OHIO'}; +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.1; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + +% {'none','noise', 'pinkNoise', 'TEN','noiseDich', 'pinkNoiseDich','whiteNoise'} +stimulusParameters.backgroundType='none'; +stimulusParameters.backgroundLevel=-100; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; + +stimulusParameters.numOHIOtones=1; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/paradigm_trainingIFMC.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,43 @@ +function paradigm_trainingIFMC(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +stimulusParameters.WRVname='maskerLevel'; +stimulusParameters.WRVstartValues=-10; +stimulusParameters.WRVsteps= [-10 -2]; +stimulusParameters.WRVlimits=[-30 110]; + +stimulusParameters.cueTestDifference = 10; +experiment.psyFunSlope = -1; +withinRuns.direction='up'; + +betweenRuns.variableName1='maskerRelativeFrequency'; +betweenRuns.variableList1=[ 0.5 .9 .7 1.3 ]; +betweenRuns.variableName2='targetFrequency'; +% keep old list of target frequencies +betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.randomizeSequence=1; % 'random sequence' + +stimulusParameters.maskerType='tone'; +stimulusParameters.maskerPhase='sin'; +stimulusParameters.maskerDuration=0.108; +stimulusParameters.maskerLevel=stimulusParameters.WRVstartValues(1); +stimulusParameters.maskerRelativeFrequency=betweenRuns.variableList1; + +stimulusParameters.gapDuration=0.03; + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=betweenRuns.variableList2(1); +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel= 30; + +stimulusParameters.rampDuration=0.004; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}=[{'YES if you hear the added click'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}=[{'count how many distinct clicks you hear'},{'ignore the tones'},{' '},... + {'The clicks must be **clearly distinct** to count'}];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/reserve team/OHIOthresholds.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,7 @@ +function experiment=OHIOthresholds(experiment) + +experiment.OHIOfrequencies=[494, 663, 870, 1125, 1442, 1838, 2338, 2957, 3725, 4680, 5866, 7334]; %Hz. +% User must specify abs thresholds (dB SPL) of each tone frequency +experiment.OHIOthresholds= [ + 9.1 8.6 8.1 7.9 9.8 10.5 13.5 15.0 17.4 19.4 22.6 25.2 +]; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/reserve team/paradigm_OHIOabs.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,47 @@ +function paradigm_OHIOabs(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones +% whose frequencies are chosen at random from a list (OHIOfrequencies) +% All tones are presented at the same level (SL) computed using absolute +% threshols specified in OHIOthresholds; +% The duration of the complex is increased across runs and the number of tones is +% controlled by OHIOdurations, (for each 20 ms a further tone is added. +% The frequency of the tones is changed on each trial + +experiment.OHIOfrequencies=[494, 663, 870, 1125, 1442, 1838, 2338, 2957, 3725, 4680, 5866, 7334]; %Hz. +% User must specify abs thresholds (dB SPL) of each tone frequency +% experiment.OHIOthresholds= [18 16 16 19 20 22 24 26 27 30 32 35]; + +% assessment method +% {'oneIntervalUpDown', 'MaxLikelihood', '2I2AFC++', '2I2AFC+++'} +experiment.threshEstMethod='oneIntervalUpDown'; +% {'cued', 'noCue'}; + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=20 ; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='numOHIOtones'; +betweenRuns.variableList1= 1:12; % i.e. the frequency to be used +betweenRuns.variableName2='stimulusDelay'; +betweenRuns.variableList2=0.05; +betweenRuns.randomizeSequence=2; % not random sequence + +stimulusParameters.targetType='OHIO'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=experiment.OHIOfrequencies; +stimulusParameters.targetDuration=0.01; % overruled by OHIO program +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.005; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/reserve team/paradigm_OHIOrand.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,41 @@ +function paradigm_OHIOrand(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones +% whose frequencies are chosen at random from a list (OHIOfrequencies) +% All tones are presented at the same level (SL) computed using absolute +% threshols specified in OHIOthresholds; +% The duration of the complex is increased across runs and the number of tones is +% controlled by OHIOdurations, (for each 20 ms a further tone is added. +% The frequency of the tones is changed on each trial + +% fetch thresholds and frequencies +experiment=OHIOthresholds(experiment); + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=0 ; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='numOHIOtones'; +betweenRuns.variableList1= [1 2 4 8 12]; +betweenRuns.variableName2='stimulusDelay'; +betweenRuns.variableList2=0.1; +betweenRuns.randomizeSequence=2; % not random sequence + +stimulusParameters.targetType='OHIO'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=experiment.OHIOfrequencies; +stimulusParameters.targetDuration=betweenRuns.variableList2; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.005; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/reserve team/paradigm_OHIOspect.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,41 @@ +function paradigm_OHIOspect(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones +% whose frequencies are chosen at random from a list (OHIOfrequencies) +% All tones are presented at the same level (SL) computed using absolute +% threshols specified in OHIOthresholds; +% The duration of the complex is increased across runs and the number of tones is +% controlled by OHIOdurations, (for each 20 ms a further tone is added. +% The frequency of the tones is changed on each trial + +% fetch thresholds and frequencies +experiment=OHIOthresholds(experiment); + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=0 ; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='numOHIOtones'; +betweenRuns.variableList1= [1 2 4 8 12]; +betweenRuns.variableName2='stimulusDelay'; +betweenRuns.variableList2=0.1; +betweenRuns.randomizeSequence=2; % not random sequence + +stimulusParameters.targetType='OHIO'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=experiment.OHIOfrequencies; +stimulusParameters.targetDuration=betweenRuns.variableList2; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.005; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/reserve team/paradigm_OHIOspectemp.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,40 @@ +function paradigm_OHIOspectemp(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones +% whose frequencies are chosen at random from a list (OHIOfrequencies) +% All tones are presented at the same level (SL) computed using absolute +% threshols specified in OHIOthresholds; +% The duration of the complex is increased across runs and the number of tones is +% controlled by OHIOdurations, (for each 20 ms a further tone is added. +% The frequency of the tones is changed on each trial + +% fetch thresholds and frequencies +experiment=OHIOthresholds(experiment); + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=0 ; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; + +betweenRuns.variableName1='numOHIOtones'; +betweenRuns.variableList1= [1 2 4 8 12]; +betweenRuns.variableName2='stimulusDelay'; +betweenRuns.variableList2=0.1; +betweenRuns.randomizeSequence=2; % not random sequence + +stimulusParameters.targetType='OHIO'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=experiment.OHIOfrequencies; +stimulusParameters.targetDuration=betweenRuns.variableList2; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.005; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/paradigms/reserve team/paradigm_OHIOtemp.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,44 @@ +function paradigm_OHIOtemp(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +% find the threshold for a tonecomplex consisting of a sequence of 10-ms tones +% whose frequencies are chosen at random from a list (OHIOfrequencies) +% All tones are presented at the same level (SL) computed using absolute +% threshols specified in OHIOthresholds; +% The duration of the complex is increased across runs and the number of tones is +% controlled by OHIOdurations, (for each 20 ms a further tone is added. +% The frequency of the tones is changed on each trial + +% fetch thresholds and frequencies +experiment=OHIOthresholds(experiment); + +stimulusParameters.WRVname='targetLevel'; +stimulusParameters.WRVstartValues=0 ; +stimulusParameters.WRVsteps=[10 2]; +stimulusParameters.WRVlimits=[-30 110]; +% target variable: slope=1, start going down. +stimulusParameters.cueTestDifference=10; +experiment.psyFunSlope= 1; +withinRuns.direction='down'; + +betweenRuns.variableName1='numOHIOtones'; +betweenRuns.variableList1= [1 2 4 8 12]; +betweenRuns.variableName2='stimulusDelay'; +betweenRuns.variableList2=0.1; +betweenRuns.randomizeSequence=2; % not random sequence + +stimulusParameters.targetType='OHIO'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=experiment.OHIOfrequencies; +stimulusParameters.targetDuration=betweenRuns.variableList2; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.005; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/printReport.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,303 @@ +function printReport(fileName, printTracks) + +% End of run report (no args) +% *or* +% reprint previous report from file + +global experiment stimulusParameters betweenRuns withinRuns statsModel audio +global LevittControl expGUIhandles + + +global inputStimulusParams OMEParams DRNLParams +global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams +global MacGregorParams MacGregorMultiParams filteredSACFParams +global experiment % used by calls from multiThreshold only +global IHC_cilia_RPParams + + +printReportGuide.structures=1; +printReportGuide.showPsychometric=0; +printReportGuide.HorizontalTracks=1; + +if nargin==0 + % print new report + printReportGuide.showTracks=experiment.printTracks; + printReportGuide.fileName=[]; + if experiment.saveData + saveFileName=['savedData/' experiment.name '_' experiment.date '_' experiment.paradigm]; + else + % save this data (just in case) + saveFileName=['savedData/mostRecentResults']; + end + experiment.minElapsed=etime(clock, betweenRuns.timeNow)/60; + save(saveFileName, 'experiment', 'stimulusParameters',... + 'betweenRuns', 'withinRuns', 'statsModel', 'expGUIhandles') + disp(['data saved as: ' saveFileName]); + +else + % reprint request (i.e print out old data) + printReportGuide.fileName=fileName; + load(printReportGuide.fileName) + saveFileName=printReportGuide.fileName; + if nargin>1 + printReportGuide.showTracks=printTracks; + else + printReportGuide.showTracks=experiment.printTracks; + end +end + +fprintf('******** multithreshold ') + +x=pwd; disp(['version ' x(end-3:end)]) +fprintf('\nName:\t%s ', experiment.name) +fprintf('\nparadigm:\t%s ', experiment.paradigm) +fprintf('\nEar:\t%s ', experiment.ear) + +method=experiment.threshEstMethod; +if stimulusParameters.includeCue && ~strcmp(method(1:6),'2I2AFC') + method=[method '/ withCue']; +end +fprintf('\nmethod:\t%s ', method) +fprintf('\ndate:\t%s ', experiment.date) +fprintf('\n\n') + +if isempty(betweenRuns.thresholds) + disp('no thresholds found') +end + +% prepare results as matrices ready to print +% first sort the actual sequence into a more readable sequence +[idx1, idx2, var1values, var2values]=... + sortVariables(betweenRuns.variableList1, betweenRuns.variableList2,... + betweenRuns.var1Sequence, betweenRuns.var2Sequence); + +header1=betweenRuns.variableName1; +header2=betweenRuns.variableName2; +header1 = strrep(header1, 'none', ' '); % none is not a useful header +header2 = strrep(header2, 'none', ' '); % none is not a useful header +headers=strvcat([header1 '/'], header2); + +disp('thresholds') +msg=printTabTable(sortTablesForPrinting(idx1,idx2,... + var1values,var2values, betweenRuns.thresholds), headers); +addToMsg(msg,0) +fprintf('\n') + +% sort tracks into the same order +betweenRuns.levelTracks=betweenRuns.levelTracks(idx1); +betweenRuns.responseTracks=betweenRuns.responseTracks(idx1); +betweenRuns.bestThresholdTracks=betweenRuns.bestThresholdTracks(idx1); +betweenRuns.levelTracks=betweenRuns.levelTracks(idx2); +betweenRuns.responseTracks=betweenRuns.responseTracks(idx2); +betweenRuns.bestThresholdTracks=betweenRuns.bestThresholdTracks(idx2); + +if printReportGuide.structures + maxNoArrayValues=30; + showStructureSummary(stimulusParameters, 'stimulusParameters', maxNoArrayValues) + showStructureSummary(experiment, 'experiment',maxNoArrayValues) + showStructureSummary(betweenRuns, 'betweenRuns',maxNoArrayValues) + showStructureSummary(withinRuns, 'withinRuns') + + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + showStructureSummary(LevittControl, 'LevittControl', maxNoArrayValues) + end + + switch experiment.ear + case {'statsModelLogistic','statsModelRareEvent'} + showStructureSummary(statsModel, 'statsModel', maxNoArrayValues) + end +end + +if printReportGuide.showTracks + % NB this procedure can only be used if all the tracks are present and + % of equal length + bigTable=[]; header=[]; + disp(' '); disp('Leveltracks starting from 1 response before the first reversal') + for i=1:length(betweenRuns.levelTracks) + if printReportGuide.HorizontalTracks + printTabTable(betweenRuns.levelTracks{i}); + end + header=strvcat(header, 'level'); + end + + disp(' '); disp('Response tracks starting from 1 response before the first reversal') + for i=1:length(betweenRuns.responseTracks) + if printReportGuide.HorizontalTracks + printTabTable(betweenRuns.responseTracks{i}); + end + header=strvcat(header, 'resp'); + end + + disp(' '); disp('threshold tracks starting from the first reversal') + for i=1:length(betweenRuns.bestThresholdTracks) + if printReportGuide.HorizontalTracks + end + printTabTable(betweenRuns.bestThresholdTracks{i}); + header=strvcat(header, 'mean'); + end + +end + +switch experiment.ear + case {'MAPmodelMultiCh', 'MAPmodelSingleCh'} + % show all parameters but do not compute the model + nm=UTIL_paramsList(whos); + for i=1:length(nm) + try + eval(['UTIL_showStruct(' nm{i} ', ''' nm{i} ''')']) + catch + end + end +end + +if experiment.saveData + fprintf('\n') + disp('To reprint this report with tracks use:') + disp([ 'printReport(''' saveFileName ''',1)']) +end + +% print final summary (repeat of above) +fprintf('\n') +fprintf('\n') +disp('thresholds') +msg=printTabTable(sortTablesForPrinting(idx1,idx2,var1values,var2values, betweenRuns.thresholds), headers); +addToMsg(msg,0) +fprintf('\n') + +if length(var1values)==1 && length(var2values)==1 && experiment.maxTrials>49 + [psy, levelsBinVector, binFrequencies, nNo, nYes]= ... + psychometricFunction(withinRuns.levelsPhaseTwo,withinRuns.responsesPhaseTwo, experiment.psyBinWidth); + disp('Psychometric function') + fprintf(' level \tfreq\tprob\n') + fprintf('%6.0f\t%6.2f\t%6.0f\n', [levelsBinVector; binFrequencies; psy]) + fprintf('\n') + fprintf('k \t %6.2f\n',logistic.bestK) + fprintf('g \t%7.5f\n',rareEvent.bestGain) + fprintf('\n') + +end + +fprintf('\nparadigm:\t%s\n ', experiment.paradigm) + +% ------------------------------------------------------- sortTablesForPrinting +function table= sortTablesForPrinting(idx1,idx2, var1values,var2values, x) +% table converts a vector to a table +% after sorting according to idx1 and idx2 +% the table is completed by adding row and column values +x=x(idx1); +x=x(idx2); +xMatrix=reshape(x,length(var1values),length(var2values)); + +table=[[-1000 var2values]; [var1values' xMatrix]]; + +% ------------------------------------------------------- showStructureSummary +function showStructureSummary(structure, name, maxNoArrayValues) +% showStructureSummary prints out the values of a single structure +% The header is the structure name and each row is a field +% e.g. showStructureSummary(params,'params') +% This not the same as 'UTIL_showstruct' + + +if nargin<3 + maxNoArrayValues=20; +end + +fprintf('\n%s:', name) + +fields=fieldnames(eval('structure')); +% for each field in the structure +for i=1:length(fields) + y=eval([ 'structure.' fields{i}]); + if isstr(y), + % strings + fprintf('\n%s=\t''%s''', fields{i},y) + elseif isnumeric(y) + % arrays + if length(y)>1 + % vectors + [r c]=size(y); + if r>c, y=y'; end + + [r c]=size(y); + if r>1 + % fprintf('\n%s.%s=\t%g x %g matrix',name, fields{i}, r, c) + fprintf('\n%s=\t%g x %g matrix',fields{i}, r, c) + + elseif c<maxNoArrayValues + % fprintf('\n%s=\t[%s]', fields{i},num2str(y)) + fprintf('\n%s=', fields{i}) + fprintf('\t%g',y) + + else + fprintf('\n%s=\t %g... [%g element array]', fields{i}, y(1),c) + end + else + % single valued arrays + % fprintf('\n%s.%s=\t%s;', name, fields{i},num2str(y)) + fprintf('\n%s=\t%s', fields{i},num2str(y)) + end + elseif iscell(y) + fprintf('\n%s=\t cell array', fields{i}) + + elseif isstruct(y) + fprintf('\n%s=\t structure', fields{i}) + end, + +end, +fprintf('\n') + + +% ------------------------------------------------------- printTabTable +function strings= printTabTable(M, headers) +% printTabTable prints a matrix as a table with tabs +%headers are optional +%headers=strvcat('firstname', 'secondname') +% printTabTable([1 2; 3 4],strvcat('a1','a2')); +stringCount=1; strings{stringCount}=[]; + +if nargin>1 + [r c]=size(headers); + for no=1:r + % print all headers in a row + fprintf('%s\t',headers(no,:)) + strings{stringCount}=sprintf('%s\t',headers(no,:)); stringCount=stringCount+1; + end + fprintf('\n') +end + +[r c]=size(M); + +for row=1:r + string=[]; + for col=1:c + if row==1 & col==1 & M(1,1)==-1000 + % Print nothing (tab follows below) + else + fprintf('%s',num2str(M(row,col))) + string=[string ' ' sprintf('%s',num2str(M(row,col)))]; + end + if col<c + fprintf('\t') + % strings{stringCount}=sprintf('\t'); stringCount=stringCount+1; + end + end % col + strings{stringCount}=string; stringCount=stringCount+1; + fprintf('\n') +end % row + +% ------------------------------------------------------- sortVariables +function [idx1, idx2, var1values, var2values]= ... + sortVariables(var1values, var2values, var1Sequence, var2Sequence) + +[x idx1]= sort(var1Sequence); +var1Sequence= x; +var2Sequence= var2Sequence(idx1); +depVarName= 'th'; + +[x idx2]=sort(var2Sequence); +var2Sequence=x; +var1Sequence=var1Sequence(idx2); + +var1values=sort(var1values); +var2values=sort(var2values);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/psychoLogisticRareEvent.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,307 @@ +function psycho + +% DATA from AbsThresholdCM, LS + +levelSequence=[16.0836 6.0836 11.0836 12.725 13.4995 11.6559 12.7168 13.9507 12.0632 11.3845 11.7754 12.8639 14.1061 14.5545 13.5589 13.4736 14.1554 13.5123 13.1537 11.5334 12.6921 11.4461 10.7112 11.9171 10.8412 12.0536 13.06 14.2345 13.8535 14.0575 14.0145 15.6385 13.7959 14.0397 12.2497 11.4383 12.7685 12.7317 11.6741 10.3955 9.0334 10.4787 11.1883 11.4687 12.0583 13.8982 13.0644 14.4722 14.0304 14.7569 13.8571 12.1521 14.0865 13.2258 11.6988 12.2186 12.2561 12.2711 13.0345 14.2948 13.7838 12.9155 12.6927 12.5757 13.4818 12.8397 14.1803 12.7524 12.3169 13.0973 14.9722 14.4422 15.8944 17.2728 16.8621 15.3074 13.7319 11.7716 12.1233 12.1576 13.0023 13.2442 12.1454 13.8298 13.3997 11.7799 12.3834 12.8387 14.3718 12.7063 14.4002 14.3674 14.7882 15.0271 13.5737 15.2095 14.1789 13.4982 14.3926 13.6277 15.0551 13.493 15.3368 16.9437 16.1645 15.9275 15.7577 14.2939 14.1069 13.6184 12.728 14.4283 15.6494 14.2216 15.8188 14.3906 12.7635 13.2973 11.9934 11.1053 12.2359 11.439 12.4735 12.5466 12.9186 13.6937 13.792 13.085 12.5016 13.8401 11.9688 13.0676 14.3708 13.4891 14.4394 15.8265 17.1478 15.2337 13.6512 12.7727 14.4818 13.7045 14.5207 13.8211 13.2874 14.9221 14.3822 14.3562 13.3132 13.5015 13.1372 14.4495 13.957 15.2124 16.6607 15.114 13.8978 12.6665 12.3469 13.3699 14.1991 15.2259 13.2326 11.9325 13.1954 12.2766 13.7996 15.5274 14.7623 13.21 12.5874 10.6431 12.2121 10.4043 11.9979 10.2153 10.7945 11.5215 12.7081 14.2288 14.4475 13.9777 13.8564 14.1923 15.393 14.5229 15.3377 13.9385 13.6328 14.2861 15.0021 15.5488 13.8067 13.0269 13.3644 13.6195 14.5834 15.6554 13.8914 13.3657 14.0566 12.9857 12.9343 14.0372 14.0156 15.6395 15.4225 14.6514 14.6498 13.6421 13.4263 13.227 14.0428 14.681 15.1661 13.5285 14.9074 13.5498 14.4265 14.0798 14.6391 12.8226 12.225 13.7883 12.7012 12.7932 13.5318 14.9207 14.064 12.9551 14.2066 14.3463 13.4565 13.9379 15.7189 14.3516 12.6425 12.8485 12.2879 13.1142 11.8093 12.0037 10.2154 11.8395 12.4643 13.0501 13.5452 13.2338 12.6246 13.292 11.5661 11.6015 13.2896 15.2506 15.5295 14.523 13.6199 13.083 12.1714 12.5977 14.2862 15.7924 14.0221 14.4042 16.0364 16.6967 14.7112 14.7594 13.9874 13.3428 13.5231 14.441 13.9983 13.6414 11.862 13.2632 13.1065 12.8701 12.2578 13.7517 14.3268 13.3849 13.9609 13.3239 14.6694 14.8172 13.654 13.8144 13.5015 14.34 14.0139 15.1029 13.3895 13.3701 13.4554 11.9646 12.2519 12.4145 13.1343 14.9372 13.2483 +]; + + +responseSequence=[1 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 1 1 1 0 1 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0 1 1 0 1 1 0 0 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 1 1 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 0 1 1 0 1 0 1 0 0 1 1 1 1 1 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 1 1 0 1 0 1 1 0 1 1 1 0 1 0 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 1 1 1 1 0 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0 0 1 1 0 1 1 0 1 0 1 1 1 1 1 1 0 0 0 1 0 1 0 1 0 1 1 0 1 0 0 0 1 1 0 0 1 0 0 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 0 1 1 0 0 1 1 1 0 1 1 1 0 0 1 0 1 0 0 1 0 1 0 1 0 1 1 0 1 0 0 0 0 1 1 +]; + + +duration=0.008; + + +% levelSequence=[23.3987 13.3987 18.9769 25.9114 18.6243 16.4689 23.7829 20.4015 19.3156 25.1232 21.4541 24.353 22.1732 24.83 21.8257 19.3798 17.885 26.0332 23.3135 20.7889 20.1446 22.3504 25.7491 25.8517 23.2701 25.2773 24.8727 26.416 23.9425 21.4652 25.3512 18.3484 26.0988 23.2303 17.0335 26.7833 17.1426 21.1627 21.8802 24.8192 18.2626 +% ]; +% responseSequence=[1 0 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 0 1 1 1 1 1 1 1 0 0 1 0 1 1 0 1 0 0 0 1 0 +% ]; +% duration=0.016; + + +% levelSequence=[24.9709 14.9709 18.3185 20.893 19.1644 17.8633 12.8493 20.2354 19.4386 14.4227 14.3361 12.0587 18.6425 20.1803 18.1533 20.8734 19.0579 20.4904 18.3061 14.8561 16.6948 19.2928 17.8098 17.6181 21.7709 16.6804 15.2661 17.967 20.0085 20.7096 15.7485 20.0475 16.0825 11.8798 19.4383 13.838 18.3323 15.8729 12.066 15.4367 12.4179 +% ]; +% responseSequence=[1 0 1 1 1 1 0 1 1 0 0 0 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 0 1 0 0 1 0 1 1 0 1 0 +% ]; +% duration=0.512; +% +% +% levelSequence=[20.9248 10.9248 17.6621 16.5301 12.8652 8.4223 7.2398 13.566 14.5773 15.7202 13.4907 15.5048 10.9308 11.9566 13.3548 18.6419 15.8288 13.6961 12.8613 11.1181 10.7736 14.6912 11.3496 18.4924 16.9867 14.6383 17.4752 19.0135 14.7333 14.0739 14.637 11.7261 10.1013 17.7782 18.4642 14.1431 18.7764 19.312 10.9071 17.2639 17.9951 +% ]; +% responseSequence=[1 0 1 1 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 1 1 1 0 1 1 +% ]; +% duration=0.256; + + +functionType='logistic'; +functionType='rareEvent'; + +[R C]=size(levelSequence); +levelSequence=reshape(levelSequence',1,R*C); + +[R C]=size(responseSequence); +responseSequence=reshape(responseSequence',1,R*C); + +figure(2),clf +figure(3),clf +figure(2), plot(levelSequence,responseSequence,'k.'),hold on +set(gca,'ytick',[0 1]) +set(gca,'yticklabel',{'0'; '1'}) +ylim([-.5 1.5]) +figure(3), plot(levelSequence,responseSequence,'k.'),hold on + +figure(2), xlabel('dB SPL'), ylabel('p(yes)') +figure(3), xlabel('dB SPL'), ylabel('p(yes)') + +set(gca,'ytick',[0 1]) +set(gca,'yticklabel',{'0'; '1'}) +ylim([-.5 1.5]) +binWidth=1; +minBinCenter=-10; +maxBinCenter=100; +binCenters=minBinCenter:binWidth:maxBinCenter; +noPointers=find(responseSequence==0); +noLevels=levelSequence(noPointers); +yesPointers=find(responseSequence==1); +yesLevels=levelSequence(yesPointers); +noHist=hist(noLevels,binCenters); +yesHist=hist(yesLevels,binCenters); +warning off MATLAB:divideByZero +yesHist=hist(yesLevels,binCenters); +proportions=yesHist./(yesHist+noHist); +warning on MATLAB:divideByZero + +idx=find(noHist | yesHist); +noHist=noHist(idx); +yesHist=yesHist(idx); +proportions=proportions(idx); +binCenters=binCenters(idx); + +for i=1:length(noHist) + marker=10*(noHist(i)+yesHist(i))/max(noHist); + figure(2), plot(binCenters(i),proportions(i),'ko','markersize',marker), hold on + figure(3), plot(binCenters(i),proportions(i),'ko','markersize',marker), hold on +end + + + + + + + +rareEventProfile= fitRareEvent2(levelSequence,responseSequence, duration) +figure(2), hold on +plot(rareEventProfile.predictionLevels, rareEventProfile.predictionsRE,'g') +xlim([min(binCenters) max(binCenters)]) +figure(3), hold on +plot(rareEventProfile.predictionLevels, rareEventProfile.predictionsRE,'g') +xlim([20 35]) + + + +[bestVmin, bestG, smallestEuclid]=... + rareEvent(levelSequence,responseSequence, duration); + +[bestThreshold, bestSlope, smallestEuclid]=... + logistic(levelSequence,responseSequence); + +% -------------------------------------------- rareEvent +function [bestVmin, bestG, smallestEuclid]=... + rareEvent(levelSequence,responseSequence, duration) +'rare event' +gs=.01:.01:4; + +Vmins=1:10:5000; +P=28*10.^(levelSequence/20); +allSmallestEuclid=[ ]; +allBestGs=[]; + +for Vmin=Vmins + Euclids=[]; + x=[];y=[]; + for G=gs; + predictions= 1-exp(-duration*(G*P-Vmin)); + idx=find(predictions<0); predictions(idx)=0; + Euclid=mean((predictions - responseSequence).^2); + Euclids=[Euclids Euclid]; + end + + [smallestEuclid idx]=min(Euclids); + % disp(num2str([idx smallestEuclid])) + allSmallestEuclid=[allSmallestEuclid smallestEuclid]; + bestG=gs(idx); + allBestGs=[allBestGs bestG]; + +end +[smallestEuclid idx2]=min(allSmallestEuclid) +bestVmin=Vmins(idx2); +bestG=allBestGs(idx2); +% [bestVmin bestG smallestEuclid] + +% predictions= 1-exp(-duration*(bestG*P-Vmin)); +% errors=responseSequence-predictions; +% rho=corr([errors; levelSequence]'); +% disp(['correlation=' num2str(rho(1,2))]) + + +levels=[min(levelSequence):max(levelSequence)]; +P=28*10.^(levels/20); +predictions= 1-exp(-duration*(bestG*P-bestVmin)); +idx=find(predictions<0); predictions(idx)=0; +figure(2), plot(levels,predictions,'r'), hold off +title(['g=' num2str(bestG) ': Vmin=' num2str(bestVmin) ': Euclid= ' num2str(smallestEuclid)]) +figure(4), plot(levels(1:end-1), diff(predictions)) + +xlim([levels(1)-10 levels(end)+10]) +ylim([-0.5 1.5]) +pause(.1) + +% -------------------------------------------- logistic +function [bestThreshold, bestSlope, smallestEuclid]=... + logistic(levelSequence,responseSequence) +'logistic' +candidateThresholds=-20:1:50; +candidateSlopes=.01:.01:10; + +allSmallestEuclid=[ ]; +allThresholds=[]; + +for thisSlope=candidateSlopes; + Euclids=[]; + for thisThreshold=candidateThresholds; + predictions=1./(1+exp(-thisSlope.*(levelSequence-thisThreshold))); + Euclid=mean((predictions - responseSequence).^2); + Euclids=[Euclids Euclid]; + end + [smallestEuclid idx]=min(Euclids); + % disp(num2str([idx smallestEuclid])) + allSmallestEuclid=[allSmallestEuclid smallestEuclid]; + bestThreshold=candidateThresholds(idx); + allThresholds=[allThresholds bestThreshold]; +end +[smallestEuclid idx2]=min(allSmallestEuclid) +bestSlope=candidateSlopes(idx2); +bestThreshold=allThresholds(idx2); +% [bestThreshold bestSlope smallestEuclid] + +% predictions= 1-exp(-duration*(bestG*P-Vmin)); +% errors=responseSequence-predictions; +% rho=corr([errors; levelSequence]'); +% disp(['correlation=' num2str(rho(1,2))]) + + +levels=[min(levelSequence):max(levelSequence)]; +bestLogistic=1./(1+exp(-bestSlope*(levels-bestThreshold))); +figure(3), plot(levels,bestLogistic,'r'), hold off +title(['k=' num2str(bestSlope) ': threshold=' num2str(bestThreshold) ': Euclid= ' num2str(smallestEuclid)]) +% figure(2), hold on, plot(levels,bestLogistic,'g'), hold off +figure(4), hold on, plot(levels(1:end-1), diff(bestLogistic), 'r') + + +xlim([levels(1)-10 levels(end)+10]) +ylim([-0.5 1.5]) + + + +% --------------------------------------------------- fitRareEvent +function rareEvent=fitRareEvent2(stimulusLevels, responses, duration, gains, Vmins) +% least squares estimate of *rare event* function +% p(event)=gain*levelmPa -Vmin +% 'responses' is a binary vector of subject's decision. +% 'stimulusLevels' are the corresponding signal levesl (values) +% duration is required to compute the expectation of an event occurring +% gains is an optional list of gains to be tried +% Vmins is an optional list of Vmins to be tried + +global experiment +if nargin<5 + minVmin=1; maxVmin=100000; nVmins=30; + Vmins=[0 logspace(log10(minVmin),log10(maxVmin),nVmins)]; + % disp(Vmins) + nGains=10; + dGain=1/nGains; + gains=dGain:dGain:20; +end + +nVmins=length(Vmins); +nGains=length(gains); + +rareEvent.bestGain=NaN; +rareEvent.bestVMin=NaN; +rareEvent.thresholddB=0; +rareEvent.bestPaMindB=NaN; +rareEvent.predictionLevels=[]; +rareEvent.predictionsRE=[]; +rareEvent.Euclid=NaN; + +if isempty(stimulusLevels), return, end + +% expected slope is negative, rareEvent can not be used +% if experiment.psyFunSlope<0 +% return +% end + +% NB calculations in microPascals! +stimulusLevelsAsPressure=28 * 10.^(stimulusLevels/20); + +allGains=reshape(repmat(gains,nVmins,1), 1, nVmins*nGains); +allVmins=repmat(Vmins, 1, nGains); + +for repeat=1:2 + predictions=NaN(1,length(stimulusLevels)); + gainCount=0; VminCount=0; + Euclid=inf; bestVmin=0; bestGain=0; + for gain= gains + gainCount=gainCount+1; + VminCount=0; + for Vmin=Vmins + VminCount=VminCount+1; + % all levels are simultaneously assessed + gP_Vmin=gain*stimulusLevelsAsPressure-Vmin; + idx=(gP_Vmin>0); + predictions(idx)= 1-exp(-duration*(gP_Vmin(idx))); + predictions(~idx)=0; + + error=(predictions - responses).^2; + error=mean(error(~isnan(error))); + if error<Euclid + Euclid=error; + bestVmin=Vmin; + bestVminCount=VminCount; + bestGainCount=gainCount; + bestGain=gain; + end + end + end + if repeat==1 + if bestVminCount>1 & bestVminCount<nVmins + minVmin=Vmins(bestVminCount-1); maxVmin=Vmins(bestVminCount+1); nVmins=30; + Vmins=[0 logspace(log10(minVmin),log10(maxVmin),nVmins)]; + elseif bestVminCount==1 + Vmins=0:Vmins(2)/30:Vmins(2); + else + disp('rareEvent: Vmin estimate may be out of range') + end + end + % disp(Vmins) +end + +if bestGainCount==1 | bestGainCount==nGains + disp('gain estimate may be out of range') +end + + +[rareEvent.Euclid idx]=min(Euclid); +rareEvent.bestGain=bestGain; +rareEvent.bestVMin=round(bestVmin); +rareEvent.thresholdPa=(-log(0.5)/duration + rareEvent.bestVMin)/rareEvent.bestGain; +rareEvent.thresholddB=20*log10(rareEvent.thresholdPa/28); +rareEvent.bestPaMindB=20*log10((rareEvent.bestVMin/rareEvent.bestGain)/28); + +predictionLevels= -50:1:120; +rareEvent.predictionLevels=predictionLevels; +rareEvent.predictionsRE=... + 1-exp(-duration*(rareEvent.bestGain*28 * 10.^(predictionLevels/20)-rareEvent.bestVMin)); +rareEvent.predictionsRE(rareEvent.predictionsRE<0)=0; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/psychometricFunction.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,49 @@ +% ------------------------------------------------------- psychometricFunction +function [psy, levelsBinVector, binFrequencies, nNo, nYes]=... + psychometricFunction(levels, responses, psyBinWidth) +% computes a psychometric function from rwo vectors (levels and responses) +% responses is a binary vectory (1=yes) +% psyBinWidth is the bin width (dB) of the output psychometric function +% this function is called by both fitPsychometricFunction and subjGUI +% for this reason it should notbe bundled with fitPsychometricFunction + +binFrequencies=[]; nNo=[]; nYes=[]; +if min(levels)+abs(psyBinWidth) < max(levels) + % create a set of bins for the psychometric function + levelsBinVector= min(levels): abs(psyBinWidth): max(levels); +else + psy=[]; levelsBinVector=[]; + return +end + +idx0=find(responses==0); % isolate 'no' +z=levels(idx0); +nNo=hist(z, levelsBinVector); + +idx1=find(responses>0); % isolate 'yes' +y=levels(idx1); +nYes=hist(y, levelsBinVector); + +if sum(nNo)==0 | sum(nYes)==0 + psy=[]; levelsBinVector=[]; + return % yesses and nos required for a function +end + +binFrequencies=nNo+nYes; + +warning off MATLAB:divideByZero +psy=nYes./binFrequencies; % psy is the proportion of 'yes' responses +warning on MATLAB:divideByZero +lastwarn(''); + +idx=~isnan(psy); %remove empty bins +idx=(nYes>0) |(nNo>0); %remove empty bins +psy=psy(idx); +levelsBinVector=levelsBinVector(idx); +binFrequencies=binFrequencies(idx); +nNo=nNo(idx); +nYes=nYes(idx); + +% [nNo' nYes'] +% [levelsBinVector' psy'] +% plot(levelsBinVector,psy,['o']) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/subjGUI_MT.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,1867 @@ +function varargout = subjGUI_MT(varargin) + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @subjGUI_MT_OpeningFcn, ... + 'gui_OutputFcn', @subjGUI_MT_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && isstr(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +% --- Executes just before subjGUI_MT is made visible. +function subjGUI_MT_OpeningFcn(hObject, eventdata, handles, varargin) + +% Choose default command line output for subjGUI_MT +handles.output = hObject; +initializeGUI(handles) +guidata(hObject, handles); + +function varargout = subjGUI_MT_OutputFcn(hObject, eventdata, handles) +% Get default command line output from handles structure +varargout{1} = handles.output; + +% -----------------------------------------------------initializeGUI +function initializeGUI(handles) +global experiment +global subjectGUIHandles expGUIhandles + addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... + ['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... + ['..' filesep 'testPrograms']) + +dbstop if error + +% subjectGUI size and location % [left bottom width height] +scrnsize=get(0,'screensize'); +set(0, 'units','pixels') +switch experiment.ear + % use default size unless... + case {'MAPmodel', 'MAPmodelMultich', 'MAPmodelSingleCh', ... + 'statsModelLogistic','statsModelRareEvent'} + % subjectGUI not needed for modelling so minimize subject GUI + set(gcf, 'units','pixels') + y=[0*scrnsize(3) 0.8*scrnsize(4) 0.1*scrnsize(3) 0.2*scrnsize(4)]; + set(gcf,'position',y, 'color',[.871 .961 .996]) + + + + case 'MAPmodelListen', + % subjectGUI is needed for display purposes. Make it large + set(gcf, 'units','pixels') + y=[.665*scrnsize(3) 0.02*scrnsize(4) ... + 0.33*scrnsize(3) 0.5*scrnsize(4)]; % alongside + set(gcf,'position',y, 'color',[.871 .961 .996]) +end + +switch experiment.ear + case{'left', 'right','diotic', 'dichoticLeft','dichoticRight'} + % Look to see if the button box exists and, if so, initialise it + buttonBoxIntitialize % harmless if no button box attached +end + +% function varargout = subjGUI_MT(varargin) +% +% % Begin initialization code - DO NOT EDIT +% gui_Singleton = 1; +% gui_State = struct('gui_Name', mfilename, ... +% 'gui_Singleton', gui_Singleton, ... +% 'gui_OpeningFcn', @subjGUI_MT_OpeningFcn, ... +% 'gui_OutputFcn', @subjGUI_MT_OutputFcn, ... +% 'gui_LayoutFcn', [] , ... +% 'gui_Callback', []); +% if nargin && isstr(varargin{1}) +% gui_State.gui_Callback = str2func(varargin{1}); +% end +% +% if nargout +% [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +% else +% gui_mainfcn(gui_State, varargin{:}); +% end +% % End initialization code - DO NOT EDIT +% +% % --- Executes just before subjGUI_MT is made visible. +% function subjGUI_MT_OpeningFcn(hObject, eventdata, handles, varargin) +% +% % Choose default command line output for subjGUI_MT +% handles.output = hObject; +% initializeGUI(handles) +% guidata(hObject, handles); +% +% function varargout = subjGUI_MT_OutputFcn(hObject, eventdata, handles) +% % Get default command line output from handles structure +% varargout{1} = handles.output; +% +% % -----------------------------------------------------initializeGUI +% function initializeGUI(handles) +% global experiment +% global subjectGUIHandles expGUIhandles +% +% dbstop if error +% +% % subjectGUI size and location % [left bottom width height] +% scrnsize=get(0,'screensize'); +% set(0, 'units','pixels') +% switch experiment.ear +% % use default size unless... +% case {'MAPmodel', 'MAPmodelMultiCh','MAPmodelSingleCh', ... +% 'statsModelLogistic','statsModelRareEvent'} +% % subjectGUI not needed for modelling so minimize subject GUI +% set(gcf, 'units','pixels') +% y=[0*scrnsize(3) 0.8*scrnsize(4) 0.1*scrnsize(3) 0.2*scrnsize(4)]; +% set(gcf,'position',y, 'color',[.871 .961 .996]) +% +% case 'MAPmodelListen', +% % subjectGUI is needed for display purposes. Make it large +% set(gcf, 'units','pixels') +% y=[.665*scrnsize(3) 0.02*scrnsize(4) ... +% 0.33*scrnsize(3) 0.5*scrnsize(4)]; % alongside +% set(gcf,'position',y, 'color',[.871 .961 .996]) +% end +% +% switch experiment.ear +% case{'left', 'right','diotic', 'dichoticLeft','dichoticRight'} +% % Look to see if the button box exists and, if so, initialise it +% buttonBoxIntitialize % harmless if no button box attached +% end + +% clear display of previous mean values. This is a new measurement series +axes(expGUIhandles.axes4), cla +reset (expGUIhandles.axes4) + +% handles needed in non-callback routines below +subjectGUIHandles=handles; + +% start immediately +startNewExperiment(handles, expGUIhandles) +% This is the end of the experiment. Exit here and return to ExpGUI. + +% ----------------------------------------------------- startNewExperiment +function startNewExperiment(handles, expGUIhandles) +% An experiment consists of a series of 'runs'. +% Resets all relevant variables at the beginning of a new experiment. +global experiment stimulusParameters betweenRuns + +% 'start new experiment' button is the only valid action now +experiment.status='waitingForStart'; + +switch experiment.threshEstMethod + % add appropriate labels to subject GUI buttons + case {'2I2AFC++', '2I2AFC+++'} + set(handles.pushbutton3,'string','') + set(handles.pushbutton2,'string','2') + set(handles.pushbutton1,'string','1') + set(handles.pushbutton0,'string','0') + case {'MaxLikelihood', 'oneIntervalUpDown'} + if stimulusParameters.includeCue + set(handles.pushbutton3,'string','') + set(handles.pushbutton2,'string','2') + set(handles.pushbutton1,'string','1') + set(handles.pushbutton0,'string','0') + else + set(handles.pushbutton3,'string','') + set(handles.pushbutton2,'string','YES') + set(handles.pushbutton1,'string','NO') + set(handles.pushbutton0,'string','') + end +end + +switch experiment.paradigm + case 'discomfort' + set(handles.pushbutton3,'string','') + set(handles.pushbutton2,'string','uncomfortable') + set(handles.pushbutton1,'string','loud') + set(handles.pushbutton0,'string','comfortable') + experiment.allowCatchTrials=0; +end + +% experiment.subjGUIfontSize is set on expGUI +set(handles.pushbutton3,'FontSize',experiment.subjGUIfontSize) +set(handles.pushbutton2,'FontSize',experiment.subjGUIfontSize) +set(handles.pushbutton1,'FontSize',experiment.subjGUIfontSize) +set(handles.pushbutton0,'FontSize',experiment.subjGUIfontSize) +set(handles.pushbuttoNotSure,'FontSize',experiment.subjGUIfontSize) +set(handles.pushbuttonGO,'FontSize',experiment.subjGUIfontSize) +set(handles.textMSG,'FontSize',experiment.subjGUIfontSize) + +set(handles.pushbutton19,'visible','off') % unused button + +% start command window summary of progress +fprintf(' \n ----------- NEW MEASUREMENTS\n') +disp(['paradigm: ' experiment.paradigm]) +cla(expGUIhandles.axes1) +cla(expGUIhandles.axes2) +cla(expGUIhandles.axes4) +cla(expGUIhandles.axes5) + +experiment.stop=0; % status of 'stop' button +experiment.pleaseRepeat=0; % status of 'repeat' button +experiment.buttonBoxStatus='not busy'; + +% date and time and replace ':' with '_' +date=datestr(now);idx=findstr(':',date);date(idx)='_'; +experiment.date=date; +timeNow=clock; betweenRuns.timeNow= timeNow; +experiment.timeAtStart=[num2str(timeNow(4)) ':' num2str(timeNow(5))]; +experiment.minElapsed=0; + +% unpack catch trial rates. The rate declines from the start rate +% to the base rate using a time constant. +stimulusParameters.catchTrialRate=stimulusParameters.catchTrialRates(1); +stimulusParameters.catchTrialBaseRate=... + stimulusParameters.catchTrialRates(2); +stimulusParameters.catchTrialTimeConstant=... + stimulusParameters.catchTrialRates(3); +if stimulusParameters.catchTrialBaseRate==0 + stimulusParameters.catchTrialRate=0; +end + +% for human measurements only, identify the start catch trial rate +switch experiment.ear + case{'left', 'right','diotic', 'dichoticLeft','dichoticRight'} + fprintf('stimulusParameters.catchTrialRate= %6.3f\n', ... + stimulusParameters.catchTrialRate) +end + +% Reset betweenRuns parameters. this occurs only at experiment start +% withinRuns values are reset in 'startNewRun' +% this approach creates a more readable structure summary printout. +betweenRuns.thresholds=[]; +betweenRuns.thresholds_mean=[]; +betweenRuns.thresholds_median=[]; +betweenRuns.forceThresholds=[]; +betweenRuns.observationCount=[]; +betweenRuns.catchTrials=[]; +betweenRuns.timesOfFirstReversals=[]; +betweenRuns.bestThresholdTracks=[]; +betweenRuns.levelTracks=[]; +betweenRuns.responseTracks=[]; +betweenRuns.slopeKTracks=[]; +betweenRuns.gainTracks=[]; +betweenRuns.VminTracks=[]; +betweenRuns.bestGain=[]; +betweenRuns.bestVMin=[]; +betweenRuns.bestPaMin=[]; +betweenRuns.bestLogisticM=[]; +betweenRuns.bestLogisticK=[]; +betweenRuns.resets=0; +betweenRuns.runNumber=0; + +% Up to two parameters can be changed between runs +% Find the variable parameters and randomize them +% e.g. 'variableList1 = stimulusParameters.targetFrequency;' +eval(['variableList1=stimulusParameters.' betweenRuns.variableName1 ';']); +eval(['variableList2=stimulusParameters.' betweenRuns.variableName2 ';']); +nVar1=length(variableList1); +nVar2=length(variableList2); + +% Create two sequence vectors to represent the sequence of var1 and var2 +% values. 'var1' changes most rapidly. +switch betweenRuns.randomizeSequence + case 'fixed sequence' + var1Sequence=repmat(betweenRuns.variableList1, 1,nVar2); + var2Sequence=reshape(repmat(betweenRuns.variableList2, ... + nVar1,1),1,nVar1*nVar2); + case 'randomize within blocks' + % the blocks are not randomized + var1Sequence=betweenRuns.variableList1; + ranNums=rand(1, length(var1Sequence)); [x idx]=sort(ranNums); + var1Sequence=var1Sequence(idx); + betweenRuns.variableList1=variableList1(idx); + var1Sequence=repmat(var1Sequence, 1,nVar2); + var2Sequence=reshape(repmat(betweenRuns.variableList2, nVar1,1)... + ,1,nVar1*nVar2); + case 'randomize across blocks' + var1Sequence=repmat(betweenRuns.variableList1, 1,nVar2); + var2Sequence=reshape(repmat(betweenRuns.variableList2, nVar1,1),... + 1,nVar1*nVar2); + ranNums=rand(1, nVar1*nVar2); + [x idx]=sort(ranNums); + var1Sequence=var1Sequence(idx); + var2Sequence=var2Sequence(idx); + % there should be one start value for every combination + % of var1/ var2. In principle this allows these values to be + % programmed. Not currently in use. + stimulusParameters.WRVstartValues=... + stimulusParameters.WRVstartValues(idx); +end +betweenRuns.var1Sequence=var1Sequence; +betweenRuns.var2Sequence=var2Sequence; + +% caught out vector needs to be linked to the length of the whole sequence +betweenRuns.caughtOut=zeros(1,length(var1Sequence)); + +disp('planned sequence:') +if min(var1Sequence)>1 + % use decidaml places only if necessary +disp([betweenRuns.variableName1 ': ' num2str(var1Sequence,'%6.0f') ]) +else +disp([betweenRuns.variableName1 ': ' num2str(var1Sequence,'%8.3f') ]) +end +if min(var1Sequence)>1 +disp([betweenRuns.variableName2 ': ' num2str(var2Sequence,'%6.0f') ]) +else +disp([betweenRuns.variableName2 ': ' num2str(var2Sequence,'%8.3f') ]) +end + +fprintf('\nvariable1 \t variable2\t \n') +fprintf('%s \t %s\t Threshold \n',betweenRuns.variableName1,... + betweenRuns.variableName2) + +% Light up 'GO' on subjGUI and advise. +set(handles.editdigitInput,'visible','off') +switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent',... + 'MAPmodel', 'MAPmodelMultiCh','MAPmodelSingleCh'} + % no changes required if model used + otherwise + set(handles.pushbuttonGO,'backgroundcolor','y') + set(handles.pushbuttonGO,'visible','on') + set(handles.frame1,'visible','off') + set(handles.textMSG,'backgroundcolor', 'w') + msg=[{'Ready to start new Experiment'}, {' '}, {'Please, click on the GO button'}]; + set(handles.textMSG,'string', msg) + + set(handles.pushbuttoNotSure,'visible','off') + set(handles.pushbuttonWrongButton,'visible','off') + set(handles.pushbutton3,'visible','off') + set(handles.pushbutton2,'visible','off') + set(handles.pushbutton1,'visible','off') + set(handles.pushbutton0,'visible','off') + pause(.1) % to allow display to be drawn +end + +% Selecting the 'GO' button is the only valid operation action now +experiment.status='waitingForGO'; % i.e. waiting for new run + +% control is now either manual, model (MAP) or randomization +switch experiment.ear + case {'MAPmodel','MAPmodelMultiCh','MAPmodelSingleCh','MAPmodelListen'} % MAP model is now the subject + stimulusParameters.calibrationdB=0; % Pascals required! + MAPmodelRunsGUI(handles) + % model is now the subject + case {'statsModelLogistic', 'statsModelRareEvent'} + % no catch trials for the statistical model + stimulusParameters.catchTrialBaseRate=0; + stimulusParameters.catchTrialRate=0; + statsModelRunsGUI(handles) + otherwise + %manual operation; wait for user to click on 'GO' +end + +% Experiment complete (after MAP or randomization) +% return to 'initializeGUI' and then back to expGUI +% Manual control finds its own way home. Program control assumed when +% the user hits the GO button + +% ----------------------------------------------------------------- startNewRun +function startNewRun(handles) +% There are many ways to arrive here. +% Under manual control this is achieved by hitting the GO button +% either via the button box or a mouse click +% MAP and randomization methods call this too + +global experiment stimulusParameters betweenRuns withinRuns expGUIhandles +global LevittControl rareEvent + +figure(handles.figure1) % guarantee subject GUI visibility + +% ignore call if program is not ready +if ~strcmp(experiment.status,'waitingForGO'), return, end + +set(handles.pushbuttonGO,'visible','off') + +% append message to expGUI message box to alert experimenter that the user +% is active +addToMsg('Starting new trial',0) + +cla(expGUIhandles.axes1), title(''); % stimulus +cla(expGUIhandles.axes2), title(''); % WRV track +drawnow + +betweenRuns.runNumber=betweenRuns.runNumber + 1; + +withinRuns.trialNumber=1; +withinRuns.variableValue=... + stimulusParameters.WRVstartValues(betweenRuns.runNumber); +% add random jitter to start level +if ~experiment.singleShot + % SS or single shot allows the user to precisely set the WRV + withinRuns.variableValue=withinRuns.variableValue +... + (rand-0.5)*stimulusParameters.jitterStartdB; +end + +withinRuns.peaks=[]; +withinRuns.troughs=[]; +withinRuns.levelList=[]; +withinRuns.meanEstTrack=[]; +withinRuns.bestSlopeK=[]; +withinRuns.bestGain=[]; +withinRuns.bestVMin=[]; +withinRuns.forceThreshold=NaN; +withinRuns.responseList=[]; +withinRuns.caughtOut=0; +withinRuns.wrongButton=0; +withinRuns.catchTrialCount=0; +withinRuns.thresholdEstimateTrack=[]; + +withinRuns.beginningOfPhase2=0; +withinRuns.nowInPhase2=0; +withinRuns.thisIsRepeatTrial=0; + +rareEvent.Euclid=NaN; +rareEvent.bestGain=NaN; +rareEvent.bestVMin=NaN; +rareEvent.thresholddB=0; +rareEvent.bestPaMindB=NaN; +rareEvent.predictionLevels=[]; +rareEvent.predictionsRE=[]; + +LevittControl.sequence=[]; + +% on-screen count of number of runs still to complete +trialsToGo=length(betweenRuns.var1Sequence)-betweenRuns.runNumber; +set(handles.toGoCounter,'string', trialsToGo); + +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + % For 2I2AFC the buttons need to be on the screen ab initio + Levitt2 % inititalize Levitt2 procedure +end + +switch experiment.ear + case{'left', 'right','diotic', 'dichoticLeft','dichoticRight'} + % allow subject time to recover from 'go' press + pause(experiment.clickToStimulusPause) +end + +errormsg=nextStimulus(handles); % get the show on the road + +% switch experiment.paradigm +% case 'SRT' +% set(handles.editdigitInput,'visible','on') +% uicontrol(handles.editdigitInput) +% end + +% terminate if there is any kind of problem +if ~isempty(errormsg) + % e.g. limits exceeded, clipping + disp(errormsg) + runCompleted(handles) + return +end + +% return route is variable (see intro to this function) + +% -----------------------------------------------------buttonBox_callback +function buttonBox_callback(obj, info) +global experiment +global serobj +global subjectGUIHandles + +% do not accept callback if one is already in process +if strcmp(experiment.buttonBoxStatus,'busy') + disp(' ignored button press') + return +end +experiment.buttonBoxStatus='busy'; +% fclose(serobj) + +% identify the code of the button pressed +buttonPressedNo = fscanf(serobj,'%c',1); + +% This is the map from the button to the Cedrus codes +switch experiment.buttonBoxType + case 'horizontal' + pbGo='7'; pb0='1'; + pb1='2'; pb2='3'; + pbRepeat='4'; pbWrong='6'; pbBlank='5'; + case 'square' + pbGo='7'; pb0='1'; + pb1='3'; pb2='4'; + pbRepeat='8'; pbWrong='6'; pbBlank='5'; +end + +% decide what to do +switch experiment.status + case {'presentingStimulus', 'waitingForStart', 'trialcompleted', ... + 'endOfExperiment'} + disp(' ignored button press') + + case 'waitingForGO' + % i.e. waiting for new run + if strcmp(buttonPressedNo,pbGo) % only GO button accepted + startNewRun(subjectGUIHandles) + else + disp(' ignored button press') + end + + case 'waitingForResponse' + % response to stimuli + switch buttonPressedNo + case pb0 % button 0 (top left) + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + disp(' ignored button press') + otherwise + set(subjectGUIHandles.pushbutton0,... + 'backgroundcolor','r') + pause(.1) + set(subjectGUIHandles.pushbutton0,... + 'backgroundcolor',get(0,... + 'defaultUicontrolBackgroundColor')) + userSelects0or1(subjectGUIHandles) + end + + case pb1 % button 1 (bottom left) + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + userSelects0or1(subjectGUIHandles) + otherwise + set(subjectGUIHandles.pushbutton1,... + 'backgroundcolor','r') + pause(.1) + set(subjectGUIHandles.pushbutton1,... + 'backgroundcolor',get(0,... + 'defaultUicontrolBackgroundColor')) + userSelects0or1(subjectGUIHandles) + end + + case pb2 % button 2 (bottom right) + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + userSelects2 (subjectGUIHandles) + otherwise + set(subjectGUIHandles.pushbutton2,... + 'backgroundcolor','r') + pause(.1) + set(subjectGUIHandles.pushbutton2,... + 'backgroundcolor',get(0,... + 'defaultUicontrolBackgroundColor')) + userSelects2 (subjectGUIHandles) + end + + case pbRepeat % extreme right button + switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + disp(' ignored button press') + otherwise + + set(subjectGUIHandles.pushbuttoNotSure,... + 'backgroundcolor','r') + pause(.1) + set(subjectGUIHandles.pushbuttoNotSure,... + 'backgroundcolor',get(0,... + 'defaultUicontrolBackgroundColor')) + userSelectsPleaseRepeat (subjectGUIHandles) + end + + case {pbWrong, pbBlank} + disp(' ignored button press') + + otherwise % unrecognised button + disp('ignored button press') + end % end (button press number) + otherwise + disp('ignored button press') +end % experiment status + +% All processing returns through here. +% fopen(serobj); % flushes the input buffer + +% buttonPressedNo = fscanf(serobj,'%c',1); + +% button box remains 'busy' until after the stimulus has been presented +experiment.buttonBoxStatus='not busy'; + +% -------------------------------------------------- pushbuttonGO_Callback +function pushbuttonGO_Callback(hObject, eventdata, handles) +% This is a mouse click path +% GO function is also called directly from button box +% and from MAP model and stats model + +set(handles.pushbuttonGO,'visible','off') +startNewRun(handles) + +% ---------------------------------------------------pushbutton0_Callback +function pushbutton0_Callback(hObject, eventdata, handles) +global experiment +% This is a mouse click path + +% ignore 0 button if 2I2AFC used +if findstr(experiment.threshEstMethod,'2I2AFC'), return, end + +% userDoesNotHearTarget(handles) % only possible interpretation +userDecides(handles, false) + +% -------------------------------------------------- pushbutton1_Callback +function pushbutton1_Callback(hObject, eventdata, handles) +userSelects0or1(handles) % also called from buttonBox + +% ---------------------------------------------------pushbutton2_Callback +function pushbutton2_Callback(hObject, eventdata, handles) +userSelects2(handles) % also called from buttonBox + +% --------------------------------------------- pushbuttoNotSure_Callback +function pushbuttoNotSure_Callback(hObject, eventdata, handles) +userSelectsPleaseRepeat(handles) % also called from buttonBox + +% -------------------------------------------------- pushbutton3_Callback +function pushbutton3_Callback(hObject, eventdata, handles) + +% ------------------------------------------------- pushbutton19_Callback +function pushbutton19_Callback(hObject, eventdata, handles) +% should be invisible (ignore) + +% --------------------------------------- pushbuttonWrongButton_Callback +function pushbuttonWrongButton_Callback(hObject, eventdata, handles) +userSelectsWrongButton(handles) + +% --------------------------------------- editdigitInput_Callback +function editdigitInput_Callback(hObject, eventdata, handles) +userSelects0or1(handles) % after digit string input + + + +% ----------------------------------------------------- userSelects0or1 +function userSelects0or1(handles) +global experiment withinRuns + +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + switch withinRuns.stimulusOrder + case 'targetFirst'; + % userHearsTarget(handles) + userDecides(handles, true) + otherwise + % userDoesNotHearTarget(handles) + userDecides(handles, false) + end + otherwise + % single interval + % 0 or 1 are treated as equivalent (i.e. target is not heard) + userDecides(handles, false) +end +% return to pushButton1 callback + +% ----------------------------------------------------- userSelects2 +function userSelects2(handles) +global experiment withinRuns +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + switch withinRuns.stimulusOrder + case 'targetSecond'; + % userDoesNotHearTarget(handles) + userDecides(handles, true) + otherwise + % userHearsTarget(handles) + userDecides(handles, false) + end + otherwise + % single interval (2 targets heard) + userDecides(handles, true) +end +% return to pushButton2 callback + +% ----------------------------------------------------- ---- userDecides +function userDecides(handles, saidYes) +global experiment stimulusParameters betweenRuns withinRuns +global rareEvent logistic psy levelsBinVector + +if experiment.singleShot + return +end + +% ignore click if not 'waitingForResponse' +if ~strcmp(experiment.status,'waitingForResponse') + disp('ignored click') + return +end + +% speech reception threshold +if strcmp(stimulusParameters.targetType,'digitStrings') + digitsInput=get(handles.editdigitInput,'string'); + % must be three digits + if ~(length(digitsInput)==3) + addToMsg(['error message: Wrong no of digits'], 0, 1) + set(handles.textMSG,'string', 'Wrong no of digits', ... + 'BackgroundColor','r', 'ForegroundColor', 'w') + set(handles.editdigitInput,'string','') + + return + end + % obtain correct answer from file name + x=stimulusParameters.digitString; + idx=find(x=='O'); x(idx)='0'; % replace 'oh' with zero + + disp([x ' ' digitsInput]) + + if x==digitsInput + saidYes=1; + else + saidYes=0; + end +set(handles.editdigitInput,'string','') +set(handles.editdigitInput,'visible','off') +pause(0.1) +end + + + +% no button presses accepted while processing +experiment.status='processingResponse'; + +% catch trials. Restart trial if caught +if withinRuns.catchTrial + if saidYes + disp('catch trial - caught out') + withinRuns.caughtOut=withinRuns.caughtOut+1; + + % special: estimate caught out rate by allowing the trial + % to continue after catch + if stimulusParameters.catchTrialBaseRate==0.5 + % To use this facility, set the catchTrialRate and the + % catchTrialBaseRate both to 0.5 + % update false positive rate + betweenRuns.caughtOut(betweenRuns.runNumber)=... + withinRuns.caughtOut; + plotProgressThisTrial(handles) + nextStimulus(handles); + return + end + + % Punishment: restart the trial + set(handles.frame1,'backgroundColor','r') + set(handles.pushbuttonGO, ... + 'visible','on', 'backgroundcolor','y') % and go again + msg=[{'Start again: catch trial error'}, {' '},... + {'Please,click on the GO button'}]; + set(handles.textMSG,'string',msg) + [y,fs]=wavread('ding.wav'); + wavplay(y/100,fs) + + % raise catch trial rate temporarily. + % this is normally reduced on each new trial (see GO) + stimulusParameters.catchTrialRate=... + stimulusParameters.catchTrialRate+0.1; + if stimulusParameters.catchTrialRate>0.5 + stimulusParameters.catchTrialRate=0.5; + end + fprintf('stimulusParameters.catchTrialRate= %6.3f\n', ... + stimulusParameters.catchTrialRate) + + betweenRuns.caughtOut(betweenRuns.runNumber)=... + 1+betweenRuns.caughtOut(betweenRuns.runNumber); + betweenRuns.runNumber=betweenRuns.runNumber-1; + experiment.status='waitingForGO'; + return % unwind and wait for button press + else % (said No) + % user claims not to have heard target. fortunate as it was not + % present. So, repeat the stimulus (possibly with target) + % and behave as if the last trial did not occur + errormsg=nextStimulus(handles); + + % terminate if there is any kind of problem + if ~isempty(errormsg) + % e.g. limits exceeded, clipping + disp(['Error nextStimulus: ' errormsg]) + runCompleted(handles) + return + end + return % no further action - next trial + end +end + +% This section analyses the responses, makes tracks and defines next stim. + +% Define response and update response list +if saidYes + % target was heard, so response=1; + withinRuns.responseList=[withinRuns.responseList 1]; % 'heard it!' +else + % target was not hear heard, so response=0; + withinRuns.responseList=[withinRuns.responseList 0]; +end +withinRuns.levelList=[withinRuns.levelList withinRuns.variableValue]; +trialNumber=length(withinRuns.responseList); + +% keep track of peaks and troughs; +% identify direction of change during initial period +if saidYes + % default step size before first reversal + WRVinitialStep=-stimulusParameters.WRVinitialStep; + WRVsmallStep=-stimulusParameters.WRVsmallStep; + % if the previous direction was 'less difficult', this must be a peak + if strcmp(withinRuns.direction,'less difficult') ... + && length(withinRuns.levelList)>1 + withinRuns.peaks=[withinRuns.peaks withinRuns.variableValue]; + end + withinRuns.direction='more difficult'; + +else + % said 'no' + % default step size before first reversal + WRVinitialStep=stimulusParameters.WRVinitialStep; + WRVsmallStep=stimulusParameters.WRVsmallStep; + + % if the previous direction was 'up', this must be a peak + if strcmp(withinRuns.direction,'more difficult') ... + && length(withinRuns.levelList)>1 + withinRuns.troughs=[withinRuns.troughs withinRuns.variableValue]; + end + withinRuns.direction='less difficult'; +end + +% phase 2 is all the levels after and incuding the first reversal +% plus the level before that +if ~withinRuns.nowInPhase2 && length(withinRuns.peaks)+ ... + length(withinRuns.troughs)>0 +% if ~withinRuns.nowInPhase2 && (~isempty(withinRuns.peaks) ... +% || ~isempty(withinRuns.troughs)) + % define phase 2 + withinRuns.beginningOfPhase2=trialNumber-1; + withinRuns.nowInPhase2=1; + WRVsmallStep=WRVinitialStep/2; +end + +if withinRuns.nowInPhase2 + % keep a record of all levels and responses in phase 2 only + withinRuns.levelsPhaseTwo=... + withinRuns.levelList(withinRuns.beginningOfPhase2:end); + withinRuns.responsesPhaseTwo=... + withinRuns.responseList(withinRuns.beginningOfPhase2:end); +else + withinRuns.levelsPhaseTwo=[]; +end + + +% get (or substitute) threshold estimate +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + % for plotting psychometric function only + if withinRuns.beginningOfPhase2>0 + [psy, levelsBinVector, logistic, rareEvent]= ... + bestFitPsychometicFunctions... + (withinRuns.levelsPhaseTwo, withinRuns.responsesPhaseTwo); + end + + if ~isempty(withinRuns.peaks) && ~isempty(withinRuns.troughs) + thresholdEstimate= ... + mean([mean(withinRuns.peaks) mean(withinRuns.troughs)]); + else + thresholdEstimate=NaN; + end + otherwise + % single interval methods + try + % using the s trial after the first reversal + [psy, levelsBinVector, logistic, rareEvent]= ... + bestFitPsychometicFunctions(withinRuns.levelsPhaseTwo,... + withinRuns.responsesPhaseTwo); + catch + logistic.bestThreshold=NaN; + end +end + +if withinRuns.nowInPhase2 + % save tracks of threshold estimates for plotting andprinting + switch experiment.functionEstMethod + case {'logisticLS', 'logisticML'} + if withinRuns.nowInPhase2 + withinRuns.meanEstTrack=... + [withinRuns.meanEstTrack ... + mean(withinRuns.levelsPhaseTwo)]; + withinRuns.thresholdEstimateTrack=... + [withinRuns.thresholdEstimateTrack ... + logistic.bestThreshold]; + end + case 'rareEvent' + withinRuns.meanEstTrack=... + [withinRuns.meanEstTrack rareEvent.thresholddB]; + withinRuns.thresholdEstimateTrack=... + [withinRuns.thresholdEstimateTrack logistic.bestThreshold]; + case 'peaksAndTroughs' + withinRuns.meanEstTrack=... + [withinRuns.meanEstTrack thresholdEstimate]; + withinRuns.thresholdEstimateTrack=... + [withinRuns.thresholdEstimateTrack thresholdEstimate]; + end +end + +% special discomfort condition +% run is completed when subject hits '2' button +switch experiment.paradigm + case 'discomfort' + if saidYes + runCompleted(handles) + return + end +end + +% choose the next level for the stimulus +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + if saidYes + [WRVinitialStep, msg]=Levitt2('hit', withinRuns.variableValue); + else + [WRVinitialStep, msg]=Levitt2('miss',withinRuns.variableValue); + end + + % empty message means continue as normal + if ~isempty(msg) + runCompleted(handles) + return + end + newWRVvalue=withinRuns.variableValue-WRVinitialStep; + + case {'MaxLikelihood', 'oneIntervalUpDown'} + % run completed by virtue of number of trials + % or restart because listener is in trouble + if length(withinRuns.levelsPhaseTwo)== experiment.maxTrials + % Use bonomial test to decide if there is an imbalance in the + % number of 'yes'es and 'no's + yesCount=sum(withinRuns.responseList); + noCount=length(withinRuns.responseList)-yesCount; + z=abs(yesCount-noCount)/(yesCount+noCount)^0.5; + if z>1.96 + betweenRuns.resets=betweenRuns.resets+1; + disp([ 'reset / z= ' num2str( z) ... + ' Nresets= ' num2str( betweenRuns.resets) ] ) + withinRuns.peaks=[]; + withinRuns.troughs=[]; + withinRuns.levelList=withinRuns.levelList(end); + withinRuns.meanEstTrack=withinRuns.meanEstTrack(end); + withinRuns.forceThreshold=NaN; + withinRuns.responseList=withinRuns.responseList(end); + withinRuns.beginningOfPhase2=0; + withinRuns.nowInPhase2=0; + withinRuns.thresholdEstimateTrack=... + withinRuns.thresholdEstimateTrack(end); + else + runCompleted(handles) + return + end + end + + % set new value for WRV + if withinRuns.nowInPhase2 + % phase 2 + currentMeanEst=withinRuns.thresholdEstimateTrack(end); + switch experiment.threshEstMethod + case 'MaxLikelihood' + newWRVvalue=currentMeanEst; + case {'oneIntervalUpDown'} + newWRVvalue=withinRuns.variableValue+WRVsmallStep; + end + else + % phase 1 + if withinRuns.variableValue+2*WRVinitialStep>... + stimulusParameters.WRVlimits(2) + % use smaller steps when close to maximum + WRVinitialStep=WRVinitialStep/2; + end + newWRVvalue=withinRuns.variableValue+WRVinitialStep; + end + otherwise + error( 'assessment method not recognised') +end + +switch experiment.paradigm + % prevent unrealistic gap durations 'gapDetection' tasks. + % Note that the gap begins when the ramp ends not when stimulus ends + case 'gapDetection' + if newWRVvalue<-2*stimulusParameters.rampDuration + newWRVvalue=-2*stimulusParameters.rampDuration; + addToMsg('gap duration fixed at - 2 * ramp!',1, 1) + end +end + +withinRuns.variableValue=newWRVvalue; +withinRuns.trialNumber=withinRuns.trialNumber+1; + +% Trial continues +plotProgressThisTrial(handles) + +% next stimulus and so the cycle continues +errormsg=nextStimulus(handles); +% after the stimulus is presented, control returns here and the system +% waits for user action. + +% terminate if there is any kind of problem +if ~isempty(errormsg) + % e.g. limits exceeded, clipping + disp(['Error nextStimulus: ' errormsg]) + runCompleted(handles) + return +end + +% ------------------------------------------------ userSelectsPleaseRepeat +function userSelectsPleaseRepeat(handles) +global experiment withinRuns +% ignore click if not 'waitingForResponse' +if ~strcmp(experiment.status,'waitingForResponse') + disp('ignored click') + return +end +% Take no action other than to make a +% tally of repeat requests +experiment.pleaseRepeat=experiment.pleaseRepeat+1; +withinRuns.thisIsRepeatTrial=1; +nextStimulus(handles); + +% ------------------------------------------------ userSelectsWrongButton +function userSelectsWrongButton(handles) +global withinRuns experiment +% restart is the simplest solution for a 'wrong button' request +withinRuns.wrongButton=withinRuns.wrongButton+1; +set(handles.pushbuttonGO, 'visible','on', 'backgroundcolor','y') +msg=[{'Start again: wrong button pressed'}, {' '},... + {'Please,click on the GO button'}]; +set(handles.textMSG,'string',msg) +experiment.status='waitingForGO'; + +% ------------------------------------------------- plotProgressThisTrial +function plotProgressThisTrial(handles) + +% used for all responses +global experiment stimulusParameters betweenRuns withinRuns expGUIhandles +global psy levelsBinVector binFrequencies rareEvent logistic statsModel + + +% plot the levelTrack and the threshold track + +% Panel 2 +% plot the levelList +axes(expGUIhandles.axes2); cla +plot( withinRuns.levelList,'o','markerFaceColor','k'), hold on +% plot the best threshold estimate tracks +if length(withinRuns.meanEstTrack)>=1 + % The length of the levelList is 2 greater than number of thresholds + ptr=withinRuns.beginningOfPhase2+1; + plot(ptr: ptr+length(withinRuns.meanEstTrack)-1, ... + withinRuns.meanEstTrack, 'r') + plot( ptr: ptr+length(withinRuns.thresholdEstimateTrack)-1, ... + withinRuns.thresholdEstimateTrack, 'g') + hold off + estThresh=withinRuns.thresholdEstimateTrack(end); + switch experiment.threshEstMethod + % add appropriate labels to subject GUI buttons + case {'2I2AFC++', '2I2AFC+++'} + title([stimulusParameters.WRVname ' = ' ... + num2str(withinRuns.variableValue, '%5.1f')]) + otherwise + title([stimulusParameters.WRVname ' = ' ... + num2str(withinRuns.variableValue, '%5.1f') ... + '; TH= ' num2str(estThresh, '%5.1f')]) + end +end +xlim([0 experiment.maxTrials+withinRuns.beginningOfPhase2]); +ylim(stimulusParameters.WRVlimits) +grid on + +% Panel 4: Summary of threshold estimates (not used here) +% Earlier estimates are set in 'runCompleted' +% However, title shows runs/trials remaining + +axes(expGUIhandles.axes4) +runsToGo=length(betweenRuns.var1Sequence)-betweenRuns.runNumber; +if withinRuns.beginningOfPhase2>0 + trialsToGo= experiment.singleIntervalMaxTrials(1) ... + + withinRuns.beginningOfPhase2- withinRuns.trialNumber; + title(['trials remaining = ' num2str(trialsToGo) ... + ': runs to go= ' num2str(runsToGo)]) +end + +% plot psychometric function - panel 5 +axes(expGUIhandles.axes5), cla +plot(withinRuns.levelList, withinRuns.responseList,'b.'), hold on +ylim([0 1]) +title('') + +switch experiment.threshEstMethod + case {'MaxLikelihood', 'oneIntervalUpDown'} + if withinRuns.beginningOfPhase2>0 + % display only when in phase 2. + withinRuns.levelsPhaseTwo=... + withinRuns.levelList(withinRuns.beginningOfPhase2:end); + withinRuns.responsesPhaseTwo=... + withinRuns.responseList(withinRuns.beginningOfPhase2:end); + + % organise data as psychometric function + [psy, levelsBinVector, binFrequencies]= ... + psychometricFunction(withinRuns.levelsPhaseTwo,... + withinRuns.responsesPhaseTwo, experiment.psyBinWidth); + + % Plot the function + % point by point with circles of appropiate weighted size + hold on, + for i=1:length(psy) + plot(levelsBinVector(i), psy(i), 'ro', ... + 'markersize', 50*binFrequencies(i)/sum(binFrequencies)) + end + % save info for later + betweenRuns.psychometicFunction{betweenRuns.runNumber}=... + [levelsBinVector; psy]; + + % fitPsychometric functions is computed in 'userDecides' + % plot(rareEvent.predictionLevels, rareEvent.predictionsRE,'k') + plot(logistic.predictionLevels, logistic.predictionsLOG, 'r') + plot(rareEvent.predictionLevels, rareEvent.predictionsRE, 'k') + if ~isnan(logistic.bestThreshold ) +% xlim([ (logistic.bestThreshold -20) ... +% (logistic.bestThreshold +20) ]) + xlim([ 0 100 ]) +% if logistic.bestK< max(experiment.possLogSlopes) + title(['k= ' num2str(logistic.bestK, '%6.2f') ' g= '... + num2str(rareEvent.bestGain,'%6.3f') ' A=' ... + num2str(rareEvent.bestVMin,'%8.1f')]) +% title('') +% end + else + title(' ') + end + + switch experiment.ear + %plot green line for statsModel a priori model + case 'statsModelLogistic' + % plot proTem logistic (green) used by stats model + p= 1./(1+exp(-statsModel.logisticSlope... + *(levelsBinVector-logistic.bestThreshold))); + if experiment.psyFunSlope<0, p=1-p;end + titleText=[ ', statsModel: logistic']; + hold on, plot(levelsBinVector, p,'g') + case 'statsModelRareEvent' + pressure=28*10.^(levelsBinVector/20); + p=1-exp(-stimulusParameters.targetDuration... + *(statsModel.rareEvenGain... + * pressure-statsModel.rareEventVmin)); + p(p<0)=0; + if experiment.psyFunSlope<0, p=1-p;end + hold on, plot(levelsBinVector, p,'g') + end %(estMethod) + end + otherwise % 2A2IFC + + message3= ... + ([ 'peaks=' num2str(withinRuns.peaks) ... + 'troughs=' num2str(withinRuns.troughs)]); + ylimRM([-0.1 1.1]) % 0=no / 1=yes + set(gca,'ytick',[0 1], 'yTickLabel', {'no';'yes'}) + ylabel('psychometric function'), xlabel('target level') + if length(levelsBinVector)>1 + xlim([ min(levelsBinVector) max(levelsBinVector)]) + xlim([ 0 100]) + end +end + +% command window summary +% Accumulate things to say in the message window +message1= (['responses: ' num2str(withinRuns.responseList,'%9.0f')]); +switch experiment.paradigm + % more decimal places needed on GUI + case { 'gapDetection', 'frequencyDiscrimination', 'forwardMaskingD'} + message2= ([stimulusParameters.WRVname ... + ': ' num2str(withinRuns.levelList,'%7.3f')]); + message3= (['Thresh (logistic mean): ' ... + num2str(withinRuns.thresholdEstimateTrack,'%7.3f')]); + otherwise + message2= ([stimulusParameters.WRVname ': ' ... + num2str(withinRuns.levelList,'%7.1f')]); + message3= (['Thresh (logistic mean): ' ... + num2str(withinRuns.thresholdEstimateTrack,'%7.1f')]); +end + +addToMsg(str2mat(message1, message2, message3), 0) + +% -----------------------------------------------------runCompleted +function runCompleted(handles) +% Used at the end of each run +global experiment stimulusParameters betweenRuns withinRuns +global rareEvent expGUIhandles +% disp('run completed') + +experiment.status='runCompleted'; + +plotProgressThisTrial(handles) + +switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent','MAPmodel', ... + 'MAPmodelMultiCh','MAPmodelSingleCh', 'MAPmodelListen'} + % no changes required if model used + otherwise + set(handles.frame1,'visible','off') + set(handles.pushbuttoNotSure,'visible','off') + set(handles.pushbuttonWrongButton,'visible','off') + set(handles.pushbutton3,'visible','off') + set(handles.pushbutton2,'visible','off') + set(handles.pushbutton1,'visible','off') + set(handles.pushbutton0,'visible','off') + set(handles.pushbuttonGO,'visible','off') +end + +if isnan(withinRuns.forceThreshold) + % the experiment has been aborted for some reason + threshold=withinRuns.forceThreshold; + stdev=NaN; + logistic.bestK=NaN; + logistic.bestThreshold=NaN; + medianThreshold=NaN; + meanThreshold=NaN; +else + % use only phase 2 levels and responses for calculating thresholds + withinRuns.levelsPhaseTwo=... + withinRuns.levelList(withinRuns.beginningOfPhase2:end); + withinRuns.responsesPhaseTwo=... + withinRuns.responseList(withinRuns.beginningOfPhase2:end); + [psy, levelsPhaseTwoBinVector, logistic, rareEvent]= ... + bestFitPsychometicFunctions... + (withinRuns.levelsPhaseTwo, withinRuns.responsesPhaseTwo); + + % plot final psychometric function + axes(expGUIhandles.axes5),cla + hold on, plot(rareEvent.predictionLevels, rareEvent.predictionsRE, 'k') + hold on, plot(logistic.predictionLevels, logistic.predictionsLOG, 'r') + % organise data as psychometric function + [psy, levelsBinVector, binFrequencies]= ... + psychometricFunction(withinRuns.levelsPhaseTwo,... + withinRuns.responsesPhaseTwo, experiment.psyBinWidth); + % point by point with circles of appropiate weighted size + hold on, + for i=1:length(psy) + plot(levelsBinVector(i), psy(i), 'ro', ... + 'markersize', 50*binFrequencies(i)/sum(binFrequencies)) + end + + + % experimental + medianThreshold=median(withinRuns.levelsPhaseTwo); + warning off + meanThreshold=mean(withinRuns.levelsPhaseTwo); + + % identify the current threshold estimate + switch experiment.paradigm + case 'discomfort' + % most recent value (not truely a mean value) + threshold=withinRuns.levelList(end); + stdev=NaN; + otherwise + switch experiment.threshEstMethod + case {'MaxLikelihood', 'oneIntervalUpDown'} + % last value in the list +% threshold=withinRuns.meanEstTrack(end); + threshold=withinRuns.thresholdEstimateTrack(end); + stdev=NaN; + + case {'2I2AFC++', '2I2AFC+++'} + % use peaks and troughs + try % there may not be enough values to use + peaksUsed=experiment.peaksUsed; + threshold=... + mean(... + [withinRuns.peaks(end-peaksUsed+1:end) ... + withinRuns.troughs(end-peaksUsed+1:end)]); + stdev=... + std([withinRuns.peaks(end-peaksUsed +1:end) ... + withinRuns.troughs(end-peaksUsed:end)]); + catch + threshold=NaN; + stdev=NaN; + end + end + end +end + +% Store thresholds +betweenRuns.thresholds=[betweenRuns.thresholds threshold]; +betweenRuns.thresholds_mean=[betweenRuns.thresholds_mean meanThreshold]; +betweenRuns.thresholds_median=... + [betweenRuns.thresholds_median medianThreshold]; +betweenRuns.forceThresholds=... + [betweenRuns.forceThresholds withinRuns.forceThreshold]; + +% count observations after the startup phase for record keeping +betweenRuns.observationCount=... + [betweenRuns.observationCount length(withinRuns.levelList)]; +betweenRuns.timesOfFirstReversals=... + [betweenRuns.timesOfFirstReversals withinRuns.beginningOfPhase2]; +betweenRuns.catchTrials=... + [betweenRuns.catchTrials withinRuns.catchTrialCount]; + +% add variable length tracks to cell arrays +if withinRuns.beginningOfPhase2>0 + betweenRuns.bestThresholdTracks{length(betweenRuns.thresholds)}=... + withinRuns.thresholdEstimateTrack; + betweenRuns.levelTracks{length(betweenRuns.thresholds)}=... + withinRuns.levelList(withinRuns.beginningOfPhase2:end); + betweenRuns.responseTracks{length(betweenRuns.thresholds)}=... + withinRuns.responseList(withinRuns.beginningOfPhase2:end); +else + betweenRuns.bestThresholdTracks{length(betweenRuns.thresholds)}=[]; + betweenRuns.levelTracks{length(betweenRuns.thresholds)}=[]; + betweenRuns.responseTracks{length(betweenRuns.thresholds)}=[]; +end + +betweenRuns.bestGain=[betweenRuns.bestGain rareEvent.bestGain]; +betweenRuns.bestVMin=[betweenRuns.bestVMin rareEvent.bestVMin]; +betweenRuns.bestPaMin=[betweenRuns.bestPaMin rareEvent.bestPaMindB]; +betweenRuns.bestLogisticM=... + [betweenRuns.bestLogisticM logistic.bestThreshold]; +betweenRuns.bestLogisticK=[betweenRuns.bestLogisticK logistic.bestK]; + +resultsSoFar=[betweenRuns.var1Sequence(betweenRuns.runNumber)'... + betweenRuns.var2Sequence(betweenRuns.runNumber)'... + betweenRuns.thresholds(betweenRuns.runNumber)' + ]; + +fprintf('%10.3f \t%10.3f \t%10.1f \n', resultsSoFar') + +switch experiment.ear + case {'left', 'right', 'diotic', 'dichoticLeft','dichoticRight'} + disp(['caught out= ' num2str(betweenRuns.caughtOut)]) +end + +% plot history of thresholds in panel 4 +axes(expGUIhandles.axes4), cla +plotColors='rgbmckywrgbmckyw'; +for i=1:length(betweenRuns.thresholds) + faceColor=plotColors(floor(i/length(betweenRuns.variableList1)-.01)+1); + switch betweenRuns.variableName1 + case {'targetFrequency', 'maskerRelativeFrequency'} + if min(betweenRuns.var1Sequence)>0 + % semilogx(betweenRuns.var1Sequence(1:betweenRuns.runNumber), ... + % betweenRuns.thresholds, 'o', ... + % 'markerSize', 5,'markerFaceColor',faceColor) + semilogx(betweenRuns.var1Sequence(i), ... + betweenRuns.thresholds(i), 'o', ... + 'markerSize', 5,'markerFaceColor',faceColor) + else + plot(betweenRuns.var1Sequence(1:betweenRuns.runNumber), ... + betweenRuns.thresholds, 'o', ... + 'markerSize', 5,'markerFaceColor',faceColor) + plot(betweenRuns.var1Sequence(i), ... + betweenRuns.thresholds(i), 'o', ... + 'markerSize', 5,'markerFaceColor',faceColor) + end + otherwise + % plot(betweenRuns.var1Sequence(1:betweenRuns.runNumber), ... + % betweenRuns.thresholds, 'o', 'markerSize', 5,... + % 'markerFaceColor',faceColor) + plot(betweenRuns.var1Sequence(i), ... + betweenRuns.thresholds(i), 'o', 'markerSize', 5,... + 'markerFaceColor',faceColor) + end + hold on +end +xlimRM([ min(betweenRuns.variableList1) max(betweenRuns.variableList1) ]) +ylim(stimulusParameters.WRVlimits) +ylabel('thresholds') +xlabel(betweenRuns.variableName1) +set(gca,'ytick', [0 20 40 60 80 100]) +try + % problems if only one x value + set(gca,'XTick', sort(betweenRuns.variableList1)) +catch +end +grid on, set(gca,'XMinorGrid', 'off') + +% If comparison data is available in pearmeter file, plot it now +if ~isempty (experiment.comparisonData) + comparisonData=experiment.comparisonData(:,1:end-1); % ignore final BF + [x, ncols]=size(comparisonData); + if length(betweenRuns.variableList1)==ncols + hold on + plot (sort(betweenRuns.variableList1), comparisonData, 'r') + hold off + end +end + +% End of the Experiment also? +if betweenRuns.runNumber==length(betweenRuns.var1Sequence) + % yes, end of experiment + fileName=['savedData/' experiment.name experiment.date ... + experiment.paradigm]; + % save (fileName, 'experiment', 'stimulusParameters', 'betweenRuns', 'withinRuns', 'variableNames', 'paradigmNames', 'LevittControl') + disp('Experiment completed') + + % update subject GUI to acknowledge end of run + subjGUImsg=[{'Experiment completed'}, {' '}, {'Thank you!'}]; + set(handles.textMSG,'string', subjGUImsg ) + % play 'Tada' + [y,fs,nbits]=wavread('TADA.wav'); + musicGain=10^(stimulusParameters.musicLeveldB/20); + y=y*musicGain; + wavplay(y/100,fs, 'async') + + % update experimenter GUI + addToMsg('Experiment completed.',1) + + printReport + experiment.status='endOfExperiment'; + return +else + % No, hang on. + switch experiment.ear + case {'statsModelLogistic', 'statsModelRareEvent','MAPmodel', ... + 'MAPmodelMultiCh','MAPmodelSingleCh', 'MAPmodelListen'} + % no changes required if model used + otherwise + % decrement catchTrialRate towards baseRate + stimulusParameters.catchTrialRate=... + stimulusParameters.catchTrialBaseRate + ... + (stimulusParameters.catchTrialRate... + -stimulusParameters.catchTrialBaseRate)... + *(1-exp(-stimulusParameters.catchTrialTimeConstant)); + fprintf('stimulusParameters.catchTrialRate= %6.3f\n', ... + stimulusParameters.catchTrialRate) + + % and go again + set(handles.pushbuttonGO,'backgroundcolor','y') + set(handles.frame1,'visible','off') + set(handles.pushbuttonGO,'visible','on') + msg=[{'Ready to start new trial'}, {' '},... + {'Please,click on the GO button'}]; + set(handles.textMSG,'string',msg) + end + experiment.status='waitingForGO'; + % fprintf('\n') + + [y,fs,nbits]=wavread('CHIMES.wav'); + musicGain=10^(stimulusParameters.musicLeveldB/20); + y=y*musicGain; + wavplay(y/100,fs,'async') +end + +% -----------------------------------------------------MAPmodelRunsGUI +% The computer presses the buttons +function MAPmodelRunsGUI(handles) +global experiment stimulusParameters method expGUIhandles +global AN_IHCsynapseParams +method=[]; + +while strcmp(experiment.status,'waitingForGO') + % no catch trials for MAP model + experiment.allowCatchTrials=0; + + % initiates run and plays first stimulus and it returns + % without waiting for button press + startNewRun(handles) + + if sum(strcmp(experiment.ear,... + {'MAPmodelMultiCh', 'MAPmodelListen'})) + % use BFlist specified in MAPparams file + BFlist= -1; + else + BFlist=stimulusParameters.targetFrequency; + end + showParams=0; + % find model parameters using the 'name' box (e.g. CTa ->MAPparamsCTa) + paramFunctionName=['method=MAPparams' experiment.name ... + '(BFlist, stimulusParameters.sampleRate, showParams);']; + eval(paramFunctionName) % go and fetch the parameters + + + % show sample Rate on GUI; it must be set in MAPparams + set(expGUIhandles.textsampleRate,'string',... + num2str(stimulusParameters.sampleRate)) + + if experiment.singleShot +% AN_IHCsynapseParams.showSummaryStatistics=1; + method.showSummaryStatistics=1; + AN_IHCsynapseParams.plotSynapseContents=1; + else + method.showSummaryStatistics=0; + AN_IHCsynapseParams.plotSynapseContents=0; + end + + if strcmp(experiment.ear, 'MAPmodelSingleCh') + method.MGmembranePotentialSave=1; + end + + % continuous loop until the program stops itself + while strcmp(experiment.status,'waitingForResponse') + % NB at this point the stimulus has been played + pause(0.1) % to allow interrupt with CTRL/C + + switch experiment.ear + case { 'MAPmodelListen'} + set(handles.pushbutton1,'backgroundcolor','y','visible','on') + set(handles.pushbutton2,'backgroundcolor','y','visible','on') + end + +AN_IHCsynapseParams.mode= 'spikes'; + +% Analayse the current stimulus using MAP + [modelResponse earObject]= MAPmodel( experiment.MAPplot, method); + + if experiment.stop || experiment.singleShot + % trap for single trial or user interrupt using 'stop' button. + experiment.status= 'waitingForStart'; + experiment.stop=0; + addToMsg('manually stopped',1); + return + end + + switch modelResponse + case 1 + % userDoesNotHearTarget(handles) + switch experiment.ear + case {'MAPmodelListen'} + % illuminate appropriate button + set(handles.pushbutton1,... + 'backgroundcolor','r','visible','on') + set(handles.pushbutton2,'backgroundcolor','y') + end + userDecides(handles, false) + if experiment.singleShot, return, end + + case 2 + % userHearsTarget(handles) + switch experiment.ear + case {'MAPmodelListen'} + % illuminate appropriate button (DEMO only) + set(handles.pushbutton2,'backgroundcolor',... + 'r','visible','on') + set(handles.pushbutton1,'backgroundcolor','y') + end + + switch experiment.paradigm + case 'discomfort' + % always treat discomfort as 'not heard' + userDecides(handles, false) + otherwise + userDecides(handles, true) + end + otherwise + % probably an abort + return + end + end +end + +function [modelResponse, MacGregorResponse]=MAPmodel( MAPplot, method) + +global experiment stimulusParameters audio withinRuns +global outerMiddleEarParams DRNLParams AN_IHCsynapseParams + +savePath=path; +addpath(['..' filesep 'MAP'], ['..' filesep 'utilities']) +modelResponse=[]; +MacGregorResponse=[]; + +% mono only (column vector) +audio=audio(:,1)'; + +% if stop button pressed earlier +if experiment.stop, return, end + +% -------------------------------------------------------------- run Model +MAPparamsName=experiment.name; +showPlotsAndDetails=experiment.MAPplot; +AN_spikesOrProbability='spikes'; + +% [response, method]=MAPsequenceSeg(audio, method, 1:8); +global ICoutput ANdt + MAP1_14(audio, 1/method.dt, method.nonlinCF,... + MAPparamsName, AN_spikesOrProbability); + +if showPlotsAndDetails + options.printModelParameters=0; + options.showModelOutput=1; + options.printFiringRates=1; + options.showACF=0; + options.showEfferent=1; + options.surfProbability=0; + showMapOptions.surfSpikes=0; + UTIL_showMAP(options) +end + +% No response, probably caused by hitting 'stop' button +if isempty(ICoutput), return, end + +% MacGregor response is the sum total of all final stage spiking +MacGregorResponse= sum(ICoutput,1); % use IC + +% ---------------------------------------------------------- end model run + +dt=ANdt; +time=dt:dt:dt*length(MacGregorResponse); + +% group delay on unit response +MacGonsetDelay= 0.004; +MacGoffsetDelay= 0.022; + +% now find the response of the MacGregor model during the target presentation + group delay +switch experiment.threshEstMethod + case {'2I2AFC++', '2I2AFC+++'} + idx= time>stimulusParameters.testTargetBegins+MacGonsetDelay ... + & time<stimulusParameters.testTargetEnds+MacGoffsetDelay; + nSpikesTrueWindow=sum(MacGregorResponse(:,idx)); + idx=find(time>stimulusParameters.testNonTargetBegins+MacGonsetDelay ... + & time<stimulusParameters.testNonTargetEnds+MacGoffsetDelay); + nSpikesFalseWindow=sum(MacGregorResponse(:,idx)); + % nSpikesDuringTarget is +ve when more spikes are found + % in the target window + difference= nSpikesTrueWindow-nSpikesFalseWindow; + + if difference>0 + % hit + nSpikesDuringTarget=experiment.MacGThreshold+1; + elseif difference<0 + % miss (wrong choice) + nSpikesDuringTarget=experiment.MacGThreshold-1; + else + if rand>0.5 + % hit (random choice) + nSpikesDuringTarget=experiment.MacGThreshold+1; + else + % miss (random choice) + nSpikesDuringTarget=experiment.MacGThreshold-1; + end + end + disp(['level target dummy decision: ' ... + num2str([withinRuns.variableValue nSpikesTrueWindow ... + nSpikesFalseWindow nSpikesDuringTarget], '%4.0f') ] ) + + otherwise + % idx=find(time>stimulusParameters.testTargetBegins+MacGonsetDelay ... + % & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); + % no delay at onset + idx=find(time>stimulusParameters.testTargetBegins +MacGonsetDelay... + & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); + nSpikesDuringTarget=sum(MacGregorResponse(:,idx)); + + % find(MacGregorResponse)*dt-stimulusParameters.stimulusDelay + timeX=time(idx); +end + +% now find the response of the MacGregor model at the end of the masker +idx2=find(time>stimulusParameters.testTargetBegins-0.02 ... + & time<stimulusParameters.testTargetBegins); +if ~isempty(idx2) + maskerRate=mean(mean(MacGregorResponse(idx2))); +else + %e.g. no masker + maskerRate=0; +end + +if experiment.MAPplot + % add vertical lines to indicate target region + figure(99), subplot(6,1,6) + hold on + yL=get(gca,'YLim'); + plot([stimulusParameters.testTargetBegins + MacGonsetDelay ... + stimulusParameters.testTargetBegins + MacGonsetDelay],yL,'r') + plot([stimulusParameters.testTargetEnds + MacGoffsetDelay ... + stimulusParameters.testTargetEnds + MacGoffsetDelay],yL,'r') +end + +% specify unambiguous response +switch experiment.paradigm + case 'gapDetection' + gapResponse=(maskerRate-nSpikesDuringTarget)/maskerRate; + if gapResponse>0.2 + modelResponse=2; % gap detected + else + modelResponse=1; % gap not detected + end + [nSpikesDuringTarget maskerRate gapResponse modelResponse] + figure(22), plot(timeX,earObject(idx)) + otherwise + if nSpikesDuringTarget>experiment.MacGThreshold + modelResponse=2; % stimulus detected + else + modelResponse=1; % nothing heard (default) + end +end + + +path(savePath) + +% -----------------------------------------------------statsModelRunsGUI +% The computer presses the buttons +function statsModelRunsGUI(handles) +% Decision are made at random using a prescribe statistical function +% to set probabilities as a function of signal level. +global experiment + +experiment.allowCatchTrials=0; + +while strcmp(experiment.status,'waitingForGO') + % i.e. waiting for new run + if experiment.stop + % user has requested an abort + experiment.status= 'waitingForStart'; + addToMsg('manually stopped',1) + return + end + + % initiates run and plays first stimulus and it returns + % without waiting for button press + % NB stimulus is not actually generated (for speed) + startNewRun(handles) + + while strcmp(experiment.status,'waitingForResponse') + % create artificial response here + modelResponse=statsModelGetResponse; + switch modelResponse + case 1 + % userDoesNotHearTarget(handles) + userDecides(handles, false) + case 2 + % userHearsTarget(handles) + userDecides(handles, true) + end + end +end + +% -----------------------------------------------------statsModelGetResponse +function modelResponse=statsModelGetResponse(handles) +global experiment withinRuns statsModel stimulusParameters +% use the generating function to decide if a detection occurs or not + +% pause(0.1) % to allow stopping with CTRL/C but slows things down + +% first compute the probability that a detection occurs +switch experiment.ear + case {'statsModelLogistic'} + prob= 1./(1+exp(-statsModel.logisticSlope.*(withinRuns.variableValue-statsModel.logisticMean))); + % if experiment.psyFunSlope<0, + % prob=1-prob; + % end + + case 'statsModelRareEvent' + if experiment.psyFunSlope<0 + addToMsg('statsModelRareEvent cannot be used with negative slope',0) + error('statsModelRareEvent cannot be used with negative slope') + end + + % standard formula is prob = 1 – exp(-d (g P – A)) + % here A->A; To find Pmin use A/gain + pressure=28*10^(withinRuns.variableValue/20); + gain=statsModel.rareEvenGain; + A=statsModel.rareEventVmin; + d=stimulusParameters.targetDuration; + gP_Vmin=gain*pressure-A; + if gP_Vmin>0 + prob=1-exp(-d*(gP_Vmin)); + else + prob=0; + end +end + +% Use the probability to choose whether or not a detection has occurred +switch experiment.threshEstMethod + case {'MaxLikelihood', 'oneIntervalUpDown'} + if rand<prob + modelResponse=2; %bingo + else + modelResponse=1; %nothing heard + end + + case {'2I2AFC++', '2I2AFC+++'} + if rand<prob + modelResponse=2; %bingo + else %if the stimulus is not audible, take a 50:50 chance of getting it right + if rand<0.5 + modelResponse=2; %bingo + else + modelResponse=1; %nothing heard + end + end +end + + +% ------------------------------------------------------- printTabTable +function printTabTable(M, headers) +% printTabTable prints a matrix as a table with tabs +%headers are optional +%headers=strvcat('firstname', 'secondname') +% printTabTable([1 2; 3 4],strvcat('a1','a2')); + +if nargin>1 + [r c]=size(headers); + for no=1:r + fprintf('%s\t',headers(no,:)) + end + fprintf('\n') +end + +[r c]=size(M); + +for row=1:r + for col=1:c + if row==1 && col==1 && M(1,1)==-1000 + % Print nothing (tab follows below) + else + fprintf('%s',num2str(M(row,col))) + end + if col<c + fprintf('\t') + end + end + fprintf('\n') +end + +% ------------------------------------------------------- xlimRM +function xlimRM(x) +try + xlim([x(1) x(2)]) +catch +end + +% ------------------------------------------------------- ylimRM +function ylimRM(x) +try + ylim([x(1) x(2)]) +catch +end + + +function editdigitInput_CreateFcn(hObject, eventdata, handles) + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% -----------------------------------------------------buttonBoxIntitialize +function buttonBoxIntitialize +% initialize button box +global serobj +try + fclose(serobj); +catch +end + +try + serobj = serial('COM4') ; % Creating serial port object now its connected to COM4 !!! button boxes in booths are connected to COM2 + serobj.Baudrate = 9600; % Set the baud rate at the specific value + set(serobj, 'Parity', 'none') ; % Set parity as none + set(serobj, 'Databits', 8) ; % set the number of data bits + set(serobj, 'StopBits', 1) ; % set number of stop bits as 1 + set(serobj, 'Terminator', 'CR') ; % set the terminator value to carriage return + set(serobj, 'InputBufferSize', 512) ; % Buffer for read operation, default it is 512 + set(serobj,'timeout',10); % 10 sec timeout on button press + set(serobj, 'ReadAsyncMode', 'continuous') + set(serobj, 'BytesAvailableFcn', @buttonBox_callback) + set(serobj, 'BytesAvailableFcnCount', 1) + set(serobj, 'BytesAvailableFcnMode', 'byte') + % set(serobj, 'BreakInterruptFcn', '@buttonBox_Calback') + + fopen(serobj); + buttonBoxStatus=get(serobj,'status'); +catch + disp('** no button box found - use mouse **') +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testAN.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,324 @@ +function vectorStrength=testAN(targetFrequency,BFlist, levels) +% testIHC used either for IHC I/O function ... +% or receptive field (doReceptiveFields=1) + +global experiment method stimulusParameters +global IHC_VResp_VivoParams IHC_cilia_RPParams IHCpreSynapseParams +global AN_IHCsynapseParams + + global ANoutput ANdt CNoutput ICoutput ICmembraneOutput tauCas + global ARattenuation MOCattenuation + +dbstop if error + +addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... + ['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... + ['..' filesep 'testPrograms']) + +if nargin<3 + levels=-10:10:80; + % levels=80:10:90; +end + +nLevels=length(levels); + +toneDuration=.2; +rampDuration=0.002; +silenceDuration=.02; +localPSTHbinwidth=0.001; + +% Use only the first frequency in the GUI targetFrequency box to defineBF +% targetFrequency=stimulusParameters.targetFrequency(1); +% BFlist=targetFrequency; + +AN_HSRonset=zeros(nLevels,1); +AN_HSRsaturated=zeros(nLevels,1); +AN_LSRonset=zeros(nLevels,1); +AN_LSRsaturated=zeros(nLevels,1); +CNLSRrate=zeros(nLevels,1); +CNHSRsaturated=zeros(nLevels,1); +ICHSRsaturated=zeros(nLevels,1); +ICLSRsaturated=zeros(nLevels,1); +vectorStrength=zeros(nLevels,1); + +AR=zeros(nLevels,1); +MOC=zeros(nLevels,1); + +% ANoutput=zeros(200,200); + +figure(15), clf +set(gcf,'position',[980 356 401 321]) +figure(5), clf +set(gcf,'position', [980 34 400 295]) +drawnow + +%% guarantee that the sample rate is at least 10 times the frequency +sampleRate=50000; +while sampleRate< 10* targetFrequency + sampleRate=sampleRate+10000; +end + +%% adjust sample rate so that the pure tone stimulus has an integer +%% numver of epochs in a period +dt=1/sampleRate; +period=1/targetFrequency; +ANspeedUpFactor=5; %anticipating MAP (needs clearing up) +ANdt=dt*ANspeedUpFactor; +ANdt=period/round(period/ANdt); +dt=ANdt/ANspeedUpFactor; +sampleRate=1/dt; +epochsPerPeriod=sampleRate*period; + +%% main computational loop (vary level) +levelNo=0; +for leveldB=levels + levelNo=levelNo+1; + + fprintf('%4.0f\t', leveldB) + amp=28e-6*10^(leveldB/20); + + time=dt:dt:toneDuration; + rampTime=dt:dt:rampDuration; + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(time)-length(rampTime))]; + ramp=ramp.*fliplr(ramp); + + silence=zeros(1,round(silenceDuration/dt)); + + % create signal (leveldB/ targetFrequency) + inputSignal=amp*sin(2*pi*targetFrequency'*time); + inputSignal= ramp.*inputSignal; + inputSignal=[silence inputSignal]; + + %% run the model + AN_spikesOrProbability='spikes'; + MAPparamsName=experiment.name; + showPlotsAndDetails=0; + + + MAP1_14(inputSignal, 1/dt, BFlist, ... + MAPparamsName, AN_spikesOrProbability); + + nTaus=length(tauCas); + + %LSR (same as HSR if no LSR fibers present) + [nANFibers nTimePoints]=size(ANoutput); + + numLSRfibers=nANFibers/nTaus; + numHSRfibers=numLSRfibers; + + LSRspikes=ANoutput(1:numLSRfibers,:); + PSTH=UTIL_PSTHmaker(LSRspikes, ANdt, localPSTHbinwidth); + PSTHLSR=mean(PSTH,1)/localPSTHbinwidth; % across fibers rates + PSTHtime=localPSTHbinwidth:localPSTHbinwidth:... + localPSTHbinwidth*length(PSTH); + AN_LSRonset(levelNo)= max(PSTHLSR); % peak in 5 ms window + AN_LSRsaturated(levelNo)= mean(PSTHLSR(round(length(PSTH)/2):end)); + + % HSR + HSRspikes= ANoutput(end- numHSRfibers+1:end, :); + PSTH=UTIL_PSTHmaker(HSRspikes, ANdt, localPSTHbinwidth); + PSTH=mean(PSTH,1)/localPSTHbinwidth; % sum across fibers (HSR only) + AN_HSRonset(levelNo)= max(PSTH); + AN_HSRsaturated(levelNo)= mean(PSTH(round(length(PSTH)/2): end)); + + figure(5), subplot(2,2,2) + hold off, bar(PSTHtime,PSTH, 'b') + hold on, bar(PSTHtime,PSTHLSR,'r') + ylim([0 1000]) + xlim([0 length(PSTH)*localPSTHbinwidth]) + set(gcf,'name',[num2str(BFlist), ' Hz: ' num2str(leveldB) ' dB']); + + % AN - CV + % CV is computed 5 times. Use the middle one (3) as most typical + cvANHSR= UTIL_CV(HSRspikes, ANdt); + + % AN - vector strength + PSTH=sum(HSRspikes); + [PH, binTimes]=UTIL_periodHistogram... + (PSTH, ANdt, targetFrequency); + VS=UTIL_vectorStrength(PH); + vectorStrength(levelNo)=VS; + disp(['sat rate= ' num2str(AN_HSRsaturated(levelNo)) ... + '; phase-locking VS = ' num2str(VS)]) + title(['AN HSR: CV=' num2str(cvANHSR(3),'%5.2f') ... + 'VS=' num2str(VS,'%5.2f')]) + + % CN - first-order neurons + + % CN LSR + [nCNneurons c]=size(CNoutput); + nLSRneurons=round(nCNneurons/nTaus); + CNLSRspikes=CNoutput(1:nLSRneurons,:); + PSTH=UTIL_PSTHmaker(CNLSRspikes, ANdt, localPSTHbinwidth); + PSTH=sum(PSTH)/nLSRneurons; + CNLSRrate(levelNo)=mean(PSTH(round(length(PSTH)/2):end))/localPSTHbinwidth; + + %CN HSR + MacGregorMultiHSRspikes=... + CNoutput(end-nLSRneurons:end,:); + PSTH=UTIL_PSTHmaker(MacGregorMultiHSRspikes, ANdt, localPSTHbinwidth); + PSTH=sum(PSTH)/nLSRneurons; + PSTH=mean(PSTH,1)/localPSTHbinwidth; % sum across fibers (HSR only) + + CNHSRsaturated(levelNo)=mean(PSTH(length(PSTH)/2:end)); + + figure(5), subplot(2,2,3) + bar(PSTHtime,PSTH) + ylim([0 1000]) + xlim([0 length(PSTH)*localPSTHbinwidth]) + cvMMHSR= UTIL_CV(MacGregorMultiHSRspikes, ANdt); + title(['CN CV= ' num2str(cvMMHSR(3),'%5.2f')]) + + % IC LSR + [nICneurons c]=size(ICoutput); + nLSRneurons=round(nICneurons/nTaus); + ICLSRspikes=ICoutput(1:nLSRneurons,:); + PSTH=UTIL_PSTHmaker(ICLSRspikes, ANdt, localPSTHbinwidth); + ICLSRsaturated(levelNo)=mean(PSTH(round(length(PSTH)/2):end))/localPSTHbinwidth; + + %IC HSR + MacGregorMultiHSRspikes=... + ICoutput(end-nLSRneurons:end,:); + PSTH=UTIL_PSTHmaker(MacGregorMultiHSRspikes, ANdt, localPSTHbinwidth); + PSTH=sum(PSTH)/nLSRneurons; + PSTH=mean(PSTH,1)/localPSTHbinwidth; % sum across fibers (HSR only) + + ICHSRsaturated(levelNo)=mean(PSTH(length(PSTH)/2:end)); + + AR(levelNo)=min(ARattenuation); + MOC(levelNo)=min(MOCattenuation(length(MOCattenuation)/2:end)); + + time=dt:dt:dt*size(ICmembraneOutput,2); + figure(5), subplot(2,2,4) + plot(time,ICmembraneOutput(2, 1:end),'k') + ylim([-0.07 0]) + xlim([0 max(time)]) + title(['IC ' num2str(leveldB,'%4.0f') 'dB']) + drawnow + + figure(5), subplot(2,2,1) + plot(20*log10(MOC), 'k'), + title(' MOC'), ylabel('dB attenuation') + ylim([-30 0]) + + +end % level +figure(5), subplot(2,2,1) +plot(levels,20*log10(MOC), 'k'), +title(' MOC'), ylabel('dB attenuation') +ylim([-30 0]) +xlim([0 max(levels)]) + +fprintf('\n') +toneDuration=2; +rampDuration=0.004; +silenceDuration=.02; +nRepeats=200; % no. of AN fibers +fprintf('toneDuration %6.3f\n', toneDuration) +fprintf(' %6.0f AN fibers (repeats)\n', nRepeats) +fprintf('levels') +fprintf('%6.2f\t', levels) +fprintf('\n') + + +% ---------------------------------------------------- display parameters + +figure(15), clf +nRows=2; nCols=2; + +% AN rate - level ONSET functions +subplot(nRows,nCols,1) +plot(levels,AN_LSRonset,'ro'), hold on +plot(levels,AN_HSRonset,'ko'), hold off +ylim([0 1000]), xlim([min(levels) max(levels)]) +ttl=['tauCa= ' num2str(IHCpreSynapseParams.tauCa)]; +title( ttl) +xlabel('level dB SPL'), ylabel('peak rate (sp/s)'), grid on +text(0, 800, 'AN onset', 'fontsize', 16) + +% AN rate - level ADAPTED function +subplot(nRows,nCols,2) +plot(levels,AN_LSRsaturated, 'ro'), hold on +plot(levels,AN_HSRsaturated, 'ko'), hold off +ylim([0 400]) +set(gca,'ytick',0:50:300) +xlim([min(levels) max(levels)]) +set(gca,'xtick',[levels(1):20:levels(end)]) +% grid on +ttl=[ 'spont=' num2str(mean(AN_HSRsaturated(1,:)),'%4.0f')... + ' sat=' num2str(mean(AN_HSRsaturated(end,1)),'%4.0f')]; +title( ttl) +xlabel('level dB SPL'), ylabel ('adapted rate (sp/s)') +text(0, 340, 'AN adapted', 'fontsize', 16), grid on + +% CN rate - level ADAPTED function +subplot(nRows,nCols,3) +plot(levels,CNLSRrate, 'ro'), hold on +plot(levels,CNHSRsaturated, 'ko'), hold off +ylim([0 400]) +set(gca,'ytick',0:50:300) +xlim([min(levels) max(levels)]) +set(gca,'xtick',[levels(1):20:levels(end)]) +% grid on +ttl=[ 'spont=' num2str(mean(CNHSRsaturated(1,:)),'%4.0f') ' sat=' ... + num2str(mean(CNHSRsaturated(end,1)),'%4.0f')]; +title( ttl) +xlabel('level dB SPL'), ylabel ('adapted rate (sp/s)') +text(0, 350, 'CN', 'fontsize', 16), grid on + +% IC rate - level ADAPTED function +subplot(nRows,nCols,4) +plot(levels,ICLSRsaturated, 'ro'), hold on +plot(levels,ICHSRsaturated, 'ko'), hold off +ylim([0 400]) +set(gca,'ytick',0:50:300) +xlim([min(levels) max(levels)]) +set(gca,'xtick',[levels(1):20:levels(end)]), grid on + + +ttl=['spont=' num2str(mean(ICHSRsaturated(1,:)),'%4.0f') ... + ' sat=' num2str(mean(ICHSRsaturated(end,1)),'%4.0f')]; +title( ttl) +xlabel('level dB SPL'), ylabel ('adapted rate (sp/s)') +text(0, 350, 'IC', 'fontsize', 16) +set(gcf,'name',' AN CN IC rate/level') + +peakVectorStrength=max(vectorStrength); + +fprintf('\n') +disp('levels vectorStrength') +fprintf('%3.0f \t %6.4f \n', [levels; vectorStrength']) +fprintf('\n') +fprintf('Phase locking, max vector strength=\t %6.4f\n\n',... + max(vectorStrength)) + +allData=[ levels' AN_HSRonset AN_HSRsaturated... + AN_LSRonset AN_LSRsaturated ... + CNHSRsaturated CNLSRrate... + ICHSRsaturated ICLSRsaturated]; +fprintf('\n levels \tANHSR Onset \tANHSR adapted\tANLSR Onset \tANLSR adapted\tCNHSR\tCNLSR\tICHSR \tICLSR \n'); +UTIL_printTabTable(round(allData)) +fprintf('VS (phase locking)= \t%6.4f\n\n',... + max(vectorStrength)) + +UTIL_showStruct(IHC_cilia_RPParams, 'IHC_cilia_RPParams') +UTIL_showStruct(IHCpreSynapseParams, 'IHCpreSynapseParams') +UTIL_showStruct(AN_IHCsynapseParams, 'AN_IHCsynapseParams') + +fprintf('\n') +disp('levels vectorStrength') +fprintf('%3.0f \t %6.4f \n', [levels; vectorStrength']) +fprintf('\n') +fprintf('Phase locking, max vector strength= \t%6.4f\n\n',... + max(vectorStrength)) + +allData=[ levels' AN_HSRonset AN_HSRsaturated... + AN_LSRonset AN_LSRsaturated ... + CNHSRsaturated CNLSRrate... + ICHSRsaturated ICLSRsaturated]; +fprintf('\n levels \tANHSR Onset \tANHSR adapted\tANLSR Onset \tANLSR adapted\tCNHSR\tCNLSR\tICHSR \tICLSR \n'); +UTIL_printTabTable(round(allData)) +fprintf('VS (phase locking)= \t%6.4f\n\n',... + max(vectorStrength)) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testBM.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,160 @@ +function testBM (BMlocations, paramsName) +% testBM generates input output functions for DRNL model for any number +% of locations. +% Computations are bast on a single channel model (channelBFs=BF) +% peak displacement (peakAmp) is measured. +% if DRNLParams.useMOC is chosen, the full model is run (slow) +% otherwise only DRNL is computed. +% Tuning curves are generated based on a range of frequencies reletove to +% the BF of the location. +% + +global DRNLParams + +savePath=path; + +addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) + +levels=-10:10:90; nLevels=length(levels); +% levels= 50; nLevels=length(levels); + +relativeFrequencies=[0.25 .5 .75 1 1.25 1.5 2]; +relativeFrequencies=1; + +% refBMdisplacement is the displacement of the BM at threshold +% 1 nm disp at threshold (9 kHz, Ruggero) +refBMdisplacement= 1e-8; % adjusted for 10 nm at 1 kHz + +toneDuration=.200; +rampDuration=0.01; +silenceDuration=0.01; + +sampleRate=30000; + +dbstop if error +figure(3), clf +set(gcf,'position',[280 350 327 326]) +set(gcf,'name','DRNL - BM') + +finalSummary=[]; +nBFs=length(BMlocations); +BFno=0; plotCount=0; +for BF=BMlocations + BFno=BFno+1; + plotCount=plotCount+nBFs; + stimulusFrequencies=BF* relativeFrequencies; + nFrequencies=length(stimulusFrequencies); + + peakAmpBM=zeros(nLevels,nFrequencies); + peakAmpBMdB=NaN(nLevels,nFrequencies); + peakEfferent=NaN(nLevels,nFrequencies); + peakAREfferent=NaN(nLevels,nFrequencies); + + + levelNo=0; + for leveldB=levels + disp(['level= ' num2str(leveldB)]) + levelNo=levelNo+1; + + freqNo=0; + for frequency=stimulusFrequencies + freqNo=freqNo+1; + + % Generate stimuli + globalStimParams.FS=sampleRate; + globalStimParams.overallDuration=... + toneDuration+silenceDuration; % s + stim.phases='sin'; + stim.type='tone'; + stim.toneDuration=toneDuration; + stim.frequencies=frequency; + stim.amplitudesdB=leveldB; + stim.beginSilence=silenceDuration; + stim.rampOnDur=rampDuration; + % no offset ramp + stim.rampOffDur=rampDuration; + doPlot=0; + inputSignal=stimulusCreate(globalStimParams, stim, doPlot); + inputSignal=inputSignal(:,1)'; + + %% run the model + MAPparamsName=paramsName; + AN_spikesOrProbability='probability'; + % spikes are slow but can be used to study MOC using IC units + AN_spikesOrProbability='spikes'; + + global DRNLoutput MOCattenuation ARattenuation + MAP1_14(inputSignal, sampleRate, BF, ... + MAPparamsName, AN_spikesOrProbability); + + DRNLresponse=DRNLoutput; + peakAmp=max(max(... + DRNLresponse(:, end-round(length(DRNLresponse)/2):end))); + peakAmpBM(levelNo,freqNo)=peakAmp; + peakAmpBMdB(levelNo,freqNo)=... + 20*log10(peakAmp/refBMdisplacement); + peakEfferent(levelNo,freqNo)=min(min(MOCattenuation)); + peakAREfferent(levelNo,freqNo)=min(min(ARattenuation)); + + end % tone frequency + end % level + + %% analyses results and plot + + % BM I/O plot (top panel) + figure(3) + subplot(3,nBFs,BFno), cla + plot(levels,peakAmpBMdB, 'linewidth',2) + hold on, plot(levels, repmat(refBMdisplacement,1,length(levels))) + hold off + title(['BF=' num2str(BF,'%5.0f') ' - ' paramsName]) + xlabel('level') + % set(gca,'xtick',levels), grid on + if length(levels)>1,xlim([min(levels) max(levels)]), end + ylabel(['dB re:' num2str(refBMdisplacement,'%6.1e') 'm']) + ylim([-20 50]) + set(gca,'ytick',[-10 0 10 20 40]) + grid on + % legend({num2str(stimulusFrequencies')}, 'location', 'EastOutside') + UTIL_printTabTable([levels' peakAmpBMdB], ... + num2str([0 stimulusFrequencies]','%5.0f'), '%5.0f') + finalSummary=[finalSummary peakAmpBMdB]; + + % Tuning curve + if length(relativeFrequencies)>2 + figure(3), subplot(3,nBFs, 2*nBFs+BFno) + % contour(stimulusFrequencies,levels,peakAmpBM,... + % [refBMdisplacement refBMdisplacement],'r') + contour(stimulusFrequencies,levels,peakAmpBM,... + refBMdisplacement.*[1 5 10 50 100]) + title(['tuning curve at ' num2str(refBMdisplacement) 'm']); + ylabel('level (dB) at reference') + xlim([100 10000]) + grid on + hold on + set(gca,'xscale','log') + end + + + % MOC contribution + figure(3) + subplot(3,nBFs,nBFs+BFno), cla + plot(levels,20*log10(peakEfferent), 'linewidth',2) + ylabel('MOC (dB attenuation)'), xlabel('level') + title(['peak MOC: model= ' AN_spikesOrProbability]) + grid on + if length(levels)>1, xlim([min(levels) max(levels)]), end + + % AR contribution + hold on + plot(levels,20*log10(peakAREfferent), 'r') + hold off + +end % best frequency + +UTIL_showStructureSummary(DRNLParams, 'DRNLParams', 10) + + UTIL_printTabTable([levels' finalSummary], ... + num2str([0 stimulusFrequencies]','%5.0f'), '%5.0f') + +path(savePath);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testFM.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,247 @@ +function testFM(showPSTHs) +% specify whether you want AN 'probability' or 'spikes' +% spikes is more realistic but takes longer +% refractory effect is included only for spikes +% + +% specify the AN ANresponse bin width (normally 1 ms). +% This can influence the measure of the AN onset rate based on the +% largest bin in the ANresponse +% +% Demonstration is based on Harris and Dallos + +global experiment stimulusParameters +global inputStimulusParams outerMiddleEarParams DRNLParams +global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams + +dbstop if error +% masker and probe levels are relative to this threshold +thresholdAtCF=10; % dB SPL +thresholdAtCF=5; % dB SPL + +if nargin<1, showPSTHs=1;end + +sampleRate=50000; + +% fetch BF from GUI: use only the first target frequency +BFlist=stimulusParameters.targetFrequency(1); +maskerFrequency=BFlist; +maskerDuration=.1; + +targetFrequency=maskerFrequency; +probeLeveldB=20+thresholdAtCF; % H&D use 20 dB SL/ TMC uses 10 dB SL +probeDuration=0.008; % HD use 15 ms probe (fig 3). +probeDuration=0.015; % HD use 15 ms probe (fig 3). + +rampDuration=.001; % HD use 1 ms linear ramp +initialSilenceDuration=0.02; +finalSilenceDuration=0.05; % useful for showing recovery + +maskerLevels=[-80 10 20 30 40 60 ] + thresholdAtCF; +% maskerLevels=[-80 40 60 ] + thresholdAtCF; + +dt=1/sampleRate; + +figure(7), clf +set(gcf,'position',[613 36 360 247]) +set(gcf,'name', ['forward masking: thresholdAtCF=' num2str(thresholdAtCF)]) + +if showPSTHs + figure(8), clf + set(gcf,'name', 'Harris and Dallos simulation') + set(gcf,'position',[980 36 380 249]) +end + +% Plot Harris and Dallos result for comparison +gapDurations=[0.001 0.002 0.005 0.01 0.02 0.05 0.1 0.3]; +HDmaskerLevels=[+10 +20 +30 +40 +60]; +HDresponse=[ + 1 1 1 1 1 1 1 1; + 0.8 0.82 0.81 0.83 0.87 0.95 1 1; + 0.48 0.5 0.54 0.58 0.7 0.85 0.95 1; + 0.3 0.31 0.35 0.4 0.5 0.68 0.82 0.94; + 0.2 0.27 0.27 0.29 0.42 0.64 0.75 0.92; + 0.15 0.17 0.18 0.23 0.3 0.5 0.6 0.82]; + +figure(7) +semilogx(gapDurations,HDresponse,'o'), hold on +legend(strvcat(num2str(maskerLevels')),'location','southeast') +title([ 'masker dB: ' num2str(HDmaskerLevels)]) + +%% Run the trials +maxProbeResponse=0; +levelNo=0; +resultsMatrix=zeros(length(maskerLevels), length(gapDurations)); +summaryFiringRates=[]; + +% initial silence +time=dt: dt: initialSilenceDuration; +initialSilence=zeros(1,length(time)); + +% probe +time=dt: dt: probeDuration; +amp=28e-6*10^(probeLeveldB/20); +probe=amp*sin(2*pi.*targetFrequency*time); +% ramps +% catch rampTime error +if rampDuration>0.5*probeDuration, rampDuration=probeDuration/2; end +rampTime=dt:dt:rampDuration; +% raised cosine ramp +ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(time)-length(rampTime))]; +% onset ramp +probe=probe.*ramp; +% offset ramp makes complete ramp for probe +ramp=fliplr(ramp); +% apply ramp mask to probe. Probe does not change below +probe=probe.*ramp; + +% final silence +time=dt: dt: finalSilenceDuration; +finalSilence=zeros(1,length(time)); + +PSTHplotCount=0; +longestSignalDuration=initialSilenceDuration + maskerDuration +... + max(gapDurations) + probeDuration + finalSilenceDuration ; +for maskerLeveldB=maskerLevels + levelNo=levelNo+1; + allDurations=[]; + allFiringRates=[]; + + %masker + time=dt: dt: maskerDuration; + masker=sin(2*pi.*maskerFrequency*time); + % masker ramps + if rampDuration>0.5*maskerDuration + % catch ramp duration error + rampDuration=maskerDuration/2; + end + % NB masker ramp (not probe ramp) + rampTime=dt:dt:rampDuration; + % raised cosine ramp + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi))... + ones(1,length(time)-length(rampTime))]; + % onset ramp + masker=masker.*ramp; + % offset ramp + ramp=fliplr(ramp); + % apply ramp + masker=masker.*ramp; + amp=28e-6*10^(maskerLeveldB/20); + maskerPa=amp*masker; + + for gapDuration=gapDurations + time=dt: dt: gapDuration; + gap=zeros(1,length(time)); + + inputSignal=... + [initialSilence maskerPa gap probe finalSilence]; + + % ********************************** run MAP model + + global ANprobRateOutput tauCas ... + + MAPparamsName=experiment.name; + showPlotsAndDetails=0; + +AN_spikesOrProbability='probability'; + +MAP1_14(inputSignal, 1/dt, targetFrequency, ... + MAPparamsName, AN_spikesOrProbability); + + [nFibers c]=size(ANprobRateOutput); + nLSRfibers=nFibers/length(tauCas); + ANresponse=ANprobRateOutput(end-nLSRfibers:end,:); + ANresponse=sum(ANresponse)/nLSRfibers; + + % analyse results + probeStart=initialSilenceDuration+maskerDuration+gapDuration; + PSTHbinWidth=dt; + responseDelay=0.005; + probeTimes=probeStart+responseDelay:... + PSTHbinWidth:probeStart+probeDuration+responseDelay; + probeIDX=round(probeTimes/PSTHbinWidth); + probePSTH=ANresponse(probeIDX); + firingRate=mean(probePSTH); + % NB this only works if you start with the lowest level masker + maxProbeResponse=max([maxProbeResponse firingRate]); + allDurations=[allDurations gapDuration]; + allFiringRates=[allFiringRates firingRate]; + + %% show PSTHs + if showPSTHs + nLevels=length(maskerLevels); + nDurations=length(gapDurations); + figure(8) + PSTHbinWidth=1e-3; + PSTH=UTIL_PSTHmaker(ANresponse, dt, PSTHbinWidth); + PSTH=PSTH*dt/PSTHbinWidth; + PSTHplotCount=PSTHplotCount+1; + subplot(nLevels,nDurations,PSTHplotCount) + probeTime=PSTHbinWidth:PSTHbinWidth:... + PSTHbinWidth*length(PSTH); + bar(probeTime, PSTH) + if strcmp(AN_spikesOrProbability, 'spikes') + ylim([0 500]) + else + ylim([0 500]) + end + xlim([0 longestSignalDuration]) + grid on + + if PSTHplotCount< (nLevels-1) * nDurations+1 + set(gca,'xticklabel',[]) + end + + if ~isequal(mod(PSTHplotCount,nDurations),1) + set(gca,'yticklabel',[]) + else + ylabel([num2str(maskerLevels... + (round(PSTHplotCount/nDurations) +1))]) + end + + if PSTHplotCount<=nDurations + title([num2str(1000*gapDurations(PSTHplotCount)) 'ms']) + end + end % showPSTHs + + end % gapDurations duration + summaryFiringRates=[summaryFiringRates allFiringRates']; + + figure(7), hold on + semilogx(allDurations, allFiringRates/maxProbeResponse) + ylim([0 1]), hold on + ylim([0 inf]), xlim([min(gapDurations) max(gapDurations)]) + xlim([0.001 1]) + pause(0.1) % to allow for CTRL/C interrupts + resultsMatrix(levelNo,:)=allFiringRates; +end % maskerLevel + +disp('delay/ rates') +disp(num2str(round( [1000*allDurations' summaryFiringRates]))) + +% replot with best adjustment +% figure(34), clf% use for separate plot +figure(7), clf +peakProbe=max(max(resultsMatrix)); +resultsMatrix=resultsMatrix/peakProbe; +semilogx(gapDurations,HDresponse,'o'), hold on +title(['FrMsk: probe ' num2str(probeLeveldB)... + 'dB SL: peakProbe=' num2str(peakProbe,'%5.0f') ' sp/s']) +xlabel('gap duration (s)'), ylabel ('probe response') +semilogx(allDurations, resultsMatrix'), ylim([0 1]) +ylim([0 inf]), +xlim([0.001 1]) +legend(strvcat(num2str(maskerLevels'-thresholdAtCF)), -1) + +% ------------------------------------------------- display parameters +disp(['parameter file was: ' experiment.name]) +fprintf('\n') +% UTIL_showStruct(inputStimulusParams, 'inputStimulusParams') +% UTIL_showStruct(outerMiddleEarParams, 'outerMiddleEarParams') +% UTIL_showStruct(DRNLParams, 'DRNLParams') +% UTIL_showStruct(IHC_VResp_VivoParams, 'IHC_VResp_VivoParams') +UTIL_showStruct(IHCpreSynapseParams, 'IHCpreSynapseParams') +UTIL_showStruct(AN_IHCsynapseParams, 'AN_IHCsynapseParams') + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testOME.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,88 @@ +function testOME + +global experiment +savePath=path; +addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) + +sampleRate=50000; + +dt=1/sampleRate; +leveldBSPL=80; % dB SPL as used by Huber (may trigger AR) +amp=10^(leveldBSPL/20)*28e-6; +duration=.05; +time=dt: dt: duration; + +%% Comparison data (human) +% These data are taken directly from Huber 2001 (Fig. 4) +HuberFrequencies=[600 800 1000 2000 3000 4000 6000 8000]; +HuberDisplacementAt80dBSPL=[1.5E-9 1.5E-09 1.5E-09 1.0E-09 7.0E-10 ... + 3.0E-10 2.0E-10 1.0E-10]; % m; +% HuberVelocityAt80dBSPL= 2*pi*HuberFrequencies.*HuberDisplacementAt80dBSPL; + +figure(2), clf, subplot(2,1,1) +set(2,'position',[5 349 268 327]) +semilogx(HuberFrequencies, 20*log10(HuberDisplacementAt80dBSPL/1e-10),... + 'ko', 'MarkerFaceColor','k', 'Marker','o', 'markerSize',6) +hold on + +%% Generate test stimulus ................................................................. + +% independent test using discrete frequencies +peakResponses=[]; +peakTMpressure=[]; +frequencies=[200 400 HuberFrequencies 10000]; +for toneFrequency=frequencies + inputSignal=amp*sin(2*pi*toneFrequency*time); + + MAPparamsName=experiment.name; + showPlotsAndDetails=0; + AN_spikesOrProbability='probability'; + % switch off AR & MOC (Huber's patients were deaf) + paramChanges{1}='OMEParams.rateToAttenuationFactorProb=0;'; + paramChanges{2}='DRNLParams.rateToAttenuationFactorProb = 0;'; + + global OMEoutput OMEextEarPressure TMoutput ARattenuation + % BF is irrelevant + MAP1_14(inputSignal, sampleRate, -1, ... + MAPparamsName, AN_spikesOrProbability, paramChanges); + + peakDisplacement=max(OMEoutput(floor(end/2):end)); + peakResponses=[peakResponses peakDisplacement]; + + peakTMpressure=[peakTMpressure max(OMEextEarPressure)]; + disp([' AR attenuation (dB): ' num2str(20*log10(min(ARattenuation)))]) +end + +%% Report +disp('frequency displacement(m)') +% disp(num2str([frequencies' peakResponses'])) +fprintf('%6.0f \t%10.3e\n',[frequencies' peakResponses']') + +% stapes peak displacement +figure(2), subplot(2,1,1), hold on +semilogx(frequencies, 20*log10(peakResponses/1e-10), 'r', 'linewidth',4) +set(gca,'xScale','log') +% ylim([1e-11 1e-8]) +xlim([100 10000]), ylim([0 30]) +grid on +title(['stapes at ' num2str(leveldBSPL) ' (NB deaf)']) +ylabel('disp: dB re 1e-10m') +xlabel('stimulus frequency (Hz)') +legend({'Huber et al','model'},'location','southWest') +set(gcf,'name','OME') + +% external ear resonance +figure(2), subplot(2,1,2),hold off +semilogx(frequencies, 20*log10(peakTMpressure/28e-6)-leveldBSPL,... + 'k', 'linewidth',2) +xlim([100 10000]) %, ylim([-10 30]) +grid on +title(['External ear resonances' ]) +ylabel('dB') +xlabel('frequency') +set(gcf,'name','OME: external resonances') +% ---------------------------------------------------------- display parameters +disp(['parameter file was: ' experiment.name]) +fprintf('\n') + +path(savePath); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testPeriphery.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,161 @@ +function testPeriphery (BMlocations, paramsName) +% testBM generates input output functions for DRNL model for any number +% of locations. +% Computations are bast on a single channel model (channelBFs=BF) +% peak displacement (peakAmp) is measured. +% if DRNLParams.useMOC is chosen, the full model is run (slow) +% otherwise only DRNL is computed. +% Tuning curves are generated based on a range of frequencies reletove to +% the BF of the location. +% + +global DRNLParams + +savePath=path; + +addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) + +levels=-10:10:90; nLevels=length(levels); +% levels= 50; nLevels=length(levels); + +% relativeFrequencies=[0.25 .5 .75 1 1.25 1.5 2]; +relativeFrequencies=1; + +% refBMdisplacement is the displacement of the BM at threshold +% 1 nm disp at threshold (9 kHz, Ruggero) +refBMdisplacement= 1e-8; % adjusted for 10 nm at 1 kHz + +toneDuration=.200; +rampDuration=0.01; +silenceDuration=0.01; + +sampleRate=30000; + +dbstop if error +figure(3), clf +% set(gcf,'position',[276 33 331 645]) +set(gcf,'name','DRNL - BM') + +finalSummary=[]; +nBFs=length(BMlocations); +BFno=0; plotCount=0; +for BF=BMlocations + BFno=BFno+1; + plotCount=plotCount+nBFs; + stimulusFrequencies=BF* relativeFrequencies; + nFrequencies=length(stimulusFrequencies); + + peakAmpBM=zeros(nLevels,nFrequencies); + peakAmpBMdB=NaN(nLevels,nFrequencies); + peakEfferent=NaN(nLevels,nFrequencies); + peakAREfferent=NaN(nLevels,nFrequencies); + + + levelNo=0; + for leveldB=levels + disp(['level= ' num2str(leveldB)]) + levelNo=levelNo+1; + + freqNo=0; + for frequency=stimulusFrequencies + freqNo=freqNo+1; + + % Generate stimuli + globalStimParams.FS=sampleRate; + globalStimParams.overallDuration=... + toneDuration+silenceDuration; % s + stim.type='tone'; + stim.phases='sin'; + stim.toneDuration=toneDuration; + stim.frequencies=frequency; + stim.amplitudesdB=leveldB; + stim.beginSilence=silenceDuration; + stim.rampOnDur=rampDuration; + stim.rampOffDur=rampDuration; + doPlot=0; + inputSignal=stimulusCreate(globalStimParams, stim, doPlot); + inputSignal=inputSignal(:,1)'; + + %% run the model + MAPparamsName=paramsName; + AN_spikesOrProbability='probability'; + % spikes are slow but can be used to study MOC using IC units + % AN_spikesOrProbability='spikes'; + + global DRNLoutput MOCattenuation ARattenuation IHCoutput + MAP1_14(inputSignal, sampleRate, BF, ... + MAPparamsName, AN_spikesOrProbability); + + DRNLresponse=IHCoutput; + peakAmp=max(max(... + DRNLresponse(:, end-round(length(DRNLresponse)/2):end))); + peakAmpBM(levelNo,freqNo)=peakAmp; + if peakAmp>0 + peakAmpBMdB(levelNo,freqNo)=... + 20*log10(peakAmp/refBMdisplacement); + else + peakAmpBMdB(levelNo,freqNo)=peakAmp; + end + peakEfferent(levelNo,freqNo)=min(min(MOCattenuation)); + peakAREfferent(levelNo,freqNo)=min(min(ARattenuation)); + + end % tone frequency + end % level + + %% analyses results and plot + + % BM I/O plot (top panel) + figure(3) + subplot(3,nBFs,BFno), cla + plot(levels,peakAmpBMdB, 'linewidth',2) + hold on, plot(levels, repmat(refBMdisplacement,1,length(levels))) + hold off + title(['BF=' num2str(BF,'%5.0f') ' - ' paramsName]) + xlabel('level') + % set(gca,'xtick',levels), grid on + if length(levels)>1,xlim([min(levels) max(levels)]), end + ylabel(['dB re:' num2str(refBMdisplacement,'%6.1e') 'm']) + ylim([-20 50]) + set(gca,'ytick',[-10 0 10 20 40]) + % legend({num2str(stimulusFrequencies')}, 'location', 'EastOutside') + UTIL_printTabTable([levels' peakAmpBMdB], ... + num2str([0 stimulusFrequencies]','%5.0f'), '%5.0f') + finalSummary=[finalSummary peakAmpBMdB]; + + % Tuning curve + if length(relativeFrequencies)>2 + figure(3), subplot(3,nBFs, nBFs+BFno) + % contour(stimulusFrequencies,levels,peakAmpBM,... + % [refBMdisplacement refBMdisplacement],'r') + contour(stimulusFrequencies,levels,peakAmpBM,... + refBMdisplacement.*[1 5 10 50 100]) + title(['tuning curve at ' num2str(refBMdisplacement) 'm']); + ylabel('level (dB) at reference') + xlim([100 10000]) + hold on + set(gca,'xscale','log') + end + + + % MOC contribution + figure(3) + subplot(3,nBFs,2*nBFs+BFno), cla + plot(levels,20*log10(peakEfferent), 'linewidth',2) + ylabel('MOC (dB attenuation)'), xlabel('level') + title(['peak MOC: model= ' AN_spikesOrProbability]) + grid on + if length(levels)>1, xlim([min(levels) max(levels)]), end + + % AR contribution + hold on + plot(levels,20*log10(peakAREfferent), 'r') + hold off + +end % best frequency + +UTIL_showStructureSummary(DRNLParams, 'DRNLParams', 10) + + UTIL_printTabTable([levels' finalSummary], ... + num2str([0 stimulusFrequencies]','%5.0f'), '%5.0f') + +path(savePath); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testPhaseLocking.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,45 @@ +function testPhaseLocking + +testFrequencies=[250 500 1000 2000 4000 8000]; +levels=50:10:80; +figure(14), clf +set(gcf,'position', [980 36 383 321]) +set(gcf,'name', 'phase locking') +allStrengths=zeros(length(testFrequencies), length(levels)); +peakVectorStrength=zeros(1,length(testFrequencies)); +freqCount=0; +for targetFrequency=testFrequencies; + %single test + freqCount=freqCount+1; + vectorStrength=testAN(targetFrequency,targetFrequency, levels); + allStrengths(freqCount,:)=vectorStrength'; + peakVectorStrength(freqCount)=max(vectorStrength'); +end +%% plot results +figure(14) +subplot(2,1,2) +plot(levels,allStrengths) +xlabel('levels') +ylabel('vector strength') +legend (num2str(testFrequencies'),'location','eastOutside') + +subplot(2,1,1) +semilogx(testFrequencies,peakVectorStrength) +grid on +title ('peak vector strength') +xlabel('frequency') +ylabel('vector strength') + +johnson=[250 0.79 +500 0.82 +1000 0.8 +2000 0.7 +4000 0.25 +5500 0.05 +]; +hold on +plot(johnson(:,1),johnson(:,2),'o') +legend({'model','Johnson 80'},'location','eastOutside') +hold off + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testRF.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,295 @@ +function testRF +% testIHC used either for IHC I/O function or receptive field (doReceptiveFields=1) + +global experiment method stimulusParameters expGUIhandles +global inputStimulusParams IHC_ciliaParams +global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams +dbstop if error +% set(expGUIhandles.pushbuttonStop, 'backgroundColor', [.941 .941 .941]) + +addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... + ['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... + ['..' filesep 'testPrograms']) + +targetFrequency=stimulusParameters.targetFrequency(1); + +sampleRate=50000; +doReceptiveFields=1; + +toneDuration=.05; +rampDuration=0.004; +silenceDuration=.02; + +nRepeats=100; % no. of AN fibers + +plotGraphsForIHC=1; +% number of MacGregor units is set in the parameter file. + +if doReceptiveFields + % show all receptive field + frequencies=targetFrequency* [ 0.5 0.7 0.9 1 1.1 1.3 1.6]; + levels=0:20:80; nLevels=length(levels); + figure(14), clf + figure(15), clf +else + % show only I/O function at BF + frequencies=targetFrequency; + levels=-20:10:90; + % levels=10:.25:13; + % levels=-20:1:-15 + nLevels=length(levels); +% figure(13), clf, +% set (gcf, 'name', ['IHC/AN input/output' num2str(AN_IHCsynapseParams.numFibers) ' repeats']) +% drawnow +end +nFrequencies=length(frequencies); + +IHC_RP_peak=zeros(nLevels,nFrequencies); +IHC_RP_min=zeros(nLevels,nFrequencies); +IHC_RP_dc=zeros(nLevels,nFrequencies); +AN_HSRonset=zeros(nLevels,nFrequencies); +AN_HSRsaturated=zeros(nLevels,nFrequencies); +AN_LSRonset=zeros(nLevels,nFrequencies); +AN_LSRsaturated=zeros(nLevels,nFrequencies); +CNLSRsaturated=zeros(nLevels,nFrequencies); +CNHSRsaturated=zeros(nLevels,nFrequencies); +ICHSRsaturated=zeros(nLevels,nFrequencies); +ICLSRsaturated=zeros(nLevels,nFrequencies); + + +levelNo=0; PSTHplotCount=0; +for leveldB=levels + fprintf('%4.0f\t', leveldB) + levelNo=levelNo+1; + amp=28e-6*10^(leveldB/20); + + freqNo=0; + for frequency=frequencies + + paramFunctionName=['method=MAPparams' experiment.name ... + '(' num2str(targetFrequency) ');' ]; + eval(paramFunctionName); % read parameters afresh each pass + + dt=method.dt; + time=dt:dt:toneDuration; + rampTime=dt:dt:rampDuration; + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ones(1,length(time)-length(rampTime))]; + ramp=ramp.*fliplr(ramp); + + silence=zeros(1,round(silenceDuration/dt)); + + toneStartptr=length(silence)+1; + toneMidptr=toneStartptr+round(toneDuration/(2*dt)) -1; + toneEndptr=toneStartptr+round(toneDuration/dt) -1; + + % create signal (leveldB/ frequency) + freqNo=freqNo+1; + inputSignal=amp*sin(2*pi*frequency'*time); + inputSignal= ramp.*inputSignal; + inputSignal=[silence inputSignal silence]; + + if doReceptiveFields % receptive field + method.plotGraphs= 0; % plot only PSTHs + else + method.plotGraphs= plotGraphsForIHC; % show progress + end + + targetChannelNo=1; + + % force parameters + % the number of AN fibers at each BF + AN_IHCsynapseParams.numFibers= nRepeats; + AN_IHCsynapseParams. mode= 'spikes'; + AN_IHCsynapseParams.plotSynapseContents=0; + AN_IHCsynapseParams.PSTHbinWidth=.001; + + method.DRNLSave=1; + method.IHC_cilia_RPSave=1; + method.PSTHbinWidth=1e-3; % useful 1-ms default for all PSTHs + method.AN_IHCsynapseSave=1; + method.MacGregorMultiSave=1; + method.MacGregorSave=1; + method.dt=dt; + + moduleSequence=[1:8]; + + global ANdt ARAttenuation TMoutput OMEoutput ... + DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... + IHCoutput ANprobRateOutput ANoutput savePavailable tauCas ... + CNoutput ICoutput ICmembraneOutput ICfiberTypeRates MOCattenuation + +AN_spikesOrProbability='spikes'; +AN_spikesOrProbability='probability'; +MAPparamsName='Normal'; + +MAP1_14(inputSignal, 1/dt, targetFrequency, ... + MAPparamsName, AN_spikesOrProbability); + + % RP + IHC_RPData=IHC_cilia_output; + IHC_RPData=IHCoutput(targetChannelNo,:); + IHC_RP_peak(levelNo,freqNo)=max(IHC_RPData(toneStartptr:toneEndptr)); + IHC_RP_min(levelNo,freqNo)=min(IHC_RPData(toneStartptr:toneEndptr)); + IHC_RP_dc(levelNo,freqNo)=mean(IHC_RPData(toneStartptr:toneEndptr)); + + % AN next + AN_IHCsynapseAllData=ANoutput; + method.PSTHbinWidth=0.001; + + nTaus=length(tauCas); + numANfibers=size(ANoutput,1); + numLSRfibers=numANfibers/nTaus; + + %LSR (same as HSR if no LSR fibers present) + channelPtr1=(targetChannelNo-1)*numANfibers+1; + channelPtr2=channelPtr1+numANfibers-1; + LSRspikes=AN_IHCsynapseAllData(channelPtr1:channelPtr2,:); + method.dt=method.AN_IHCsynapsedt; + PSTH=UTIL_PSTHmaker(LSRspikes, method); + PSTH=sum(PSTH,1); % sum across fibers (HSR only) + PSTHStartptr=round(silenceDuration/method.PSTHbinWidth)+1; + PSTHMidptr=PSTHStartptr+round(toneDuration/(2*method.PSTHbinWidth)) -1; + PSTHEndptr=PSTHStartptr+round(toneDuration/method.PSTHbinWidth) -1; + AN_LSRonset(levelNo,freqNo)=max(max(PSTH))/(method.PSTHbinWidth*method.numANfibers); + AN_LSRsaturated(levelNo,freqNo)=sum(PSTH(PSTHMidptr:PSTHEndptr))/(method.numANfibers*toneDuration/2); + + % HSR + channelPtr1=numLSRfibers+(targetChannelNo-1)*method.numANfibers+1; + channelPtr2=channelPtr1+method.numANfibers-1; + HSRspikes=AN_IHCsynapseAllData(channelPtr1:channelPtr2,:); + method.dt=method.AN_IHCsynapsedt; + PSTH=UTIL_PSTHmaker(HSRspikes, method); + PSTH=sum(PSTH,1); % sum across fibers (HSR only) + PSTHStartptr=round(silenceDuration/method.PSTHbinWidth)+1; + PSTHMidptr=PSTHStartptr+round(toneDuration/(2*method.PSTHbinWidth)) -1; + PSTHEndptr=PSTHStartptr+round(toneDuration/method.PSTHbinWidth) -1; + AN_HSRonset(levelNo,freqNo)=max(max(PSTH))/(method.PSTHbinWidth*method.numANfibers); + AN_HSRsaturated(levelNo,freqNo)=sum(PSTH(PSTHMidptr:PSTHEndptr))/(method.numANfibers*toneDuration/2); + [cvANHSR, cvTimes, allTimeStamps, allISIs]= UTIL_CV(HSRspikes, method.AN_IHCsynapsedt); + + PSTHplotCount=PSTHplotCount+1; + if doReceptiveFields % receptive field for HSR only + figure(14), set(gcf,'name','AN') + plotReceptiveFields(method, PSTH, PSTHplotCount, levels, frequencies) + ylim([0 method.numANfibers]) + xlabel(['CV= ' num2str(max(cvANHSR),'%4.2f')],'fontsize',8) + end % doReceptiveFields + + % CN + MacGregorMultiAllData=method.MacGregorMultiData; + numLSRfibers=method.McGMultinNeuronsPerBF*length(method.nonlinCF)* (nTaus-1); + + %LSR (same as HSR if no LSR fibers present) + channelPtr1=(targetChannelNo-1)*method.McGMultinNeuronsPerBF+1; + channelPtr2=channelPtr1+method.McGMultinNeuronsPerBF-1; + MacGregorMultiLSRspikes=MacGregorMultiAllData(channelPtr1:channelPtr2,:); + method.dt=method.MacGregorMultidt; + PSTH=UTIL_PSTHmaker(MacGregorMultiLSRspikes, method); + PSTH=sum(PSTH,1); % sum across fibers (HSR only) + PSTHStartptr=round(silenceDuration/method.PSTHbinWidth)+1; + PSTHMidptr=PSTHStartptr+round(toneDuration/(2*method.PSTHbinWidth)) -1; + PSTHEndptr=PSTHStartptr+round(toneDuration/method.PSTHbinWidth) -1; + CNLSRsaturated(levelNo,freqNo)=sum(PSTH(PSTHMidptr:PSTHEndptr)); + CNLSRsaturated(levelNo,freqNo)=CNLSRsaturated(levelNo,freqNo)... + /((toneDuration/2)*method.McGMultinNeuronsPerBF); + + %HSR + channelPtr1=numLSRfibers+(targetChannelNo-1)*method.McGMultinNeuronsPerBF+1; + channelPtr2=channelPtr1+method.McGMultinNeuronsPerBF-1; + MacGregorMultiHSRspikes=MacGregorMultiAllData(channelPtr1:channelPtr2,:); + method.dt=method.MacGregorMultidt; + PSTH=UTIL_PSTHmaker(MacGregorMultiHSRspikes, method); + PSTH=sum(PSTH,1); % sum across fibers (HSR only) + PSTHStartptr=round(silenceDuration/method.PSTHbinWidth)+1; + PSTHMidptr=PSTHStartptr+round(toneDuration/(2*method.PSTHbinWidth)) -1; + PSTHEndptr=PSTHStartptr+round(toneDuration/method.PSTHbinWidth) -1; + CNHSRsaturated(levelNo,freqNo)=sum(PSTH(PSTHMidptr:PSTHEndptr)); + CNHSRsaturated(levelNo,freqNo)=CNHSRsaturated(levelNo,freqNo)... + /((toneDuration/2)*method.McGMultinNeuronsPerBF); + [cvMMHSR, cvTimes, allTimeStamps, allISIs]= UTIL_CV(MacGregorMultiHSRspikes, method.MacGregorMultidt); + + if doReceptiveFields % receptive field + figure(15), set(gcf,'name','CN HSR input') + plotReceptiveFields(method, PSTH, PSTHplotCount, levels, frequencies) + ylim([0 method.McGMultinNeuronsPerBF]) + xlabel(['CV= ' num2str(max(cvMMHSR),'%4.2f')],'fontsize',8) + end + + MacGregorAllData=method.MacGregorData; + numLSRfibers=length(method.nonlinCF)* (nTaus-1); + + %LSR (same as HSR if no LSR fibers present) + channelPtr1=targetChannelNo; + MacGregorLSR=MacGregorAllData(channelPtr1,:); + method.dt=method.MacGregordt; + PSTH=UTIL_PSTHmaker(MacGregorLSR, method); + PSTHStartptr=round(silenceDuration/method.PSTHbinWidth)+1; + PSTHMidptr=PSTHStartptr+round(toneDuration/(2*method.PSTHbinWidth)) -1; + PSTHEndptr=PSTHStartptr+round(toneDuration/method.PSTHbinWidth) -1; + ICLSRsaturated(levelNo,freqNo)=sum(PSTH(PSTHMidptr:PSTHEndptr)); + ICLSRsaturated(levelNo,freqNo)=ICLSRsaturated(levelNo,freqNo)/(toneDuration/2); + + %LSR (same as HSR if no LSR fibers present) + channelPtr1=numLSRfibers+targetChannelNo; + MacGregorHSR=MacGregorAllData(channelPtr1,:); + method.dt=method.MacGregordt; + PSTH=UTIL_PSTHmaker(MacGregorHSR, method); + PSTHStartptr=round(silenceDuration/method.PSTHbinWidth)+1; + PSTHMidptr=PSTHStartptr+round(toneDuration/(2*method.PSTHbinWidth)) -1; + PSTHEndptr=PSTHStartptr+round(toneDuration/method.PSTHbinWidth) -1; + ICHSRsaturated(levelNo,freqNo)=sum(PSTH(PSTHMidptr:PSTHEndptr)); + ICHSRsaturated(levelNo,freqNo)=ICHSRsaturated(levelNo,freqNo)/(toneDuration/2); + [cvICHSR, cvTimes, allTimeStamps, allISIs]= UTIL_CV(MacGregorHSR, method.MacGregordt); + +% if doReceptiveFields % receptive field +% figure(16), set(gcf,'name','IC HSR input') +% plotReceptiveFields(method, PSTH, PSTHplotCount, levels, frequencies) +% ylim([0 method.McGMultinNeuronsPerBF]) +% xlabel(['CV= ' num2str(max(cvICHSR),'%4.2f')],'fontsize',8) +% end + end % frequency +end % level +fprintf('\n') +toneDuration=2; +rampDuration=0.004; +silenceDuration=.02; +nRepeats=200; % no. of AN fibers +fprintf('toneDuration %6.3f\n', toneDuration) +fprintf(' %6.0f AN fibers (repeats)\n', nRepeats) +fprintf('levels') +fprintf('%6.2f\t', levels) +fprintf('\n') + + +% ---------------------------------------------------------- display parameters +disp(['parameter file was: ' experiment.name]) +fprintf('\n') +UTIL_showStruct(IHC_VResp_VivoParams, 'IHC_cilia_RPParams') +UTIL_showStruct(IHCpreSynapseParams, 'IHCpreSynapseParams') +UTIL_showStruct(AN_IHCsynapseParams, 'AN_IHCsynapseParams') + + + +function plotReceptiveFields(method, PSTH, PSTHplotCount, levels, frequencies) + +% show PSTH for each level/frequency combination +nLevels=length(levels); +nFrequencies=length(frequencies); + +PSTHtime=method.PSTHbinWidth:method.PSTHbinWidth:method.PSTHbinWidth*length(PSTH); +subplot(nLevels,nFrequencies,PSTHplotCount) +bar(PSTHtime, PSTH) +xlim([0 max(PSTHtime)]) +% write axis labels only at left and bottom +if PSTHplotCount< (nLevels-1) * nFrequencies+1 + set(gca,'xticklabel',[]) +end +if ~isequal(mod(PSTHplotCount,nFrequencies),1) + set(gca,'yticklabel',[]) +else + ylabel([num2str(levels(round(PSTHplotCount/nFrequencies) +1)) ' dB']) +end +% add titles only on top row +if PSTHplotCount<=nFrequencies + title([num2str(frequencies(PSTHplotCount)) ' Hz']) +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testRP.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,207 @@ +function testRP(BFs,MAPparamsName,paramChanges) +% testIHC used for IHC I/O function + +global experiment method inputStimulusParams +global stimulusParameters IHC_VResp_VivoParams IHC_cilia_RPParams +savePath=path; +addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) +dbstop if error + +figure(4), clf, +set (gcf, 'name', ['IHC']) +set(gcf,'position',[613 354 360 322]) +drawColors='rgbkmcy'; +drawnow + +if nargin<3, paramChanges=[]; end + +levels=-20:10:100; +nLevels=length(levels); +toneDuration=.05; +silenceDuration=.01; +sampleRate=50000; +dt=1/sampleRate; + +allIHC_RP_peak=[]; +allIHC_RP_dc=[]; + +changes{1}=[]; +% changes{1}='IHC_cilia_RPParams.Et= 0.100;'; +% changes{2}='IHC_cilia_RPParams.Et= 0.070;'; + +for changeNo=1:length(changes) + if isempty(changes{1}) + paramChanges=[]; + else + paramChanges{1}=changes{changeNo}; + end +for BFno=1:length(BFs) + BF=BFs(BFno); + targetFrequency=BF; + % OR + %Patuzzi and Sellick test (see ELP & AEM, 2006) + % targetFrequency=100; + + IHC_RP_peak=zeros(nLevels,1); + IHC_RP_min=zeros(nLevels,1); + IHC_RP_dc=zeros(nLevels,1); + + time=dt:dt:toneDuration; + + rampDuration=0.004; + rampTime=dt:dt:rampDuration; + ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(time)-length(rampTime))]; + ramp=ramp.*fliplr(ramp); + + silence=zeros(1,round(silenceDuration/dt)); + + toneStartptr=length(silence)+1; + toneMidptr=toneStartptr+round(toneDuration/(2*dt)) -1; + toneEndptr=toneStartptr+round(toneDuration/dt) -1; + + levelNo=0; + for leveldB=levels + levelNo=levelNo+1; + % replicate at all levels + amp=28e-6*10^(leveldB/20); + + %% create signal (leveldB/ frequency) + inputSignal=amp*sin(2*pi*targetFrequency'*time); + inputSignal= ramp.*inputSignal; + inputSignal=[silence inputSignal silence]; + inputStimulusParams.sampleRate=1/dt; +% global IHC_ciliaParams + + %% disable efferent for fast processing + method.DRNLSave=1; + method.IHC_cilia_RPSave=1; + method.IHCpreSynapseSave=1; + method.IHC_cilia_RPSave=1; + method.segmentDuration=-1; + moduleSequence=1:4; + + %% run the model + global DRNLoutput IHC_cilia_output IHCrestingCiliaCond IHCrestingV... + IHCoutput + AN_spikesOrProbability='probability'; + + MAP1_14(inputSignal, sampleRate, BF, ... + MAPparamsName, AN_spikesOrProbability, paramChanges); + + % DRNL + DRNLoutput=DRNLoutput; + DRNL_peak(levelNo,1)=max(DRNLoutput(toneMidptr:toneEndptr)); + DRNL_min(levelNo,1)=min(DRNLoutput(toneMidptr:toneEndptr)); + DRNL_dc(levelNo,1)=mean(DRNLoutput(toneMidptr:toneEndptr)); + + % cilia + IHC_ciliaData=IHC_cilia_output; + IHC_ciliaData=IHC_ciliaData; + IHC_cilia_peak(levelNo,1)=... + max(IHC_ciliaData(toneMidptr:toneEndptr)); + IHC_cilia_min(levelNo,1)=... + min(IHC_ciliaData(toneMidptr:toneEndptr)); + IHC_cilia_dc(levelNo,1)=... + mean(IHC_ciliaData(toneMidptr:toneEndptr)); + + % RP + IHC_RPData=IHCoutput; + IHC_RPData=IHC_RPData; + IHC_RP_peak(levelNo,1)=... + max(IHC_RPData(toneMidptr:toneEndptr)); + IHC_RP_min(levelNo,1)=... + min(IHC_RPData(toneMidptr:toneEndptr)); + IHC_RP_dc(levelNo,1)=... + mean(IHC_RPData(toneMidptr:toneEndptr)); + + end % level + + + disp(['parameter file was: ' MAPparamsName]) + fprintf('\n') + + %% plot DRNL + subplot(2,2,1) +% referenceDisp= 9e-9*1000/targetFrequency; +% plot(levels,20*log10(DRNL_peak/referenceDisp), drawColors(BFno), ... +% 'linewidth',2), hold on + referenceDisp=10e-9; + plot(levels,20*log10(DRNL_peak/referenceDisp), drawColors(BFno), ... + 'linewidth',2), hold on + title([' DRNL peak: ' num2str(BFs) ' Hz']) + ylabel ('log10DRNL(m)'), xlabel('dB SPL') + xlim([min(levels) max(levels)]), ylim([-10 50]) + grid on + + %% plot cilia displacement + figure(4) + subplot(2,2,2) + restingIHC_cilia=IHCrestingCiliaCond; + plot(levels, IHC_cilia_peak,'k', 'linewidth',2), hold on + plot(levels, IHC_cilia_min,'r', 'linewidth',2) + hold on, + plot([min(levels) max(levels)], ... + [restingIHC_cilia restingIHC_cilia], 'g') + title(' IHC apical cond.') + ylabel ('IHCcilia(conductance)'), xlabel('dB SPL') + xlim([min(levels) max(levels)]) + grid on + + %% plot receptor potentials + figure(4) + subplot(2,2,3) + % RP I/O function min and max + restingRP=IHC_RP_peak(1); + toPlot= [fliplr(IHC_RP_min(:,1)') IHC_RP_peak(:,1)']; + microPa= 28e-6*10.^(levels/20); + microPa=[-fliplr(microPa) microPa]; + plot(microPa,toPlot, drawColors(BFno), 'linewidth',2) + % ylim([0 300]) + + %% Dallos and Harris data + dallosx=[-0.9 -0.1 -0.001 0.001 0.01 0.9]; + dallosy=[-8 -7.8 -6.5 11 16.5 22]/1000 + restingRP; + hold on, plot(dallosx,dallosy, 'o') + plot([-1 1], [restingRP restingRP], 'r') + title(' Dallos(86) data at 800 Hz') + ylabel ('receptor potential(V)'), xlabel('Pa') + ylim([-0.08 -0.02]), xlim([-1 1]) + grid on + + %% RP I/O function min and max + figure(4) + subplot(2,2,4) + restingRP=IHC_RP_peak(1); + peakRP=max(IHC_RP_peak); + plot(levels, IHC_RP_peak,drawColors(BFno), 'linewidth',2) + hold on + plot(levels, IHC_RP_dc, [drawColors(BFno) ':'], 'linewidth',2) + hold on, + plot([min(levels) max(levels)], [restingRP restingRP], 'r') + xlim([min(levels) max(levels)]) + grid on + title(['Et= ' num2str(IHC_cilia_RPParams.Et) ': RP (AC- / DC:']) + ylabel ('RP(V)'), xlabel('dB SPL') + ylim([-0.08 -0.02]) + allIHC_RP_peak=[allIHC_RP_peak IHC_RP_peak]; + allIHC_RP_dc=[allIHC_RP_dc IHC_RP_dc]; + + fprintf('level\t peak\t DC\n') + UTIL_printTabTable([levels' IHC_RP_peak IHC_RP_dc]) + % disp(['restingIHC_cilia= ' num2str(restingIHC_cilia)]) + fprintf('peakRP= \t%6.3f', peakRP) + fprintf('\nrestingRP= \t%6.3f', restingRP) + fprintf('\ndifference= \t%6.3f\n', (peakRP-restingRP)) + drawnow +end +end +% UTIL_showStruct(IHC_VResp_VivoParams, 'IHC_VResp_VivoParams') +UTIL_showStruct(IHC_cilia_RPParams, 'IHC_cilia_RPParams') + fprintf('level\t peak\n') + UTIL_printTabTable([levels' allIHC_RP_peak]) + fprintf('level\t DC\n') + UTIL_printTabTable([levels' allIHC_RP_dc]) + +path(savePath); +disp(paramChanges)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Copy_of_multithreshold 1.46/testSynapse.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,89 @@ +function testSynapse +% testSynapse tracks the quantity of available transmitter vesicles +% the computations are single channel using the first frequency +% in the targetFrequency box of the expGUI. +% For, speed this function uses only probability and HSR fibers. +% This cannot be changed because of the way AN_IHCsynapse is coded.This). + +global experiment method IHCpreSynapseParams +global AN_IHCsynapseParams stimulusParameters +savePath=path; +addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) + +figure(6),clf +plotColors='rbgkrbgkrbgkrbgkrbgkrbgk'; +set(gcf,'position',[5 32 264 243]) + +sampleRate=5e4; dt=1/sampleRate; + +maskerLevels=-0:10:100; + +BFlist=stimulusParameters.targetFrequency(1); +targetFrequency=stimulusParameters.targetFrequency; +targetFrequency=targetFrequency(1); % only one frequency used + +showParams=0; +useEfferent=0; % no efferent + +silenceDuration=0.005; +silenceDuration=0.015; +maskerDuration=0.1; +recoveryDuration=0.15; +rampDuration=0.004; + +maskerTime=dt:dt:maskerDuration; + +rampTime=dt:dt:rampDuration; +ramp=[0.5*(1+cos(2*pi*rampTime/(2*rampDuration)+pi)) ... + ones(1,length(maskerTime)-length(rampTime))]; +ramp=ramp.*fliplr(ramp); + +initialSilence=zeros(1,round(silenceDuration/dt)); +recoverySilence=zeros(1,round(recoveryDuration/dt)); + +signal=sin(2*pi*targetFrequency'*maskerTime); +signal= ramp.*signal; +signal=[initialSilence signal recoverySilence]; + +levelCount=0; +qtMatrix=[]; +for leveldB=maskerLevels + levelCount=levelCount+1; + + amp=28e-6*10^(leveldB/20); + inputSignal=amp*signal; + + AN_spikesOrProbability='probability'; + MAPparamsName=experiment.name; + showPlotsAndDetails=0; + + global savePavailable + + MAP1_14(inputSignal, 1/dt, targetFrequency, ... + MAPparamsName, AN_spikesOrProbability); + + % ignore LSR channels (if any) at the top of the matrix + qt=savePavailable(end, :); + + synapsedt=dt; + time=synapsedt:synapsedt:synapsedt*length(qt); + + figure(6) + qtMatrix=[qtMatrix; qt]; + plot(time,qt, plotColors(levelCount)) + hold on + xlim([0 max(time)]) + ylim([0 AN_IHCsynapseParams.M]) +end + +set(gcf,'name','pre-synaptic available transmitter') +title(['q - available vesicles:' num2str(BFlist) ' Hz']) +legend(strvcat(num2str(maskerLevels')),'location','southeast') +legend boxoff +grid on + +figure(88), [c,H]=contour(time, maskerLevels,qtMatrix); clabel(c, H); +set(gcf,'position',[ 276 31 328 246]) +xlabel('time'), ylabel('maskerLevels') + +path(savePath);
--- a/MAP/MAP1_14.m Wed Jun 22 12:02:45 2011 +0100 +++ b/MAP/MAP1_14.m Fri Jul 01 12:59:47 2011 +0100 @@ -5,15 +5,13 @@ % % All arguments are mandatory. % -% BFlist is a list of BFs but can be '-1' to allow MAPparams to choose -% - -% MAPparamsName='Normal'; % source of model parameters +% BFlist is a vector of BFs but can be '-1' to allow MAPparams to choose +% MAPparamsName='Normal'; % source of model parameters % AN_spikesOrProbability='spikes'; % or 'probability' % paramChanges is a cell array of strings that can be used to make last % minute parameter changes, e.g., to simulate OHC loss -% paramChanges{1}= 'DRNLParams.a=0;'; - +% e.g. paramChanges{1}= 'DRNLParams.a=0;'; % disable OHCs +% e.g. paramchanges={}; % no changes % The model parameters are established in the MAPparams<***> file % and stored as global @@ -60,11 +58,11 @@ paramChanges=[]; end % Read parameters from MAPparams<***> file in 'parameterStore' folder +% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<> +% It means that the calling program allows MAPparams to specify the list cmd=['method=MAPparams' MAPparamsName ... '(BFlist, sampleRate, 0, paramChanges);']; eval(cmd); -% Beware, 'BFlist=-1' is a legitimate argument for MAPparams<> -% if the calling program allows MAPparams to specify the list BFlist=DRNLParams.nonlinCFs; % save as global for later plotting if required
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multithreshold 1.46/UTIL_testPhysiology.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,11 @@ +function UTIL_testPhysiology(BF) +testOME('Normal') +relativeFrequencies=[0.25 .5 .75 1 1.25 1.5 2]; +testBM (BF, 'Normal',relativeFrequencies) +testRP(BF,'Normal') +testSynapse(BF,'Normal') +testFM(BF,'Normal',1) +testPhaseLocking +testAN(BF,BF, 10:10:80); +figure(14) +figure(15)
--- a/multithreshold 1.46/expGUI_MT.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/expGUI_MT.m Fri Jul 01 12:59:47 2011 +0100 @@ -46,7 +46,7 @@ % Edit the above text to modify the response to help expGUI_MT -% Last Modified by GUIDE v2.5 29-May-2011 16:02:02 +% Last Modified by GUIDE v2.5 25-Jun-2011 21:41:35 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -610,59 +610,99 @@ % ------------------------------------------------ pushbuttonRun_Callback function pushbuttonRun_Callback(hObject, eventdata, handles) global checkForPreviousGUI % holds screen positioning across repeated calls -global experiment betweenRuns paradigmNames +global experiment betweenRuns paradigmNames errormsg checkForPreviousGUI.GUIposition=get(handles.figure1,'position'); experiment.singleShot=0; switch experiment.paradigm - case 'thr_IFMC' - %% special option for two successive and linked measurements - clc - experiment.paradigm='threshold_16ms'; - set(handles.editstopCriteriaBox,'string','30') % nTrials - run (handles) - - % use these threshold for IFMC - thresholds16ms=betweenRuns.thresholds; - optionNo=strmatch('IFMC_16ms',paradigmNames); - set(handles.popupmenuParadigm,'value',optionNo); - aParadigmSelection(handles) - set(handles.edittargetLevel,'string', thresholds16ms+10); - set(handles.editstopCriteriaBox,'string','30') % nTrials - pause(.1) - run (handles) - - % reset original paradigm - optionNo=strmatch('thr_IFMC',paradigmNames); - set(handles.popupmenuParadigm,'value',optionNo); - aParadigmSelection(handles) - - case 'thr_TMC' + case 'profile' %% special option for two successive and linked measurements clc experiment.paradigm='threshold_16ms'; set(handles.edittargetDuration,'string', num2str(0.25)) - set(handles.editstopCriteriaBox,'string','30') % nTrials + set(handles.editstopCriteriaBox,'string','10') % nTrials run (handles) + if ~isempty(errormsg) + disp(errormsg) + optionNo=strmatch('profile',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + experiment.paradigm='profile'; + aParadigmSelection(handles) + return + end + + global resultsTable + longTone=resultsTable(2:end,2:end); + set(handles.edittargetDuration,'string', num2str(0.016)) - set(handles.editstopCriteriaBox,'string','30') % nTrials + set(handles.editstopCriteriaBox,'string','10') % nTrials run (handles) + if ~isempty(errormsg) + disp(errormsg) + optionNo=strmatch('profile',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + experiment.paradigm='profile'; + experiment.stop=-0; + aParadigmSelection(handles) + return + end + + shortTone=resultsTable(2:end,2:end); % use these threshold for TMC thresholds16ms=betweenRuns.thresholds; - optionNo=strmatch('TMC_16ms',paradigmNames); + optionNo=strmatch('TMC',paradigmNames); set(handles.popupmenuParadigm,'value',optionNo); aParadigmSelection(handles) set(handles.edittargetLevel,'string', thresholds16ms+10); - set(handles.editstopCriteriaBox,'string','30') % nTrials + set(handles.editstopCriteriaBox,'string','10') % nTrials pause(.1) run (handles) + if ~isempty(errormsg) + disp(errormsg) + optionNo=strmatch('profile',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + experiment.paradigm='profile'; + experiment.stop=-0; + aParadigmSelection(handles) + return + end + + TMC=resultsTable(2:end,2:end); + gaps=resultsTable(2:end,1); + BFs=resultsTable(1, 2:end); + + % use these threshold for IFMC + optionNo=strmatch('IFMC',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + aParadigmSelection(handles) + set(handles.edittargetLevel,'string', thresholds16ms+10); + set(handles.editstopCriteriaBox,'string','10') % nTrials + pause(.1) + run (handles) + + if ~isempty(errormsg) + disp(errormsg) + optionNo=strmatch('profile',paradigmNames); + set(handles.popupmenuParadigm,'value',optionNo); + experiment.paradigm='profile'; + experiment.stop=-0; + aParadigmSelection(handles) + return + end + + IFMCs=resultsTable(2:end,2:end); + offBFs=resultsTable(2:end,1); + % reset original paradigm - optionNo=strmatch('thr_TMC',paradigmNames); + optionNo=strmatch('profile',paradigmNames); set(handles.popupmenuParadigm,'value',optionNo); aParadigmSelection(handles) + save profile longTone shortTone gaps BFs TMC offBFs IFMCs + plotProfile(longTone,shortTone,gaps,BFs,TMC,offBFs,IFMCs) + otherwise run (handles) experiment.stop=0; @@ -673,6 +713,7 @@ tic expGUIhandles=handles; set(handles.pushbuttonStop, 'backgroundColor', [.941 .941 .941]) +set(handles.editparamChanges,'visible','off') % message box white (removes any previous error message) set(handles.textMSG,... @@ -1030,11 +1071,14 @@ option=get(handles.popupmenuEar,'value'); options=get(handles.popupmenuEar,'string'); % left/right/model experiment.ear=options{option}; +set(handles.editparamChanges,'visible','off') switch experiment.ear case 'statsModelLogistic' set(handles.editStatsModel,'string', '15, 0.5') case 'statsModelRareEvent' set(handles.editStatsModel,'string', '20 1') + case {'MAPmodelListen', 'MAPmodelMultiCh', 'MAPmodelSingleCh'} + set(handles.editparamChanges,'visible','on') end earSetUp(handles) @@ -1355,13 +1399,17 @@ drawnow function pushbuttonOME_Callback(hObject, eventdata, handles) +global experiment aReadAndCheckParameterBoxes(handles); -testOME +testOME(experiment.name); function pushbuttonBM_Callback(hObject, eventdata, handles) global stimulusParameters experiment aReadAndCheckParameterBoxes(handles); -testBM(stimulusParameters.targetFrequency, experiment.name); +relativeFrequencies=[0.25 .5 .75 1 1.25 1.5 2]; + +testBM(stimulusParameters.targetFrequency, ... + experiment.name,relativeFrequencies); function pushbuttonAN_Callback(hObject, eventdata, handles) global stimulusParameters @@ -1382,8 +1430,10 @@ testSynapse function pushbuttonFM_Callback(hObject, eventdata, handles) +global stimulusParameters experiment aReadAndCheckParameterBoxes(handles); -testFM +showPSTHs=1; +testFM(stimulusParameters.targetFrequency(1),experiment.name, showPSTHs) function popupmenuPhase_Callback(hObject, eventdata, handles) global stimulusParameters @@ -1399,8 +1449,11 @@ aReadAndCheckParameterBoxes(handles); % print model parameters using the 'name' box (e.g. CTa -> MAPparamsCTa) showParams=1; BFlist=-1; +paramChanges=get(handles.editparamChanges,'string'); +eval(paramChanges) + paramFunctionName=['method=MAPparams' experiment.name ... - '(BFlist, stimulusParameters.sampleRate, showParams);']; + '(BFlist, stimulusParameters.sampleRate, showParams,paramChanges);']; eval(paramFunctionName) % go and fetch the parameters requesting parameter printout @@ -1703,3 +1756,17 @@ + + +function editparamChanges_Callback(hObject, eventdata, handles) + + +function editparamChanges_CreateFcn(hObject, eventdata, handles) + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +
--- a/multithreshold 1.46/nextStimulus.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/nextStimulus.m Fri Jul 01 12:59:47 2011 +0100 @@ -2,7 +2,7 @@ % Handles everything concerned with the stimulus presentation % called from startNewRun in subjGUI -global experiment stimulusParameters withinRuns betweenRuns +global experiment stimulusParameters withinRuns experiment.status='presentingStimulus'; errormsg=''; @@ -10,7 +10,8 @@ if experiment.stop disp('******** experiment manually stopped *****************') experiment.status= 'waitingForStart'; - addToMsg('manually stopped',1) + errormsg='manually stopped'; + addToMsg(errormsg,1) return end
--- a/multithreshold 1.46/paradigms/paradigm_TMC.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/paradigms/paradigm_TMC.m Fri Jul 01 12:59:47 2011 +0100 @@ -13,7 +13,7 @@ withinRuns.direction='up'; betweenRuns.variableName1='gapDuration'; -betweenRuns.variableList1=[.05 .08 .02 .06 .04 ]; +betweenRuns.variableList1=[.05 .09 .01 .07 .03 ]; betweenRuns.variableName2='targetFrequency'; % retain existing targetFrequencies betweenRuns.variableList2=str2num(get(handles.edittargetFrequency,'string'));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multithreshold 1.46/paradigms/paradigm_profile.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,36 @@ +function paradigm_profile(handles) +global stimulusParameters experiment betweenRuns + +paradigm_training(handles) % default + +betweenRuns.variableName1='targetFrequency'; +betweenRuns.variableList1=[250 500 1000 2000 4000 8000 ]; +betweenRuns.variableList1=str2num(get(handles.edittargetFrequency,'string')); +betweenRuns.variableName2='targetDuration'; +betweenRuns.variableList2=0.016; +betweenRuns.randomizeSequence=1; % 'random sequence' + +% delay > masker > gap > target + + +stimulusParameters.targetType='tone'; +stimulusParameters.targetPhase='sin'; +stimulusParameters.targetFrequency=1000; +stimulusParameters.targetDuration=0.016; +stimulusParameters.targetLevel=stimulusParameters.WRVstartValues(1); + +stimulusParameters.rampDuration=0.004; + +experiment.stopCriteria2IFC=[75 3 5]; +experiment.singleIntervalMaxTrials=[20]; + + +% forced choice window interval +stimulusParameters.AFCsilenceDuration=0.5; + +% instructions to user +% single interval up/down no cue +stimulusParameters.instructions{1}= [{'YES if you hear the tone clearly'}, { }, { 'NO if not (or you are uncertain'}]; +% single interval up/down with cue +stimulusParameters.instructions{2}= [{'count the tones you hear clearly'}, { }, { 'ignore indistinct tones'}]; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multithreshold 1.46/plotProfile.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,71 @@ +function plotProfile(longTone,shortTone,gaps,BFs,TMC,offBFs,IFMCs) + +%% plot profile +if nargin<1 + load profile +end + +normLongTone=[ 11.4 1.55 -13.5 -6.35 -6.4 7.45]; +normShortTone=[ 23.85 18.9 9.85 10.6 9.55 21.9]; + +normGaps=0.01:0.01:0.09; +normTMC= [ +28.5 35.0 49.3 70.1 80.5 85.5 NaN NaN NaN; +31.1 44.3 48.4 59.5 56.4 76.7 70.2 82.4 76.3; +33.4 38.4 48.8 55.8 64.5 78.7 84.2 88.3 90.3; +25.4 37.0 49.2 49.7 58.2 69.6 87.7 95.8 93.0; +18.2 23.5 27.4 41.5 64.3 82.1 86.7 91.2 NaN; +32.5 35.8 43.5 52.1 69.1 78.6 86.6 86.0 NaN; + ]; +normTMC=normTMC'; + +normIFMC=[ +50 42 34 35 34 33 37; +58 51 38 33 28 41 49; +57 41 27 20 28 37 66; +61 49 27 20 34 68 79; +67 45 27 22 46 74 87; +62 62 43 22 47 56 83; +]; +normIFMC=normIFMC'; + +% absolute thresholds +figure(90), clf +subplot(2,1,2) +semilogx(BFs,longTone,'ko-','lineWidth',2); hold on +semilogx(BFs,shortTone,'bo-','lineWidth',2); hold on +semilogx(BFs,normLongTone,'ko:'); hold on +semilogx(BFs,normShortTone,'bo:'); hold on +ylim([0 100]) + +% TMC +for BFno=1:length(BFs) + subplot(2,6,BFno) + plot(gaps,TMC(:,BFno)-longTone(BFno),'r','lineWidth',3), hold on + plot(normGaps,normTMC(:,BFno)-longTone(BFno),'k:') + ylim([-10 90]) + xlim([0.01 0.1]) + grid on + if BFno==1 + ylabel('masker dB SL') + xlabel('gap') + text(0.02,80,' TMC','backgroundColor','w') + end + title([num2str(BFs(BFno)) ' Hz']) + set(gca,'XTick',[ 0.1],'xTickLabel', { '0.1'}) +end + +% IFMCs +for BFno=1:length(BFs) + BF=BFs(BFno); + freq=offBFs'*BFs(BFno); + subplot(2,1,2) + semilogx(freq,IFMCs(:,BFno),'r','lineWidth',3), hold on + semilogx(freq,normIFMC(:,BFno),'k:') + ylim([0 100]) + xlim([100 12000]) + grid on +end +xlabel('frequency (Hz)') +ylabel('masker dB / probe dB') +set(gca,'XTick',BFs)
--- a/multithreshold 1.46/printReport.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/printReport.m Fri Jul 01 12:59:47 2011 +0100 @@ -78,8 +78,10 @@ headers=strvcat([header1 '/'], header2); disp('thresholds') -msg=printTabTable(sortTablesForPrinting(idx1,idx2,... - var1values,var2values, betweenRuns.thresholds), headers); +global resultsTable +resultsTable= sortTablesForPrinting(idx1,idx2,... + var1values,var2values, betweenRuns.thresholds); +msg=printTabTable(resultsTable, headers); addToMsg(msg,0) fprintf('\n')
--- a/multithreshold 1.46/subjGUI_MT.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/subjGUI_MT.m Fri Jul 01 12:59:47 2011 +0100 @@ -35,7 +35,7 @@ function initializeGUI(handles) global experiment global subjectGUIHandles expGUIhandles - addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... +addpath (['..' filesep 'MAP'], ['..' filesep 'utilities'], ... ['..' filesep 'parameterStore'], ['..' filesep 'wavFileStore'],... ['..' filesep 'testPrograms']) @@ -52,9 +52,7 @@ set(gcf, 'units','pixels') y=[0*scrnsize(3) 0.8*scrnsize(4) 0.1*scrnsize(3) 0.2*scrnsize(4)]; set(gcf,'position',y, 'color',[.871 .961 .996]) - - case 'MAPmodelListen', % subjectGUI is needed for display purposes. Make it large set(gcf, 'units','pixels') @@ -69,74 +67,8 @@ buttonBoxIntitialize % harmless if no button box attached end -% function varargout = subjGUI_MT(varargin) -% -% % Begin initialization code - DO NOT EDIT -% gui_Singleton = 1; -% gui_State = struct('gui_Name', mfilename, ... -% 'gui_Singleton', gui_Singleton, ... -% 'gui_OpeningFcn', @subjGUI_MT_OpeningFcn, ... -% 'gui_OutputFcn', @subjGUI_MT_OutputFcn, ... -% 'gui_LayoutFcn', [] , ... -% 'gui_Callback', []); -% if nargin && isstr(varargin{1}) -% gui_State.gui_Callback = str2func(varargin{1}); -% end -% -% if nargout -% [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); -% else -% gui_mainfcn(gui_State, varargin{:}); -% end -% % End initialization code - DO NOT EDIT -% -% % --- Executes just before subjGUI_MT is made visible. -% function subjGUI_MT_OpeningFcn(hObject, eventdata, handles, varargin) -% -% % Choose default command line output for subjGUI_MT -% handles.output = hObject; -% initializeGUI(handles) -% guidata(hObject, handles); -% -% function varargout = subjGUI_MT_OutputFcn(hObject, eventdata, handles) -% % Get default command line output from handles structure -% varargout{1} = handles.output; -% -% % -----------------------------------------------------initializeGUI -% function initializeGUI(handles) -% global experiment -% global subjectGUIHandles expGUIhandles -% -% dbstop if error -% -% % subjectGUI size and location % [left bottom width height] -% scrnsize=get(0,'screensize'); -% set(0, 'units','pixels') -% switch experiment.ear -% % use default size unless... -% case {'MAPmodel', 'MAPmodelMultiCh','MAPmodelSingleCh', ... -% 'statsModelLogistic','statsModelRareEvent'} -% % subjectGUI not needed for modelling so minimize subject GUI -% set(gcf, 'units','pixels') -% y=[0*scrnsize(3) 0.8*scrnsize(4) 0.1*scrnsize(3) 0.2*scrnsize(4)]; -% set(gcf,'position',y, 'color',[.871 .961 .996]) -% -% case 'MAPmodelListen', -% % subjectGUI is needed for display purposes. Make it large -% set(gcf, 'units','pixels') -% y=[.665*scrnsize(3) 0.02*scrnsize(4) ... -% 0.33*scrnsize(3) 0.5*scrnsize(4)]; % alongside -% set(gcf,'position',y, 'color',[.871 .961 .996]) -% end -% -% switch experiment.ear -% case{'left', 'right','diotic', 'dichoticLeft','dichoticRight'} -% % Look to see if the button box exists and, if so, initialise it -% buttonBoxIntitialize % harmless if no button box attached -% end - % clear display of previous mean values. This is a new measurement series -axes(expGUIhandles.axes4), cla +axes(expGUIhandles.axes4), cla reset (expGUIhandles.axes4) % handles needed in non-callback routines below @@ -182,7 +114,7 @@ set(handles.pushbutton2,'string','uncomfortable') set(handles.pushbutton1,'string','loud') set(handles.pushbutton0,'string','comfortable') - experiment.allowCatchTrials=0; + experiment.allowCatchTrials=0; end % experiment.subjGUIfontSize is set on expGUI @@ -209,13 +141,13 @@ experiment.buttonBoxStatus='not busy'; % date and time and replace ':' with '_' -date=datestr(now);idx=findstr(':',date);date(idx)='_'; +date=datestr(now);idx=findstr(':',date);date(idx)='_'; experiment.date=date; timeNow=clock; betweenRuns.timeNow= timeNow; experiment.timeAtStart=[num2str(timeNow(4)) ':' num2str(timeNow(5))]; -experiment.minElapsed=0; +experiment.minElapsed=0; -% unpack catch trial rates. The rate declines from the start rate +% unpack catch trial rates. The rate declines from the start rate % to the base rate using a time constant. stimulusParameters.catchTrialRate=stimulusParameters.catchTrialRates(1); stimulusParameters.catchTrialBaseRate=... @@ -265,7 +197,7 @@ nVar1=length(variableList1); nVar2=length(variableList2); -% Create two sequence vectors to represent the sequence of var1 and var2 +% Create two sequence vectors to represent the sequence of var1 and var2 % values. 'var1' changes most rapidly. switch betweenRuns.randomizeSequence case 'fixed sequence' @@ -289,8 +221,8 @@ [x idx]=sort(ranNums); var1Sequence=var1Sequence(idx); var2Sequence=var2Sequence(idx); - % there should be one start value for every combination - % of var1/ var2. In principle this allows these values to be + % there should be one start value for every combination + % of var1/ var2. In principle this allows these values to be % programmed. Not currently in use. stimulusParameters.WRVstartValues=... stimulusParameters.WRVstartValues(idx); @@ -304,14 +236,14 @@ disp('planned sequence:') if min(var1Sequence)>1 % use decidaml places only if necessary -disp([betweenRuns.variableName1 ': ' num2str(var1Sequence,'%6.0f') ]) + disp([betweenRuns.variableName1 ': ' num2str(var1Sequence,'%6.0f') ]) else -disp([betweenRuns.variableName1 ': ' num2str(var1Sequence,'%8.3f') ]) + disp([betweenRuns.variableName1 ': ' num2str(var1Sequence,'%8.3f') ]) end if min(var1Sequence)>1 -disp([betweenRuns.variableName2 ': ' num2str(var2Sequence,'%6.0f') ]) + disp([betweenRuns.variableName2 ': ' num2str(var2Sequence,'%6.0f') ]) else -disp([betweenRuns.variableName2 ': ' num2str(var2Sequence,'%8.3f') ]) + disp([betweenRuns.variableName2 ': ' num2str(var2Sequence,'%8.3f') ]) end fprintf('\nvariable1 \t variable2\t \n') @@ -331,7 +263,7 @@ set(handles.textMSG,'backgroundcolor', 'w') msg=[{'Ready to start new Experiment'}, {' '}, {'Please, click on the GO button'}]; set(handles.textMSG,'string', msg) - + set(handles.pushbuttoNotSure,'visible','off') set(handles.pushbuttonWrongButton,'visible','off') set(handles.pushbutton3,'visible','off') @@ -350,9 +282,9 @@ stimulusParameters.calibrationdB=0; % Pascals required! MAPmodelRunsGUI(handles) % model is now the subject - case {'statsModelLogistic', 'statsModelRareEvent'} + case {'statsModelLogistic', 'statsModelRareEvent'} % no catch trials for the statistical model - stimulusParameters.catchTrialBaseRate=0; + stimulusParameters.catchTrialBaseRate=0; stimulusParameters.catchTrialRate=0; statsModelRunsGUI(handles) otherwise @@ -372,7 +304,7 @@ % MAP and randomization methods call this too global experiment stimulusParameters betweenRuns withinRuns expGUIhandles -global LevittControl rareEvent +global LevittControl rareEvent errormsg figure(handles.figure1) % guarantee subject GUI visibility @@ -447,12 +379,6 @@ errormsg=nextStimulus(handles); % get the show on the road -% switch experiment.paradigm -% case 'SRT' -% set(handles.editdigitInput,'visible','on') -% uicontrol(handles.editdigitInput) -% end - % terminate if there is any kind of problem if ~isempty(errormsg) % e.g. limits exceeded, clipping @@ -460,11 +386,12 @@ runCompleted(handles) return end - % return route is variable (see intro to this function) % -----------------------------------------------------buttonBox_callback function buttonBox_callback(obj, info) +% deals with a button press on the button box. + global experiment global serobj global subjectGUIHandles @@ -472,10 +399,9 @@ % do not accept callback if one is already in process if strcmp(experiment.buttonBoxStatus,'busy') disp(' ignored button press') - return + return % to quiescent state end experiment.buttonBoxStatus='busy'; -% fclose(serobj) % identify the code of the button pressed buttonPressedNo = fscanf(serobj,'%c',1); @@ -483,12 +409,12 @@ % This is the map from the button to the Cedrus codes switch experiment.buttonBoxType case 'horizontal' - pbGo='7'; pb0='1'; - pb1='2'; pb2='3'; + pbGo='7'; pb0='1'; + pb1='2'; pb2='3'; pbRepeat='4'; pbWrong='6'; pbBlank='5'; case 'square' - pbGo='7'; pb0='1'; - pb1='3'; pb2='4'; + pbGo='7'; pb0='1'; + pb1='3'; pb2='4'; pbRepeat='8'; pbWrong='6'; pbBlank='5'; end @@ -497,7 +423,7 @@ case {'presentingStimulus', 'waitingForStart', 'trialcompleted', ... 'endOfExperiment'} disp(' ignored button press') - + case 'waitingForGO' % i.e. waiting for new run if strcmp(buttonPressedNo,pbGo) % only GO button accepted @@ -505,7 +431,7 @@ else disp(' ignored button press') end - + case 'waitingForResponse' % response to stimuli switch buttonPressedNo @@ -522,11 +448,11 @@ 'defaultUicontrolBackgroundColor')) userSelects0or1(subjectGUIHandles) end - + case pb1 % button 1 (bottom left) switch experiment.threshEstMethod case {'2I2AFC++', '2I2AFC+++'} - userSelects0or1(subjectGUIHandles) + userSelects0or1(subjectGUIHandles) otherwise set(subjectGUIHandles.pushbutton1,... 'backgroundcolor','r') @@ -536,7 +462,7 @@ 'defaultUicontrolBackgroundColor')) userSelects0or1(subjectGUIHandles) end - + case pb2 % button 2 (bottom right) switch experiment.threshEstMethod case {'2I2AFC++', '2I2AFC+++'} @@ -550,13 +476,13 @@ 'defaultUicontrolBackgroundColor')) userSelects2 (subjectGUIHandles) end - + case pbRepeat % extreme right button switch experiment.threshEstMethod case {'2I2AFC++', '2I2AFC+++'} disp(' ignored button press') otherwise - + set(subjectGUIHandles.pushbuttoNotSure,... 'backgroundcolor','r') pause(.1) @@ -565,10 +491,10 @@ 'defaultUicontrolBackgroundColor')) userSelectsPleaseRepeat (subjectGUIHandles) end - + case {pbWrong, pbBlank} disp(' ignored button press') - + otherwise % unrecognised button disp('ignored button press') end % end (button press number) @@ -576,11 +502,6 @@ disp('ignored button press') end % experiment status -% All processing returns through here. -% fopen(serobj); % flushes the input buffer - -% buttonPressedNo = fscanf(serobj,'%c',1); - % button box remains 'busy' until after the stimulus has been presented experiment.buttonBoxStatus='not busy'; @@ -599,7 +520,9 @@ % This is a mouse click path % ignore 0 button if 2I2AFC used -if findstr(experiment.threshEstMethod,'2I2AFC'), return, end +if findstr(experiment.threshEstMethod,'2I2AFC') + return % to quiescent state +end % userDoesNotHearTarget(handles) % only possible interpretation userDecides(handles, false) @@ -637,7 +560,7 @@ function userSelects0or1(handles) global experiment withinRuns -switch experiment.threshEstMethod +switch experiment.threshEstMethod case {'2I2AFC++', '2I2AFC+++'} switch withinRuns.stimulusOrder case 'targetFirst'; @@ -657,7 +580,7 @@ % ----------------------------------------------------- userSelects2 function userSelects2(handles) global experiment withinRuns -switch experiment.threshEstMethod +switch experiment.threshEstMethod case {'2I2AFC++', '2I2AFC+++'} switch withinRuns.stimulusOrder case 'targetSecond'; @@ -676,20 +599,21 @@ % ----------------------------------------------------- ---- userDecides function userDecides(handles, saidYes) global experiment stimulusParameters betweenRuns withinRuns -global rareEvent logistic psy levelsBinVector +global rareEvent logistic psy levelsBinVector errormsg if experiment.singleShot - return + return % not clear why this should be here end % ignore click if not 'waitingForResponse' if ~strcmp(experiment.status,'waitingForResponse') disp('ignored click') - return + return % to userSelects end % speech reception threshold if strcmp(stimulusParameters.targetType,'digitStrings') + % read triple digits from userGUI digitsInput=get(handles.editdigitInput,'string'); % must be three digits if ~(length(digitsInput)==3) @@ -697,27 +621,22 @@ set(handles.textMSG,'string', 'Wrong no of digits', ... 'BackgroundColor','r', 'ForegroundColor', 'w') set(handles.editdigitInput,'string','') - return end % obtain correct answer from file name x=stimulusParameters.digitString; idx=find(x=='O'); x(idx)='0'; % replace 'oh' with zero - disp([x ' ' digitsInput]) - if x==digitsInput - saidYes=1; + saidYes=1; % i.e. correct response else - saidYes=0; + saidYes=0; % i.e wrong response end -set(handles.editdigitInput,'string','') -set(handles.editdigitInput,'visible','off') -pause(0.1) + set(handles.editdigitInput,'string','') + set(handles.editdigitInput,'visible','off') + pause(0.1) end - - % no button presses accepted while processing experiment.status='processingResponse'; @@ -726,21 +645,21 @@ if saidYes disp('catch trial - caught out') withinRuns.caughtOut=withinRuns.caughtOut+1; - - % special: estimate caught out rate by allowing the trial + + % special: estimate caught out rate by allowing the trial % to continue after catch if stimulusParameters.catchTrialBaseRate==0.5 - % To use this facility, set the catchTrialRate and the + % To use this facility, set the catchTrialRate and the % catchTrialBaseRate both to 0.5 % update false positive rate betweenRuns.caughtOut(betweenRuns.runNumber)=... - withinRuns.caughtOut; + withinRuns.caughtOut; plotProgressThisTrial(handles) nextStimulus(handles); return end - - % Punishment: restart the trial + + % Punishment: caught out restarts the trial set(handles.frame1,'backgroundColor','r') set(handles.pushbuttonGO, ... 'visible','on', 'backgroundcolor','y') % and go again @@ -749,28 +668,29 @@ set(handles.textMSG,'string',msg) [y,fs]=wavread('ding.wav'); wavplay(y/100,fs) - - % raise catch trial rate temporarily. + + % raise catch trial rate temporarily. % this is normally reduced on each new trial (see GO) stimulusParameters.catchTrialRate=... stimulusParameters.catchTrialRate+0.1; - if stimulusParameters.catchTrialRate>0.5 - stimulusParameters.catchTrialRate=0.5; + if stimulusParameters.catchTrialRate>0.5 + stimulusParameters.catchTrialRate=0.5; end fprintf('stimulusParameters.catchTrialRate= %6.3f\n', ... stimulusParameters.catchTrialRate) - + betweenRuns.caughtOut(betweenRuns.runNumber)=... 1+betweenRuns.caughtOut(betweenRuns.runNumber); betweenRuns.runNumber=betweenRuns.runNumber-1; experiment.status='waitingForGO'; return % unwind and wait for button press else % (said No) - % user claims not to have heard target. fortunate as it was not - % present. So, repeat the stimulus (possibly with target) + % user claims not to have heard target. + % This is good as it was not present. + % So, repeat the stimulus (possibly with target) % and behave as if the last trial did not occur errormsg=nextStimulus(handles); - + % terminate if there is any kind of problem if ~isempty(errormsg) % e.g. limits exceeded, clipping @@ -780,9 +700,9 @@ end return % no further action - next trial end -end +end % of catch trial -% This section analyses the responses, makes tracks and defines next stim. +% Real target: analyse the response, make tracks and define next stim. % Define response and update response list if saidYes @@ -799,7 +719,7 @@ % identify direction of change during initial period if saidYes % default step size before first reversal - WRVinitialStep=-stimulusParameters.WRVinitialStep; + WRVinitialStep=-stimulusParameters.WRVinitialStep; WRVsmallStep=-stimulusParameters.WRVsmallStep; % if the previous direction was 'less difficult', this must be a peak if strcmp(withinRuns.direction,'less difficult') ... @@ -807,13 +727,12 @@ withinRuns.peaks=[withinRuns.peaks withinRuns.variableValue]; end withinRuns.direction='more difficult'; - else % said 'no' % default step size before first reversal - WRVinitialStep=stimulusParameters.WRVinitialStep; + WRVinitialStep=stimulusParameters.WRVinitialStep; WRVsmallStep=stimulusParameters.WRVsmallStep; - + % if the previous direction was 'up', this must be a peak if strcmp(withinRuns.direction,'more difficult') ... && length(withinRuns.levelList)>1 @@ -822,12 +741,11 @@ withinRuns.direction='less difficult'; end -% phase 2 is all the levels after and incuding the first reversal +% phase 2 is all the levels after and incuding the first reversal % plus the level before that +% Look for the end of phase 1 if ~withinRuns.nowInPhase2 && length(withinRuns.peaks)+ ... length(withinRuns.troughs)>0 -% if ~withinRuns.nowInPhase2 && (~isempty(withinRuns.peaks) ... -% || ~isempty(withinRuns.troughs)) % define phase 2 withinRuns.beginningOfPhase2=trialNumber-1; withinRuns.nowInPhase2=1; @@ -844,7 +762,6 @@ withinRuns.levelsPhaseTwo=[]; end - % get (or substitute) threshold estimate switch experiment.threshEstMethod case {'2I2AFC++', '2I2AFC+++'} @@ -854,13 +771,14 @@ bestFitPsychometicFunctions... (withinRuns.levelsPhaseTwo, withinRuns.responsesPhaseTwo); end - + if ~isempty(withinRuns.peaks) && ~isempty(withinRuns.troughs) thresholdEstimate= ... mean([mean(withinRuns.peaks) mean(withinRuns.troughs)]); else thresholdEstimate=NaN; end + otherwise % single interval methods try @@ -916,16 +834,16 @@ else [WRVinitialStep, msg]=Levitt2('miss',withinRuns.variableValue); end - + % empty message means continue as normal - if ~isempty(msg) + if ~isempty(msg) runCompleted(handles) return end newWRVvalue=withinRuns.variableValue-WRVinitialStep; - + case {'MaxLikelihood', 'oneIntervalUpDown'} - % run completed by virtue of number of trials + % run completed by virtue of number of trials % or restart because listener is in trouble if length(withinRuns.levelsPhaseTwo)== experiment.maxTrials % Use bonomial test to decide if there is an imbalance in the @@ -952,14 +870,14 @@ return end end - + % set new value for WRV if withinRuns.nowInPhase2 % phase 2 currentMeanEst=withinRuns.thresholdEstimateTrack(end); switch experiment.threshEstMethod case 'MaxLikelihood' - newWRVvalue=currentMeanEst; + newWRVvalue=currentMeanEst; case {'oneIntervalUpDown'} newWRVvalue=withinRuns.variableValue+WRVsmallStep; end @@ -1013,7 +931,7 @@ disp('ignored click') return end -% Take no action other than to make a +% Take no action other than to make a % tally of repeat requests experiment.pleaseRepeat=experiment.pleaseRepeat+1; withinRuns.thisIsRepeatTrial=1; @@ -1024,7 +942,7 @@ global withinRuns experiment % restart is the simplest solution for a 'wrong button' request withinRuns.wrongButton=withinRuns.wrongButton+1; -set(handles.pushbuttonGO, 'visible','on', 'backgroundcolor','y') +set(handles.pushbuttonGO, 'visible','on', 'backgroundcolor','y') msg=[{'Start again: wrong button pressed'}, {' '},... {'Please,click on the GO button'}]; set(handles.textMSG,'string',msg) @@ -1032,12 +950,11 @@ % ------------------------------------------------- plotProgressThisTrial function plotProgressThisTrial(handles) +% updates GUI: used for all responses -% used for all responses global experiment stimulusParameters betweenRuns withinRuns expGUIhandles global psy levelsBinVector binFrequencies rareEvent logistic statsModel - % plot the levelTrack and the threshold track % Panel 2 @@ -1070,9 +987,8 @@ grid on % Panel 4: Summary of threshold estimates (not used here) -% Earlier estimates are set in 'runCompleted' -% However, title shows runs/trials remaining - +% Estimates from previous runs are set in 'runCompleted' +% It is only necessary to change title showing runs/trials remaining axes(expGUIhandles.axes4) runsToGo=length(betweenRuns.var1Sequence)-betweenRuns.runNumber; if withinRuns.beginningOfPhase2>0 @@ -1096,12 +1012,12 @@ withinRuns.levelList(withinRuns.beginningOfPhase2:end); withinRuns.responsesPhaseTwo=... withinRuns.responseList(withinRuns.beginningOfPhase2:end); - + % organise data as psychometric function [psy, levelsBinVector, binFrequencies]= ... psychometricFunction(withinRuns.levelsPhaseTwo,... withinRuns.responsesPhaseTwo, experiment.psyBinWidth); - + % Plot the function % point by point with circles of appropiate weighted size hold on, @@ -1112,25 +1028,20 @@ % save info for later betweenRuns.psychometicFunction{betweenRuns.runNumber}=... [levelsBinVector; psy]; - + % fitPsychometric functions is computed in 'userDecides' % plot(rareEvent.predictionLevels, rareEvent.predictionsRE,'k') plot(logistic.predictionLevels, logistic.predictionsLOG, 'r') plot(rareEvent.predictionLevels, rareEvent.predictionsRE, 'k') if ~isnan(logistic.bestThreshold ) -% xlim([ (logistic.bestThreshold -20) ... -% (logistic.bestThreshold +20) ]) xlim([ 0 100 ]) -% if logistic.bestK< max(experiment.possLogSlopes) - title(['k= ' num2str(logistic.bestK, '%6.2f') ' g= '... - num2str(rareEvent.bestGain,'%6.3f') ' A=' ... - num2str(rareEvent.bestVMin,'%8.1f')]) -% title('') -% end + title(['k= ' num2str(logistic.bestK, '%6.2f') ' g= '... + num2str(rareEvent.bestGain,'%6.3f') ' A=' ... + num2str(rareEvent.bestVMin,'%8.1f')]) else title(' ') end - + switch experiment.ear %plot green line for statsModel a priori model case 'statsModelLogistic' @@ -1150,8 +1061,8 @@ hold on, plot(levelsBinVector, p,'g') end %(estMethod) end + otherwise % 2A2IFC - message3= ... ([ 'peaks=' num2str(withinRuns.peaks) ... 'troughs=' num2str(withinRuns.troughs)]); @@ -1191,7 +1102,7 @@ % disp('run completed') experiment.status='runCompleted'; - +% quick update after final trial just to make sure plotProgressThisTrial(handles) switch experiment.ear @@ -1226,7 +1137,7 @@ [psy, levelsPhaseTwoBinVector, logistic, rareEvent]= ... bestFitPsychometicFunctions... (withinRuns.levelsPhaseTwo, withinRuns.responsesPhaseTwo); - + % plot final psychometric function axes(expGUIhandles.axes5),cla hold on, plot(rareEvent.predictionLevels, rareEvent.predictionsRE, 'k') @@ -1242,26 +1153,25 @@ 'markersize', 50*binFrequencies(i)/sum(binFrequencies)) end - % experimental medianThreshold=median(withinRuns.levelsPhaseTwo); warning off meanThreshold=mean(withinRuns.levelsPhaseTwo); - + % identify the current threshold estimate switch experiment.paradigm case 'discomfort' % most recent value (not truely a mean value) threshold=withinRuns.levelList(end); - stdev=NaN; + stdev=NaN; otherwise switch experiment.threshEstMethod case {'MaxLikelihood', 'oneIntervalUpDown'} % last value in the list -% threshold=withinRuns.meanEstTrack(end); + % threshold=withinRuns.meanEstTrack(end); threshold=withinRuns.thresholdEstimateTrack(end); stdev=NaN; - + case {'2I2AFC++', '2I2AFC+++'} % use peaks and troughs try % there may not be enough values to use @@ -1300,7 +1210,7 @@ % add variable length tracks to cell arrays if withinRuns.beginningOfPhase2>0 betweenRuns.bestThresholdTracks{length(betweenRuns.thresholds)}=... - withinRuns.thresholdEstimateTrack; + withinRuns.thresholdEstimateTrack; betweenRuns.levelTracks{length(betweenRuns.thresholds)}=... withinRuns.levelList(withinRuns.beginningOfPhase2:end); betweenRuns.responseTracks{length(betweenRuns.thresholds)}=... @@ -1338,9 +1248,6 @@ switch betweenRuns.variableName1 case {'targetFrequency', 'maskerRelativeFrequency'} if min(betweenRuns.var1Sequence)>0 - % semilogx(betweenRuns.var1Sequence(1:betweenRuns.runNumber), ... - % betweenRuns.thresholds, 'o', ... - % 'markerSize', 5,'markerFaceColor',faceColor) semilogx(betweenRuns.var1Sequence(i), ... betweenRuns.thresholds(i), 'o', ... 'markerSize', 5,'markerFaceColor',faceColor) @@ -1353,9 +1260,6 @@ 'markerSize', 5,'markerFaceColor',faceColor) end otherwise - % plot(betweenRuns.var1Sequence(1:betweenRuns.runNumber), ... - % betweenRuns.thresholds, 'o', 'markerSize', 5,... - % 'markerFaceColor',faceColor) plot(betweenRuns.var1Sequence(i), ... betweenRuns.thresholds(i), 'o', 'markerSize', 5,... 'markerFaceColor',faceColor) @@ -1374,25 +1278,14 @@ end grid on, set(gca,'XMinorGrid', 'off') -% If comparison data is available in pearmeter file, plot it now -if ~isempty (experiment.comparisonData) - comparisonData=experiment.comparisonData(:,1:end-1); % ignore final BF - [x, ncols]=size(comparisonData); - if length(betweenRuns.variableList1)==ncols - hold on - plot (sort(betweenRuns.variableList1), comparisonData, 'r') - hold off - end -end - -% End of the Experiment also? +% final run? if betweenRuns.runNumber==length(betweenRuns.var1Sequence) % yes, end of experiment fileName=['savedData/' experiment.name experiment.date ... experiment.paradigm]; % save (fileName, 'experiment', 'stimulusParameters', 'betweenRuns', 'withinRuns', 'variableNames', 'paradigmNames', 'LevittControl') disp('Experiment completed') - + % update subject GUI to acknowledge end of run subjGUImsg=[{'Experiment completed'}, {' '}, {'Thank you!'}]; set(handles.textMSG,'string', subjGUImsg ) @@ -1401,12 +1294,12 @@ musicGain=10^(stimulusParameters.musicLeveldB/20); y=y*musicGain; wavplay(y/100,fs, 'async') - + % update experimenter GUI addToMsg('Experiment completed.',1) - + printReport - experiment.status='endOfExperiment'; + experiment.status='endOfExperiment'; return else % No, hang on. @@ -1423,9 +1316,9 @@ *(1-exp(-stimulusParameters.catchTrialTimeConstant)); fprintf('stimulusParameters.catchTrialRate= %6.3f\n', ... stimulusParameters.catchTrialRate) - + % and go again - set(handles.pushbuttonGO,'backgroundcolor','y') + set(handles.pushbuttonGO,'backgroundcolor','y') set(handles.frame1,'visible','off') set(handles.pushbuttonGO,'visible','on') msg=[{'Ready to start new trial'}, {' '},... @@ -1434,7 +1327,7 @@ end experiment.status='waitingForGO'; % fprintf('\n') - + [y,fs,nbits]=wavread('CHIMES.wav'); musicGain=10^(stimulusParameters.musicLeveldB/20); y=y*musicGain; @@ -1448,69 +1341,48 @@ global AN_IHCsynapseParams method=[]; -while strcmp(experiment.status,'waitingForGO') +while strcmp(experiment.status,'waitingForGO') % no catch trials for MAP model experiment.allowCatchTrials=0; - - % initiates run and plays first stimulus and it returns + + % initiates run and plays first stimulus and it returns % without waiting for button press - startNewRun(handles) - - if sum(strcmp(experiment.ear,... - {'MAPmodelMultiCh', 'MAPmodelListen'})) - % use BFlist specified in MAPparams file - BFlist= -1; - else - BFlist=stimulusParameters.targetFrequency; - end - showParams=0; - % find model parameters using the 'name' box (e.g. CTa ->MAPparamsCTa) - paramFunctionName=['method=MAPparams' experiment.name ... - '(BFlist, stimulusParameters.sampleRate, showParams);']; - eval(paramFunctionName) % go and fetch the parameters - + startNewRun(handles) % show sample Rate on GUI; it must be set in MAPparams set(expGUIhandles.textsampleRate,'string',... num2str(stimulusParameters.sampleRate)) - + if experiment.singleShot -% AN_IHCsynapseParams.showSummaryStatistics=1; - method.showSummaryStatistics=1; AN_IHCsynapseParams.plotSynapseContents=1; else - method.showSummaryStatistics=0; AN_IHCsynapseParams.plotSynapseContents=0; end - - if strcmp(experiment.ear, 'MAPmodelSingleCh') - method.MGmembranePotentialSave=1; - end - + % continuous loop until the program stops itself while strcmp(experiment.status,'waitingForResponse') % NB at this point the stimulus has been played pause(0.1) % to allow interrupt with CTRL/C - + switch experiment.ear case { 'MAPmodelListen'} - set(handles.pushbutton1,'backgroundcolor','y','visible','on') - set(handles.pushbutton2,'backgroundcolor','y','visible','on') + % flash the buttons to show model response + set(handles.pushbutton1,'backgroundcolor','y','visible','on') + set(handles.pushbutton2,'backgroundcolor','y','visible','on') end -AN_IHCsynapseParams.mode= 'spikes'; + % Analayse the current stimulus using MAP + [modelResponse earObject]= MAPmodel; -% Analayse the current stimulus using MAP - [modelResponse earObject]= MAPmodel( experiment.MAPplot, method); - if experiment.stop || experiment.singleShot % trap for single trial or user interrupt using 'stop' button. experiment.status= 'waitingForStart'; experiment.stop=0; - addToMsg('manually stopped',1); + errormsg='manually stopped'; + addToMsg(errormsg,1) return end - + switch modelResponse case 1 % userDoesNotHearTarget(handles) @@ -1533,7 +1405,7 @@ 'r','visible','on') set(handles.pushbutton1,'backgroundcolor','y') end - + switch experiment.paradigm case 'discomfort' % always treat discomfort as 'not heard' @@ -1548,7 +1420,8 @@ end end -function [modelResponse, MacGregorResponse]=MAPmodel( MAPplot, method) +% -------------------------------------------------------MAPmodel +function [modelResponse, MacGregorResponse]=MAPmodel global experiment stimulusParameters audio withinRuns global outerMiddleEarParams DRNLParams AN_IHCsynapseParams @@ -1562,18 +1435,34 @@ audio=audio(:,1)'; % if stop button pressed earlier -if experiment.stop, return, end +if experiment.stop + errormsg='manually stopped'; + addToMsg(errormsg,1) + return +end -% -------------------------------------------------------------- run Model +% ---------------------------------------------- run Model MAPparamsName=experiment.name; showPlotsAndDetails=experiment.MAPplot; AN_spikesOrProbability='spikes'; +AN_spikesOrProbability='probability'; % [response, method]=MAPsequenceSeg(audio, method, 1:8); -global ICoutput ANdt - MAP1_14(audio, 1/method.dt, method.nonlinCF,... - MAPparamsName, AN_spikesOrProbability); - +global ICoutput ANdt dt savedBFlist ANprobRateOutput expGUIhandles +global stimulusParameters experiment + +if sum(strcmp(experiment.ear,{'MAPmodelMultiCh', 'MAPmodelListen'})) + % use BFlist specified in MAPparams file + BFlist= -1; +else + BFlist=stimulusParameters.targetFrequency; +end +paramChanges=get(expGUIhandles.editparamChanges,'string'); +eval(paramChanges) + +MAP1_14(audio, stimulusParameters.sampleRate, BFlist,... + MAPparamsName, AN_spikesOrProbability, paramChanges); + if showPlotsAndDetails options.printModelParameters=0; options.showModelOutput=1; @@ -1586,29 +1475,47 @@ end % No response, probably caused by hitting 'stop' button -if isempty(ICoutput), return, end - -% MacGregor response is the sum total of all final stage spiking -MacGregorResponse= sum(ICoutput,1); % use IC - +if strcmp(AN_spikesOrProbability,'spikes') && isempty(ICoutput) + return +end % ---------------------------------------------------------- end model run -dt=ANdt; -time=dt:dt:dt*length(MacGregorResponse); +if strcmp(AN_spikesOrProbability,'spikes') + MacGregorResponse= sum(ICoutput,1); % use IC + dt=ANdt; + time=dt:dt:dt*length(MacGregorResponse); +else + % for one channel, ANprobResponse=ANprobRateOutput + % for multi channel take strongest in any epoch + nChannels=length(savedBFlist); + % use only HSR fibers + ANprobRateOutput=ANprobRateOutput(end-nChannels+1:end,:); + time=dt:dt:dt*length(ANprobRateOutput); +end -% group delay on unit response -MacGonsetDelay= 0.004; -MacGoffsetDelay= 0.022; +% group delay on unit response - these values are iffy +windowOnsetDelay= 0.004; +windowOffsetDelay= 0.022; % long ringing time % now find the response of the MacGregor model during the target presentation + group delay switch experiment.threshEstMethod case {'2I2AFC++', '2I2AFC+++'} - idx= time>stimulusParameters.testTargetBegins+MacGonsetDelay ... - & time<stimulusParameters.testTargetEnds+MacGoffsetDelay; + idx= time>stimulusParameters.testTargetBegins+windowOnsetDelay ... + & time<stimulusParameters.testTargetEnds+windowOffsetDelay; nSpikesTrueWindow=sum(MacGregorResponse(:,idx)); - idx=find(time>stimulusParameters.testNonTargetBegins+MacGonsetDelay ... - & time<stimulusParameters.testNonTargetEnds+MacGoffsetDelay); - nSpikesFalseWindow=sum(MacGregorResponse(:,idx)); + idx=find(time>stimulusParameters.testNonTargetBegins+windowOnsetDelay ... + & time<stimulusParameters.testNonTargetEnds+windowOffsetDelay); + if strcmp(AN_spikesOrProbability,'spikes') + nSpikesFalseWindow=sum(MacGregorResponse(:,idx)); + else + nSpikesDuringTarget=mean(ANprobRateOutput(end,idx)); + % compare with spontaneous rate + if nSpikesDuringTarget>ANprobRateOutput(end,1)+10 + nSpikesDuringTarget=1; % i.e. at leastone MacG spike + else + nSpikesDuringTarget=0; + end + end % nSpikesDuringTarget is +ve when more spikes are found % in the target window difference= nSpikesTrueWindow-nSpikesFalseWindow; @@ -1631,27 +1538,23 @@ disp(['level target dummy decision: ' ... num2str([withinRuns.variableValue nSpikesTrueWindow ... nSpikesFalseWindow nSpikesDuringTarget], '%4.0f') ] ) + otherwise + % single interval + idx=find(time>stimulusParameters.testTargetBegins +windowOnsetDelay... + & time<stimulusParameters.testTargetEnds+windowOffsetDelay); + if strcmp(AN_spikesOrProbability,'spikes') + nSpikesDuringTarget=sum(MacGregorResponse(:,idx)); + timeX=time(idx); + else + % probability, use channel with the highest average rate + nSpikesDuringTarget=max(mean(ANprobRateOutput(:,idx),2)); + if nSpikesDuringTarget>ANprobRateOutput(end,1)+10 + nSpikesDuringTarget=1; + else + nSpikesDuringTarget=0; + end - otherwise - % idx=find(time>stimulusParameters.testTargetBegins+MacGonsetDelay ... - % & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); - % no delay at onset - idx=find(time>stimulusParameters.testTargetBegins +MacGonsetDelay... - & time<stimulusParameters.testTargetEnds+MacGoffsetDelay); - nSpikesDuringTarget=sum(MacGregorResponse(:,idx)); - - % find(MacGregorResponse)*dt-stimulusParameters.stimulusDelay - timeX=time(idx); -end - -% now find the response of the MacGregor model at the end of the masker -idx2=find(time>stimulusParameters.testTargetBegins-0.02 ... - & time<stimulusParameters.testTargetBegins); -if ~isempty(idx2) - maskerRate=mean(mean(MacGregorResponse(idx2))); -else - %e.g. no masker - maskerRate=0; + end end if experiment.MAPplot @@ -1659,32 +1562,19 @@ figure(99), subplot(6,1,6) hold on yL=get(gca,'YLim'); - plot([stimulusParameters.testTargetBegins + MacGonsetDelay ... - stimulusParameters.testTargetBegins + MacGonsetDelay],yL,'r') - plot([stimulusParameters.testTargetEnds + MacGoffsetDelay ... - stimulusParameters.testTargetEnds + MacGoffsetDelay],yL,'r') + plot([stimulusParameters.testTargetBegins + windowOnsetDelay ... + stimulusParameters.testTargetBegins + windowOnsetDelay],yL,'r') + plot([stimulusParameters.testTargetEnds + windowOffsetDelay ... + stimulusParameters.testTargetEnds + windowOffsetDelay],yL,'r') end % specify unambiguous response -switch experiment.paradigm - case 'gapDetection' - gapResponse=(maskerRate-nSpikesDuringTarget)/maskerRate; - if gapResponse>0.2 - modelResponse=2; % gap detected - else - modelResponse=1; % gap not detected - end - [nSpikesDuringTarget maskerRate gapResponse modelResponse] - figure(22), plot(timeX,earObject(idx)) - otherwise - if nSpikesDuringTarget>experiment.MacGThreshold - modelResponse=2; % stimulus detected - else - modelResponse=1; % nothing heard (default) - end +if nSpikesDuringTarget>experiment.MacGThreshold + modelResponse=2; % stimulus detected +else + modelResponse=1; % nothing heard (default) end - path(savePath) % -----------------------------------------------------statsModelRunsGUI @@ -1704,12 +1594,12 @@ addToMsg('manually stopped',1) return end - + % initiates run and plays first stimulus and it returns % without waiting for button press % NB stimulus is not actually generated (for speed) startNewRun(handles) - + while strcmp(experiment.status,'waitingForResponse') % create artificial response here modelResponse=statsModelGetResponse; @@ -1738,13 +1628,13 @@ % if experiment.psyFunSlope<0, % prob=1-prob; % end - + case 'statsModelRareEvent' if experiment.psyFunSlope<0 addToMsg('statsModelRareEvent cannot be used with negative slope',0) error('statsModelRareEvent cannot be used with negative slope') end - + % standard formula is prob = 1 – exp(-d (g P – A)) % here A->A; To find Pmin use A/gain pressure=28*10^(withinRuns.variableValue/20); @@ -1767,7 +1657,7 @@ else modelResponse=1; %nothing heard end - + case {'2I2AFC++', '2I2AFC+++'} if rand<prob modelResponse=2; %bingo @@ -1859,7 +1749,7 @@ set(serobj, 'BytesAvailableFcnCount', 1) set(serobj, 'BytesAvailableFcnMode', 'byte') % set(serobj, 'BreakInterruptFcn', '@buttonBox_Calback') - + fopen(serobj); buttonBoxStatus=get(serobj,'status'); catch
--- a/multithreshold 1.46/testBM.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/testBM.m Fri Jul 01 12:59:47 2011 +0100 @@ -1,4 +1,4 @@ -function testBM (BMlocations, paramsName) +function testBM (BMlocations, paramsName,relativeFrequencies) % testBM generates input output functions for DRNL model for any number % of locations. % Computations are bast on a single channel model (channelBFs=BF) @@ -18,9 +18,6 @@ levels=-10:10:90; nLevels=length(levels); % levels= 50; nLevels=length(levels); -relativeFrequencies=[0.25 .5 .75 1 1.25 1.5 2]; -relativeFrequencies=1; - % refBMdisplacement is the displacement of the BM at threshold % 1 nm disp at threshold (9 kHz, Ruggero) refBMdisplacement= 1e-8; % adjusted for 10 nm at 1 kHz @@ -35,6 +32,7 @@ figure(3), clf set(gcf,'position',[280 350 327 326]) set(gcf,'name','DRNL - BM') +pause(0.1) finalSummary=[]; nBFs=length(BMlocations); @@ -80,8 +78,7 @@ %% run the model MAPparamsName=paramsName; AN_spikesOrProbability='probability'; - % spikes are slow but can be used to study MOC using IC units - AN_spikesOrProbability='spikes'; +% AN_spikesOrProbability='spikes'; global DRNLoutput MOCattenuation ARattenuation MAP1_14(inputSignal, sampleRate, BF, ...
--- a/multithreshold 1.46/testFM.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/testFM.m Fri Jul 01 12:59:47 2011 +0100 @@ -1,4 +1,4 @@ -function testFM(showPSTHs) +function testFM(BFlist,paramsName,showPSTHs) % specify whether you want AN 'probability' or 'spikes' % spikes is more realistic but takes longer % refractory effect is included only for spikes @@ -10,7 +10,6 @@ % % Demonstration is based on Harris and Dallos -global experiment stimulusParameters global inputStimulusParams outerMiddleEarParams DRNLParams global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams @@ -24,7 +23,6 @@ sampleRate=50000; % fetch BF from GUI: use only the first target frequency -BFlist=stimulusParameters.targetFrequency(1); maskerFrequency=BFlist; maskerDuration=.1; @@ -141,13 +139,12 @@ global ANprobRateOutput tauCas ... - MAPparamsName=experiment.name; showPlotsAndDetails=0; AN_spikesOrProbability='probability'; MAP1_14(inputSignal, 1/dt, targetFrequency, ... - MAPparamsName, AN_spikesOrProbability); + paramsName, AN_spikesOrProbability); [nFibers c]=size(ANprobRateOutput); nLSRfibers=nFibers/length(tauCas); @@ -235,7 +232,7 @@ legend(strvcat(num2str(maskerLevels'-thresholdAtCF)), -1) % ------------------------------------------------- display parameters -disp(['parameter file was: ' experiment.name]) +disp(['parameter file was: ' paramsName]) fprintf('\n') % UTIL_showStruct(inputStimulusParams, 'inputStimulusParams') % UTIL_showStruct(outerMiddleEarParams, 'outerMiddleEarParams')
--- a/multithreshold 1.46/testOME.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/testOME.m Fri Jul 01 12:59:47 2011 +0100 @@ -1,6 +1,5 @@ -function testOME +function testOME(paramsName) -global experiment savePath=path; addpath (['..' filesep 'utilities'],['..' filesep 'MAP']) @@ -34,7 +33,6 @@ for toneFrequency=frequencies inputSignal=amp*sin(2*pi*toneFrequency*time); - MAPparamsName=experiment.name; showPlotsAndDetails=0; AN_spikesOrProbability='probability'; % switch off AR & MOC (Huber's patients were deaf) @@ -44,7 +42,7 @@ global OMEoutput OMEextEarPressure TMoutput ARattenuation % BF is irrelevant MAP1_14(inputSignal, sampleRate, -1, ... - MAPparamsName, AN_spikesOrProbability, paramChanges); + paramsName, AN_spikesOrProbability, paramChanges); peakDisplacement=max(OMEoutput(floor(end/2):end)); peakResponses=[peakResponses peakDisplacement]; @@ -82,7 +80,7 @@ xlabel('frequency') set(gcf,'name','OME: external resonances') % ---------------------------------------------------------- display parameters -disp(['parameter file was: ' experiment.name]) +disp(['parameter file was: ' paramsName]) fprintf('\n') -path(savePath); \ No newline at end of file +path(savePath);
--- a/multithreshold 1.46/testRP.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/testRP.m Fri Jul 01 12:59:47 2011 +0100 @@ -180,10 +180,15 @@ hold on, plot([min(levels) max(levels)], [restingRP restingRP], 'r') xlim([min(levels) max(levels)]) + % animal data + sndLevel=[5 15 25 35 45 55 65 75]; +RPanimal=restingRP+[0.5 2 4.6 5.8 6.4 7.2 8 10.2]/1000; +hold on, plot(sndLevel,RPanimal,'o') + grid on - title(['Et= ' num2str(IHC_cilia_RPParams.Et) ': RP (AC- / DC:']) + title(['Et= ' num2str(IHC_cilia_RPParams.Et) ': RP data 7 kHz Patuzzi']) ylabel ('RP(V)'), xlabel('dB SPL') - ylim([-0.08 -0.02]) + ylim([-0.08 -0.04]) allIHC_RP_peak=[allIHC_RP_peak IHC_RP_peak]; allIHC_RP_dc=[allIHC_RP_dc IHC_RP_dc];
--- a/multithreshold 1.46/testSynapse.m Wed Jun 22 12:02:45 2011 +0100 +++ b/multithreshold 1.46/testSynapse.m Fri Jul 01 12:59:47 2011 +0100 @@ -1,4 +1,4 @@ -function testSynapse +function testSynapse(BFlist,paramsName) % testSynapse tracks the quantity of available transmitter vesicles % the computations are single channel using the first frequency % in the targetFrequency box of the expGUI. @@ -18,7 +18,6 @@ maskerLevels=-0:10:100; -BFlist=stimulusParameters.targetFrequency(1); targetFrequency=stimulusParameters.targetFrequency; targetFrequency=targetFrequency(1); % only one frequency used @@ -54,13 +53,12 @@ inputSignal=amp*signal; AN_spikesOrProbability='probability'; - MAPparamsName=experiment.name; showPlotsAndDetails=0; global savePavailable MAP1_14(inputSignal, 1/dt, targetFrequency, ... - MAPparamsName, AN_spikesOrProbability); + paramsName, AN_spikesOrProbability); % ignore LSR channels (if any) at the top of the matrix qt=savePavailable(end, :);
--- a/parameterStore/MAPparamsEndo.m Wed Jun 22 12:02:45 2011 +0100 +++ b/parameterStore/MAPparamsEndo.m Fri Jul 01 12:59:47 2011 +0100 @@ -11,11 +11,11 @@ % output argument % method passes a miscelleny of values -global inputStimulusParams OMEParams DRNLParams +global inputStimulusParams OMEParams DRNLParams IHC_cilia_RPParams global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams global MacGregorParams MacGregorMultiParams filteredSACFParams global experiment % used by calls from multiThreshold only -global IHC_cilia_RPParams + currentFile=mfilename; % i.e. the name of this mfile method.parameterSource=currentFile(10:end); % for the record @@ -76,6 +76,7 @@ % DRNL nonlinear path DRNLParams.a=5e4; % DRNL.a=0 means no OHCs (no nonlinear path) +DRNLParams.a=2e4; % DRNL.a=0 means no OHCs (no nonlinear path) DRNLParams.b=8e-6; % *compression threshold raised compression % DRNLParams.b=1; % b=1 means no compression @@ -115,19 +116,21 @@ IHC_cilia_RPParams.tc= 0.0003; % 0.0003 filter time simulates viscocity % IHC_cilia_RPParams.tc= 0.0005; % 0.0003 filter time simulates viscocity -IHC_cilia_RPParams.C= 0.05; % 0.1 scalar (C_cilia ) +IHC_cilia_RPParams.C= 0.03; % 0.1 scalar (C_cilia ) IHC_cilia_RPParams.u0= 5e-9; IHC_cilia_RPParams.s0= 30e-9; IHC_cilia_RPParams.u1= 1e-9; IHC_cilia_RPParams.s1= 1e-9; -IHC_cilia_RPParams.Gmax= 5e-9; % 2.5e-9 maximum conductance (Siemens) +IHC_cilia_RPParams.Gmax= 6e-9; % 2.5e-9 maximum conductance (Siemens) IHC_cilia_RPParams.Ga= 1e-9; % 4.3e-9 fixed apical membrane conductance +IHC_cilia_RPParams.Ga= .8e-9; % 4.3e-9 fixed apical membrane conductance % #5 IHC_RP IHC_cilia_RPParams.Cab= 4e-012; % IHC capacitance (F) -IHC_cilia_RPParams.Cab= 1e-012; % IHC capacitance (F) -IHC_cilia_RPParams.Et= 0.07; % endocochlear potential (V) +% IHC_cilia_RPParams.Cab= 1e-012; % IHC capacitance (F) +IHC_cilia_RPParams.Et= 0.100; % endocochlear potential (V) +IHC_cilia_RPParams.Et= 0.05; % endocochlear potential (V) IHC_cilia_RPParams.Gk= 2e-008; % 1e-8 potassium conductance (S) IHC_cilia_RPParams.Ek= -0.08; % -0.084 K equilibrium potential @@ -204,7 +207,7 @@ MacGregorMultiParams.dendriteLPfreq=50; % dendritic filter MacGregorMultiParams.currentPerSpike=35e-9; % *per spike - MacGregorMultiParams.currentPerSpike=30e-9; % *per spike +% MacGregorMultiParams.currentPerSpike=30e-9; % *per spike MacGregorMultiParams.Cap=1.67e-8; % ??cell capacitance (Siemens) MacGregorMultiParams.tauM=0.002; % membrane time constant (s) @@ -225,7 +228,7 @@ MacGregorParams.fibersPerNeuron=10; % N input fibers MacGregorParams.dendriteLPfreq=100; % dendritic filter MacGregorParams.currentPerSpike=120e-9;% *(A) per spike -MacGregorParams.currentPerSpike=30e-9;% *(A) per spike +MacGregorParams.currentPerSpike=40e-9;% *(A) per spike MacGregorParams.Cap=16.7e-9; % cell capacitance (Siemens) MacGregorParams.tauM=0.002; % membrane time constant (s) @@ -296,61 +299,5 @@ end end - - -% ********************************************************************** comparison data -% store individual data here for display on the multiThreshold GUI (if used) -% the final value in each vector is an identifier (BF or duration)) -if isstruct(experiment) - switch experiment.paradigm - case {'IFMC','IFMC_8ms'} - % based on MPa - comparisonData=[ - 66 51 49 48 46 45 54 250; - 60 54 46 42 39 49 65 500; - 64 51 38 32 33 59 75 1000; - 59 51 36 30 41 81 93 2000; - 71 63 53 44 36 76 95 4000; - 70 64 43 35 35 66 88 6000; - 110 110 110 110 110 110 110 8000; - ]; - if length(BFlist)==1 && ~isempty(comparisonData) - availableFrequencies=comparisonData(:,end)'; - findRow= find(BFlist==availableFrequencies); - if ~isempty (findRow) - experiment.comparisonData=comparisonData(findRow,:); - end - end - - case {'TMC','TMC_8ms'} - % based on MPa - comparisonData=[ - 48 58 63 68 75 80 85 92 99 250; - 33 39 40 49 52 61 64 77 79 500; - 39 42 50 81 83 92 96 97 110 1000; - 24 26 32 37 46 51 59 71 78 2000; - 65 68 77 85 91 93 110 110 110 4000; - 20 19 26 44 80 95 96 110 110 6000; - ]; - if length(BFlist)==1 && ~isempty(comparisonData) - availableFrequencies=comparisonData(:,end)'; - findRow= find(BFlist==availableFrequencies); - if ~isempty (findRow) - experiment.comparisonData=comparisonData(findRow,:); - end - end - - case { 'absThreshold', 'absThreshold_8'} - % MPa thresholds - experiment.comparisonData=[ - 32 26 16 18 22 22 0.008; - 16 13 6 9 15 11 0.500 - ]; - - - otherwise - experiment.comparisonData=[]; - end -end - - +% for backward compatibility +experiment.comparisonData=[];
--- a/parameterStore/MAPparamsNormal.m Wed Jun 22 12:02:45 2011 +0100 +++ b/parameterStore/MAPparamsNormal.m Fri Jul 01 12:59:47 2011 +0100 @@ -76,6 +76,7 @@ % DRNL nonlinear path DRNLParams.a=5e4; % DRNL.a=0 means no OHCs (no nonlinear path) +DRNLParams.a=2e4; % DRNL.a=0 means no OHCs (no nonlinear path) DRNLParams.b=8e-6; % *compression threshold raised compression % DRNLParams.b=1; % b=1 means no compression @@ -115,18 +116,19 @@ IHC_cilia_RPParams.tc= 0.0003; % 0.0003 filter time simulates viscocity % IHC_cilia_RPParams.tc= 0.0005; % 0.0003 filter time simulates viscocity -IHC_cilia_RPParams.C= 0.05; % 0.1 scalar (C_cilia ) +IHC_cilia_RPParams.C= 0.03; % 0.1 scalar (C_cilia ) IHC_cilia_RPParams.u0= 5e-9; IHC_cilia_RPParams.s0= 30e-9; IHC_cilia_RPParams.u1= 1e-9; IHC_cilia_RPParams.s1= 1e-9; -IHC_cilia_RPParams.Gmax= 5e-9; % 2.5e-9 maximum conductance (Siemens) +IHC_cilia_RPParams.Gmax= 6e-9; % 2.5e-9 maximum conductance (Siemens) IHC_cilia_RPParams.Ga= 1e-9; % 4.3e-9 fixed apical membrane conductance +IHC_cilia_RPParams.Ga= .8e-9; % 4.3e-9 fixed apical membrane conductance % #5 IHC_RP IHC_cilia_RPParams.Cab= 4e-012; % IHC capacitance (F) -IHC_cilia_RPParams.Cab= 1e-012; % IHC capacitance (F) +% IHC_cilia_RPParams.Cab= 1e-012; % IHC capacitance (F) IHC_cilia_RPParams.Et= 0.100; % endocochlear potential (V) IHC_cilia_RPParams.Gk= 2e-008; % 1e-8 potassium conductance (S) @@ -204,7 +206,7 @@ MacGregorMultiParams.dendriteLPfreq=50; % dendritic filter MacGregorMultiParams.currentPerSpike=35e-9; % *per spike - MacGregorMultiParams.currentPerSpike=30e-9; % *per spike +% MacGregorMultiParams.currentPerSpike=30e-9; % *per spike MacGregorMultiParams.Cap=1.67e-8; % ??cell capacitance (Siemens) MacGregorMultiParams.tauM=0.002; % membrane time constant (s) @@ -225,7 +227,7 @@ MacGregorParams.fibersPerNeuron=10; % N input fibers MacGregorParams.dendriteLPfreq=100; % dendritic filter MacGregorParams.currentPerSpike=120e-9;% *(A) per spike -MacGregorParams.currentPerSpike=30e-9;% *(A) per spike +MacGregorParams.currentPerSpike=40e-9;% *(A) per spike MacGregorParams.Cap=16.7e-9; % cell capacitance (Siemens) MacGregorParams.tauM=0.002; % membrane time constant (s)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parameterStore/MAPparamsNormalHold.m Fri Jul 01 12:59:47 2011 +0100 @@ -0,0 +1,300 @@ +function method=MAPparamsNormal ... + (BFlist, sampleRate, showParams, paramChanges) +% MAPparams<> establishes a complete set of MAP parameters +% Parameter file names must be of the form <MAPparams> <name> +% +% input arguments +% BFlist (optional) specifies the desired list of channel BFs +% otherwise defaults set below +% sampleRate (optional), default is 50000. +% showParams (optional) =1 prints out the complete set of parameters +% output argument +% method passes a miscelleny of values + +global inputStimulusParams OMEParams DRNLParams IHC_cilia_RPParams +global IHC_VResp_VivoParams IHCpreSynapseParams AN_IHCsynapseParams +global MacGregorParams MacGregorMultiParams filteredSACFParams +global experiment % used by calls from multiThreshold only + + +currentFile=mfilename; % i.e. the name of this mfile +method.parameterSource=currentFile(10:end); % for the record + +efferentDelay=0.010; +method.segmentDuration=efferentDelay; + +if nargin<3, showParams=0; end +if nargin<2, sampleRate=50000; end +if nargin<1 || BFlist(1)<0 % if BFlist= -1, set BFlist to default + lowestBF=250; highestBF= 8000; numChannels=21; + % 21 chs (250-8k)includes BFs at 250 500 1000 2000 4000 8000 + BFlist=round(logspace(log10(lowestBF),log10(highestBF),numChannels)); +end +% BFlist=1000; + +% preserve for backward campatibility +method.nonlinCF=BFlist; +method.dt=1/sampleRate; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% set model parameters +%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% #1 inputStimulus +inputStimulusParams=[]; +inputStimulusParams.sampleRate= sampleRate; + +%% #2 outerMiddleEar +OMEParams=[]; % clear the structure first +% outer ear resonances band pass filter [gain lp order hp] +OMEParams.externalResonanceFilters= [ 10 1 1000 4000]; + +% highpass stapes filter +% Huber gives 2e-9 m at 80 dB and 1 kHz (2e-13 at 0 dB SPL) +OMEParams.OMEstapesLPcutoff= 1000; +OMEParams.stapesScalar= 45e-9; + +% Acoustic reflex: maximum attenuation should be around 25 dB Price (1966) +% i.e. a minimum ratio of 0.056. +% 'spikes' model: AR based on brainstem spiking activity (LSR) +OMEParams.rateToAttenuationFactor=0.006; % * N(all ICspikes) +% OMEParams.rateToAttenuationFactor=0; % * N(all ICspikes) + +% 'probability model': Ar based on AN firing probabilities (LSR) +OMEParams.rateToAttenuationFactorProb=0.01;% * N(all ANrates) +% OMEParams.rateToAttenuationFactorProb=0;% * N(all ANrates) + +% asymptote should be around 100-200 ms +OMEParams.ARtau=.05; % AR smoothing function +% delay must be longer than the segment length +OMEParams.ARdelay=efferentDelay; %Moss gives 8.5 ms latency +OMEParams.ARrateThreshold=0; + +%% #3 DRNL +DRNLParams=[]; % clear the structure first +DRNLParams.BFlist=BFlist; + +% DRNL nonlinear path +DRNLParams.a=5e4; % DRNL.a=0 means no OHCs (no nonlinear path) + +DRNLParams.b=8e-6; % *compression threshold raised compression +% DRNLParams.b=1; % b=1 means no compression + +DRNLParams.c=0.2; % compression exponent +% nonlinear filters +DRNLParams.nonlinCFs=BFlist; +DRNLParams.nonlinOrder= 3; % order of nonlinear gammatone filters +p=0.2895; q=170; % human (% p=0.14; q=366; % cat) +DRNLParams.nlBWs= p * BFlist + q; +DRNLParams.p=p; DRNLParams.q=q; % save p and q for printing only + +% DRNL linear path: +DRNLParams.g=100; % linear path gain factor +% linCF is not necessarily the same as nonlinCF +minLinCF=153.13; coeffLinCF=0.7341; % linCF>nonlinBF for BF < 1 kHz +DRNLParams.linCFs=minLinCF+coeffLinCF*BFlist; +DRNLParams.linOrder= 3; % order of linear gammatone filters +minLinBW=100; coeffLinBW=0.6531; +DRNLParams.linBWs=minLinBW + coeffLinBW*BFlist; % bandwidths of linear filters + +% DRNL MOC efferents +DRNLParams.MOCdelay = efferentDelay; % must be < segment length! + +% 'spikes' model: MOC based on brainstem spiking activity (HSR) +DRNLParams.rateToAttenuationFactor = .01; % strength of MOC +% DRNLParams.rateToAttenuationFactor = 0; % strength of MOC +% 'probability' model: MOC based on AN spiking activity (HSR) +DRNLParams.rateToAttenuationFactorProb = .0055; % strength of MOC +% DRNLParams.rateToAttenuationFactorProb = .0; % strength of MOC +DRNLParams.MOCrateThresholdProb =70; % spikes/s probability only + +DRNLParams.MOCtau =.1; % smoothing for MOC + + +%% #4 IHC_cilia_RPParams + +IHC_cilia_RPParams.tc= 0.0003; % 0.0003 filter time simulates viscocity +% IHC_cilia_RPParams.tc= 0.0005; % 0.0003 filter time simulates viscocity +IHC_cilia_RPParams.C= 0.05; % 0.1 scalar (C_cilia ) +IHC_cilia_RPParams.u0= 5e-9; +IHC_cilia_RPParams.s0= 30e-9; +IHC_cilia_RPParams.u1= 1e-9; +IHC_cilia_RPParams.s1= 1e-9; + +IHC_cilia_RPParams.Gmax= 5e-9; % 2.5e-9 maximum conductance (Siemens) +IHC_cilia_RPParams.Ga= 1e-9; % 4.3e-9 fixed apical membrane conductance + +% #5 IHC_RP +IHC_cilia_RPParams.Cab= 4e-012; % IHC capacitance (F) +IHC_cilia_RPParams.Cab= 1e-012; % IHC capacitance (F) +IHC_cilia_RPParams.Et= 0.100; % endocochlear potential (V) + +IHC_cilia_RPParams.Gk= 2e-008; % 1e-8 potassium conductance (S) +IHC_cilia_RPParams.Ek= -0.08; % -0.084 K equilibrium potential +IHC_cilia_RPParams.Rpc= 0.04; % combined resistances + + +%% #5 IHCpreSynapse +IHCpreSynapseParams=[]; +IHCpreSynapseParams.GmaxCa= 14e-9;% maximum calcium conductance +IHCpreSynapseParams.GmaxCa= 12e-9;% maximum calcium conductance +IHCpreSynapseParams.ECa= 0.066; % calcium equilibrium potential +IHCpreSynapseParams.beta= 400; % determine Ca channel opening +IHCpreSynapseParams.gamma= 100; % determine Ca channel opening +IHCpreSynapseParams.tauM= 0.00005; % membrane time constant ?0.1ms +IHCpreSynapseParams.power= 3; +% reminder: changing z has a strong effect on HF thresholds (like Et) +IHCpreSynapseParams.z= 2e42; % scalar Ca -> vesicle release rate + +LSRtauCa=35e-6; HSRtauCa=85e-6; % seconds +% LSRtauCa=35e-6; HSRtauCa=70e-6; % seconds +IHCpreSynapseParams.tauCa= [LSRtauCa HSRtauCa]; %LSR and HSR fiber + +%% #6 AN_IHCsynapse +% c=kym/(y(l+r)+kl) (spontaneous rate) +% c=(approx) ym/l (saturated rate) +AN_IHCsynapseParams=[]; % clear the structure first +AN_IHCsynapseParams.M= 12; % maximum vesicles at synapse +AN_IHCsynapseParams.y= 4; % depleted vesicle replacement rate +AN_IHCsynapseParams.y= 6; % depleted vesicle replacement rate + +AN_IHCsynapseParams.x= 30; % replenishment from re-uptake store +AN_IHCsynapseParams.x= 60; % replenishment from re-uptake store + +% reduce l to increase saturated rate +AN_IHCsynapseParams.l= 100; % *loss rate of vesicles from the cleft +AN_IHCsynapseParams.l= 250; % *loss rate of vesicles from the cleft + +AN_IHCsynapseParams.r= 500; % *reuptake rate from cleft into cell +% AN_IHCsynapseParams.r= 300; % *reuptake rate from cleft into cell + +AN_IHCsynapseParams.refractory_period= 0.00075; +% number of AN fibers at each BF (used only for spike generation) +AN_IHCsynapseParams.numFibers= 100; +AN_IHCsynapseParams.TWdelay=0.004; % ?delay before stimulus first spike + +AN_IHCsynapseParams.ANspeedUpFactor=5; % longer epochs for computing spikes. + +%% #7 MacGregorMulti (first order brainstem neurons) +MacGregorMultiParams=[]; +MacGregorMultiType='chopper'; % MacGregorMultiType='primary-like'; %choose +switch MacGregorMultiType + case 'primary-like' + MacGregorMultiParams.nNeuronsPerBF= 10; % N neurons per BF + MacGregorMultiParams.type = 'primary-like cell'; + MacGregorMultiParams.fibersPerNeuron=4; % N input fibers + MacGregorMultiParams.dendriteLPfreq=200; % dendritic filter + MacGregorMultiParams.currentPerSpike=0.11e-6; % (A) per spike + MacGregorMultiParams.Cap=4.55e-9; % cell capacitance (Siemens) + MacGregorMultiParams.tauM=5e-4; % membrane time constant (s) + MacGregorMultiParams.Ek=-0.01; % K+ eq. potential (V) + MacGregorMultiParams.dGkSpike=3.64e-5; % K+ cond.shift on spike,S + MacGregorMultiParams.tauGk= 0.0012; % K+ conductance tau (s) + MacGregorMultiParams.Th0= 0.01; % equilibrium threshold (V) + MacGregorMultiParams.c= 0.01; % threshold shift on spike, (V) + MacGregorMultiParams.tauTh= 0.015; % variable threshold tau + MacGregorMultiParams.Er=-0.06; % resting potential (V) + MacGregorMultiParams.Eb=0.06; % spike height (V) + + case 'chopper' + MacGregorMultiParams.nNeuronsPerBF= 10; % N neurons per BF + MacGregorMultiParams.type = 'chopper cell'; + MacGregorMultiParams.fibersPerNeuron=10; % N input fibers +% MacGregorMultiParams.fibersPerNeuron=6; % N input fibers + + MacGregorMultiParams.dendriteLPfreq=50; % dendritic filter + MacGregorMultiParams.currentPerSpike=35e-9; % *per spike + MacGregorMultiParams.currentPerSpike=30e-9; % *per spike + + MacGregorMultiParams.Cap=1.67e-8; % ??cell capacitance (Siemens) + MacGregorMultiParams.tauM=0.002; % membrane time constant (s) + MacGregorMultiParams.Ek=-0.01; % K+ eq. potential (V) + MacGregorMultiParams.dGkSpike=1.33e-4; % K+ cond.shift on spike,S + MacGregorMultiParams.tauGk= 0.0005;% K+ conductance tau (s) + MacGregorMultiParams.Th0= 0.01; % equilibrium threshold (V) + MacGregorMultiParams.c= 0; % threshold shift on spike, (V) + MacGregorMultiParams.tauTh= 0.02; % variable threshold tau + MacGregorMultiParams.Er=-0.06; % resting potential (V) + MacGregorMultiParams.Eb=0.06; % spike height (V) + MacGregorMultiParams.PSTHbinWidth= 1e-4; +end + +%% #8 MacGregor (second-order neuron). Only one per channel +MacGregorParams=[]; % clear the structure first +MacGregorParams.type = 'chopper cell'; +MacGregorParams.fibersPerNeuron=10; % N input fibers +MacGregorParams.dendriteLPfreq=100; % dendritic filter +MacGregorParams.currentPerSpike=120e-9;% *(A) per spike +MacGregorParams.currentPerSpike=30e-9;% *(A) per spike + +MacGregorParams.Cap=16.7e-9; % cell capacitance (Siemens) +MacGregorParams.tauM=0.002; % membrane time constant (s) +MacGregorParams.Ek=-0.01; % K+ eq. potential (V) +MacGregorParams.dGkSpike=1.33e-4; % K+ cond.shift on spike,S +MacGregorParams.tauGk= 0.0005; % K+ conductance tau (s) +MacGregorParams.Th0= 0.01; % equilibrium threshold (V) +MacGregorParams.c= 0; % threshold shift on spike, (V) +MacGregorParams.tauTh= 0.02; % variable threshold tau +MacGregorParams.Er=-0.06; % resting potential (V) +MacGregorParams.Eb=0.06; % spike height (V) +MacGregorParams.debugging=0; % (special) +% wideband accepts input from all channels (of same fiber type) +% use wideband to create inhibitory units +MacGregorParams.wideband=0; % special for wideband units +% MacGregorParams.saveAllData=0; + +%% #9 filteredSACF +minPitch= 300; maxPitch= 3000; numPitches=60; % specify lags +pitches=100*log10(logspace(minPitch/100, maxPitch/100, numPitches)); +filteredSACFParams.lags=1./pitches; % autocorrelation lags vector +filteredSACFParams.acfTau= .003; % time constant of running ACF +filteredSACFParams.lambda= 0.12; % slower filter to smooth ACF +filteredSACFParams.plotFilteredSACF=1; % 0 plots unfiltered ACFs +filteredSACFParams.plotACFs=0; % special plot (see code) +% filteredSACFParams.usePressnitzer=0; % attenuates ACF at long lags +filteredSACFParams.lagsProcedure= 'useAllLags'; +% filteredSACFParams.lagsProcedure= 'useBernsteinLagWeights'; +% filteredSACFParams.lagsProcedure= 'omitShortLags'; +filteredSACFParams.criterionForOmittingLags=3; + +% checks +if AN_IHCsynapseParams.numFibers<MacGregorMultiParams.fibersPerNeuron + error('MacGregorMulti: too few input fibers for input to MacG unit') +end + + +%% now accept last minute parameter changes required by the calling program +% paramChanges +if nargin>3 && ~isempty(paramChanges) + nChanges=length(paramChanges); + for idx=1:nChanges + eval(paramChanges{idx}) + end +end + + +%% write all parameters to the command window +% showParams is currently set at the top of htis function +if showParams + fprintf('\n %%%%%%%%\n') + fprintf('\n%s\n', method.parameterSource) + fprintf('\n') + nm=UTIL_paramsList(whos); + for i=1:length(nm) + % eval(['UTIL_showStruct(' nm{i} ', ''' nm{i} ''')']) + if ~strcmp(nm(i), 'method') + eval(['UTIL_showStructureSummary(' nm{i} ', ''' nm{i} ''', 10)']) + end + end + + % highlight parameter changes made locally + if nargin>3 && ~isempty(paramChanges) + fprintf('\n Local parameter changes:\n') + for i=1:length(paramChanges) + disp(paramChanges{i}) + end + end +end + +% for backward compatibility +experiment.comparisonData=[];