% RunExperimentCT % imageSize = 64; % Image size in pixels expandSize = 2; % Amount to expand image for display cyclesPerImage = 3; % Spatial freq, c/image. spaceConstant=imageSize/4; % Gaussian grating envelope durationMs = 200; % Trial duration nTrials = 15; % Number of trials noiseRmsContrast=0.2; % Noise contrast screenNumber = 0; % Which screen are we running on? % Measure detection threshold for grating in noise % Each call to RunExperimentCT will measure one threshold. % This is meant to be called as a subprogram after parameters % have been set, not to be executed directly. % % BUG: Student Matlab sometimes hangs up in the call to CmdWinToUpperLeft(), % and continues if you hit Command-Period. % 6/26/96 dgp Wrote it. % 3/8/97 dhb Massive simplifications. % Much more documentation. % 1/12/98 dgp Noted problem in Student Matlab. % 7/9/98 dgp Cope when GetClut is not available. % 4/08/02 awi -Added platform conditionals to avoid SCREENWinToFront calls in Windows % -Added platform condtionals to use Matlab's Sound on Windows. % -Fixed GetClicks.dll so that we can count more than double clicks. % 4/13/02 dgp Replaced platform-dependent call to obsolete SndPlay by unconditional call to SND. % Open up the experimental screen backgroundEntry = 128; [window,screenRect]=SCREEN(screenNumber,'OpenWindow',backgroundEntry); matlabClut = SCREEN(window,'GetClut'); % a misnomer. SCREEN 'OpenWindow' just set up the CLUT. if isempty(matlabClut) matlabClut=ClutDefault(window); end if strcmp('PCWIN',computer) SCREEN(window,'Close'); else % Bring command window to front and move it to upper left. % That way we can print lots of stuff in the command window % that tells the user what's going on. [cmdDx,cmdDy,bufferWindow] = CmdWinToUpperLeft(window,matlabClut); end % Provide introductory remarks. fprintf(1,'\n**************************************\n\n'); fprintf('This program demonstrates how to measure a threshold.\n'); fprintf('In this case we are measuring the contrast required to detect a grating in noise.\n'); fprintf('You will be presented with 15 Gabor patches with noise overlain\n'); fprintf('and have to indicate whether you detect the stimulus or not.\n'); fprintf('Click the mouse now to proceed\n'); GetClicks; fprintf('\n'); % Seed random number generator ClockRandSeed; % Read screen calibration and compute cluts. InitializeClutsCT; % Make the signal waveforms disp(' Making signals.'); MakeSignalsCT; %%%%Notice that "Quest", that is q, contains history etc % Initialize Quest. The threshold guess is set % relative to the signal to noise ratio. % We aim a bit high because observers do better if they % clearly see the signal on the first few trials. disp(' Initialize Quest parameters.'); nIntervals=1; nResponses = 1;%%%%%%%%%%%CHANGE THIS LINE%%%%%%%%%%%% beta=3.5; delta=0.01; gamma=1/nIntervals; if nIntervals==1; gamma=0; end pCorrect=0.82; if (Enoise > 0) thresholdGuess = 0.5*log10(80/(Esignal/Enoise))-0.5; else thresholdGuess = -1.5; end thresholdGuess = max(thresholdGuess,-1.5); priorSd = 4; q=QuestCreate(thresholdGuess,priorSd,pCorrect,beta,delta,gamma); if strcmp('PCWIN',computer) [window,screenRect]=SCREEN(screenNumber,'OpenWindow',backgroundEntry); else % Bring up screen window to show images. SCREENWinToFront(window,bufferWindow,cmdDx,cmdDy,offClut); end % Set the linear clut for the experiment SCREEN(window,'SetClut',linearClut); putRect = CenterRect(signalRect,screenRect); % Set up text style for user interface. SCREEN(window,'TextFont','Arial'); SCREEN(window,'TextSize',20); SCREEN(window,'TextStyle',0); SCREEN(window,'TextMode','srcOr'); % We should modify the CLUT to reserve entries 0 and 255 to show white and black, respectively, % as required by the Mac OS 9.1+ Palette Manager. However, this hasn't been done yet. black=255; % actually this produces white, but 0 produces gray. white=255; % Run the trials theData = zeros(nTrials,4); wrongRight = ['Wrong' ; 'Right']; HideCursor; for trial=1:nTrials % Make noise images MakeNoisesCT; % Get level to test trialCon=10^QuestQuantile(q); trialCon=min(maxQuestCon,trialCon); % On first trial, wait for user. if trial==1 fixationRect=CenterRect(SetRect(0,0,4,4),screenRect); SCREEN(window,'FillRect',white,fixationRect); instString = 'Click once if you detect the sitmulus, twice if you do not, three times to quit. Now click mouse when ready'; SCREEN(window,'DrawText',instString,50,100,black); GetClicks; SCREEN(window,'DrawText',instString,50,100,backgroundEntry); instString = 'Click once if you detect the sitmulus, twice if you do not, three times to quit.'; SCREEN(window,'DrawText',instString,50,100,black); end whichInterval=randi(nIntervals); signal0=zeros(size(signal1)); for interval=1:nIntervals % Create stimulus by adding signal and noise noiseName=sprintf('noise%d',interval); if interval == whichInterval eval(['stimulus = trialCon*signal1+' noiseName ';']);%trialCon sets strength of signal else eval(['stimulus = trialCon*signal0+' noiseName ';']); end stimulus=backgroundEntry+entriesPerContrast*stimulus; % Display stimulus WaitSecs(0.3); %SND('Play',beep,22000); SCREEN(window,'PutImage',stimulus,putRect) SCREEN(window,'SetClut',linearClut); WaitSecs(durationMs/1000); SCREEN(window,'FillRect',backgroundEntry,putRect); end % Process response choice=GetClicks; if choice > 2 break; end response=(choice==whichInterval); %GiveFeedback(response); respString = sprintf('Trial %g: %s',trial+1);%,wrongRight(response+1,:)); xLoc = screenRect(rectRight)/2-SCREEN(window,'TextWidth',respString)/2; yLoc = screenRect(rectBottom)/2; SCREEN(window,'DrawText',respString,xLoc,yLoc,black); WaitSecs(0.5); SCREEN(window,'DrawText',respString,xLoc,yLoc,backgroundEntry); WaitSecs(0.2); SCREEN(window,'FillRect',white,fixationRect); % Update Quest and store data q = QuestUpdate(q,log10(trialCon),response); theData(trial,1) = log10(trialCon); theData(trial,2) = response; %list of 0 and 1 responses (right/wrong) theData(trial,3) = QuestMean(q); %takes mean of q.pdf +q.tguess theData(trial,4) = QuestSd(q); %calculates std of q.pdf end % Close up ShowCursor; SCREEN(window,'Close'); % Tell user about threshold fprintf('\n**************************************\n\n'); fprintf('Threshold estimate is %g ± %g (mean ± sd, in log units).\n',QuestMean(q),QuestSd(q)); if 0 % boring fprintf('Array theData contains the data. It has four\n'); fprintf('columns. The first column provides for each trial\n'); fprintf('the log contrast value tested. The second column tells\n'); fprintf('whether the trial was right (1) or wrong (0)\n'); fprintf('The third column gives Quest''s running threshold estimate.\n'); fprintf('The fourth column gives Quest''s running estimate standard\n'); fprintf('deviation.\n\n'); end fprintf('The plot shows how the threshold estimate converged\n'); fprintf('over %g trials.\n\n',trial); % Plot the threshold estimates. plot(theData(1:trial,3),'g'); xlabel('Trial number'); ylabel('Log contrast threshold'); title('Threshold estimate vs. Trial Number'); drawnow;