You really should strive to use non-slip timing if possible. You don’t state why that currently isn’t achieved, but do look into a variety of past topics on this:
The documentation states:
When creating experiments in the Builder, PsychoPy will attempt to identify whether a particular Routine has a known endpoint in seconds. If so then it will use non-slip timing for this Routine (…). Routines that are able to use this non-slip method are shown in green in the Flow, whereas Routines using relative timing are shown in red."
What if I would like to define the length of a routine based on a column in the input file (to achieve variable intertrial interva…
That probably just introduces unnecessary complexity. You can rely on the TR of the scanner being very precise. Similarly, PsychoPy can show stimuli very precisely for two second durations, subject to some caveats. The important thing is to test that your task duration matches the scanner run precisely. The only important TR signal to catch is the very first one. After that, if things are specified correctly, you should find that your task ends within a millisecond or two of the intended duratio…
I’m using PsychoPy in an fMRI experiment. The PsychoPy routine is a total length of 297 seconds (composed of 66 trials of 4.5 seconds each). I would like to use non-slip timing and have read about the clock feature that would allow for it at https://www.psychopy.org/general/timing/nonSlipTiming.html . I’d really appreciate it if someone could direct me to a publicly assessible experiment on Pavlovia that uses it, so that I can see how the code is written within PsychoPy (I don’t have a computi…
opened 05:17AM - 06 Feb 19 UTC
🌟 enhancement
💻 app/ui
_Apologies for the length of this, but it might be useful to provide context for… the problem to then explore how it might be resolved._
Builder has a long-standing issue that leads to unnecessary accumulation of timing errors across consecutive trials. At the moment it makes a distinction between routines whose duration is known "at compile time", which get non-slip timing applied (and the cherished green routine icon in the flow panel). If the duration is not known in advance (e.g. because it is dependent on a participant response), then that form of timing can not be used, and the routine is coloured red:
https://github.com/psychopy/psychopy/blob/master/docs/source/general/timing/nonSlipTiming.rst
However, deciding which routines are eligible for non-slip timing is currently overly strict. e.g. if the duration of any of the stimuli within a routine is defined by a variable rather than a literal numeric value, then non-slip timing is not applied. This is despite the fact that even if the value of that variable is not known at the time the script is generated, it will be known at runtime, before the routine begins. Therefore, the value of that variable could be used in place of a literal value with no issue at all.
This can be demonstrated by editing a generated non-slip timing script to use a variable to specify trial duration. Let's say a routine contains a single stimulus with a duration of a constant 1.0 seconds, expressed as a literal value of 1.0, in a loop that runs 60 times. Non-slip timing will be applied, and the loop will run for almost exactly 60 s. But let's say the design requires the duration to vary across trials pseudo-randomly (20 trials each of 0.5, 1.0, and 1.5 seconds). The total duration should still be 60 seconds, but now the actual performance will run slightly longer than that, as non-slip timing will not be applied, due to the stimulus duration being specified as a variable. But if the generated non-slip version of the script is manually edited, with the variable name simply replacing the literal `1.0` value, it will run perfectly well and finish exactly at 60 s.
This sort of requirement (of consecutive trials of variable but deterministically-specified duration) is crucial in any task that requires staying in sync with some specified timeline (e.g. an fMRI acquisition sequence, or presenting words in time with an audio track playing in the background), and the absence of non-slip timing very quickly accumulates apparent errors over anything more than few repetitions.
Would it be possible to disallow "non-slip" timing only when it is actually impossible (e.g. when durations or end times are unspecified or contingent on a condition?) i.e. if duration, time, or frameN is specified with a variable name, that variable name should be treated just like a literal value in constructing an expression for the total duration of the routine.
I've tested this by manually editing scripts which have just a single duration specified, but things would naturally get more involved when dealing with multiple components, some or all of which might have variables in their duration or time fields. The key function in determining whether non-slip timing will be applied is `getMaxTime()` in `routine.py`:
https://github.com/psychopy/psychopy/blob/494d7fe4e7b24e41b67a692f1a077b1d308ac9ed/psychopy/experiment/routine.py#L382
This returns a `maxTime` value and a boolean specified whether non-slip timing can be applied. I guess it might need to be modified to return a list of times and variable names rather than a single numeric variable, which could then be used in a `max()` function in the line which determines the duration of a non-slip routine, in place of the current literal numeric value.
I'm reluctant to try to make changes to this function, and the code that handles its result when generating the script, as I'm not sure I really understand it and so am also not sure that I wouldn't introduce unintended consequences.
Any comments on this? Is it worth pursuing? I'd say it is, because it really does hamstring users in generating reliable scripts that are intended to produce long runs of consecutive trials, and those users will often be surprised by that non-obvious behaviour (the red/vs green routine icons notwithstanding).
1 Like