Pavlovia: time-out routine after specified time

URL of experiment: https://run.pavlovia.org/Artabanos/primingbehavioural/html
Gitlab: Sign in · GitLab

Description of the problem: I’m trying to run an experiment I built with the PsychoPy builder online through Pavlovia. The experiment consists of two main parts: the first asks participants to judge whether two letter strings are the same or different for 30 seconds, the second is a more complex syntactic priming task.

I have the second part of the study all worked out, however I’m getting stuck with the conversion of my in-line builder script used to time-out the first part into JavaScript. The current code is as follows:

Does anyone have an idea about how I would go about converting these bits of code for Pavlovia? I attempted to work in this solution, but to no avail. All I really want is for the LCTtrials routine to time out after 30 seconds.

Thanks a lot for your help!

Hi @Artabanos, globalClock isn’t available in js.

The workaround I’ve used is initializing a max time in Begin Experiment:

maxTime = 30;

Then in Each Frame:

if (startTime.getTime() >= maxTime) {
    LCTTrials.finished = true;
    }

I think startTime is a clock property automatically set at the start of the routine, as least in psychojs as I don’t initialize it anywhere but it works as expected.

Hi! Thanks a lot for your suggestion. I tried putting in the lines of code you suggested, however I’m now facing the following error whenever the experiment progresses to the routine the code applies to:

image

It sounds like the getTime function doesn’t recognise startTime? As you said, startTime doesn’t appear to be initialised anywhere in the code - the first time it appears is as a variable in the routine I’m trying to time out.

Oh whoops, I made the task awhile ago and forgot I had a line in a separate code component in the prior routine that initializes. I have a code component in the routine immediately preceeding the task loop that initializes startTime in Begin Routine, along with the code described previously within the LCTTrials loop.
I’m guessing there’s a cleaner way to do this by including the initializing code within the Begin Routine tab of the task loop by initializing only if trials.thisN === 0, but I haven’t been successful.

For js you can use new util.Clock();. In addition to the code described above, create a code component in the routine just prior to LCTTrials with this in Begin Routine:

startTime = new util.Clock();

Hope that works for you!

Hi! Thanks again for your help, I now tried defining startTime using new util.Clock() in the previous routine - this worked! The trial ends after 30 seconds. Thanks a lot for your suggestions.

However, although the timing now works, it seems that after 30 seconds the routine isn’t actually terminated - it simply moves to the following trial in the loop. What I am aiming for is to end the whole routine and move to the following block of trials after 30 seconds. Would this be to do with the exact positioning of the continueRoutine = false statement?

@Artabanos Glad it worked for you!

Yes, this should work (I have it working in Each Frame):

if (startTime.getTime() >= maxTime) {
    LCTTrials.finished = true;
    continueRoutine = false;
}

Is that not ending the current routine? Your gitlab link doesn’t seem to be pointing to the experiment anymore so I can’t check it out. It’s only the online version that has the issue correct?

I hope this link works for you? If not, I’ve also uploaded my .psyexp file here.primingBehav.psyexp (355.4 KB)

I just checked again whether it’s under Each Frame - which it is, and whether the code is correct - which it seems to be. I just did another re-run of the experiment and it just seems like it’s progressing from trial to trial after 30 seconds, rather than actually finishing the routine and the loop.

The offline experiment is actually having some trouble running at the moment as the edits to the online JS script seems to have caused the offline Python script to not recognise the startTime.getTime() syntax, as per the image below. I’m guessing this is due to the JS timestamp syntax being different from the Python syntax?

image

Hi @Artabanos, thanks for sharing your experiment.

  1. The casing of true/false matters for it to be recognized correctly for both py & js. In py, both True and False need to be capitalized, while in js, they both need to be lowercase. You’ll see in py that once you capitalize True, it will turn a dark pink color which means it’s being recognized correctly.

  2. the “{” syntax is specific to js-- with py you use “:” for if statements

  3. In this case, the best Py version of timer I found to use is similar to the original code you posted.
    For initializing “startTime” & “maxTime”, you can use Auto > JS (and those are already working).
    For the Each Frame component, change to “Both” so that you can manually edit py & js separately.

Py:

if globalClock.getTime() - startTime >= maxTime:
    LCTTrials.finished = True;
    continueRoutine = False;

JS:

if (startTime.getTime() >= maxTime) {
    LCTTrials.finished = true;
    continueRoutine = false;
}

I haven’t tested on your exp but that should work, let me know how it goes!

Hi!
So after a lot of wrangling this morning it appeared there were conflicts between my offline code and online code (as I had mistakenly edited the code on gitlab rather than on psychopy alone). I followed your suggestions for selecting ‘both’ in psychopy and editing the code through there. After deleting and re-uploading my project with code edits only in psychopy, everything seems to work!

Thank you so much for your extensive and detailed help, the timer now works perfectly and the routine is ended completely after 30 seconds!

So glad to hear the timer works for you and you’ve solved the merge conflict, @Artabanos! Cheers!

1 Like