-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
146 changed files
with
14,573 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
function desc= stimutil_readDescription(file,varargin) | ||
|
||
%STIMUTIL_READDESCRIPTION - Reads the description of an experiment from a | ||
% text file | ||
% | ||
%Synopsis: | ||
% desc= stimutil_readDescription(file,OPT) | ||
% | ||
%Arguments: | ||
% OPT: struct or property/value list of optional properties | ||
% 'dir': directory of the thext file | ||
% 'suffix': suffix of the text file (default .txt) | ||
% | ||
|
||
global BCI_DIR | ||
|
||
|
||
props= {'Dir' 'BCI_DIR/acquisition/data/task_descriptions/' 'CHAR|CELL{CHAR}' | ||
'Suffix' '.txt' 'CHAR|DOUBLE'} | ||
|
||
if nargin==0, | ||
desc = props; | ||
return | ||
end | ||
|
||
opt= opt_proplistToStruct(varargin{:}); | ||
opt= opt_setDefaults(opt, props); | ||
opt_checkProplist(opt, props); | ||
|
||
desc= textread([opt.dir filesep file opt.suffix],'%s','delimiter','\n'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
function HANDLE= stimutil_showDescription(desc, varargin) | ||
%STIMUTIL_SHOWDESCRIPTION - Show a Description and Wait | ||
% | ||
%Synopsis: | ||
% HANDLE= stimutil_showDescription(DESC, <OPT>) | ||
% | ||
%Arguments: | ||
% DESC: String or cell array of strings. | ||
% OPT: struct or property/value list of optional arguments: | ||
% 'handle_msg': Handle to text object which is used to display the countdown | ||
% message. If empty a new object is generated. Default []. | ||
% 'handle_background': Handle to axis object on which the message should be | ||
% rendered. If empty a new object is generated. Default []. | ||
% 'desc_textspec': Cell array. Text object specifications for description | ||
% text object. Default: {'FontSize',0.05, 'Color',[0 0 0]}) | ||
% 'waitfor': Stop criterium. Possible values are numeric values specifying | ||
% the time to wait in seconds, the string 'key' which means waiting | ||
% until the experimentor hits a key in the matlab console or a string | ||
% or cell arrow of strings which is interpreted as marker descriptions | ||
% for which the EEG is scanned then (e.g. 'R*' waits until some response | ||
% marker is acquired). | ||
% Use value 0 for no waiting. | ||
% 'delete': Delete graphic objects at the end. Default 1, except for | ||
% opt.waitfor=0. | ||
% | ||
%Returns: | ||
% HANDLE: Struct of handles to graphical objects (only available for | ||
% opt.delete=0). | ||
% | ||
%Example: | ||
% shows the message 'Hello World' for 5 seconds. | ||
% stimutil_showDescription('Hello World', 'waitfor', 5) | ||
|
||
% [email protected], Jul-2007 | ||
|
||
global VP_SCREEN | ||
|
||
props= {'clf' 0 'BOOL' | ||
'handle_background' [] 'HANDLE' | ||
'desc_maxsize' [0.9 0.8] 'DOUBLE[2]' | ||
'desc_textspec' { 'FontSize',0.05, ... | ||
'Color',.0*[1 1 1]} 'STRUCT' | ||
'desc_pos' [0.5 0.5] 'DOUBLE[2]' | ||
'desc_boxgap' 0.05 'DOUBLE[1]' | ||
'delete' 1 'BOOL' | ||
'position' VP_SCREEN 'DOUBLE[2]' | ||
'waitfor' 'R*' 'CHAR' | ||
'waitfor_msg' 'Press <ENTER> to continue: ' 'CHAR'}; | ||
|
||
if nargin==0, | ||
HANDLE = props; | ||
return | ||
end | ||
|
||
opt= opt_proplistToStruct(varargin{:}); | ||
opt= opt_setDefaults(opt, props); | ||
opt_checkProplist(opt, props); | ||
|
||
if isequal(opt.waitfor, 0), | ||
opt.delete= 0; | ||
end | ||
|
||
HANDLE= []; | ||
if opt.clf, | ||
clf; | ||
set(gcf, 'Position',opt.position); | ||
set(gcf, 'ToolBar','none', 'MenuBar','none'); | ||
end | ||
|
||
if isempty(get(gcf, 'Children')), | ||
memo.axis= []; | ||
else | ||
memo.axis= gca; | ||
end | ||
h.axis= axes('Position',[0 0 1 1]); | ||
set(h.axis, 'XLim',[0 1], 'YLim',[0 1], 'Visible','off'); | ||
|
||
if iscell(desc), | ||
%% Description has linebreaks: | ||
%% Choose size of the description box by trial and error | ||
col_background= get(gcf, 'Color'); | ||
factor= 1; | ||
too_small= 1; | ||
nLines= length(desc); | ||
nChars= max(apply_cellwise2(desc, 'length')); | ||
while too_small, | ||
desc_fontsize= factor * min( opt.desc_maxsize./[nChars nLines] ); | ||
ht= text(opt.desc_pos(1), opt.desc_pos(2), desc); | ||
set(ht, 'FontUnits','normalized', 'FontSize',desc_fontsize, ... | ||
'Color',col_background, 'HorizontalAli','center'); | ||
drawnow; | ||
rect= get(ht, 'Extent'); | ||
too_small= rect(3)<opt.desc_maxsize(1) & rect(4)<opt.desc_maxsize(2); | ||
if too_small, | ||
factor= factor*1.1; | ||
end | ||
delete(ht); | ||
end | ||
factor= factor/1.1; | ||
%% render description text | ||
desc_fontsize= factor * min( opt.desc_maxsize./[nChars nLines] ); | ||
h.text= text(opt.desc_pos(1), opt.desc_pos(2), desc); | ||
set(h.text, opt.desc_textspec{:}, 'HorizontalAli','center', ... | ||
'FontUnits','normalized', 'FontSize',desc_fontsize); | ||
else | ||
%% Description is given as plain string: | ||
%% Determine number of characters per row | ||
textfield_width= opt.desc_maxsize(1); | ||
textfield_height= opt.desc_maxsize(2); | ||
ht= text(0, 0, {'MMMMMMM','MMMMMMM','MMMMMMM','MMMMMMM','MMMMMMM'}); | ||
set(ht, 'FontName','Courier New', 'FontUnits','normalized', ... | ||
opt.desc_textspec{:}); | ||
rect= get(ht, 'Extent'); | ||
char_width= rect(3)/7; | ||
linespacing= rect(4)/5; | ||
char_height= linespacing*0.85; | ||
textfield_nLines= floor((textfield_height-2*char_height)/linespacing)+2; | ||
textfield_nChars= floor(textfield_width/char_width); | ||
delete(ht); | ||
h.text= text(opt.desc_pos(1), opt.desc_pos(2), {' '}); | ||
set(h.text, 'HorizontalAli','center', 'FontUnits','normalized', ... | ||
opt.desc_textspec{:}); | ||
|
||
%% Determine linebreaking. | ||
writ= [desc ' ']; | ||
iBreaks= find(writ==' '); | ||
ll= 0; | ||
clear textstr; | ||
while length(iBreaks)>0, | ||
ll= ll+1; | ||
linebreak= iBreaks(max(find(iBreaks<textfield_nChars))); | ||
if isempty(linebreak), | ||
%% word too long: insert hyphenation | ||
linebreak= textfield_nChars; | ||
writ= [writ(1:linebreak-1) '-' writ(linebreak:end)]; | ||
end | ||
textstr{ll}= writ(1:linebreak); | ||
writ(1:linebreak)= []; | ||
iBreaks= find(writ==' '); | ||
end | ||
textstr{end}= textstr{end}(1:end-1); | ||
textstr= textstr(max(1,end-textfield_nLines+1):end); | ||
set(h.text, 'String',textstr); | ||
end | ||
|
||
drawnow; | ||
rect= get(h.text, 'Extent'); | ||
set(h.text, 'Position',[rect(1) opt.desc_pos(2), 0]); | ||
set(h.text, 'HorizontalAli','left'); | ||
|
||
%% render description frame | ||
h.frame= line([rect(1)+rect(3) rect(1)+rect(3) rect(1) rect(1); ... | ||
rect(1)+rect(3) rect(1) rect(1) rect(1)+rect(3)] + ... | ||
opt.desc_boxgap*[1 1 -1 -1; 1 -1 -1 1], [rect(2)+rect(4) ... | ||
rect(2) rect(2) rect(2)+rect(4); rect(2) rect(2) ... | ||
rect(2)+rect(4) rect(2)+rect(4)] + opt.desc_boxgap*[1 ... | ||
-1 -1 1; -1 -1 1 1]); | ||
set(h.frame, 'LineWidth',2, 'Color',[0 0 0]); | ||
|
||
if ~isempty(opt.waitfor), | ||
if isnumeric(opt.waitfor), | ||
pause(opt.waitfor), | ||
elseif isequal(opt.waitfor, 'key'), | ||
fprintf(opt.waitfor_msg); | ||
pause; | ||
fprintf('\n'); | ||
else | ||
stimutil_waitForMarker(opt, 'stopmarkers',opt.waitfor); | ||
end | ||
end | ||
|
||
if isequal(opt.delete, 'fig'), | ||
close; | ||
elseif opt.delete, | ||
delete(h.axis); | ||
drawnow; | ||
else | ||
if ~isempty(memo.axis), | ||
axes(memo.axis); | ||
end | ||
if nargout>0, | ||
HANDLE= h; | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
function str= stimutil_waitForInput(varargin) | ||
%STIMUTIL_WAITFORINPUT - Wait for a specific input from keyboard | ||
% | ||
%Synopsis: | ||
% STR= stimutil_waitForInput(OPT) | ||
% | ||
%Arguments: | ||
% OPT: struct or property/value list of optional properties | ||
% 'phrase': phrase that needs to be input before this function returns | ||
% (excluding <RETURN>, which is always required at the end), default: ''; | ||
% 'msg': Message template that prompts the user, | ||
% default 'Press "%s<RETURN>" %s > '. The first %s is filled with | ||
% OPT.phrase, the second %s is filled with OPT.msg_next. | ||
% 'msg_next': see above, default: 'to continue' | ||
% | ||
%Example: | ||
% stimutil_waitForInput('phrase','go', 'msg_next','to go to the next run'); | ||
|
||
|
||
props= {'phrase' '' 'CHAR' | ||
'msg' 'Press "%s<RETURN>" %s > ' 'CHAR' | ||
'msg_next' 'to continue' 'CHAR' | ||
} | ||
|
||
if nargin==0, | ||
str = props; | ||
return | ||
end | ||
|
||
opt= opt_proplistToStruct(varargin{:}); | ||
[opt, isdefault] = opt_setDefaults(opt, props); | ||
opt_checkProplist(opt, props); | ||
|
||
if isdefault.msg, | ||
msg= sprintf(opt.msg, opt.phrase, opt.msg_next); | ||
else | ||
msg= opt.msg; | ||
end | ||
|
||
str= 'xXqQimpossibleQqXx'; | ||
|
||
while ~strcmp(str, opt.phrase), | ||
str= input(msg, 's'); | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
function marker = stimutil_waitForMarker(varargin) | ||
%STIMUTIL_WAITFORMARKER - Wait until specified marker is received | ||
% | ||
%Synopsis: | ||
% stimutil_waitForMarker(<OPT>) | ||
% or | ||
% stimutil_waitForMarker(STOPMARKERS) | ||
% as shorthand for | ||
% stimutil_waitForMarker('stopmarkers', STOPMARKERS) | ||
% | ||
%Arguments: | ||
% OPT: struct or property/value list of optional arguments: | ||
% 'stopmarkers', string or cell array of strings which specify those | ||
% marker types that are awaited, e.g., {'R 1','R128'}. Using 'S' or | ||
% 'R' as stopmarkers matches all Stimulus resp. Response markers. | ||
% OPT.stopmarker can also be a vector of integers, which are interpreted | ||
% as stimulus markers. Default: 'R*'. | ||
% 'bv_host': IP or host name of computer on which BrainVision Recorder | ||
% is running, default 'localhost'. | ||
% 'bv_bbciclose': true or false. If true, perform initially bbciclose. | ||
% | ||
%Example: | ||
% stimutil_waitForMarker('stopmarkers', [254, 255], 'verbose', 1) | ||
% | ||
% 07-2007 Benjamin Blankertz | ||
% 06-2012 Javier Pascual - update, new acquire_fcn used | ||
|
||
props = { 'stopmarkers' [250, 255] 'DOUBLE[2]' | ||
'bv_host' 'localhost' 'CHAR' | ||
'bv_bbciclose' 0 'BOOL' | ||
'acquire_fcn' @bbci_acquire_bv 'FUNC' | ||
'acquire_param' {} 'STRUCT' | ||
'fs' 1000 'DOUBLE' | ||
'state' struct 'STRUCT' | ||
'pause' 0.05 'DOUBLE' | ||
'verbose' 0 'BOOL' | ||
}; | ||
|
||
if nargin==0, | ||
marker = props; | ||
return | ||
elseif mod(nargin,2)==1 & ~isstruct(varargin{1}), | ||
stopmarkers= varargin{1}; | ||
opt= opt_proplistToStruct(varargin{2:end}); | ||
opt.stopmarkers= stopmarkers; | ||
else, | ||
opt= opt_proplistToStruct(varargin{:}); | ||
end; | ||
|
||
[opt,isdefault] = opt_setDefaults(opt, props); | ||
opt_checkProplist(opt, props); | ||
|
||
if isequal(opt.acquire_fcn, @acquire_sigserv), | ||
[opt,isdefault]= opt_overrideIfDefault(opt, isdefault, 'pause',0); | ||
if isdefault.fs, | ||
% get sampling rate from signal server | ||
[sig_info, dmy, dmy]= mexSSClient('localhost',9000,'tcp'); | ||
opt.fs= sig_info(1); | ||
acquire_func('close'); | ||
end | ||
end | ||
|
||
if isempty(opt.bv_host), | ||
fprintf('Waiting for marker disabled by OPT. Press any key to continue.\n'); | ||
pause; | ||
return; | ||
end | ||
|
||
if opt.bv_bbciclose, | ||
bbciclose(); | ||
end | ||
|
||
if opt.verbose, | ||
fprintf('connecting to acquisition system\n'); | ||
end | ||
|
||
if isdefault.state, | ||
opt.state = opt.acquire_fcn('init'); | ||
opt.state.reconnect= 1; | ||
[dmy]= opt.acquire_fcn(opt.state); %% clear the queue | ||
end | ||
|
||
if opt.verbose, | ||
fprintf('waiting for marker %s\n', toString(opt.stopmarkers)); | ||
end | ||
|
||
stopmarker = 0; | ||
while ~stopmarker, | ||
if opt.verbose>2, | ||
fprintf('%s: acquiring data\n', datestr(now,'HH:MM:SS.FFF')); | ||
end | ||
[data, markertime, markerdescr, opt.state]= opt.acquire_fcn(opt.state); | ||
if ~isempty(markerdescr) && opt.verbose>1, | ||
fprintf('%s: received markers: %s\n', datestr(now,'HH:MM:SS.FFF'), vec2str(markerdescr)); | ||
end | ||
for mm= 1:length(markerdescr), | ||
for mmm= 1:length(opt.stopmarkers), | ||
if (markerdescr(mm) == opt.stopmarkers(mmm)), | ||
stopmarker= 1; | ||
if opt.verbose, | ||
fprintf('stop marker received: %d\n', markerdescr(mm)); | ||
end | ||
end | ||
end | ||
end | ||
pause(opt.pause); %% this is to allow breaks | ||
end; | ||
|
||
opt.acquire_fcn('close'); | ||
|
||
if nargin>0 | ||
marker = markerdescr(mm); | ||
end; | ||
|
||
end |
Oops, something went wrong.