Routine isn't working as usual after insert an if-loop

Hej all,

I’m having difficulties with the code I’m currently writing for an experiment. It’s about the self-other distinction in spatial and temporal conflicts.
These are the routines of the entire experiment.

That’s my problem: the routines “trial_delay” and “trial_spatial” work without any problems. But when I insert an if loop that says if the condition is “delay” the routine “trial_delay” continues, otherwise skip it, the routine “trial_delay” no longer works as planned. The cursor (red dot) is no longer visible.

This is the section of the code.

# --- Prepare to start Routine "trial_delay" ---
        continueRoutine = True
        if stim_cond == 'temp_delay':
            continueRoutine = True
        else:
            continueRoutine = False
        
        if continueRoutine:
            mouse.x = []
            mouse.y = []
            mouse.time = []
            gotValidClick = False  # until a click is received
                
            # Variables to store delayed_x and delayed_y
            delayed_x_values = []
            delayed_y_values = []
                
            thisExp.addData('trial_delay.started', globalClock.getTime())
            key_resp_ready_delay.keys = []
            key_resp_ready_delay.rt = []
            _key_resp_ready_delay_allKeys = []
            
            # keep track of which components have finished
            trial_delayComponents = [mouse, key_resp_ready_delay]
            for thisComponent in trial_delayComponents:
                thisComponent.tStart = None
                thisComponent.tStop = None
                thisComponent.tStartRefresh = None
                thisComponent.tStopRefresh = None
                if hasattr(thisComponent, 'status'):
                    thisComponent.status = NOT_STARTED
            
            # reset timers
            t = 0
            _timeToFirstFrame = win.getFutureFlipTime(clock="now")
            frameN = -1
                
            # setup ellipse
            ellipse_vertices = draw_ellipse(a, b, points, x_off, y_off)
            ellipse.setVertices(np.array(ellipse_vertices).T)  
                
            # --- Run Routine "trial_delay" ---
                
            routineForceEnded = not continueRoutine
            while continueRoutine and routineTimer.getTime() < 20.0:
                # get current time
                t = routineTimer.getTime()
                tThisFlip = win.getFutureFlipTime(clock=routineTimer)
                tThisFlipGlobal = win.getFutureFlipTime(clock=None)
                frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
                # is it time to end the Routine?
                if tThisFlip > 20-frameTolerance:
                    continueRoutine = False
                
                # delay for x and y (deque)
                delay = stim_list[current_stim]
                #delayed_x, delayed_y = 0, 0
                my_deque_x, my_deque_y = deque ([]), deque ([])
                    
                # Get the current mouse position
                current_mouse_pos = mouse.getPos()
                        
                # Append the current y-coordinate to the deque
                my_deque_x.append(current_mouse_pos[0])
                my_deque_y.append(current_mouse_pos[1])
                
                if len(my_deque_x) > delay:
                    my_deque_x.popleft()
                if len(my_deque_y) > delay:
                    my_deque_y.popleft()

                # Calculate the new position with a delay
                delayed_x = my_deque_x[0]
                delayed_y = my_deque_y[0]
                
                new_pos = (delayed_x, delayed_y)
                    
                # Update the dot's position
                cursor.setPos(new_pos)
                
                # Draw the ellipse
                ellipse.draw()
                
                # Draw the dot
                cursor.draw()  
                    
                   
                #store the values of delayed_x and delayed_y in each frame
                delayed_x_values.append(delayed_x)
                delayed_y_values.append(delayed_y)
                    
                # if key_resp_ready_delay is starting this frame...
                if key_resp_ready_delay.status == NOT_STARTED and t >= 0.0-frameTolerance:
                    # keep track of start time/frame for later
                    key_resp_ready_delay.frameNStart = frameN  # exact frame index
                    key_resp_ready_delay.tStart = t  # local t and not account for scr refresh
                    key_resp_ready_delay.tStartRefresh = tThisFlipGlobal  # on global time
                    win.timeOnFlip(key_resp_ready_delay, 'tStartRefresh')  # time at next scr refresh
                    # add timestamp to datafile
                    thisExp.addData('key_resp_ready_delay.started', t)
                    # update status
                    key_resp_ready_delay.status = STARTED
                    # keyboard checking is just starting
                    key_resp_ready_delay.clock.reset()  # now t=0
                    key_resp_ready_delay.clearEvents(eventType='keyboard')
                # if key_resp_ready is stopping this frame...
                if key_resp_ready_delay.status == STARTED:
                    # is it time to stop? (based on global clock, using actual start)
                    if tThisFlipGlobal > key_resp_ready_delay.tStartRefresh + 20.0-frameTolerance:
                        # keep track of stop time/frame for later
                        key_resp_ready_delay.tStop = t  # not accounting for scr refresh
                        key_resp_ready_delay.frameNStop = frameN  # exact frame index
                        # add timestamp to datafile
                        thisExp.addData('key_resp_ready_delay.stopped', t)
                        # update status
                        key_resp_ready_delay.status = FINISHED
                        key_resp_ready_delay.status = FINISHED
                if key_resp_ready_delay.status == STARTED:
                    theseKeys = key_resp_ready_delay.getKeys(keyList=['down'], ignoreKeys=["escape"], waitRelease=False)
                    _key_resp_ready_delay_allKeys.extend(theseKeys)
                    if len(_key_resp_ready_delay_allKeys):
                        key_resp_ready_delay.keys = _key_resp_ready_delay_allKeys[-1].name  # just the last key pressed
                        key_resp_ready_delay.rt = _key_resp_ready_delay_allKeys[-1].rt
                        key_resp_ready_delay.duration = _key_resp_ready_delay_allKeys[-1].duration
                        # a response ends the routine
                        continueRoutine = False
                    
                # if mouse is starting this frame...
                if mouse.status == NOT_STARTED and t >= 0.0-frameTolerance:
                    # keep track of start time/frame for later
                    mouse.frameNStart = frameN  # exact frame index
                    mouse.tStart = t  # local t and not account for scr refresh
                    mouse.tStartRefresh = tThisFlipGlobal  # on global time
                    win.timeOnFlip(mouse, 'tStartRefresh')  # time at next scr refresh
                    # update status
                    mouse.status = STARTED
                    mouse.mouseClock.reset()
                    prevButtonState = mouse.getPressed()  # if button is down already this ISN'T a new click
                    
                # if mouse is stopping this frame...
                if mouse.status == STARTED:
                    # is it time to stop? (based on global clock, using actual start)
                    if tThisFlipGlobal > mouse.tStartRefresh + 20.0-frameTolerance:
                        # keep track of stop time/frame for later
                        mouse.tStop = t  # not accounting for scr refresh
                        mouse.frameNStop = frameN  # exact frame index
                        # update status
                        mouse.status = FINISHED
                if mouse.status == STARTED:  # only update if started and not finished!
                    x, y = mouse.getPos()
                    mouse.x.append(x)
                    mouse.y.append(y)
                    buttons = mouse.getPressed()
                    mouse.time.append(mouse.mouseClock.getTime())
                    #mouse not visible
                    mouse.setVisible(False)
                    
                # check for quit (typically the Esc key)
                if defaultKeyboard.getKeys(keyList=["escape"]):
                    thisExp.status = FINISHED
                if thisExp.status == FINISHED or endExpNow:
                    endExperiment(thisExp, inputs=inputs, win=win)
                    return
                    
                # check if all components have finished
                if not continueRoutine:  # a component has requested a forced-end of Routine
                    routineForceEnded = True
                    break
                continueRoutine = False  # will revert to True if at least one component still running
                for thisComponent in trial_delayComponents:
                    if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                        continueRoutine = True
                        break  # at least one component has not yet finished
                    
                # refresh the screen
                if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
                    win.flip()
                
            # --- Ending Routine "trial_delay" ---
            for thisComponent in trial_delayComponents:
                if hasattr(thisComponent, "setAutoDraw"):
                    thisComponent.setAutoDraw(False)
            thisExp.addData('trial_delay.stopped', globalClock.getTime())

            # store data for thisExp (ExperimentHandler)
            thisExp.addData('mouse.x', mouse.x)
            thisExp.addData('mouse.y', mouse.y)
            thisExp.addData('mouse.time', mouse.time)
            # store the date of delayed_x and delayed_y
            thisExp.addData('delayed_x_values', delayed_x_values)
            thisExp.addData('delayed_y_values', delayed_y_values)
            thisExp.addData('stimulus', stim_list[current_stim])
            thisExp.addData('stim_condition', stim_cond) 
            thisExp.nextEntry()
            # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
            if routineForceEnded:
                routineTimer.reset()
            else:
                routineTimer.addTime(-20.000000)

Where is the mistake? I would be very happy if someone had an idea about this. Thanks. :slight_smile:

Hej everyone,

I would like to make some adjustments to my last entry.

I’ve tried a few more things. However, I’m worried that the problem might be the .xlsx file that I’m using.
This is an example of my Excel file.
image

I upload this file in the “StimLoader” routine and randomize it in the ‘StimShuffler’ routine. By using the print function, I know that the uploading of the data works and also the randomization.
The units for the delays are frames. The unit of the radius ‘r’ is heights.

Does anyone have a solution based on the information? I would be very happy if anyone has an idea. It’s the first time I’m coding.

Attached is part of the code.

# --- Prepare to start Routine "trial_delay" ---
        #continueRoutine = True
        if stim_cond == 'temp_delay':
            continueRoutine = True
        if stim_cond == 'spat_off':
            continueRoutine = False
        
        if continueRoutine:
            mouse.x = []
            mouse.y = []
            mouse.time = []
            gotValidClick = False  # until a click is received
                
            # Variables to store delayed_x and delayed_y
            delayed_x_values = []
            delayed_y_values = []
            
            # delay for x and y (deque)
            delay = stim_list[current_stim] #unit:frames
            delayed_x, delayed_y = 0, 0
            my_deque_x, my_deque_y = deque ([]), deque ([])
# Rest of the code for Routine 'trial_delay'
# --- Prepare to start Routine "trial_spatial" ---
        #continueRoutine = True
        if stim_cond == 'spat_off':
            continueRoutine = True
        if stim_cond == 'temp_delay':
            continueRoutine = False
            
        # update component parameters for each repeat
        # setup some python lists for storing info about the mouse
        mouse.x = []
        mouse.y = []
        mouse.time = []
        gotValidClick = False  # until a click is received
            
        def find_the_intersection(X_e, Y_e, x, y, r, tol=1e-3):
            all_i = []
            for i in range(0, len(X_e)):
                if ((X_e[i] - x) ** 2 + (Y_e[i] - y) ** 2 - r ** 2 < tol) and ((X_e[i] - x) ** 2 + (Y_e[i] - y) ** 2 - r ** 2 > 0):
                    all_i.append(i)
            return all_i

        def draw_circle(x, y, r, points=1000):
            all_x = []
            all_y = []
            for t in np.linspace(0, 2 * np.pi, points):
                x_point = r * np.cos(t)
                y_point = r * np.sin(t)
                all_x.append(x_point)
                all_y.append(y_point)
            return np.array(all_x) + x, np.array(all_y) + y

        # Empty list to hold the intersection dots
        intersection_dots = []
            
        thisExp.addData('trial_spatial.started', globalClock.getTime())
        key_resp_ready_offset.keys = []
        key_resp_ready_offset.rt = []
        _key_resp_ready_offset_allKeys = []
        # keep track of which components have finished
        trial_spatialComponents = [mouse, key_resp_ready_offset]
        for thisComponent in trial_spatialComponents:
            thisComponent.tStart = None
            thisComponent.tStop = None
            thisComponent.tStartRefresh = None
            thisComponent.tStopRefresh = None
            if hasattr(thisComponent, 'status'):
                thisComponent.status = NOT_STARTED
        # reset timers
        t = 0
        _timeToFirstFrame = win.getFutureFlipTime(clock="now")
        frameN = -1
            
        # --- Run Routine "trial_spatial" ---
                
        routineForceEnded = not continueRoutine
        while continueRoutine and routineTimer.getTime() < 20.0:
            # get current time
            t = routineTimer.getTime()
            tThisFlip = win.getFutureFlipTime(clock=routineTimer)
            tThisFlipGlobal = win.getFutureFlipTime(clock=None)
            frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
            # update/draw components on each frame
            # is it time to end the Routine? (based on local clock)
            if tThisFlip > 20-frameTolerance:
                continueRoutine = False

            # draw functions to draw ellipse
            ellipse_vertices = draw_ellipse(a, b, points=1000, x_off=0, y_off=0)
                
            # parameters for the circle
            r = stim_list[current_stim]  # radius - change for spatial offset (unit: height)
            # draw functions to draw circle
            circle_vertices = draw_circle(x, y, r, points=1000)
# Rest of the code for Routine 'trial_offset'

Thank you. :slight_smile:

stim_overall has a comma instead of a decimal point. You could get around this by multiplying by 100 in the Excel and then divide by 100 in the code.

Avoid t as a variable in Builder. t is used for the time since the trial started.

Don’t define functions in Begin Routine if the routine is going to be used more than once. Is there a reason why you are using draw_circle instead of a polygon component?

Some of that code looks like it has been generated by Builder. Please make it easy for people to help by only showing code in code components and then showing your other components, routines and flow as screenshots.

Thanks for your answers and advice.