Problems with randomized inter-trial intervals

Hi,

[Explanation for why I am shamelessly asking for help] I am sorry for asking for help in this shameful manner. If you are the kind of person who think that people should have a bit more knowledge themselves before posting here, please stop reading now.

I had built an experiment in the psychopy builder. Then, my collaborator was gonna tweak it and changed everything from the builder to just pure code. Then, however, my collaborator switched jobs with short notice and no longer had time to help me with this. Thus, I am now stuck with some code that I do not understand at all (I have extremely limited coding experience). [End of that explanation]

Almost everything in the code works perfectly except for one thing. I want to show some images with a random interstimulus interval between them. The interval should be randomized between 20 and 25 seconds (during which a fixation cross should be showing). The problem I have though is that the code just picks a number between 20 and 25, and then sticks with that number for every single trial, instead of individually picking one for each trial. I simply don’t know enough about programming to fix this, even if I imagine the solution to be pretty simple. Therefore I was wondering if anyone could perhaps take a look at the code to see if they could help me fix this?

I have created two different experiments, one that is a learning session, and one that is a re-test session. For the re-test session, things are even weirder, as the interstimulus interval is much shorter than what I have set it to be. I have uploaded both files here. There are a few hundreds lines of code in each, and they are nicely commented/annotated by my previous collaborator.

Once again, sorry for asking for help in such a shameless way while having almost no knowledge myself. Everything else in the code is working fine, and this is the last thing standing in the way for me to start the data collection, so if anyone could take a look, I’d be extremely grateful.

Best

Per

Conditioning_FINAL.py (37.6 KB)
ReTest_FINAL.py (26.6 KB)

Hi,

No need to apologise - this forum is here for people to get help!

OK, for a start I would ask how complicated is the task, if you are now stuck with code that you don’t understand - would it be faster to make the task from scratch in builder, in a way that you and most likely your future lab mates would feel comfortable editing in the future? If you would not feel confident making the experiment from scratch, but your department/lab has spare funds - you could also contact the team directly, who can make tasks from scratch (though this is a paid option).

In terms of this specific issue, “The problem I have though is that the code just picks a number between 20 and 25, and then sticks with that number for every single trial, instead of individually picking one for each trial” To make sure that the community can help as fast as possible, I would recommend sharing the specific code snippet where you are trying to achieve this (rather than the whole code file) then we can quickly eyeball what might be going wrong.

Thanks!
Becca

Hi,

As I am not 100 % sure exactly what part of the code does what, it has been a little difficult to find those exact places, but I think these are the parts regulating the fixation cross, which is what I want to be shown for between 20 and 25 seconds.

Initialize components for Routine “FixationCross”

FixationCrossClock = core.Clock()
import random
durre = random.randint(20,25)
thisExp.addData(‘random_duration’, durre)
fixationcross = visual.TextStim(win=win, name=‘fixationcross’,
text=’+’,
font=‘Arial’,
pos=(0, 0), height=0.05, wrapWidth=None, ori=0,
color=‘black’, colorSpace=‘rgb’, opacity=1,
languageStyle=‘LTR’,
depth=-1.0);

Initialize components for Routine “FixationCross”

FixationCrossClock = core.Clock()
import random
durre = random.randint(20,25)
thisExp.addData(‘random_duration’, durre)
fixationcross = visual.TextStim(win=win, name=‘fixationcross’,
text=’+’,
font=‘Arial’,
pos=(0, 0), height=0.05, wrapWidth=None, ori=0,
color=‘black’, colorSpace=‘rgb’, opacity=1,
languageStyle=‘LTR’,
depth=-1.0);

# ------Prepare to start Routine "FixationCross"-------
continueRoutine = True
# update component parameters for each repeat
# keep track of which components have finished
FixationCrossComponents = [fixationcross]
for thisComponent in FixationCrossComponents:
    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")
FixationCrossClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
frameN = -1

# -------Run Routine "FixationCross"-------
while continueRoutine:
    # get current time
    t = FixationCrossClock.getTime()
    tThisFlip = win.getFutureFlipTime(clock=FixationCrossClock)
    tThisFlipGlobal = win.getFutureFlipTime(clock=None)
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *fixationcross* updates
    if fixationcross.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
        # keep track of start time/frame for later
        fixationcross.frameNStart = frameN  # exact frame index
        fixationcross.tStart = t  # local t and not account for scr refresh
        fixationcross.tStartRefresh = tThisFlipGlobal  # on global time
        win.timeOnFlip(fixationcross, 'tStartRefresh')  # time at next scr refresh
        fixationcross.setAutoDraw(True)
    if fixationcross.status == STARTED:
        # is it time to stop? (based on global clock, using actual start)
        if tThisFlipGlobal > fixationcross.tStartRefresh + durre-frameTolerance:
            # keep track of stop time/frame for later
            fixationcross.tStop = t  # not accounting for scr refresh
            fixationcross.frameNStop = frameN  # exact frame index
            win.timeOnFlip(fixationcross, 'tStopRefresh')  # time at next scr refresh
            fixationcross.setAutoDraw(False)
    
    # check for quit (typically the Esc key)
    if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
        core.quit()
    
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in FixationCrossComponents:
        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 "FixationCross"-------
for thisComponent in FixationCrossComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
trials.addData('fixationcross.started', fixationcross.tStartRefresh)
trials.addData('fixationcross.stopped', fixationcross.tStopRefresh)
# the Routine "FixationCross" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()

------Prepare to start Routine “FixationCross”-------

continueRoutine = True
# update component parameters for each repeat
# keep track of which components have finished
FixationCrossComponents = [fixationcross]
for thisComponent in FixationCrossComponents:
    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")
FixationCrossClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
frameN = -1

# -------Run Routine "FixationCross"-------
while continueRoutine:
    # get current time
    t = FixationCrossClock.getTime()
    tThisFlip = win.getFutureFlipTime(clock=FixationCrossClock)
    tThisFlipGlobal = win.getFutureFlipTime(clock=None)
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *fixationcross* updates
    if fixationcross.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
        # keep track of start time/frame for later
        fixationcross.frameNStart = frameN  # exact frame index
        fixationcross.tStart = t  # local t and not account for scr refresh
        fixationcross.tStartRefresh = tThisFlipGlobal  # on global time
        win.timeOnFlip(fixationcross, 'tStartRefresh')  # time at next scr refresh
        fixationcross.setAutoDraw(True)
    if fixationcross.status == STARTED:
        # is it time to stop? (based on global clock, using actual start)
        if tThisFlipGlobal > fixationcross.tStartRefresh + durre-frameTolerance:
            # keep track of stop time/frame for later
            fixationcross.tStop = t  # not accounting for scr refresh
            fixationcross.frameNStop = frameN  # exact frame index
            win.timeOnFlip(fixationcross, 'tStopRefresh')  # time at next scr refresh
            fixationcross.setAutoDraw(False)
    
    # check for quit (typically the Esc key)
    if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
        core.quit()
    
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in FixationCrossComponents:
        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 "FixationCross"-------
for thisComponent in FixationCrossComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
Final2.addData('fixationcross.started', fixationcross.tStartRefresh)
Final2.addData('fixationcross.stopped', fixationcross.tStopRefresh)
# the Routine "FixationCross" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()

If anyone can figure out the issue, I’d be very very grateful!

//
Per

Hi

If you are using Builder then please only post your custom code components and describe or screenshot relevant components, routines and flow. Please help your potential helpers.

Best wishes,

Wakefield

Hi, as I said above I really wish I could be of more help. But as I said in my opening message - I don’t know what part of the code does what, and thus, that is sort of the best I can do in terms of sending you the code. I totally get that it gets difficult to help we this way but I thought it was worth a shot.

Best

Per

Screen shots of your components. For example, here’s a couple of screenshots related to one of my fixation crosses.

# Relevant variables in Begin Experiment
localHeight = .02
localWidth = .015
globalHeight = .2
globalWidth = .15
nY = 9
localHeight = globalHeight/nY