Presenting multiple stimuli in parallel and getting mouse response

I’m new to psych toolbox box and familiar with matlab basics. I want to present three stimuli first.say, for example I present images of three restaurants R1,R2,R3, the user can click on any one of the restaurant to view three of its signature dish .e.g clicking on restaurant R1 leads to three signature dish choices S11,S12,S13 . I want all the mouse response of the participant to be recorded by the code the image is tagged with, e.g if they click R1 first and then S11,S12. I want it to be recorded serially as R1,S11,S12. How to implement this in psych tool box?

GetMouse() returns the X, Y coordinates and mouse button state. When you draw an image [Screen('DrawTexture')] you use a PsychRect [LEFT TOP RIGHT BOTTOM] to place it on the screen and, and you can use IsInRect() to test if the X/Y position is within the rect of the particular image you drew. It is your responsibility to keep track of which click occured when…

http://psychtoolbox.org/docs/GetMouse

http://psychtoolbox.org/docs/Screen-DrawTexture

http://psychtoolbox.org/docs/PsychRects

http://psychtoolbox.org/docs/IsInRect

1 Like

I need to present already made images as stimuli. is there a function to insert them?

There are ways to do that yes. Look here for some demos
https://peterscarfe.com/ptbtutorials.html

1 Like

Specifically: https://peterscarfe.com/showimagedemo.html

@dcnieho @Ian-Max-Andolina I have a couple of doubt regarding my question which is about uploading multiple images and presenting them in parallel.
1.So here i’m trying to present three images of continents in parallel, one of which the user can click on to view few countries from the corresponding Continent. I’m unable to present multiple images because I’m not sure how to define destination for each texture with the screen function for the corresponding images. now the code which i tried just displays one picture in the top right corner. I want all three pictures to form a row in the middle of the screen, with one picture in the middle and other two on either side.
2. how to define the mouse response, such that if the user clicks on any of Continent, it will lead to presentation of three more images of countries within that Continent.
p.s i’m a beginner, so any ideas on how to implement this will be helpful.
the code so far is ,
close all
clear all
sca
clc
PsychDefaultSetup(2);

%finding screen
screens=Screen(‘Screens’);

screenNumber=max(screens);
%creating screen
%opening window with black screen
black=BlackIndex(screenNumber);

%uploading images from the folder
Stimulifolder=([‘C:\Users\RAMPRIYADARSHNI\Desktop’ filesep ‘agency experiment’ filesep ‘southamerica’]);
C1=imread(‘southamerica.png’);
% C2=imread([Stimulifolder ‘africa.png’]);
% C3=imread([Stimulifolder ‘europe.png’]);

%opening window
[window, windowRect]=PsychImaging(‘Openwindow’,screenNumber,black);

%converting C1 image into texture and presenting it
imageTexture = Screen(‘MakeTexture’, window,C1);
Screen(‘DrawTexture’, window, imageTexture,[],[200 200 600 600]);
Screen(‘Flip’, window);

WaitSecs(2);
sca;

You are almost there. You create a texture for each image, and a [rect] for each image; then you can use Screen('DrawTextures') to efficiently draw them in one go (you can also use 3 seperate 'DrawTexture' commands, but it is less efficient). Next you use IsInRect to work out if the mouse is inside one of the rects and perform some logical action. In my sample 3 images are shown and a mouse hover over the first highlights the image with a yellow box; you need to change the logic for your case to present the next set of images.

PsychDefaultSetup(2);
screen=max(Screen('Screens'));
C1=imread('I1.png');
C2=imread('I2.png');
C3=imread('I3.png');
%opening window
[window, windowRect]=PsychImaging('Openwindow', screen, [0.2 0.2 0.2], [0 0 900 900]);
xcen = windowRect(3)/2;
ycen = windowRect(4)/2;
% make a texture for each picture
T1 = Screen('MakeTexture', window, C1);
T2 = Screen('MakeTexture', window, C2);
T3 = Screen('MakeTexture', window, C3);
T = [T1 T2 T3]; %make an vector of texture pointers
% make a rect for each
rect1 = CenterRectOnPointd([0 0 200 200], xcen-(xcen/2), ycen)';
rect2 = CenterRectOnPointd([0 0 200 200], xcen, ycen)';
rect3 = CenterRectOnPointd([0 0 200 200], xcen+(xcen/2), ycen)';
rects = [rect1 rect2 rect3]; %row for each rect
vbl = Screen('Flip',window); startT = vbl;
while vbl <= startT + 5
	Screen('DrawTextures', window, T,[],rects);
	[x,y]=GetMouse(window);
	if IsInRect(x, y, rect1) %check mouse is inside rect1
		Screen('FrameRect', window , [1 1 0], rect1, 5);
	end
	vbl = Screen('Flip', window);
end
sca
2 Likes

Thank you so much for taking time to respond. one more query.I have changed the condition to the way i want, so moving the cursor onto the continent , displays its countries. But is there a function instead of IsInRect which will allow the user to click on the Continent to view the countries. And i want to log all the mouse responses, in which order the user clicks it.

 vbl = Screen('Flip',window); startT = vbl;
    while vbl <= startT + 1000
    	Screen('DrawTextures', window,T,[],rects);
    	[x,y]=GetMouse(window);
        if IsInRect(x,y, rect1) %check mouse is inside rect1
    		
            Screen('DrawTextures',window,t1,[],rects);
        end
        if IsInRect(x,y,rect2)
            
            Screen('DrawTextures',window,t2,[],rects);
        end
       
        if IsInRect(x,y,rect3)
            Screen('DrawTextures',window,t3,[],rects);
        end
    	vbl = Screen('Flip', window);
    end
    sca

GetMouse returns button presses:

http://psychtoolbox.org/docs/GetMouse

Therefore just get the buttons and && that in your logic. PTB will not log any of this, you need to do it yourself:

whatClicked = struct();
startT = GetSecs;
nTrials = 1;
while nTrials <= 10
	nextPhase = false;
	while nextPhase == false
		Screen('DrawTextures', window, T,[],rects);
		vbl = Screen('Flip', window);
		[x,y,buttons]=GetMouse(window);
		if IsInRect(x,y,rect1) && any(buttons)
			nextPhase = true;
			whatClicked(nTrials).option = 1; %#ok<*SAGROW>
			whatClicked(nTrials).time = GetSecs-startT;	
		elseif IsInRect(x,y,rect2) && any(buttons)
			nextPhase = true;
			whatClicked(nTrials).option = 2; 
			whatClicked(nTrials).time = GetSecs-startT;	
		elseif IsInRect(x,y,rect3) && any(buttons)
			nextPhase = true;
			whatClicked(nTrials).option = 3; 
			whatClicked(nTrials).time = GetSecs-startT;	
		end
	end
	while false
	% your next phase code here
	end
	Screen('Flip', window); WaitSecs(1); %inter trial time
	nTrials = nTrials + 1;
end

I don’t understand whats the function of the code below.

whatClicked(nTrials).option = 1; %#ok<*SAGROW>
			whatClicked(nTrials).time = GetSecs-startT;

This is just logging for each trial (nTrials = number of the trial), which of the three pictures was clicked (option = 1, 2 or 3) and the time is the time relative to the start of the experiment (GetSecs-startT). So you can then check for e.g. what the subject clicked on the third trial with whatClicked(3).option. This nothing to do with PTB, it is just the sort of logic you need to keep track of what your subjects are doing when.

1 Like

Thanks makes sense. Is there a function similar to KbWait for mouse response, where the stimulus is present till the next mouse response.

Not that I know of, but it would be easy to write your own, something like this (untested):

function [x,y,buttons] = WaitMouse(window)
  x=[]; y=[]; buttons=[];
  while 1
    [x,y,buttons] = GetMouse(window);
    if any(buttons)
        break;
    end
  end
end
1 Like

One more question regarding the code i’m working on. i have tried to implement using while loop as the below code. i do not understand why my second loop is skipped
%level 1 displays images of three continents, when clicked on either one of them, it leads to level 2 where countries within the clicked continent appears and when clicked on, leads to level three which has information about countries, its food, culture etc. P.s code is not yet complete for rect2,rect 3 of level 3.

        >  level_1=true;
         while level_1==true
        Screen('DrawTextures', window,T,[],rects);
    [x,y,buttons]=GetMouse(window);
    % europe response
    if IsInRect(x,y, rect1)
        Screen('FrameRect', window , [1 0 0], rect1,5)
        
        if any (buttons)
            level_2=true;
            level_1=false;
            europe=true;
        end
            
    
         
    %south america response
        elseif IsInRect(x,y,rect2)
            Screen('FrameRect',window,[1 0 0],rect2,5)
            if any (buttons)
            level_2=true;
            level_1=false;
            southamerica=true;
        end
    
    % africa response
    elseif IsInRect(x,y,rect3)
        Screen('FrameRect',window,[1 0 0],rect3,5)
        if any (buttons)
            level_2=true;
            level_1=false;
            africa=true;
        end
    end
    vbl = Screen('Flip', window);
    
end
%LEVEL 2:COUNTRIES (GREECE,SPAIN,FRANCE)
while level_2==true
    if europe==true
        Screen('DrawTextures', window,t1,[],rects);
        [x,y,buttons]=GetMouse(window);
        if IsInRect(x,y, rect1)
            Screen('FrameRect', window , [1 0 0], rect1,5)
            if any (buttons)
                level_3=true;
                level_2=false;
                greece=true;
            end
            
        end
   
    
    elseif southamerica==true
        Screen('DrawTextures', window,t2,[],rects);
        [x,y,buttons]=GetMouse(window);
        if IsInRect(x,y, rect1)
            Screen('FrameRect', window , [1 0 0], rect1,5)
            if any (buttons)
                level_3=true;
                level_2=false;
            end
            
        end
    
    
    elseif africa==true
        Screen('DrawTextures', window,t3,[],rects);
        [x,y,buttons]=GetMouse(window);
        if IsInRect(x,y, rect1)
            Screen('FrameRect', window , [1 0 0], rect1,5)
            if any (buttons)
                level_3=true;
                level_2=false;
            end
            
        end
    end
    vbl = Screen('Flip', window);
   
  
end


%LEVEL3: INFORMATION ON EACH COUNTRIES (CULTURE,HISTORY&POLITICS,FOOD)
while level_3==true
    if greece==true
        Screen('DrawTextures', window,t11,[],rects);
        [x,y,buttons]=GetMouse(window);
        if IsInRect(x,y, rect1)
            Screen('FrameRect', window , [1 0 0], rect1,5)
            if any (buttons)
                level_3=false;
            end
        end
    end
    vbl = Screen('Flip', window);
    
    
end

GetClicks does that:
http://psychtoolbox.org/docs/GetClicks

thanks.what is the difference between GetMouse and GetClicks? Get click waits for the mouse click while get mouse is just for tracking? i dont undersatnd what buttons in the get mouse function means.

GetClicks is a wrapper around GetMouse (i.e. it uses GetMouse, read the code), handling the logic of recording multiple mouse clicks (unless you set interClickSecs to 0), whereas GetMouse returns the current state of the mouse immediately.

buttons is an array of which button (left,right,middle) was pressed. From the help:

“buttons” is a 1xN matrix where N is the number of
mouse buttons. Each element of the matrix represents one mouse button.
The element is true (1) if the corresponding mouse button is pressed and
false (0) otherwise.

I’m not sure why your loop fails, you should use the MATLAB step debugger and step line-by-line to work out what is going wrong, you can use PsychDebugWindowConfiguration so you can see and manipulate the debugger if you are using a single screen…

1 Like

Thanks for the clarification. :slightly_smiling_face: