lptwrite before or after Screen('Flip')?

Hi there,

I've programmed an experiment using PTB-3 (for a Windows XP system) and need to add code for sending event codes to an EEG system via the parallel port.

I learned about PortTalk after finding the FAQ on TTL triggers via the parallel port. I also read about how Screen('Flip') works and the variables it returns for timing information. The Flip documentation and the posts that I have found here suggest to me that the correct way to sync events codes with stimulus onsets is to call lptwrite once Screen('Flip') returns after being paused.

But I had second thoughts after re-reading the Setting Up an ERP Lab section in Steven Luck's Event-Related Potential Technique book. Specifically, on pg. 328 it says that the sequence of events below should be followed to ensure correct timing: "a) wait of the interrupt signal, b) send an event code, c) draw the stimuli in a manner that ensures that any changes in the intensity values stored by the frame buffer occur after the interrupt but before those values are read by the raster beam."

It sounds like the trigger is sent immediately *before* the flip occurs in this description. Since the book was written a while ago, I'm assuming that the sequence could refer to how to implement correct timing for triggers with previous versions of PTB or other stimulus presentation software.

But I'd like to know for sure. So my question is: Is the correct approach to call lptwrite immediately after Screen('Flip') returns? Or can the trigger be somehow synced to stimulus onset by calling lptwrite immediately before the flip occurs?

Many thanks,
Naveed
--- In psychtoolbox@yahoogroups.com, "naveedmtl" <naveedmtl@...> wrote:
> Thanks, Mario.
>
> I'm using DrawFormattedText to draw the stim and pass 'center' for both sx and sy.
>
> Can I use the second return value from DrawFormattedText (i.e., ny) as the value for ypos in the code that you provided below (i.e., the stimulus scanline)?
>

Should be good enough, ny - textSize would be a bit more accurate, but we're talking here about errors of maybe 10-20 microseconds per scanline.

For additional paranoia you can check for:

ok = (winfo.VBLEndline ~= -1) && (Screen('Preference', 'VBLTimestampingmode') == 1)

This would be false if beamposition timestamping is broken, disabled or fails at any point in the session.

If winfo.VBLEndline isn't > winfo.VBLStartLine then that is a sign ptb can't correct for the vblank duration -- onset timestamp would be up to 4% of a refresh duration too early, typically around 0.5 msecs.

And given how easy it is to make mistakes, i'd test this whole thing once with a photo-diode for peace of mind. Place the photo-diode at the stimulus position, record its signal on a channel on the eeg system and see if ttl trigger and photo-diode spike are offset by the amount of time you expect them to be offset, after all corrections etc.

-mario

> Best,
> Naveed
>
> --- In psychtoolbox@yahoogroups.com, "Mario" <mario.kleiner@> wrote:
> >
> >
> >
> > --- In psychtoolbox@yahoogroups.com, Naveed <naveedmtl@> wrote:
> > >
> > > Thanks, Andreas.
> > >
> > > The interrupt referred to in the quoted text is the vertical retrace
> > > interrupt that is sent by the video card just after the raster beam
> > > finishes a cycle.
> > >
> > > With regard to what you mentioned about stimulus onset delay due to
> > > vertical offset, that delay would be constant if the stimuli are always
> > > presented at a given location, right? I'm guessing that I just have to
> > > factor in that constant delay and I'll be good to go. Is that correct?
> > >
> >
> > Yes.
> >
> > > I'm more worried about variable delays between when the stimulus is drawn
> > > on the screen and when lptwrite actually gets called after Screen('Flip')
> > > returns. I was wondering whether I could factor in that variable delay by
> > > using the difference between FlipTimestamp and VBLTimestamp to identify the
> > > time-locking event across trials. Is that legitimate?
> > >
> >
> > Yes. With:
> >
> > [VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('Flip', ...);
> > lptwrite(whatever);
> > tpostwrite = GetSecs;
> >
> > % Margin of error for calculated triggerdelay: Trigger signal happened
> > % sometime between Fliptimestamp and tpostwrite:
> > uncertainty = tpostwrite - FlipTimestamp;
> >
> > % Delay between trigger signal and stimulus onset at top of screen:
> > triggerdelay = FlipTimestamp - StimulusOnsetTime;
> >
> > % True stimulus onset, corrected for vertical stimulus location ypos on screen:
> >
> > ifi = Screen('GetFlipInterval', window);
> > winfo = Screen('GetWindowInfo', window);
> >
> > % Correct for time from top scanline to "stimulus scanline":
> > trueOnset = StimulusOnsetTime + ifi * (ypos / winfo.VBLEndline);
> >
> > Compare trueOnset with FlipTimestamp to find relative offset between trigger signal and true stimulus update.
> >
> > This assumes timestamping works correctly - no warnings with regard to it, beampositiontimestamping enabled. It also assumes use of a CRT monitor.
> >
> > Certain gpu + driver combos on Windows and also os/x have bugs which can add a *constant* offset to the reported timestamps of up to 4% of the videorefresh duration, e.g., typically around < 0.5 msecs @ 60 Hz. PTB on OS/X can compensate for this for some gpu's iirc, the bias never happens on Linux, but ptb for Windows can't compensate for this.
> >
> > Other than that the timestamps should be usually accurate to better than < 0.1 msecs precision on a properly working system, if you use the Priority() command.
> >
> > -mario
> >
> > > Thanks again,
> > > Naveed
> > >
> > > On Wed, Nov 9, 2011 at 5:19 AM, Andreas Widmann <widmann@>wrote:
> > >
> > > > Hi Naveed,
> > > >
> > > > not sure what kind of interrupt Steve Luck referred to. Anyway, sending
> > > > the trigger directly after flip command returns is indeed the robust and
> > > > pragmatic approach for the majority of applications.
> > > >
> > > > Be aware that actual stimulus onset is delayed by a fraction of the flip
> > > > interval depending on vertical offset of the stimulus. We compensate
> > > > offline for this delay not to possibly introduce additional timing jitter.
> > > >
> > > > Best,
> > > > Andreas
> > > >
> > > > Am 08.11.2011 um 21:43 schrieb Naveed:
> > > >
> > > > >
> > > > >
> > > > > Hi there,
> > > > >
> > > > > I've programmed an experiment using PTB-3 (for a Windows XP system) and
> > > > need to add code for sending event codes to an EEG system via the parallel
> > > > port.
> > > > >
> > > > > I learned about PortTalk after finding the FAQ on TTL triggers via the
> > > > parallel port. I also read about how Screen('Flip') works and the variables
> > > > it returns for timing information. The Flip documentation and the posts
> > > > that I have found here suggest to me that the correct way to sync events
> > > > codes with stimulus onsets is to call lptwrite once Screen('Flip') returns
> > > > after being paused.
> > > > >
> > > > > But I had second thoughts after re-reading the Setting Up an ERP Lab
> > > > section in Steven Luck's Event-Related Potential Technique book.
> > > > Specifically, on pg. 328 it says that the sequence of events below should
> > > > be followed to ensure correct timing: "a) wait of the interrupt signal, b)
> > > > send an event code, c) draw the stimuli in a manner that ensures that any
> > > > changes in the intensity values stored by the frame buffer occur after the
> > > > interrupt but before those values are read by the raster beam."
> > > > >
> > > > > It sounds like the trigger is sent immediately *before* the flip occurs
> > > > in this description. Since the book was written a while ago, I'm assuming
> > > > that the sequence could refer to how to implement correct timing for
> > > > triggers with previous versions of PTB or other stimulus presentation
> > > > software.
> > > > >
> > > > > But I'd like to know for sure. So my question is: Is the correct
> > > > approach to call lptwrite immediately after Screen('Flip') returns? Or can
> > > > the trigger be somehow synced to stimulus onset by calling lptwrite
> > > > immediately before the flip occurs?
> > > > >
> > > > > Many thanks,
> > > > > Naveed
> > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> >
>