📄 pop_chanevent.m
字号:
% Initial revision
%
function [EEG, command] = pop_chanevent(EEG, chan, varargin);
command = '';
if nargin < 1
help pop_chanevent;
return;
end;
if nargin < 2
geometry = { [1.5 1 1] [1] [1.5 1 1] [1.5 1 1] [1.5 1 1] [1.5 0.2 0.36 0.84] ...
[1] [1.5 0.21 1] [1.5 0.21 1] [1.5 0.21 1] };
% callback from listbox to disable duration checkbox (if leading event is not selected)
% --------------------------------------------------
cb_list = [ 'if get(gcbo, ''value'') == 1,' ...
' set(findobj(gcbf, ''tag'', ''dur''), ''enable'', ''on'');' ...
'else,' ...
' set(findobj(gcbf, ''tag'', ''dur''), ''enable'', ''off'', ''value'', 0);' ...
'end;' ];
strgui = { { 'style' 'text' 'string' 'Event channel(s)' 'tooltipstring' 'indexes of event channels' } ...
{ 'style' 'edit' 'string' '' } { } ...
{} ...
{ 'style' 'text' 'string' 'Preprocessing transform (data=''X'')' 'tooltipstring' ...
[ 'For example, ''X>3'' will test the value of X' 10 ...
'at each time point (returning 1 if the data channel value' 10 ...
'is larger than 3, and 0 otherwise).' ] } ...
{ 'style' 'edit' 'string' '' } { 'style' 'text' 'string' 'Optional. Ex: X>3' } ...
{ 'style' 'text' 'string' 'Transitions to extract? (up|down)' 'tooltipstring' ...
[ 'Extract events whenever values in the (transformed) event channel(s) shift up' 10 ...
'(''leading''), down (''trailing'') or either (''both'').' 10 ...
'AFTER SCROLLING CLICK TO SELECT' ] } ...
{ 'style' 'listbox' 'string' 'up (leading)|both|down (trailing)' 'value' 1 'callback' cb_list } ...
{ 'style' 'text' 'string' '(click to select)'} ...
{ 'style' 'text' 'string' 'Transition length (1=perfect edges)' 'tooltipstring' ...
[ 'Increase this number to avoid having events very close to each other due.' 10 ...
'to a not perfectly straight edge' ] } ...
{ 'style' 'edit' 'string' '1' } { } ...
{ 'style' 'text' 'string' 'Assign duration to each events?' 'tag' 'dur' 'tooltipstring' ...
[ 'You may assign an event duration to each event if you select to detect' 10 ...
'event on the leading edge above. Event will last as long as the signal is non-0.' ] } ...
{ 'style' 'checkbox' 'string' '' 'value' 0 'tag' 'dur'} { } ...
{ 'style' 'text' 'string' '(set=yes)' } ...
{} ...
{ 'style' 'text' 'string' 'Delete event channel(s)? ' } ...
{ 'style' 'checkbox' 'value' 1 } { 'style' 'text' 'string' ' (set = yes)'} ...
{ 'style' 'text' 'string' 'Delete old events if any? ' } ...
{ 'style' 'checkbox' 'value' 1 } { } ...
{ 'style' 'text' 'string' 'All events of same type? ' 'tooltipstring' ...
['If set, all transitions are considered the same event type,' 10 ...
'If unset, each (transformed) event channel value following a transition' 10 ...
'determines an event type (Ex: Detecting leading-edge transitions of' 10 ...
'0 0 1 0 2 0 ... produces event types 1 and 2).' ] } ...
{ 'style' 'checkbox' 'value' 0 } { } };
result = inputgui( geometry, strgui, 'pophelp(''pop_chanevent'');', 'Extract event from channel(s) - pop_chanevent()');
if length(result) == 0 return; end;
chan = eval( [ '[' result{1} ']' ] );
options = {};
if ~isempty(result{2}), options = { options{:} 'oper' result{2} }; end;
switch result{3},
case 1, options = { options{:} 'edge' 'leading' };
case 2, options = { options{:} 'edge' 'both' };
case 3, options = { options{:} 'edge' 'trailing' };
end;
options = { options{:} 'edgelen' eval( [ '[' result{4} ']' ] ) };
if result{5}, options = { options{:} 'duration' 'on' }; end;
if ~result{6}, options = { options{:} 'delchan' 'off'}; end;
if ~result{7}, options = { options{:} 'delevent' 'off'}; end;
if result{8}, options = { options{:} 'nbtype' 1}; end;
else
options = varargin;
end;
listcheck = { 'edge' 'string' { 'both' 'leading' 'trailing'} 'both';
'edgelen' 'integer' [1 Inf] 1;
'delchan' 'string' { 'on' 'off' } 'on';
'oper' 'string' [] '';
'delevent' 'string' { 'on' 'off' } 'on';
'duration' 'string' { 'on' 'off' } 'off';
'typename' 'string' [] [ 'chan' int2str(chan) ];
'nbtype' 'integer' [1 NaN] NaN };
g = finputcheck( options, listcheck, 'pop_chanedit');
if isstr(g), error(g); end;
% check inut consistency
% ----------------------
if strcmpi(g.duration, 'on') & ~strcmpi(g.edge, 'leading')
error('Must detect leading edge to extract event duration');
end;
% process events
% --------------
fprintf('pop_chanevent: importing events from data channel %d ...\n', chan);
counte = 1; % event counter
events(10000).latency = 0;
if isnan(g.nbtype)
if length(unique(EEG.data(chan, :))) == 2, g.nbtype = 1; end;
end;
for ci = chan
X = EEG.data(ci, :);
% apply preprocessing
% -------------------
if ~isempty(g.oper)
try, eval( [ 'X = ' g.oper ';' ]);
catch, error('pop_chanevent: error executing preprocessing string');
end;
end;
% extract edges
% -------------
tmpdiff = diff(X);
switch g.edge
case 'both' , tmpevent1 = find( tmpdiff > 0)-1; tmpevent2 = find( tmpdiff < 0);
case 'trailing', tmpevent2 = find( tmpdiff < 0);
case 'leading' , tmpevent1 = find( tmpdiff > 0)-1; tmpdur = find( tmpdiff < 0);
end;
% fuse close events if necessary
% ------------------------------
if exist('tmpevent1')
tmpclose = find( tmpevent1(2:end)-tmpevent1(1:end-1) < g.edgelen)+1;
tmpevent1(tmpclose) = [];
tmpevent = tmpevent1+1;
tmpeventval = tmpevent1+2;
end;
if exist('tmpevent2')
tmpclose = find( tmpevent2(2:end)-tmpevent2(1:end-1) < g.edgelen); % not +1
tmpevent2(tmpclose) = [];
tmpevent = tmpevent2+1;
tmpeventval = tmpevent2;
end;
if exist('tmpevent1') & exist('tmpevent2')
tmpevent = sort([ tmpevent1+1 tmpevent2+1]);
tmpeventval = sort([ tmpevent1+2 tmpevent2]);
end;
% adjust edges for duration if necessary
% ---------------------------------------
if strcmpi(g.duration, 'on')
tmpclose = find( tmpdur(2:end)-tmpdur(1:end-1) < g.edgelen); % not +1 (take out the first)
tmpdur(tmpclose) = [];
if tmpdur(1) < tmpevent(1), tmpdur(1) = []; end;
if length(tmpevent) > length(tmpdur), tmpdur(end+1) = EEG.pnts; end;
if length(tmpevent) ~= length(tmpdur)
error([ 'Error while attempting to extract event durations' 10 ...
'Maybe edges are not perfectly defined, try increasing edge length' ]);
end;
end;
if isempty(tmpevent),
fprintf('No event found for channel %d\n', ci);
else
for tmpi = 1:length(tmpevent)
if ~isnan(g.nbtype)
events(counte).type = g.typename;
else
events(counte).type = X(tmpeventval(tmpi));
end;
events(counte).latency = tmpevent(tmpi);
if strcmpi(g.duration, 'on')
events(counte).duration = tmpdur(tmpi) - tmpevent(tmpi);
end;
counte = counte+1;
end;
end;
events = events(1:counte-1);
end;
% resort events
% --------------
if strcmp(g.delevent, 'on')
EEG.event = events;
if EEG.trials > 1
for index = 1:length(events)
EEG.event(index).epoch = 1+floor((EEG.event(index).latency-1) / EEG.pnts);
end;
end;
else
for index = 1:length(events)
EEG.event(end+1).type = events(index).type;
EEG.event(end).latency = events(index).latency;
if EEG.trials > 1 | isfield(EEG.event, 'epoch');
EEG.event(end).epoch = 1+floor((EEG.event(end).latency-1) / EEG.pnts);
end;
end;
if EEG.trials > 1
EEG = pop_editeventvals( EEG, 'sort', { 'epoch' 0 'latency', [0] } );
else
EEG = pop_editeventvals( EEG, 'sort', { 'latency', [0] } );
end;
end;
if isfield(EEG.event, 'urevent'), EEG.event = rmfield(EEG.event, 'urevent'); end;
EEG = eeg_checkset(EEG, 'eventconsistency');
EEG = eeg_checkset(EEG, 'makeur');
% delete channels
% ---------------
if strcmp(g.delchan, 'on')
EEG = pop_select(EEG, 'nochannel', chan);
end;
if nargin < 2
command = sprintf('%s = pop_chanevent(%s, %s);', inputname(1), inputname(1), ...
vararg2str({ chan options{:} }));
end;
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -