Setting ElementArray settings throws shape error

Hi,

I’m having an issue with getting my elementArrayStim to work as part of my experiment.
Essentially I am doing a retinal rivalry method of limits study whereby participants see conflicting gratings to each eye and we are interested at the point at which this rivalry stabilizes by starting with such gratings either with lots of dots (elementarrays, should start stable) or no dots (should be rivalrous).
I want to add about 125 dots every 500ms (around 30 frames @ 60Hz) until it stabilizes or degrades and participants press space.
To avoid heavy listing in the draw loop I have set my element arrays up top and want to simply adjust its settings on the fly in the loop:


dot_stim_L = visual.ElementArrayStim(
                                    winA,
                                    nElements = 100,
                                    xys = None,
                                    elementTex = None,
                                    units = "pix",
                                    colorSpace = "rgb",
                                    elementMask ="circle",
                                    sizes = dotSize)

dot_stim_R = visual.ElementArrayStim(
                                    winB,
                                    nElements = 100,
                                    xys = None,
                                    elementTex = None,
                                    units = "pix",
                                    colorSpace = "rgb",
                                    elementMask ="circle",
                                    sizes = dotSize)

… and in the while loop:

while True:

        dotsOnScreen = len(dotArray[0:dotIndex])
        
        dot_stim_L.nElements = dotsOnScreen
        dot_stim_R.nElements = dotsOnScreen
        dot_stim_L.xys = dotArray[0:dotIndex]
        dot_stim_R.xys = dotArray[0:dotIndex]
        dot_stim_L.colors = colorArray[0:dotIndex]
        dot_stim_R.colors = colorArray[0:dotIndex]

        #print dotArray[0:dotIndex]
        for frameN in range(30): 
            keys = kb.getKeys() 
            if len(keys) > 0:
                break

            grate_L.draw()
            grate_R.draw()

            dot_stim_L.draw()
            dot_stim_R.draw()

            winA.flip()
            winB.flip()

However, I end up with an error:

Traceback (most recent call last):
  File "dots_v3.2.py", line 285, in <module>
    dot_stim_L.draw()
  File "C:\Python27\lib\site-packages\psychopy\visual\elementarray.py", line 507, in draw
    self._updateVertices()
  File "C:\Python27\lib\site-packages\psychopy\visual\elementarray.py", line 590, in _updateVertices
    verts[0::4, 0] = -wx - hx
ValueError: could not broadcast input array from shape (100) into shape (1)

I managed to get this working by putting the dot_stim_L / R in the while loop (which resulted in awful performance) which is why I’m so puzzled.

For reference, here is my coordinate / color function that generates the array in dotArray and colorArray


def dotCoords(maxDots = 5000, radius = 300):
    ''' a function that generates coordinates of a circle 
        and pairs them with a color, either black or white
    '''

    # Define some random coordinates and convert to x and y coordinates
    rad = radius
    t = np.random.uniform(0.0, 2.0*np.pi, maxDots) # Angle between 0 and 2Pi (in radians)
    r = rad * np.sqrt(np.random.uniform(0.0, 1.0, maxDots)) 
    x = r * np.cos(t)                                       
    y = r * np.sin(t) #these convert to x,y from rads     
            
    
    coords = np.stack((x,y), axis = 1) # stack the two arrays horizontally (column wise)
    
    np.random.shuffle(coords)
    
    # Define a list of colors and shuffle them 
    color_lists = []
    for i in range(maxDots/2):
        color_lists.append([-1,-1,-1])
    for i in range(maxDots/2):
        color_lists.append([1,1,1])

    np.random.shuffle(color_lists)

    return coords, color_lists

Any ideas anyone?

for my full script, see this link: Rivarly experiment

Possibly something like sizes is not being updated with the change to nElements.

I’d suggest using the opacities parameter to change how many dots are visible on a given iteration. In other words, initialise with a large number of dots but then use opacities to make a subset of them not visible within your loop.

1 Like