Using E-Prime's Onset Signal mechanism
Much has been written on the topic of accurate timing using E-Prime. See also the dedicated page on Using_E-Prime. There are several ways to send a trigger signal from the stimulation (STIM) computer to the MEG acquisition computer, but some of these will produce unpredictable timing errors under certain circumstances (e.g., using inline code & pre-release time together). I strongly recommend this page on the E-Prime support site.
Timing seems to work well with the 'OnsetSignalEnabled' method. The basic strategy is to insert inline code at the beginning of the experiment telling E-Prime to send a trigger every time it presents a certain object or objects (e.g., 'Target' and 'Blank'). This ensures that the trigger is time-locked to the presentation of the stimulus. [Note that this time-locking is NOT guaranteed if you simply insert an inline 'writeport' command ahead of the object if you are using pre-release time and vertical refresh syncing!] You will generally want to reset the port to 0 by enabling OnsetSignal on the following object with a value of '0', by setting an OffsetSignal with value '0' or by inserting inline code with 'writeport' and value 0 after the object. If you want the trigger value to vary with stimulus condition, you can accomplish this using inline code at the beginning of the trial.
The equivalent 'OffsetData' command will allow a trigger to be send when the object terminates. This can be used to send 0 to the parallel port, preparing the port for the next trigger. Used in this way the duration of your triggers will be the same as the duration of the actual stimulus presentation. Be careful when using pre-release, though, as we've found that this will make the object send the Offset trigger at pre-release time and not at the actual offset of the object.
There's one thing that you should be careful with when using the OffsetSignal. This is triggered at offset of the object, as you would expect, but sadly also on pre-release. In the latest version of E-Prime pre-release is set to the full duration of the object by default. This means that OnsetSignal and OffsetSignal now happen at the same time! You'll have to set pre-release to 0 to get the correct behaviour.
E-Prime have now also introduced a new mechanism, 'Task Events', that is supposed to replace the SignalData mechanism. To make sure your scripts will keep runnning correctly in the long run, you might want to look into Task Events and replace your SignalData calls.
Here's an example. Imagine a simple trial structure with a DisplayTarget text object followed by a DisplayBlank text object. We want to send a trigger from STIM to MEG whenever DisplayTarget is presented, and we want the trigger value to reflect the stimulus condition.
In the following code the address of the parallel port is assumed to be 0xD030, which is true for the current stimulus presentation computer. This is represented in E-Prime as &HD030. A more frequenly used address is 0x378, btw. The best way to get the correct address is to add a ParallelPort device to your script (in 'devices') and ask that for the correct address. That way your script will work on any machine with a parallel port, even if the addresses are different. This is how to do it:
Dim address as Long address = CLng("&H" & Hex(ParallelPort.Reserved1))
At the beginning of the session procedure, insert an inline object containing:
' Enable port signal (value 1 for now) for DisplayTarget: DisplayTarget.OnsetSignalEnabled = True DisplayTarget.OnsetSignalPort = &HD030 DisplayTarget.OnsetSignalData = 1 ' Or the same, but now using the 'address' variable: DisplayTarget.OnsetSignalEnabled = True DisplayTarget.OnsetSignalPort = address DisplayTarget.OnsetSignalData = 1
'Enable port signal (value 0) for DisplayBlank: DisplayBlank.OnsetSignalEnabled = True DisplayBlank.OnsetSignalPort = &HD030 DisplayBlank.OnsetSignalData = 0
At the beginning of the trial procedure, insert an inline object containing:
' Set DisplayTarget port signal value based on condition: DisplayTarget.OnsetSignalData = c.getattrib("ConditionCode")
Where 'ConditionCode' is a numeric variable in the range (1:255). This variable can be defined as a column in your List or using inline code.