Programming Reference:FeedbackTask Class

From BCI2000 Wiki
Jump to: navigation, search




The FeedbackTask class is a base class for application modules that that provide feedback in a trial-based paradigm. You do not use objects of type FeedbackTask directly; rather, you implement your own class that inherits from it, and implements specialized behavior building on the base functionality provided by the FeedbackTask class.

The FeedbackTask class performs sequencing, creates a block-randomized sequence of target codes, and dispatches GenericFilter::Process() calls to its virtual member functions. Child classes (descendants) of FeedbackTask implement event handlers by overriding its virtual functions.

In the BCI2000 core distribution, the CursorTask application module is based on the FeedbackTask base class, and implements its own specialized behavior on top of it. As a simplified example, the FeedbackDemo application module demonstrates how to create your own feedback-trial application module based on FeedbackTask.


Events Summary

The following table indicates which events exist, and the temporal sequence in which they occur. Trial-based applicatons proceed in "phases"; each trial consists of a PreFeedback, Feedback, and PostFeedback phase, and is followed with an ITI (Inter-Trial Interval) phase lasting until the next trial begins.

Events marked with * may occur multiple times in a row.

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
OnStartRun       display initial message such as "please prepare"
DoPreRun*   PreRun
Loop {
    OnTrialBegin       display target
    DoPreFeedback*   PreFeedback
    OnFeedbackBegin       show cursor
    DoFeedback*   Feedback   update cursor position
    OnFeedbackEnd       hide cursor, mark target as hit
    DoPostFeedback*   PostFeedback
    OnTrialEnd       hide targets
    DoITI*   ITI
OnStopRun       display final message, e.g. "finished"

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 FeedbackTask class always writes its input signal through to its output signal, so no output signal properties are provided to these event handlers.




These events are forwarded from GenericFilter's StartRun, StopRun, and Halt events.

Phase transition Events

These events are triggered by phase transitions during a run, e.g., the OnFeedbackBegin event handler is called whenever the phase changes from PreFeedback to Feedback.


Typically, an application will announce or display the desired target from this event handler.


From this event handler, an application will typically clear the feedback screen.


A feedback application will typically display the feedback cursor at its initial position.


From this event handler, visual feedback about the classification result is typically provided, e.g. by changing the color of a target that has been hit.

Input Events

Each call to GenericFilter::Process() is dispatched to one of these event handlers, depending on the phase in the feedback trial, with each handler function corresponding to a phase.

With the exception of DoFeedback, these event handlers will typically not be used by a task class that inherits from FeedbackTask, 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.

DoPreRun(GenericSignal (r), bool doProgress (rw))

DoPreFeedback(GenericSignal (r), bool doProgress (rw))

DoFeedback(GenericSignal (r), bool doProgress (rw))

From this event handler, a typical feedback application will update cursor position according to the current control signal. In case of variable-length trials, it will also test whether a target has been hit, and set doProgress to true if this is the case.

DoPostFeedback(GenericSignal (r), bool doProgress (rw))

DoITI(GenericSignal (r), bool doProgress (rw))


FeedbackTask properties are protected, i.e. intended for use from descendant classes only.

ostream AppLog, AppLog.File, AppLog.Screen (w)

Inheriting from ApplicationBase, descendants of FeedbackTask 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 are declared protected, i.e. for use by descendants only.


The FeedbackTask constructor allows to specify a pointer to a [[Programming Reference:GUI::GraphDisplay Class|GUI::GraphDisplay object representing the screen area where the output should appear, e.g. the application window. The constructor parameter is not used by the FeedbackTask class itself but forwarded to the ApplicationBase class constructor; for details, see Programming Reference:ApplicationBase Class.



The duration of the pause preceding the first trial. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.


The duration of target display before feedback begins. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.


Typical duration of feedback. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.

This parameter is not a hard limit to feedback duration but determines cursor speed such that, for a normalized control signal, cursor movement will take the specified time from the cursor's starting point to the screen's edge. Feedback trials will typically have this duration, provided that the cursor starts at the center of the screen, targets are located at the screen's edges, and ignoring cursor and target width (for further details, see User Reference:Normalizer).


The duration of result display after feedback. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.


The duration of the inter-trial interval. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.


The number of trials in a run. If this parameter is set, then MinRunLength should be blank, and vice-versa.


The duration of a run, i.e. the time corresponding to a continuously recorded data file. A run will not stop during a trial, so its actual length may be larger than this value by the length of a trial. If this parameter is set, then NumberOfTrials should be blank, and vice-versa. Given in sample blocks, or in time units when immediately followed with 's', 'ms', or similar.


The number of targets on the feedback screen.


A list of indices, each one being from 1 to NumberTargets. This list specifies an optional fixed sequence of stimuli, through which the presentation will cycle. Leave this parameter blank if you want the default behavior, which is for stimuli to be selected randomly.



During a feedback trial, this state indicates the user's task, i.e. the target the cursor is supposed to hit. A TargetCode value of zero indicates that there is no target specified; TargetCode switching from zero to nonzero indicates the beginning of a trial.


At the end of a feedback trial, ResultCode is set to the target code of the outcome, i.e. the target that was hit by the cursor. When a time of PostTrialDuration has passed, ResultCode is reset to zero.


This state's value is 1 when the cursor is displayed on the feedback screen. Typically, this also implies that the cursor moves according to the control signal.


While this state is set to 1, no task processing occurs, i.e. the task is paused, and may be resumed by setting PauseApplication to 0.


CursorTask Timeline.png

See also

Programming Reference:ApplicationBase Class,Programming Reference:GenericFilter Class,Programming Reference:FeedbackDemo Application

User Reference:CursorTask