Psychophysiology Markers Standard
From ACLab Wiki
ACL PP Marker Standard
Contents |
[edit] Introduction
[edit] Experiment Structure
Let's say you have an experiment with 2 blocks, 2 trials each (4 total), and 1 event per trial. It would look roughly like this with markers:
[Experiment Begin Marker]
[Block 1 Begin Marker]
[Trial 1 Begin Marker]
Event 1
[Event 1 Marker]
[Trial 1 End Marker]
[Trial 2 Begin Marker]
Event 1
[Event 1 Marker]
[Trial 2 End Marker]
[Block 1 End Marker]
[Block 2 Begin Marker]
[Trial 3 Begin Marker]
Event 1
[Event 1 Marker]
[Trial 3 End Marker]
[Trial 4 Begin Marker]
Event 1
[Event 1 Marker]
[Trial 4 End Marker]
[Block 2 End Marker]
[Experiment End Marker]
[edit] Marker Structure
Each marker is actually a set of different numbers sent to Biopac in a certain sequence. Roughly:
SendPulse 111 '111 denotes that a marker set is coming
SendPulse [type] '1 = Experiment, 2 = Block, 3 = Trial
SendPulse [begin/end] '1 = Begin, 2 = End
SendPulse [other info] 'e.g. block/trial #
Event markers are special, and discussed further below.
SendPulse is a function defined in the user code and reused throughout. (see below)
[edit] User Code: SendPulse Function & Others
A Function is a common programming construct, generally used to simplify repeatable code. Below,
- the SendPulse function, in detail, sets the 8 pins of the parallel port to a certain value, waits 20 ms, then sets it to 0, then waits another 20 ms. It also does some error checking.
- the SendEventPulse function uses SendPulse to handle event markers, which require more careful attention to timing constraints.
- to see how the other parts of the code are used, read on and take a look at the sample experiment below.
Paste the following text into the User Script (push ALT-5) section of your experiment:
'SendPulse(..) - PP Marker function
Public Sub SendPulse(ByVal Value As Integer)
if Value = 0 then Value = 254
if (Value > 0) And (Value < 256) Then
WritePort 888,Value
Sleep 20
WritePort 888,0
Sleep 20
Else
MsgBox "SendPulse value of " & Value & " is invalid. Must be between 0 and 256"
End If
End Sub
'SendEventPulse(..) - PP Marker function for events
Public Sub SendEventPulse (ByVal eventType As Integer, ByVal timeMillisec As Integer)
If (timeMillisec < 0) Or (timeMillisec > 25500) Then
Msgbox "ERROR in SendEventPulse():\n" & _
"timeMillisec value of " & timeMillisec & " is invalid." &_
"Cannot have delays that are negative or longer than 25.5 seconds"
Else
SendPulse 111
SendPulse eventType
'If longer than 100 ms calculate and send the [100ms] and [ms] pulses
If timeMillisec > 100 Then
SendPulse timeMillisec \ 100
SendPulse timeMillisec Mod 100
Else
SendPulse 0
SendPulse timeMillisec
End If
End If
End Sub
'Global trial counter for trial markers
Dim trialCount As Integer
'Variables used for event markers
Dim startTime As Long
Dim elapsed As Long
'Pulsing Constants (these are used just like variables and make code more readable)
Const SOUND_EVENT As Integer = 11
Const TEXT_EVENT As Integer = 12
Const PICTURE_EVENT As Integer = 13
Const NO_CATEGORY As Integer = 1
[edit] Why Do I Need This Standard?
The markers that a PP experiment sends to Biopac need not have any standard--imagine you have an experiment with 4 trials and 3 events in each trial, you can send 12 markers, 1-12, and just note which trial marker refers to which trial & event combination. Remembering that we can send only 255 different markers, this would still be sufficient and easier for analysing a single-experiment. However, most experiments have more than 255 different trials + conditions combinations, and when you have more than a handful, it quickly becomes choresome, error-prone, and difficult to analyse. The ACL PP Marker Standard is one solution to reduce this with only a small cost (if followed correctly!) to the experiment programmer.
[edit] Important Notes
- DO NOT SEND A MARKER OF 0. The figure beneath shows what sending a 0 would look like. That is to say, sending a 0 is the same as sending nothing at all (the SendPulse function checks for this and sends a 254 instead of 0).
This means variables must also be ensured to be non-zero, such as in this case:
SendPulse c.GetAttrib("Subject")
[edit] Marker Code
[edit] Experiment Begin
SendPulse 111
SendPulse 1
SendPulse 1
[edit] Experiment End
SendPulse 111
SendPulse 1
SendPulse 2
[edit] Description Markers
SendPulse 111
SendPulse 99
SendPulse 1
SendPulse c.GetAttrib("Subject")
SendPulse c.GetAttrib("Session")
SendPulse 111
SendPulse 99
SendPulse 2
[edit] Block Begin
SendPulse 111
SendPulse 2
SendPulse 1
SendPulse c.GetAttrib("BlockNum")
- The BlockNum attribute must be defined by the experiment programmer. Or you can use a blockCount variable similar to trialCount.
[edit] Block End
SendPulse 111
SendPulse 2
SendPulse 2
[edit] Trial Begin
SendPulse 111
SendPulse 3
SendPulse 1
SendPulse c.GetAttrib("TrialType")
SendPulse trialCount
- The TrialType attribute must be defined by the experiment programmer.
- Don't forget to increment the trialCount variable (trialCount = trialCount + 1) after trial.
[edit] Trial End
SendPulse 111
SendPulse 3
SendPulse 2
[edit] Event Markers
Event Markers do not require a Begin and End. However, they require greater sensitivity to temporal accuracy. That is, if you're doing event analysis, you need to know as precisely as possible when certain events occurred. This becomes problematic because the experimenter cannot be certain of the duration from the time the command is issued to the time the stimuli is presented, as it depends on a multitude of factors such as stimuli type (e.g., image, audio), stimuli size, computer load, and general randomness. For example, loading an image to the screen can take tens of milliseconds, which might hurt analysis of startle eye-blink measures, which occur in tens of milliseconds.
This is solved by sending the Event Marker always and immediately after the event occurs (these function calls still occupy computer time and resources, but far minimal to larger event stimuli), and including in the Event Marker the duration that elapsed. This means that you need to record when the event started, when it ended, and subtract the two. Then in analysis, you can offset the signal by that amount of time. The SendEventPulse function added in the User Code section handles this by taking in two parameters: an event code and a duration. The event codes and the required variables have also been defined in the User Code.
An example of marking a sound event is shown belows. Download the Sample Experiment below for a more thorough implementation.
startTime = clock.readmillisec 'assigns current clock time to startTime variable
[Play Sound Event] 'the event happens here (using some appropriate E-Prime object)
elapsed = clock.readmillisec - startTime 'subtracts current time from startTime immediately after event
SendEventPulse SOUND_EVENT, elapsed 'call the SendEventPulse User Code function
[edit] Sample E-Prime PP Experiment
A sample E-Prime experiment containing all the above elements can be downloaded here: PP_Example.zip.
Going through it should clarify any questions. Also try running the experiment with the Biopac and AcqKnowledge set up in the Testing Cubes as well.
This sample experiment has 4 trials of the same structure. Randomly selected into 2 blocks of 2 trials each. In each trial, there are 3 events or types of stimuli which the participant is asked to rate on valence:
- Text event
- Picture event
- Sound event
[edit] History
This standard was designed by Wojtek Grabski for his pp_gui analysis program. Though our primary PP analysis software has changed, the standard was still applicable and useful enough to continue using, with minor modifications.



