Howdy, Stranger!

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

Supported by

[solved] Pip & Pop concentric presentation

edited February 2014 in OpenSesame

Hello,

First of all, thank you for this great resource you are making available to us.

My question: I would like to adapt the script you published for the Pip & Pop task so that:

  • the stimuli appear on a specific number of concentric circles (I'm thinking 3 or 4) instead of in a rectangular grid.
  • I can store the location where the target appeared in each trial as one or two variables (preferably angle + distance to center)

My understanding of Python is very limited. I guessed that the piece of script below (your original script) handles building the stimulus. I thought maybe the RadialStim object (http://www.psychopy.org/epydoc/psychopy.visual.RadialStim-class.html) could do the job, however I am at a loss as to how I should implement it in this script or if it's even the way to go.

If there is any way you can point me in the right direction I would appreciate it very much!

Cheers,
Raquel

# Generate a list of orientations and positions
l_stim = [] # List of all stimuli
for i in range(n_dist):

    # Pick an orientation
    if i == 0:
        ori = ori_target
    else:
        ori = choice(ori_dist)

    # Pick a color:
    col = choice(colors)

    # Pick an available position on the screen
    redo = True
    while redo:
        x = randint(xmin, xmax)
        y = randint(ymin, ymax)
        redo = False
        for _stim,_x,_y,_ori,_col in l_stim+[fixdot]:
            d = sqrt( (_x-x)**2 + (_y-y)**2 )
            if d < min_d:
                redo = True
                break

    # Generate and save the stimulus            
    stim = PatchStim(self.experiment.window, tex=None, mask="gauss", pos=(x,y), size=size, ori=ori, color=col)
    l_stim.append( (stim,x,y,ori,col) )

Comments

  • edited 8:52PM

    Hi Raquel,

    The PsychoPy RadialStim class is used to display retinotopic-mapping-like stimuli. In your case, what you need to do is pick your stimulus coordinates so that they lie on an imaginary circle. This is actually quite easy, and you see it demonstrated in the script below, which is snippet from the script in the Pip & Pop example. As you can see, you need to change very little relative to the original.

    Basically, you use the stimulus number (i) to determine the angle. Because the first stimulus is always the target, you also need to rotate the stimulus display in its entirety by a random offset, otherwise the target will always appear at the same location. Does that make sense?

    If you have no experience with Python, I would recommend walking through one of the tutorials. You will need some knowledge if you want to create these types of dynamic stimulus displays!

    Cheers!
    Sebastiaan

    # (...)
    # This script is not standalone, but a snippet from the `dynamic_search_display`
    # script in the Pip & Pop example
    
    from math import cos, sin, pi   
    from random import randint
    
    # An offset, which determines the position of the target. I.e. how much the
    # entire circle of stimuli is rotated.
    offset = randint(1, n_dist) 
    
    # Generate a list of orientations and positions
    l_stim = [] # List of all stimuli
    for i in range(n_dist):
    
        # Pick an orientation
        if i == 0:
            ori = ori_target
        else:
            ori = choice(ori_dist)
    
        # Pick a color:
        col = choice(colors)
    
        # Use a radius and angle to determine the position of the stimulus
        a = 2*pi*(i+offset) / n_dist # Angle
        r = 200 # Radius
        x = cos(a) * r
        y = sin(a) * r
    
        # Generate and save the stimulus            
        stim = PatchStim(self.experiment.window, tex=None, mask="gauss", \
            pos=(x,y), size=size, ori=ori, color=col)
        l_stim.append( (stim,x,y,ori,col) )
    
    # (...)
    
  • edited 8:52PM

    This was exactly what I needed, many thanks!

    Cheers,
    Raquel

  • edited February 2014

    Hi Sebastiaan,

    Thanks again for your help, I have an experiment now that does ALMOST exactly what I want :). I was hoping to be able to share the code for a working experiment, instead I'm asking another question..

    I've adapted your code so that the stimuli appear on three concentric circles. The target can appear on any one of those circles. It works perfectly, except for when the target appears on the middle circle. In that case it jumps to the other side of the circle where it overlaps with the distractor at that same spot. I can't for the life of me figure out what I did wrong, maybe you can see my mistake?

    I'm only using set sizes 24 and 48. I've added the variable "eccent" which stands for eccentricity and determines value r for radius (100, 175 or 250).

    Cheers,
    Raquel

    # (...)
    # This script is not standalone, but a snippet from the `dynamic_search_display`
    # script in the Pip & Pop example
    
        # functions needed for radial stimuli generation
        from math import cos, sin, pi   
        from random import randint
    
        # An offset, which determines the position of the target. I.e. how much the
        # entire circle of stimuli is rotated. Depends on if the target appears on the 
        # inner, middle or outer circle
        offset_inner = randint(1, n_dist/6)
        offset_middle = randint(1, n_dist/3)
        offset_outer = randint(1, n_dist/2)
    
        # Generate a list of orientations and positions
        l_stim = [] # List of all stimuli
    
        # Lists of remaining values of r, after r has been assigned to the target 
        #(by the variable "eccent"). e.g. if eccent is 100 (inner circle) and
        # n_dist is 48, only 7 spots remain on the inner circle for distractors.
    
        radii_inner_48 = [100, 100, 100, 100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_middle_48 = [100, 100, 100, 100, 100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_outer_48 = [100, 100, 100, 100, 100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_inner_24 = [100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_middle_24 = [100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_outer_24 = [100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
    
        #Assigning a value r for radius and a value a for angle to the target and distractors:
    
        for i in range(n_dist):
    
            # Pick an orientation
            if i == 0:
                ori = ori_target
            else:
                ori = choice(ori_dist)
    
            # Pick a color:
            col = choice(colors)
    
            # Pick a radius
            if i == 0:
                r = eccent
            else:
                if n_dist == 48:
                    if eccent == 100:
                        r = radii_inner_48[i-1]
                    elif eccent == 175:
                        r = radii_middle_48[i-1]
                    else:
                        r = radii_outer_48[i-1]
                else:
                    if eccent == 100:
                        r = radii_inner_24[i-1]
                    elif eccent == 175:
                        r = radii_middle_24[i-1]            
                    else:
                        r = radii_outer_24[i-1]
    
    
            # Pick an angle, the number added to i represents the offset, which 
            # determines the position of the target. I.e. how much the
            # entire circle of stimuli is rotated.
            if r == 100:
                a = 2*pi*(i+offset_inner) / (n_dist/6)
            elif r == 175:
                a = 2*pi*(i+offset_middle) / (n_dist/3)
            else:
                a = 2*pi*(i+offset_outer) / (n_dist/2)
    
            # Use radius r and angle a to determine the position of the stimulus
    
            x = cos(a) * r
            y = sin(a) * r
    
            # Generate and save the stimulus            
            stim = PatchStim(self.experiment.window, tex=None, mask="gauss", pos=(x,y), size=size, ori=ori, color=col)
            l_stim.append( (stim,x,y,ori,col) )
    
    
    #(...)
    
  • edited 8:52PM

    Hi Raquel,

    One (probably the) thing that goes wrong is the division. Let's take a look at this:

     a = 2*pi*(i+offset_inner) / (n_dist/6)
    

    What you are doing is dividing by the division of two ints: (n_dist/6). The problem here is that int divisions always return an int, and never a float (in Python 2, which is used by OpenSesame). Or, phrased differently, decimals are lost.

    print 0/3 # will print 0
    print 1/3 # will print 0
    print 2/3 # will print 0
    print 3/3 # will print 1
    print 4/3 # will print 1
    

    What you need to do is make sure that one of the numbers is a float:

    print 1.0/3 # will print 0.333 ...
    print 1/3.0 # will print 0.333 ...
    

    For example:

     a = 2*pi*(i+offset_inner) / (float(n_dist)/6)
    

    Does that solve the issue?

    See also:

    Cheers,
    Sebastiaan

  • edited February 2014

    Hi Sebastiaan,

    Thanks for your comment! I used floats as you suggested, but that didn't solve the issue. In the end the problem was the order of the items in the lists defining the radii for the distracter items. If anyone would like to know about the reason for the problem just let me know. Below is a version of the script that seems to be working.

    Cheers,
    Raquel

    # (...)
    # This script is not standalone, but a snippet from the `dynamic_search_display`
    # script in the Pip & Pop example modified to present stimuli on 3 concentric circles.
    
    # functions needed for radial stimuli generation
        from math import cos, sin, pi   
        from random import randint
    
        # An offset, which determines the position of the target. I.e. how much the
        # entire circle of stimuli is rotated. Depends on if the target appears on the inner, middle or outer circle
        offset_inner = randint(1, float(n_dist)/6)
        offset_middle = randint(1, float(n_dist)/3)
        offset_outer = randint(1, float(n_dist)/2)
    
        # Generate a list of orientations and positions
        l_stim = [] # List of all stimuli
    
        # Lists of remaining values of r, after r has been assigned to the target (by the variable "eccent"). e.g. if eccent is 100 (inner circle) and
        # n_dist is 48, only 7 spots remain on the inner circle for distractors.
    
        radii_inner_48 = [100, 100, 100, 100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_middle_48 = [175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 100, 100, 100, 100, 100, 100, 100, 100, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_outer_48 = [250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 100, 100, 100, 100, 100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175]
        radii_inner_24 = [100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_middle_24 = [175, 175, 175, 175, 175, 175, 175, 100, 100, 100, 100, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250]
        radii_outer_24 = [250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 100, 100, 100, 100, 175, 175, 175, 175, 175, 175, 175, 175]
    
        #Assigning a value r for radius and a value a for angle to the target and distractors:
    
        for i in range(n_dist):
    
            # Pick an orientation
            if i == 0:
                ori = ori_target
            else:
                ori = choice(ori_dist)
    
            # Pick a color:
            col = choice(colors)
    
            # Pick a radius
            if i == 0:
                r = eccent
            else:
                if n_dist == 48:
                    if eccent == 100:
                        r = radii_inner_48[i-1]
                    elif eccent == 175:
                        r = radii_middle_48[i-1]
                    else:
                        r = radii_outer_48[i-1]
                else:
                    if eccent == 100:
                        r = radii_inner_24[i-1]
                    elif eccent == 175:
                        r = radii_middle_24[i-1]            
                    else:
                        r = radii_outer_24[i-1]
    
    
            # Pick an angle, the number added to i represents the offset, which determines the position of the target. I.e. how much the
            # entire circle of stimuli is rotated.
            if r == 100:
                a = 2*pi*(i+offset_inner) / (float(n_dist)/6)
            elif r == 175:
                a = 2*pi*(i+offset_middle) / (float(n_dist)/3)
            else:
                a = 2*pi*(i+offset_outer) / (float(n_dist)/2)
    
            # Use radius r and angle a to determine the position of the stimulus
    
            x = cos(a) * r
            y = sin(a) * r
    
            # Generate and save the stimulus            
            stim = PatchStim(self.experiment.window, tex=None, mask="gauss", pos=(x,y), size=size, ori=ori, color=col)
            l_stim.append( (stim,x,y,ori,col) )
    
    #...
    
  • edited 8:52PM

    Good to hear you got it working, and thanks for sharing the script!

Sign In or Register to comment.

agen judi bola , sportbook, casino, togel, number game, singapore, tangkas, basket, slot, poker, dominoqq, agen bola. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 50.000 ,- bonus cashback hingga 10% , diskon togel hingga 66% bisa bermain di android dan IOS kapanpun dan dimana pun. poker , bandarq , aduq, domino qq , dominobet. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 10.000 ,- bonus turnover 0.5% dan bonus referral 20%. Bonus - bonus yang dihadirkan bisa terbilang cukup tinggi dan memuaskan, anda hanya perlu memasang pada situs yang memberikan bursa pasaran terbaik yaitu http://45.77.173.118/ Bola168. Situs penyedia segala jenis permainan poker online kini semakin banyak ditemukan di Internet, salah satunya TahunQQ merupakan situs Agen Judi Domino66 Dan BandarQ Terpercaya yang mampu memberikan banyak provit bagi bettornya. Permainan Yang Di Sediakan Dewi365 Juga sangat banyak Dan menarik dan Peluang untuk memenangkan Taruhan Judi online ini juga sangat mudah . Mainkan Segera Taruhan Sportbook anda bersama Agen Judi Bola Bersama Dewi365 Kemenangan Anda Berapa pun akan Terbayarkan. Tersedia 9 macam permainan seru yang bisa kamu mainkan hanya di dalam 1 ID saja. Permainan seru yang tersedia seperti Poker, Domino QQ Dan juga BandarQ Online. Semuanya tersedia lengkap hanya di ABGQQ. Situs ABGQQ sangat mudah dimenangkan, kamu juga akan mendapatkan mega bonus dan setiap pemain berhak mendapatkan cashback mingguan. ABGQQ juga telah diakui sebagai Bandar Domino Online yang menjamin sistem FAIR PLAY disetiap permainan yang bisa dimainkan dengan deposit minimal hanya Rp.25.000. DEWI365 adalah Bandar Judi Bola Terpercaya & resmi dan terpercaya di indonesia. Situs judi bola ini menyediakan fasilitas bagi anda untuk dapat bermain memainkan permainan judi bola. Didalam situs ini memiliki berbagai permainan taruhan bola terlengkap seperti Sbobet, yang membuat DEWI365 menjadi situs judi bola terbaik dan terpercaya di Indonesia. Tentunya sebagai situs yang bertugas sebagai Bandar Poker Online pastinya akan berusaha untuk menjaga semua informasi dan keamanan yang terdapat di POKERQQ13. Kotakqq adalah situs Judi Poker Online Terpercayayang menyediakan 9 jenis permainan sakong online, dominoqq, domino99, bandarq, bandar ceme, aduq, poker online, bandar poker, balak66, perang baccarat, dan capsa susun. Dengan minimal deposit withdraw 15.000 Anda sudah bisa memainkan semua permaina pkv games di situs kami. Jackpot besar,Win rate tinggi, Fair play, PKV Games