Skip to content

Builder routine: routineTimer for nonSlip can get reset too early #822

Description

@jeremygray

This is not necessarily a bug, but it tripped me up, and I think at the very least we need to tell people more about this situation: when a nonSlip routine follows a non-nonSlip (dynamic length) routine.

In a dynamic routine, the global routineTimer gets .reset() if the while loop is not exiting:

if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
    win.flip()
else:  # this Routine was not non-slip safe so reset non-slip timer
    routineTimer.reset()

(Seems like that could just be done once, just after the while loop when it exits, not every frame?)

However, if you have a code component in that dynamic routine and it has code in End Routine, that code will get run after the loop has ended (= after routineTimer has been reset). the routineTimer then ticks away and time elapses. In my case this was during launchScan(), which waits for user input. If the next routine is nonSlip (in my case: fMRI trials), time is then added to the routineTimer. But any already-elapsed time (during launchScan) will count against the total, which is incorrect behavior. Fortunately I noticed by eye because it was seconds, but I would not have noticed even 200ms (e.g., to load a large file). Maybe I would have seen this in the log or data files, but it would be easily missed.

To fix, I ended up putting routineTimer.reset(); routineTimer.add(someTimeValue) in code at the start of the next (= nonSlip) routine, but I think it would be better just to do routineTimer.reset() in the code at the end of the previous (dynamic) routine.

If there's a way to handle this properly in code, I think we should do it.

If its too complicated to try to handle programmatically, we should document and warn people about it.

Are there any other cases where routineTimer could get off from the intended behavior?

Activity

  1. jeremygray commented on Feb 1, 2015

    @jeremygray
    ContributorAuthor

    I suspect that the right thing to do is for routineTimer.reset() to happen as the very last thing upon completing a non-nonSlip (dynamic / unknown duration) routine, after any code in End Routine.

    But I have not fully thought through the logic of nonSlip as implemented, however, so maybe I am missing something. I am unsure what happens (and what should happen) when chaining multiple nonSlip routines together. Lets say we have A, B, C that are all supposed to take 1.000s, all are nonSlip. If A ends up taking 1.100s (say 1.000s during the while loop and 0.1s for something after the while loop but before the next routine, like code in a code comp end routine, or the code to set up a loop), then the next routine B will start late (by 0.1s) but will end "on time" (after 2.000s). I think there's a warning given that A took longer than expected? I did not get such a warning. Maybe that's only for ISI periods.

  2. added 2 commits that reference this issue on Feb 1, 2015
    01832d4
    d517c56
  3. added a commit that references this issue on Feb 2, 2015
    f8b6a14
  4. added 3 commits that reference this issue on Apr 21, 2015
    8309814
    6d63f58
    6445423
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions