Stimulus Presentation

Known Issues and Problems with BCI2000
Post Reply
stephaniel
Posts: 4
Joined: 11 Sep 2014, 09:36

Stimulus Presentation

Post by stephaniel » 20 Feb 2015, 10:01

Hello,

I am quite new to BCI2000. I am currently developing and RSVP stimulus presentation using BCI2000. I have used the prebuilt batch file in order to get me started. The problem i am having is that within a sequence of 100 images i have 10 different target images that i would like to mark as events. I have noticed that the parameters of the focusOn matrix only allow for 1 image to be focused on per sequence, is there any way that this can be changed so that more than 1 image can be focused on per sequence.

Thank you

Stephanie Lees

pbrunner
Posts: 344
Joined: 17 Sep 2010, 12:43

Re: Stimulus Presentation

Post by pbrunner » 23 Feb 2015, 10:40

Stephanie,

the solution for your problem depends on your experimental needs:

1) You want to provide a cue on the stimuli that the subjects need to focus on.
2) You want to run the paradigm in online mode, i.e., the subject receives feedback on the item that was decoded from the EEG.
3) You only want to present stimuli in an RSVP mode and perform the analysis post-hoc in MATLAB.


For 1|2: You probably need to modify the BCI2000 code.
For 3: You can define your own parameters in the Stimuli section. You then can reference from the StimulusCode to this parameter whether this is a target or not.

Let me which of the requirements you have.

Regards, Peter

stephaniel
Posts: 4
Joined: 11 Sep 2014, 09:36

Re: Stimulus Presentation

Post by stephaniel » 25 Feb 2015, 09:45

Peter,

Basically i want to provide a cue to a subject (i.e. focus on images containing dalmatians), then i will show 100 images 10 of which will be different images of dalmatians. I wIll perform analysis post-hoc in MATLAB. From what i have gathered you can only focuson 1 image per sequence, were i want the 10 different dalmatians images to be marked as targets.

Regards
Stephanie

pbrunner
Posts: 344
Joined: 17 Sep 2010, 12:43

Re: Stimulus Presentation

Post by pbrunner » 25 Feb 2015, 10:37

Stephanie,

this sounds like as you are trying to evaluate whether the EEG reveals evidence of the human's ability to perform a widely studied computer vision task.

As you are not evaluating the EEG response in real-time, you can just program yourself a parameter fragment for StimulusPresentation that presents your stimuli and cues as well as the sequence which they are presented. In the post-hoc analysis in MATALB you just need to refer from the StimulusCode to the Stimulus.

I have attached a MATLAB script that does exactly this. All you need is, to modify this script to have all image stimuli twice, lets say StimulusCode 1-10 for the different inter-stimulus intervals, StimulusCode 101-200 for the possible cues and StimulusCode 201-300 for the stimuli. To annotate the meaning of the Stimuli, you can have another RowLabels element that can be ISI, CUE or STIM. You then take the first 10 elements of randperm(100) for the cues and the another randperm(100) for the stimuli. Interleave the appropriate interstimulus intervall StimulusCode and concatenate the cues and stimuli to have your final sequence (param.Sequence). At the end of this script the convert_bciprm function is called. You find this mex function for all platforms in the /tools/mex folder within BCI2000. Please note that this function expects that you have populated all fields of the struct correctly, and will crash otherwise.

in this case you do not need the FocusOn feature. You can just generate a parameter fragment for StimulusPresentation that

Code: Select all

function framework_task_bitmaps(settings)

% clear all
% close all
% 
% settings.xls_filename               = '../naming_task/naming8_1column.xls';
% settings.prm_filename               = [cd,'/../../parms/','fragment_naming_task.prm'];
% settings.directory                  = '..\tasks\naming_task\stimuli';
% settings.bmp_instructions           = [settings.directory,'\','instructions_picture_naming.bmp'];
% settings.list_pause                 = [32,64,96];
% settings.InstructionDuration        = '10s'; 
% settings.FixationDuration           = '500ms'; 
% settings.StimulusDuration           = '2000ms';
% settings.PostStimDuration           = '2000ms';
% settings.PreSequenceDuration        = '5s';
% settings.PostSequenceDuration       = '5s';
% settings.ISIMinDuration             = '0s';
% settings.ISIMaxDuration             = '0s';
% settings.UserComment                = 'Picture Naming Task';
% settings.WindowTop                  = '0';
% settings.WindowLeft                 = '0';
% settings.WindowWidth                = '1024';
% settings.WindowHeight               = '768';
% settings.BackgroundColor            = '0xFFFFFF';
% settings.WindowBackgroundColor      = '0xFFFFFF';

[void,stimuli.xls,void] = xlsread(settings.xls_filename); %#ok<ASGLU>
%load(settings.xls_filename);

for idx=1:length(stimuli.xls),
    stimuli.name{idx}       = stimuli.xls{idx}(1:end-7);
    stimuli.location{idx}   = stimuli.xls{idx}(end-5);
    stimuli.color{idx}      = stimuli.xls{idx}(end-4);
    stimuli.filename{idx}   = [settings.directory,'\',stimuli.xls{idx}];
end


%%

num_stimuli = length(stimuli.xls);

param.Stimuli.Section      = 'Application';
param.Stimuli.Type         = 'matrix';
param.Stimuli.DefaultValue = '';
param.Stimuli.LowRange     = '';
param.Stimuli.HighRange    = '';
param.Stimuli.Comment      = 'captions and icons to be displayed, sounds to be played for different stimuli';
param.Stimuli.Value        = cell(10,5+num_stimuli);
param.Stimuli.RowLabels    = cell(10,1);
param.Stimuli.ColumnLabels = cell(1,5+num_stimuli);

param.Stimuli.RowLabels{1}  = 'caption';
param.Stimuli.RowLabels{2}  = 'icon';
param.Stimuli.RowLabels{3}  = 'audio';
param.Stimuli.RowLabels{4}  = 'StimulusDuration';
param.Stimuli.RowLabels{5}  = 'AudioVolume';
param.Stimuli.RowLabels{6}  = 'Name';
param.Stimuli.RowLabels{7}  = 'Location';
param.Stimuli.RowLabels{8}  = 'Color';
param.Stimuli.RowLabels{9}  = 'EarlyOffsetExpression';
param.Stimuli.RowLabels{10} = 'CaptionColor';

% beeps for marking audio file
idx = 1;
param.Stimuli.ColumnLabels{idx} = sprintf('%d',idx);
param.Stimuli.Value{1,idx}      = '[+++]';
param.Stimuli.Value{2,idx}      = '';
param.Stimuli.Value{3,idx}      = [settings.directory,'\','beeps.wav'];
param.Stimuli.Value{4,idx}      = '4s';
param.Stimuli.Value{5,idx}      = '100'; 
param.Stimuli.Value{6,idx}      = 'Beeps';
param.Stimuli.Value{7,idx}      = '';
param.Stimuli.Value{8,idx}      = '';
param.Stimuli.Value{9,idx}      = '';
param.Stimuli.Value{10,idx}     = settings.CaptionColor;

% instructions
idx = 2;
param.Stimuli.ColumnLabels{idx} = sprintf('%d',idx);
param.Stimuli.Value{1,idx}      = '';
param.Stimuli.Value{2,idx}      = settings.bmp_instructions;
param.Stimuli.Value{3,idx}      = settings.wav_instructions;
param.Stimuli.Value{4,idx}      = settings.InstructionDuration;
param.Stimuli.Value{5,idx}      = '100';
param.Stimuli.Value{6,idx}      = 'Instructions';
param.Stimuli.Value{7,idx}      = '';
param.Stimuli.Value{8,idx}      = '';
param.Stimuli.Value{9,idx}      = 'KeyDown==32';
param.Stimuli.Value{10,idx}     = settings.CaptionColor;

% fixation cross 
idx = 3;
param.Stimuli.ColumnLabels{idx} = sprintf('%d',idx);
param.Stimuli.Value{1,idx}      = '';
param.Stimuli.Value{2,idx}      = [settings.directory,'\','fixation.bmp'];
param.Stimuli.Value{3,idx}      = '';
param.Stimuli.Value{4,idx}      = settings.FixationDuration;
param.Stimuli.Value{5,idx}      = '';
param.Stimuli.Value{6,idx}      = 'Fixation';
param.Stimuli.Value{7,idx}      = '';
param.Stimuli.Value{8,idx}      = '';
param.Stimuli.Value{9,idx}      = '';
param.Stimuli.Value{10,idx}     = settings.CaptionColor;

% post stimulation
idx = 4;
param.Stimuli.ColumnLabels{idx} = sprintf('%d',idx);
param.Stimuli.Value{1,idx}      = '';
param.Stimuli.Value{2,idx}      = [settings.directory,'\','vide.bmp'];
param.Stimuli.Value{3,idx}      = '';
param.Stimuli.Value{4,idx}      = settings.PostStimDuration;
param.Stimuli.Value{5,idx}      = '';
param.Stimuli.Value{6,idx}      = 'Post Stimulus';
param.Stimuli.Value{7,idx}      = '';
param.Stimuli.Value{8,idx}      = '';
param.Stimuli.Value{9,idx}      = '';
param.Stimuli.Value{10,idx}     = settings.CaptionColor;

% pause
idx = 5;
param.Stimuli.ColumnLabels{idx} = sprintf('%d',idx);
param.Stimuli.Value{1,idx}      = 'Lets take a break ...';
param.Stimuli.Value{2,idx}      = '';
param.Stimuli.Value{3,idx}      = '';
param.Stimuli.Value{4,idx}      = '3600s';
param.Stimuli.Value{5,idx}      = '';
param.Stimuli.Value{6,idx}      = 'Break';
param.Stimuli.Value{7,idx}      = '';
param.Stimuli.Value{8,idx}      = '';
param.Stimuli.Value{9,idx}      = 'KeyDown==32';
param.Stimuli.Value{10,idx}     = settings.CaptionColor;

offset = idx;

for idx=1:num_stimuli,

    param.Stimuli.ColumnLabels{offset+idx} = sprintf('%d',offset+idx);
    param.Stimuli.Value{1,offset+idx}      = '';
    param.Stimuli.Value{2,offset+idx}      = stimuli.filename{idx};
    param.Stimuli.Value{3,offset+idx}      = '';
    param.Stimuli.Value{4,offset+idx}      = settings.StimulusDuration;
    param.Stimuli.Value{5,offset+idx}      = '';
    param.Stimuli.Value{6,offset+idx}      = stimuli.name{idx};
    param.Stimuli.Value{7,offset+idx}      = stimuli.location{idx};
    param.Stimuli.Value{8,offset+idx}      = stimuli.color{idx};
    param.Stimuli.Value{9,offset+idx}      = '';
    param.Stimuli.Value{10,offset+idx}     = settings.CaptionColorPicture;
    
end


%%

param.Sequence.Section                   = 'Application';
param.Sequence.Type                      = 'intlist';
param.Sequence.DefaultValue              = '1';
param.Sequence.LowRange                  = '1';
param.Sequence.HighRange                 = '';
param.Sequence.Comment                   = 'Sequence in which stimuli are presented (deterministic mode)/ Stimulus frequencies for each stimulus (random mode)';
param.Sequence.Value                     = cell(3+num_stimuli*3+length(settings.list_pause),1);

% marking audiofile with beeps
idx_counter = 1;
param.Sequence.Value{idx_counter,1} = sprintf('%d',1);
idx_counter = idx_counter + 1;

idx_counter = 2;
param.Sequence.Value{idx_counter,1} = sprintf('%d',2);
idx_counter = idx_counter + 1;

for idx = 1:num_stimuli,
    
    if ~isempty(intersect(idx,settings.list_pause))
        % pause
        param.Sequence.Value{idx_counter,1} = sprintf('%d',5);  
        idx_counter = idx_counter + 1;           
    end
    
    % fixation
    param.Sequence.Value{idx_counter,1} = sprintf('%d',3);  
    idx_counter = idx_counter + 1;   
    
    % stimulus
    param.Sequence.Value{idx_counter,1} = sprintf('%d',idx+offset);  
    idx_counter = idx_counter + 1;
 
    % post stimulus
    param.Sequence.Value{idx_counter,1} = sprintf('%d',4);  
    idx_counter = idx_counter + 1;   
end

% marking audiofile with beeps
param.Sequence.Value{idx_counter,1} = sprintf('%d',1);
idx_counter = idx_counter + 1;

%%

param.NumberOfSequences.Section         = 'Application';
param.NumberOfSequences.Type            = 'int';
param.NumberOfSequences.DefaultValue    = '1';
param.NumberOfSequences.LowRange        = '0';
param.NumberOfSequences.HighRange       = '';
param.NumberOfSequences.Comment         = 'number of sequence repetitions in a run';
param.NumberOfSequences.Value           = {'1'};

%%

param.SequenceType.Section              = 'Application';
param.SequenceType.Type                 = 'int';
param.SequenceType.DefaultValue         = '0';
param.SequenceType.LowRange             = '0';
param.SequenceType.HighRange            = '1';
param.SequenceType.Comment              = 'Sequence of stimuli is 0 deterministic, 1 random (enumeration)';
param.SequenceType.Value                = {'0'};

%%

param.StimulusDuration.Section           = 'Application';
param.StimulusDuration.Type              = 'float';
param.StimulusDuration.DefaultValue      = '40ms';
param.StimulusDuration.LowRange          = '0';
param.StimulusDuration.HighRange         = '';
param.StimulusDuration.Comment           = 'stimulus duration';
param.StimulusDuration.Value             = {settings.StimulusDuration};

%%

param.ISIMaxDuration.Section       = 'Application';
param.ISIMaxDuration.Type          = 'float';
param.ISIMaxDuration.DefaultValue  = '80ms';
param.ISIMaxDuration.LowRange      = '0';
param.ISIMaxDuration.HighRange     = '';
param.ISIMaxDuration.Comment       = 'maximum duration of inter-stimulus interval';
param.ISIMaxDuration.Value         = {settings.ISIMaxDuration};

%%

param.ISIMinDuration.Section       = 'Application';
param.ISIMinDuration.Type          = 'float';
param.ISIMinDuration.DefaultValue  = '80ms';
param.ISIMinDuration.LowRange      = '0';
param.ISIMinDuration.HighRange     = '';
param.ISIMinDuration.Comment       = 'minimum duration of inter-stimulus interval';
param.ISIMinDuration.Value         = {settings.ISIMinDuration};

%%

param.PreSequenceDuration.Section       = 'Application';
param.PreSequenceDuration.Type          = 'float';
param.PreSequenceDuration.DefaultValue  = '2s';
param.PreSequenceDuration.LowRange      = '0';
param.PreSequenceDuration.HighRange     = '';
param.PreSequenceDuration.Comment       = 'pause preceding sequences/sets of intensifications';
param.PreSequenceDuration.Value         = {settings.PreSequenceDuration};

%%

param.PostSequenceDuration.Section       = 'Application';
param.PostSequenceDuration.Type          = 'float';
param.PostSequenceDuration.DefaultValue  = '2s';
param.PostSequenceDuration.LowRange      = '0';
param.PostSequenceDuration.HighRange     = '';
param.PostSequenceDuration.Comment       = 'pause following sequences/sets of intensifications';
param.PostSequenceDuration.Value         = {settings.PostSequenceDuration};

%%

param.PreRunDuration.Section       = 'Application';
param.PreRunDuration.Type          = 'float';
param.PreRunDuration.DefaultValue  = '2000ms';
param.PreRunDuration.LowRange      = '0';
param.PreRunDuration.HighRange     = '';
param.PreRunDuration.Comment       = 'pause preceding first sequence';
param.PreRunDuration.Value         = {settings.PreSequenceDuration};

%%

param.PostRunDuration.Section       = 'Application';
param.PostRunDuration.Type          = 'float';
param.PostRunDuration.DefaultValue  = '2000ms';
param.PostRunDuration.LowRange      = '0';
param.PostRunDuration.HighRange     = '';
param.PostRunDuration.Comment       = 'pause following last squence';
param.PostRunDuration.Value         = {settings.PostSequenceDuration};


%%

param.BackgroundColor.Section      = 'Application';
param.BackgroundColor.Type         = 'string';
param.BackgroundColor.DefaultValue = '0x00FFFF00';
param.BackgroundColor.LowRange     = '0x00000000';
param.BackgroundColor.HighRange    = '0x00000000';
param.BackgroundColor.Comment      = 'Color of stimulus background (color)';
param.BackgroundColor.Value        = {settings.BackgroundColor};

%%

param.CaptionColor.Section      = 'Application';
param.CaptionColor.Type         = 'string';
param.CaptionColor.DefaultValue = '0x00FFFF00';
param.CaptionColor.LowRange     = '0x00000000';
param.CaptionColor.HighRange    = '0x00000000';
param.CaptionColor.Comment      = 'Color of stimulus caption text (color)';
param.CaptionColor.Value        = {settings.CaptionColor};

%%

param.WindowBackgroundColor.Section      = 'Application';
param.WindowBackgroundColor.Type         = 'string';
param.WindowBackgroundColor.DefaultValue = '0x00FFFF00';
param.WindowBackgroundColor.LowRange     = '0x00000000';
param.WindowBackgroundColor.HighRange    = '0x00000000';
param.WindowBackgroundColor.Comment      = 'background color (color)';
param.WindowBackgroundColor.Value        = {settings.WindowBackgroundColor};

%%

param.IconSwitch.Section          = 'Application';
param.IconSwitch.Type             = 'int';
param.IconSwitch.DefaultValue     = '1';
param.IconSwitch.LowRange         = '0';
param.IconSwitch.HighRange        = '1';
param.IconSwitch.Comment          = 'Present icon files (boolean)';
param.IconSwitch.Value            = {'1'};

%%

param.AudioSwitch.Section         = 'Application';
param.AudioSwitch.Type            = 'int';
param.AudioSwitch.DefaultValue    = '1';
param.AudioSwitch.LowRange        = '0';
param.AudioSwitch.HighRange       = '1';
param.AudioSwitch.Comment         = 'Present audio files (boolean)';
param.AudioSwitch.Value           = {'1'};

%%

param.CaptionSwitch.Section       = 'Application';
param.CaptionSwitch.Type          = 'int';
param.CaptionSwitch.DefaultValue  = '1';
param.CaptionSwitch.LowRange      = '0';
param.CaptionSwitch.HighRange     = '1';
param.CaptionSwitch.Comment       = 'Present captions (boolean)';
param.CaptionSwitch.Value         = {'1'};

%%

param.UserComment.Section         = 'Application';
param.UserComment.Type            = 'string';
param.UserComment.DefaultValue    = '';
param.UserComment.LowRange        = '';
param.UserComment.HighRange       = '';
param.UserComment.Comment         = 'User comments for a specific run';
param.UserComment.Value           = {settings.UserComment};

%%

param.WindowHeight.Section        = 'Application';
param.WindowHeight.Type           = 'int';
param.WindowHeight.DefaultValue   = '480';
param.WindowHeight.LowRange       = '0';
param.WindowHeight.HighRange      = '';
param.WindowHeight.Comment        = 'height of application window';
param.WindowHeight.Value          = {settings.WindowHeight};

%%

param.WindowWidth.Section        = 'Application';
param.WindowWidth.Type           = 'int';
param.WindowWidth.DefaultValue   = '480';
param.WindowWidth.LowRange       = '0';
param.WindowWidth.HighRange      = '';
param.WindowWidth.Comment        = 'width of application window';
param.WindowWidth.Value          = {settings.WindowWidth};

%%

param.WindowLeft.Section        = 'Application';
param.WindowLeft.Type           = 'int';
param.WindowLeft.DefaultValue   = '0';
param.WindowLeft.LowRange       = '';
param.WindowLeft.HighRange      = '';
param.WindowLeft.Comment        = 'screen coordinate of application window''s left edge';
param.WindowLeft.Value          = {settings.WindowLeft};

%%

param.WindowTop.Section        = 'Application';
param.WindowTop.Type           = 'int';
param.WindowTop.DefaultValue   = '0';
param.WindowTop.LowRange       = '';
param.WindowTop.HighRange      = '';
param.WindowTop.Comment        = 'screen coordinate of application window''s top edge';
param.WindowTop.Value          = {settings.WindowTop};

%%

param.StimulusWidth.Section      = 'Application';
param.StimulusWidth.Type         = 'int';
param.StimulusWidth.DefaultValue = '0';
param.StimulusWidth.LowRange     = '0';
param.StimulusWidth.HighRange    = '100';
param.StimulusWidth.Comment      = 'StimulusWidth in percent of screen width (zero for original pixel size)';
param.StimulusWidth.Value        = {'0'};

%%

param.CaptionHeight.Section      = 'Application';
param.CaptionHeight.Type         = 'int';
param.CaptionHeight.DefaultValue = '0';
param.CaptionHeight.LowRange     = '0';
param.CaptionHeight.HighRange    = '100';
param.CaptionHeight.Comment      = 'Height of stimulus caption text in percent of screen height';
param.CaptionHeight.Value        = {'10'};

%%

param.WarningExpression.Section      = 'Filtering';
param.WarningExpression.Type         = 'string';
param.WarningExpression.DefaultValue = '';
param.WarningExpression.LowRange     = '';
param.WarningExpression.HighRange    = '';
param.WarningExpression.Comment      = 'expression that results in a warning when it evaluates to true';
param.WarningExpression.Value        = {''};

%%

param.Expressions.Section      = 'Filtering';
param.Expressions.Type         = 'matrix';
param.Expressions.DefaultValue = '';
param.Expressions.LowRange     = '';
param.Expressions.HighRange    = '';
param.Expressions.Comment      = 'expressions used to compute the output of the ExpressionFilter';
param.Expressions.Value        = {''};


%

parameter_lines = convert_bciprm( param );

fid = fopen(settings.prm_filename,'w');

for idx=1:length(parameter_lines),
    fprintf(fid,'%s',parameter_lines{idx});
    fprintf(fid,'\r\n');
end

fclose(fid);




Regards, Peter

stephaniel
Posts: 4
Joined: 11 Sep 2014, 09:36

Re: Stimulus Presentation

Post by stephaniel » 26 Feb 2015, 16:54

Thank for your help Peter

Stephanie

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest