Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

[solved] Dynamic visual search experiment

edited April 2016 in OpenSesame

I'm trying to create a simple visual search experiment in which a variable number of objects move around randomly on screen throughout the trial. A target (defined by colour) may be present or absent on each trial. I've been trying to adapt the code from a previous request for a multiple-object-tracking experiment (http://forum.cogsci.nl/index.php?p=/discussion/277/open-using-opensesame-for-m-o-t-task/p1). That code generates displays which are ALMOST exactly what I need.

That is, it gives me:

  1. A fixation screen containing items in a starting position
  2. Items that move around at a specified velocity, avoiding one another and elastically bouncing back from the display boundaries.

All I need in addition is to have one target maintain its different colour throughout the trial, and have the trial terminate with a keypress.

Can anyone help?

Comments

  • edited 11:04PM

    Hey,

    would you mind pasting the code that you currently use here? In the discussion you are referring to, there are plenty versions around, so it could be a bit confusing trying to add the stuff you need.

    Thanks,

    Eduard

  • edited April 2016

    Hi Eduard,

    Thanks for your response. This is the code I'm currently using. Some of it is unnecessary for what I want, but it is a good starting point.

    # Import the necessary modules
    import random
    import math
    from openexp.canvas import canvas
    from openexp.mouse import mouse
    
    # Define some general properties of the experiment
    NStim = 18
    NTarget = 1
    NFrames = 5000
    maxRotSpeed = .1
    firstFrameDur = 500
    targetColor = 'red'
    normalColor = 'black'
    
    # Create a list of stimuli, with various properties
    stimList = []
    for i in range(NStim):
            x = random.randint(0, self.get('width'))
            y = random.randint(0, self.get('height'))
            a = random.random() * 2*math.pi
            v = 50
            r = 20
            stimList.append( (x, y, a, v, r) )
    
    # Create a canvas
    # (See documentation: http://osdoc.cogsci.nl/python-inline-code/canvas-functions)
    myCanvas = canvas(exp)
    
    # Loop through all frames
    for j in range(NFrames):
    
            # For each frame, clear the canvas and then loop through all stimuli
            myCanvas.clear()
            for i in range(NStim):
                    # Get the stimulus properties
                    x, y, a, v, r = stimList[i]
                    # Update the position of the stimulus based on the angle and the speed
                    x += v * math.cos(a)
                    y += v * math.sin(a)   
                    # If the stimulus leaves the screen, reverse direction by 180 deg (= 1pi radial)
                    if x <= 0 or x >= self.get('width') or y <= 0 or y >= self.get('height'):
                            a = a + math.pi
                    else:
                            # else randomly rotate the stimulus a bit
                            a += (random.random()-.5) * maxRotSpeed                
                    # Highlight the targets on the first frame
                    if i < NTarget and j == 0:
                            color = targetColor
                    else:
                            color = normalColor                    
                    # Draw the stimulus
                    myCanvas.circle(x, y, r, fill=True, color=color)
                    # Store the new stimulus properties back in the stimulus list
                    stimList[i] = x, y, a, v, r
            # Show the canvas      
            myCanvas.show()
            # Sleep after the first frame so that the participant can identify the targets
            if j == 0:
                    self.sleep(firstFrameDur)
    # Store the coordinates of the stimuli in the last frame, in order to compare
    # the mouse click responses with the actual positions
    
    stimID = 0
    # Loop through the stimulus list
    for stimProperties in stimList:
            stimID +=1
            # By setting variables with the exp.set() function you make sure the variables
            # are also available in the GUI (notably, the logger item)
            exp.set("xStim"+str(stimID), stimProperties[0])
            exp.set("yStim"+str(stimID), stimProperties[1])
    
    # Collect response
    responseID = 0
    for i in range(NTarget):
            responseID +=1
            print responseID
            # Initiate a mouse object
            # (See documentation: http://osdoc.cogsci.nl/python-inline-code/mouse-functions)
            my_mouse = mouse(exp, visible = True)
            # Collect the response
            button, position, timestamp = my_mouse.get_click()
            # Set the x and y coordinates of the response so that they will be logged by the
            # logger item. Position is an (x,y) tuple in screen coordinates
            exp.set("xMouseClick"+str(responseID), position[0])
            exp.set("yMouseClick"+str(responseID), position[1])
    
  • edited 11:04PM

    Can you try to replace these lines:

    if i < NTarget and j == 0:
        color = targetColor
    

    with these ones:

    if i < NTarget:
        color = targetColor
    

    Does this work?

    Eduard

    Btw. I edited your post, so that it is easier to read.

  • edited 11:04PM

    Hang on - need to make that clearer...

  • edited 11:04PM

    I can't embed the code, but here's the weblink where you can find it:

    http://pastebin.com/giytX4uF

  • edited 11:04PM

    Have you seen my response?

  • edited 11:04PM

    I have, thanks. It's hard to tell if it works because there is another problem: the display does not appear centrally on my monitor. The whole display is shifted to the bottom right quadrant, meaning I cannot see all the items.

    Incidentally, this second issue has occurred with the latest version of OpenSesame v3.

  • edited 11:04PM

    That is, it worked OK on v1, but has gone askew on v3.

  • edited 11:04PM

    Either disable the checkbox Uniform coordinates in the very first item in the overview area (New experiment, or something similar), or subtract half the width/height from all coordinates in the code. The code was written in a version of Opensesame that was older then 3.0.x, in which (0,0) refers to the top left corner. From 3.0.x on, (0,0) refers to the center of the screen.

    Eduard

  • edited 11:04PM

    That's more like it - it seems to be working!

    I would like to recolor the targets on a trial-by-trial basis. If I were to do this in the experimental loop, can I create a variable (say, called, "TargCol") and then refer to it in the script, as

    targetColor = '[TargCol]'

    And in the experiment loop, would that variable contain the colors as stipulated in RGB values?

  • edited 11:04PM

    Almost. you would have to refer to it like so: var.TargCol. If you use standard colors, you can also use strings (e.g. red,green, etc). If you need very particular colors, you probably better use the exact labels. You can have a look on this site here. There are many color related information that might help you.

    Good luck,

    Eduard

  • edited 11:04PM

    Seems to work perfectly now. Many thanks, Eduard.

  • edited 11:04PM

    My query is a continuation of the above thread, started by my colleague. The experiment is a visual search task in which a variable number of objects move around randomly on screen throughout the trial. A target (defined by colour) may be present or absent on each trial.

    As it stands, the array is on screen for a specified number of frames, after which a mouse cursor appears and is controlled by the user. A left click records the xy position of the cursor and the trial terminates and the next trial begins.

    What I need is the following:

    1. Even though the velocity of the objects is fixed (defined as v in the script below), the smaller arrays move noticeably faster than the larger arrays. Is this likely to be a hardware issue?

    2. Rather than have the display run to a fixed number of frames (defined as NFrames in the script), after which the mouse cursor appears and a response can be made, I would like NFrame to specify the maximum run length of a trial before time-out. The trial should be terminated at any point before NFrame completion, where any movement of the mouse makes the cursor appear. When the left click takes place, the data logger records the coordinates and a new trial can begin.

    3. I have defined the target in the script as TC (when it is present in the array) or as DS (when it is absent, and all objects are then the same colour). In the resulting data file, the xy coordinates of all the stimulus objects in the array are provided. Would you know: (i) whether the target is always assigned the same same object number in the data file (e.g., Stim1)? and (ii) whether those xy coordinates refer to the starting positions of the objects, or their positions at the end of the sequence?

    Many thanks in advance! You can access the script at the link below (as I can't get the embed function to work)...

    https://gist.github.com/anonymous/a29b67a3a125bbe35c4ff9e8fe60b717

Sign In or Register to comment.