Programming Reference:StimulusTask Class
From BCI2000 Wiki
Location
BCI2000/src/shared/modules/application
Synopsis
The StimulusTask class is a base class for application modules that present a sequence of stimuli. You do not use objects of type StimulusTask directly; rather, you implement your own class that inherits from it, and implements specialized behavior building on the base functionality provided by the StimulusTask class.
The StimulusTask class performs sequencing, and dispatches GenericFilter::Process() calls to its virtual member functions. Child classes (descendants) of StimulusTask implement event handlers by overriding its virtual functions, and populate the stimulus-target association map, thereby associating stimulus codes with sets of stimuli, and possible selection targets.
In the BCI2000 core distribution, both the P3SpellerTask and the StimulusPresentationTask are based on the StimulusTask base class, and implement their own specialized behavior on top of it.
Events
Events Summary
The following table indicates which events exist, and the temporal sequence in which they occur. Stimulus presentation proceeds in "phases", which are distinct parts of the stimulus presentation: Each presentation sequence is preceded by a "PreSequence" interval; the sequence itself consists of alternating "Stimulus" and "Inter Stimulus Intervals (ISIs)"; a "PostSequence" follows after the sequence.
Events marked with * may occur multiple times in a row. Events given in square brackets depend on the signal processing module, and may not occur at all; however, when they occur, their place in the temporal sequence will be as specified in the table.
Progress from one application state to the next will occur according to the sequencing parameters, or if requested by a handler via its doProgress output argument (see Input events below).
| Sequence of events | Phase | Typical application behavior | ||
|---|---|---|---|---|
| OnPreflight | ||||
| OnInitialize | ||||
| OnStartRun | display initial message | |||
| DoPreRun* | PreRun | |||
| Loop { | ||||
| OnNextStimulusCode | provide a stimulus code, or 0 to finish run | |||
| OnPreSequence | determine attended target | |||
| DoPreSequence* | PreSequence | |||
| OnSequenceBegin | ||||
| Loop { | ||||
| OnStimulusBegin | present stimulus | |||
| DoStimulus* | Stimulus | |||
| OnStimulusEnd | hide visual stimulus | |||
| OnNextStimulusCode | provide a stimulus code, or 0 to finish sequence | |||
| DoISI* | ISI | |||
| [OnClassInput]* | store classification input (copy/free modes only) -- this event may occur any time during the sequence, and during the post sequence phase | |||
| } | ||||
| OnSequenceEnd | ||||
| DoPostSequence* | PostSequence | |||
| [OnClassResult] | determine selected target (copy/free modes only) | |||
| } | ||||
| OnPostRun | ||||
| DoPostRun* | PostRun | |||
| OnStopRun | display final message | |||
| OnHalt |
Stimulus Code Event
int OnNextStimulusCode
This event handler is called immediately before stimulus presentation, and determines the sequence in which stimuli (or associations thereof) are presented. This handler should return the next element of the current sequence of stimulus codes, or zero to indicate the end of the sequence. A null sequence indicates the end of a run, i.e. the current run will end when OnNextStimulusCode returns two zeros in a row.
The OnNextStimulusCode event handler is mandatory for a StimulusPresentation descendant to implement. Thus, a minimal stimulus presentation application consists of a StimulusPresentation descendant that
- declares its own additional parameters from its constructor,
- checks those parameters for consistency in its OnPreflight handler,
- populates the Association Map in its OnInitialize handler, and
- provides a sequence of stimulus codes in its OnNextStimulusCode event handler.
Events forwarded from the GenericFilter interface
OnPreflight(SignalProperties (r))
OnInitialize(SignalProperties (r))
These events are forwarded from the inherited GenericFilter::Preflight and GenericFilter::Initialize events, with input signal properties as an argument. Within the BCI2000 filter chain, the StimulusTask class always writes its input signal through to its output signal, so no output signal properties are provided to these event handlers.
OnStartRun
OnStopRun
OnHalt
These events are forwarded from GenericFilter's StartRun, StopRun, and Halt events.
Phase transition Events
OnPreSequence
OnSequenceBegin
OnSequenceEnd
OnStimulusBegin(int stimulusCode (r))
OnStimulusEnd(int stimulusCode (r))
OnPostRun
These events are triggered by phase transitions during a run, e.g., the OnPreSequence event handler is called whenever the phase changes from PreRun to PreSequence.
The stimulusCode arguments to the OnStimulusBegin and OnStimulusEnd event handlers contain the stimulus code present in the StimulusCode state variable; the default behavior of these handlers is to present and conceal the respective stimuli. For the remaining event handlers of this category, the default behavior is to do nothing.
Input Events
DoPreRun(GenericSignal (r), bool doProgress (rw))
DoPreSequence(GenericSignal (r), bool doProgress (rw))
DoStimulus(GenericSignal (r), bool doProgress (rw))
DoISI(GenericSignal (r), bool doProgress (rw))
DoPostSequence(GenericSignal (r), bool doProgress (rw))
DoPostRun(GenericSignal (r), bool doProgress (rw))
Each call to GenericFilter::Process() is dispatched to one of these event handlers, depending on the phase in the sequence, with each handler function corresponding to a phase.
These event handlers will typically not be used by a task class that inherits from StimulusTask, unless it needs to modify the standard sequencing behavior, such that it progresses faster or slower from one phase to the next, or subdivides a phase into two or more sub-phases.
Modifying sequencing behavior is possible through the handlers' doProgress argument. doProgress will typically be set to false, except for the last call to the handler during the current phase in the sequence. A handler may modify the application's sequencing behavior by setting the doProgress argument: setting it from false to true will proceed to the next phase earlier than prescribed by the sequencing parameters, and setting it to false from true will defer progressing, such that the handler will be called again, until its doProgress argument is actually true on exit.
Classification Events
Target classification is based on the behavior of the P3TemporalFilter signal processing filter. This filter performs per-stimulus averaging over EEG epochs; once it has acquired the desired amount of epochs, it sets its output to the average wave form, and the StimulusCodeRes state to the respective stimulus code. In conjunction with the LinearClassifier (or other classification filter), this implies that the application module receives, in its input signal, a single classification value for stimulus k whenever StimulusCodeRes equals k.
OnClassInput(stimulusCode (r), GenericSignal (r))
The OnClassInput event handler is called each time a classification value has been received from the signal processing module. Classification values are stored in a ClassResult object. A StimulusPresentation descendant class may take additional action by implementing its own OnClassInput event handler.
Target* OnClassResult(ClassResult (r))
The StimulusPresentationTask' accumulates classification values in a ClassResult class, and then calls the OnClassResult event handler once classification input has been received for all stimulus codes.
The OnClassResult event handler is supposed to determine a selection target from these classification values. Classification values are provided in a ClassResult object; the OnClassResult handler returns a pointer to a Target object representing the chosen selection target, or a null pointer to indicate that no target has been chosen. On return from the OnClassResult event handler, and in case of a non-null pointer, the target object's Select() method is then called, which typically results in some action associated with the target object in question, such as entering a letter into a speller.
The default OnClassResult handler calls AssociationMap::ClassifyTargets() to translate classification values into selection targets; you may override this behavior by providing your own handler.
Properties
All properties are protected, i.e. intended for use from descendant classes only.
AssociationMap Associations (rw)
An object of type AssociationMap, representing sets of stimuli and selection targets associated with a given stimulus code.
Typically, a stimulus presentation application populates the Associations object with stimuli and targets in its OnInitialize event handler, and relies on the StimulusPresentationTask default mechanisms for stimulus presentation, and target classification.
Often, but not always, there is a 1-to-1-to-1 correspondence between stimuli, stimulus codes, and selection targets; for a detailed discussion of these terms, and how to use the related objects in your own application, refer to Programming Reference:AssociationMap Class.
Target* AttendedTarget (rw)
A pointer that refers to a selection target object, or a null pointer. When non-null, the StimulusType state variable is set based on the AttendedTarget property such that StimulusType is set to 1 whenever the current StimulusCode state variable refers to an Association that contains the specified target.
For a discussion of how stimuli, stimulus codes, and selection targets are related to each other via Association objects, refer to Programming Reference:AssociationMap Class#AssociationMap Class.
GUI::GraphDisplay Display (r)
The Display property provides access to the GUI::GraphDisplay object representing the application module's output window.
ostream AppLog, AppLog.File, AppLog.Screen (w)
Inheriting from ApplicationBase, descendants of StimulusTask have access to the AppLog, AppLog.File, and AppLog.Screen streams which are members of ApplicationBase. These streams allow convenient output into an application log file (AppLog.File), an application log window (AppLog.Screen), and both simultaneously (AppLog).
RandomGenerator RandomNumberGenerator (rw)
An object of type RandomGenerator which behaves according to the user setting in the RandomSeed parameter.
Methods
Methods are declared protected, i.e. for use by descendants only.
DisplayMessage(string)
Displays a text message in the application window. This function is provided for convenience and consistency of appearance; for detailed control over appearance of text messages, add your own TextField object to the GUI::GraphDisplay represented by the Display property.
Parameters
WindowBackgroundColor
The window's background color, given as an RGB value. For convenience, RGB values may be entered in hexadecimal notation, e.g. 0xff0000 for red.
PreRunDuration
The duration of the pause preceding the first sequence. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.
PostRunDuration
Duration of the pause following last sequence. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.
PreSequenceDuration
Duration of the pause preceding sequences (or sets of intensifications). Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.
In free or copy mode, the PreSequenceDuration and PostSequenceDuration parameters may not go below twice the value of the StimulusDuration parameters, in order to allow for presentation of FocusOn and Result announcement stimuli.
PostSequenceDuration
Duration of the pause following sequences (or sets of intensifications). Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.
When used in conjunction with the P3TemporalFilter, this value needs to be larger than the EpochLength parameter. This allows classification to complete before the next sequence of stimuli is presented.
StimulusDuration
For visual stimuli, the duration of stimulus presentation. For auditory stimuli, the maximum duration, i.e. playback of audio extending above the specified duration will be muted. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.
ISIMinDuration, ISIMaxDuration
Minimum and maximum duration of the inter-stimulus interval. During the inter-stimulus interval, the screen is blank, and audio is muted.
Actual inter-stimulus intervals vary randomly between minimum and maximum value, with uniform probability for all intermediate values. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar. Note that temporal resolution is limited to a single sample block.
InterpretMode
An enumerated value selecting on-line classification of evoked responses:
- 0: no target is announced "attended", and no classification is performed;
- 1: online or free mode: classification is performed, but no "attended target" is defined;
- 2: copy mode: "attended" targets are defined, classification is performed.
DisplayResults
Switches result display of copy/free spelling on or off. In the P3Speller, setting DisplayResults to 'off' will disable execution of all speller commands (such as switching matrices) as well.
States
StimulusCode
The numerical ID of the stimulus being presented (16 bit).
StimulusType
This state is 1 during presentation of an attended stimulus, and 0 otherwise. The notion of an "attended" stimulus requires data recording in copy mode.
StimulusBegin
This state is 1 during the first block of stimulus presentation, and 0 otherwise.
PhaseInSequence
This state is 1 during pre-sequence, 2 during sequence and 3 during post-sequence (see Timeline).
Timeline
See also
User Reference:P3TemporalFilter, User Reference:P3SpellerTask, User Reference:StimulusPresentationTask;
Programming Reference:AssociationMap Class, Programming Reference:Stimulus Class, Programming Reference:Target Class
