Skip to content
Permalink
develop
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
% POP_SELECT - given an input EEG dataset structure, output a new EEG data structure
% retaining and/or excluding specified time/latency, data point, channel,
% and/or epoch range(s).
% Usage:
% >> OUTEEG = pop_select(INEEG, 'key1', value1, 'key2', value2 ...);
%
% Graphic interface:
% "Time range" - [edit box] RETAIN only the indicated epoch latency or continuous data
% time range: [low high] in ms, inclusive. For continuous data, several
% time ranges may be specified, separated by semicolons.
% Example: "5 10; 12 EEG.xmax" will retain the indicated
% stretches of continuous data, and remove data portions outside
% the indicated ranges, e.g. from 0 s to 5 s and from 10 s to 12 s.
% Command line equivalent: 'time' (or 'notime' - see below)
% "Time range" - [checkbox] EXCLUDE the indicated latency range(s) from the data.
% For epoched data, it is not possible to remove a range of latencies
% from the middle of the epoch, so either the low and/or the high values
% in the specified latency range (see above) must be at an epoch boundary
% (EEG.xmin, EEGxmax). Command line equivalent: [if checked] 'notime'
% "Point range" - [edit box] RETAIN the indicated data point range(s).
% Same options as for the "Time range" features (above).
% Command line equivalent: 'point' (or 'nopoint' - see below).
% "Point range" - [checkbox] EXCLUDE the indicated point range(s).
% Command line equivalent: [if checked] 'nopoint'
% "Epoch range" - [edit box] RETAIN the indicated data epoch indices in the dataset.
% This checkbox is only visible for epoched datasets.
% Command line equivalent: 'trial' (or 'notrial' - see below)
% "Epoch range" - [checkbox] EXCLUDE the specified data epochs.
% Command line equivalent: [if checked] 'notrial'
% "Channel range" - [edit box] RETAIN the indicated vector of data channels
% Command line equivalent: 'channel' (or 'nochannel' - see below)
% "Channel range" - [checkbox] EXCLUDE the indicated channels.
% Command line equivalent: [if checked] 'nochannel'
% "..." - [button] select channels by name.
% "Scroll dataset" - [button] call the EEGPLOT function to scroll the
% channel activities in a new window for visual inspection.
% Commandline equivalent: EEGPLOT - see its help for details.
% Inputs:
% INEEG - input EEG dataset structure
%
% Optional inputs
% 'time' - [min max] in seconds. Epoch latency or continuous data time range
% to retain in the new dataset, (Note: not ms, as in the GUI text entry
% above). For continuous data (only), several time ranges can be specified,
% separated by semicolons. Example: "5 10; 12 EEG.xmax" will retain
% the indicated times ranges, removing data outside the indicated ranges
% e.g. here from 0 to 5 s and from 10 s to 12 s. (See also, 'notime')
% 'rmtime' - [min max] in seconds. Epoch latency or continuous dataset time range
% to exclude from the new dataset. For continuous data, may be
% [min1 max1; min2 max2; ...] to exclude several time ranges. For epoched
% data, the latency range must include an epoch boundary, as latency
% ranges in the middle of epochs cannot be removed from epoched data.
% 'point' - [min max] epoch or continuous data point range to retain in the new
% dataset. For continuous datasets, this may be [min1 max1; min2 max2; ...]
% to retain several point ranges. (Notes: If both 'point'/'nopoint' and
% 'time' | 'notime' are specified, the 'point' limit values take precedence.
% The 'point' argument was originally a point vector, now deprecated).
% 'rmpoint' - [min max] epoch or continuous data point range to exclude in the new dataset.
% For epoched data, the point range must include either the first (0)
% or the last point (EEG.pnts), as a central point range cannot be removed.
% 'trial' - [integer array] array of trial indices to retain in the new dataset
% 'rmtrial' - [integer array] array of trial indices to exclude from the new dataset
% 'sorttrial' - ['on'|'off'] sort trial indices before extracting them (default: 'on').
% 'checkchans' - ['on'|'off'] check that channels are present before
% rejecting them (default: 'on')
% 'channel' - vector of channel indices to retain in the new
% dataset. Can also be a cell array of channel names.
% 'rmchannel' - vector of channel indices to exclude from the new
% dataset. Can also be a cell array of channel names.
% 'chantype' - [string|cell] list of channel types to keep
% 'rmchantype' - [string|cell] list of channel types to remove
%
% Outputs:
% OUTEEG - new EEG dataset structure
%
% Note: This function performs a conjunction (AND) of all its optional inputs.
% Using negative counterparts of all options, any logical combination is
% possible. Legacy input 'notrial', 'notime', 'nochannel', 'nopoint'
% are still supported.
%
% Author: Arnaud Delorme, CNL/Salk Institute, 2001; SCCN/INC/UCSD, 2002-
%
% see also: EEGLAB
% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.
% 01-25-02 reformated help & license -ad
% 01-26-02 changed the format for events and trial conditions -ad
% 02-04-02 changed display format and allow for negation of inputs -ad
% 02-17-02 removed the event removal -ad
% 03-17-02 added channel info subsets selection -ad
% 03-21-02 added event latency recalculation -ad
function [EEG, com] = pop_select( EEG, varargin)
com = '';
if nargin < 1
help pop_select;
return;
end
if isempty(EEG(1).data)
disp('Pop_select error: cannot process empty dataset'); return;
end
if nargin < 2
geometry = { [1 1 1] [1 1 0.25 0.23 0.51] [1 1 0.25 0.23 0.51] [1 1 0.25 0.23 0.51] [1 1 0.25 0.23 0.51] ...
[1 1 0.25 0.23 0.51] [1] [1 1 1]};
enabletype = ~isempty(EEG(1).chanlocs) && isfield(EEG(1).chanlocs, 'type') && ~isempty(EEG(1).chanlocs(1).type);
uilist = { ...
{ 'Style', 'text', 'string', 'Select data in:', 'fontweight', 'bold' }, ...
{ 'Style', 'text', 'string', 'Input desired range', 'fontweight', 'bold' }, ...
{ 'Style', 'text', 'string', 'on->remove these', 'fontweight', 'bold' }, ...
{ 'Style', 'text', 'string', 'Time range [min max] (s)', 'fontangle', fastif(length(EEG)>1, 'italic', 'normal') }, ...
{ 'Style', 'edit', 'string', '', 'enable', 'on' }, ...
{ }, { 'Style', 'checkbox', 'string', ' ', 'enable', 'on' },{ }, ...
...
{ 'Style', 'text', 'string', 'Point range (ex: [1 10])', 'fontangle', fastif(length(EEG)>1, 'italic', 'normal') }, ...
{ 'Style', 'edit', 'string', '', 'enable', 'on' }, ...
{ }, { 'Style', 'checkbox', 'string', ' ', 'enable', 'on' },{ }, ...
...
{ 'Style', 'text', 'string', 'Epoch range (ex: 3:2:10)', 'fontangle', fastif(length(EEG)>1, 'italic', 'normal') }, ...
{ 'Style', 'edit', 'string', '', 'enable', 'on' }, ...
{ }, { 'Style', 'checkbox', 'string', ' ', 'enable', 'on' },{ }, ...
...
{ 'Style', 'text', 'string', 'Channel(s)' }, ...
{ 'Style', 'edit', 'string', '', 'tag', 'chans' }, ...
{ }, { 'Style', 'checkbox', 'string', ' ' }, ...
{ 'style' 'pushbutton' 'string' '...', 'enable' fastif(isempty(EEG(1).chanlocs), 'off', 'on') ...
'callback' 'pop_chansel(get(gcbf, ''userdata''), ''field'', ''labels'', ''handle'', findobj(''parent'', gcbf, ''tag'', ''chans''));' }, ...
...
{ 'Style', 'text', 'string', 'Channel type(s)' }, ...
{ 'Style', 'edit', 'string', '', 'tag', 'chantype' }, ...
{ }, { 'Style', 'checkbox', 'string', ' ' }, ...
{ 'style' 'pushbutton' 'string' '...', 'enable' fastif(enabletype, 'on', 'off') ...
'callback' 'pop_chansel(get(gcbf, ''userdata''), ''field'', ''type'', ''handle'', findobj(''parent'', gcbf, ''tag'', ''chantype''));' }, ...
...
{ }, { }, { 'Style', 'pushbutton', 'string', 'Scroll dataset', 'enable', fastif(length(EEG)>1, 'off', 'on'), 'callback', ...
'eegplot(EEG.data, ''srate'', EEG.srate, ''winlength'', 5, ''limits'', [EEG.xmin EEG.xmax]*1000, ''position'', [100 300 800 500], ''xgrid'', ''off'', ''eloc_file'', EEG.chanlocs);' } {}};
% 'callback' 'tmplabels = get(gcbf, ''userdata''); [~, tmpvalchan] = pop_chansel(tmplabels, ''withindex'', ''on''); set(findobj(gcbf, ''tag'', ''chans''), ''string'',tmpvalchan); clear tmplabels tmpvalchan' }, ...
chanlocs = eeg_mergelocs(EEG.chanlocs);
results = inputgui( 'geometry', geometry, 'uilist', uilist, 'helpcom', 'pophelp(''pop_select'');', 'title', 'Select data -- pop_select()', 'userdata', chanlocs );
if isempty(results), return; end
% decode inputs
% -------------
args = {};
if ~isempty( results{1} )
if ~results{2}, args = { args{:}, 'time', eval( [ '[' results{1} ']' ] ) };
else args = { args{:}, 'rmtime', eval( [ '[' results{1} ']' ] ) }; end
end
if ~isempty( results{3} )
if ~results{4}, args = { args{:}, 'point', eval( [ '[' results{3} ']' ] ) };
else args = { args{:}, 'rmpoint', eval( [ '[' results{3} ']' ] ) }; end
end
if ~isempty( results{5} )
if ~results{6}, args = { args{:}, 'trial', eval( [ '[' results{5} ']' ] ) };
else args = { args{:}, 'rmtrial', eval( [ '[' results{5} ']' ] ) }; end
end
if ~isempty( results{7} )
[ chaninds, chanlist ] = eeg_decodechan(chanlocs, results{7});
if isempty(chanlist)
if length(EEG) > 1 && length(unique([EEG.nbchan])) > 1
error([ 'Cannot use channel indices when processing multiple datasets' 10 ...
'with some channels already removed' ])
end
chanlist = chaninds;
end
if ~results{8}, args = { args{:}, 'channel' , chanlist };
else args = { args{:}, 'rmchannel', chanlist }; end
end
if ~isempty( results{9} )
[ ~, chantypes ] = eeg_decodechan(chanlocs, results{9}, 'type');
if ~results{10}, args = { args{:}, 'chantype' , unique(chantypes) };
else args = { args{:}, 'rmchantype', unique(chantypes) }; end
end
else
args = varargin;
end
% process multiple datasets
% -------------------------
if length(EEG) > 1
if nargin < 2
[ EEG, com ] = eeg_eval( 'pop_select', EEG, 'warning', 'on', 'params', args);
else
[ EEG, com ] = eeg_eval( 'pop_select', EEG, 'warning', 'off', 'params',args);
end
return;
end
%----------------------------AMICA---------------------------------
if isfield(EEG.etc,'amica') && isfield(EEG.etc.amica,'prob_added')
for index = 1:2:length(args)
if strcmpi(args{index}, 'channel')
args{index+1} = [ args{index+1} EEG.nbchan-(0:2*EEG.etc.amica.num_models-1)];
end
end
end
%--------------------------------------------------------------------
g = finputcheck(args, { 'time' 'real' [] []; ...
'notime' 'real' [] []; ...
'rmtime' 'real' [] []; ...
'trial' 'integer' [] [1:EEG.trials]; ...
'notrial' 'integer' [] []; ...
'rmtrial' 'integer' [] []; ...
'point' 'integer' [] []; ...
'nopoint' 'integer' [] []; ...
'rmpoint' 'integer' [] []; ...
'channel' { 'integer','cell' } [] [];
'nochannel' { 'integer','cell' } [] [];
'rmchannel' { 'integer','cell' } [] [];
'chantype' { 'string','cell' } [] {};
'rmchantype' { 'string','cell' } [] {};
'trialcond' 'integer' [] []; ...
'notrialcond' 'integer' [] []; ...
'sort' 'integer' [] []; ...
'sorttrial' 'string' { 'on','off' } 'on' }, 'pop_select');
if ischar(g), error(g); end
if ~isempty(g.sort)
if g.sort, g.sorttrial = 'on';
else g.sorttrial = 'off';
end
end
if strcmpi(g.sorttrial, 'on')
g.trial = sort(setdiff( g.trial, g.notrial ));
if isempty(g.trial), error('Error: dataset %s is empty',EEG.filename); end
else
g.trial(ismember(g.trial,g.notrial)) = [];
% still warn about & remove duplicate trials (may be removed in the future)
[p,q] = unique_bc(g.trial);
if length(p) ~= length(g.trial)
disp('Warning: trial selection contained duplicated elements, which were removed.');
end
g.trial = g.trial(sort(q));
end
% rename parameters
% -----------------
if ~isempty(g.rmtime) g.notime = g.rmtime; end
if ~isempty(g.rmpoint) g.nopoint = g.rmpoint; end
if ~isempty(g.rmtrial) g.notrial = g.rmtrial; end
if ~isempty(g.rmchannel) g.nochannel = g.rmchannel; end
% decode channels
% ---------------
if ~isempty(g.channel) || ~isempty(g.nochannel)
% find channels by name
if ~isempty(g.channel)
if ~isempty(g.chantype) || ~isempty(g.rmchantype)
error('You can select channels by name or by type but not both');
end
inds = eeg_decodechan(EEG, g.channel, 'labels', true);
chanFlag = zeros(1, EEG.nbchan);
chanFlag(inds) = 1;
else
chanFlag = ones(1, EEG.nbchan);
end
if ~isempty(g.nochannel)
if ~isempty(g.chantype) || ~isempty(g.rmchantype)
error('You can select channels by name or by type but not both');
end
inds = eeg_decodechan(EEG, g.nochannel, 'labels', true);
chanFlag(inds) = 0;
end
else
% find channels by type
if ~isempty(g.chantype)
inds = eeg_decodechan(EEG, g.chantype, 'type', true);
chanFlag = zeros(1, EEG.nbchan);
chanFlag(inds) = 1;
else
chanFlag = ones(1, EEG.nbchan);
end
if ~isempty(g.rmchantype)
inds = eeg_decodechan(EEG, g.rmchantype, 'type', true);
chanFlag(inds) = 0;
end
end
g.channel = find(chanFlag);
% time selection
% --------------
if ~isempty(g.time) && (g.time(1) < EEG.xmin*1000) && (g.time(2) > EEG.xmax*1000)
error('Wrong time range');
end
if min(g.trial) < 1 || max( g.trial ) > EEG.trials
error('Wrong trial range');
end
if size(g.point,2) > 2
g.point = [g.point(1) g.point(end)];
disp('Warning: vector format for point range is deprecated');
end
if size(g.nopoint,2) > 2
g.nopoint = [g.nopoint(1) g.nopoint(end)];
disp('Warning: vector format for point range is deprecated');
end
if ~isempty( g.point )
g.time = zeros(size(g.point));
for index = 1:length(g.point(:))
g.time(index) = eeg_point2lat(g.point(index), 1, EEG.srate, [EEG.xmin EEG.xmax]);
end
g.notime = [];
end
if ~isempty( g.nopoint )
g.notime = zeros(size(g.nopoint));
for index = 1:length(g.nopoint(:))
g.notime(index) = eeg_point2lat(g.nopoint(index), 1, EEG.srate, [EEG.xmin EEG.xmax]);
end
g.time = [];
end
if ~isempty( g.notime )
if size(g.notime,2) ~= 2
error('Time/point range must contain 2 columns exactly');
end
if g.notime(2) == EEG.xmax
g.time = [EEG.xmin g.notime(1)];
else
if g.notime(1) == EEG.xmin
g.time = [g.notime(2) EEG.xmax];
elseif EEG.trials > 1
error('Wrong notime range. Remember that it is not possible to remove a slice of time for data epochs.');
end
end
if g.notime(end) > EEG.xmax, g.notime(end) = EEG.xmax; end
if g.notime(1) < EEG.xmin, g.notime(1) = EEG.xmin; end
if floor(max(g.notime(:))) > EEG.xmax
error('Time/point range exceed upper data limits');
end
if min(g.notime(:)) < EEG.xmin
error('Time/point range exceed lower data limits');
end
end
if ~isempty(g.time)
if size(g.time,2) ~= 2
error('Time/point range must contain 2 columns exactly');
end
for index = 1:length(g.time)
if g.time(index) > EEG.xmax
g.time(index) = EEG.xmax;
disp('Upper time limits exceed data, corrected');
elseif g.time(index) < EEG.xmin
g.time(index) = EEG.xmin;
disp('Lower time limits exceed data, corrected');
end
end
end
% select trial values
%--------------------
if ~isempty(g.trialcond)
try
tt = struct( g.trialcond{:} ); catch
error('Trial conditions format error');
end
ttfields = fieldnames (tt);
for index = 1:length(ttfields)
if ~isfield( EEG.epoch, ttfields{index} )
error([ ttfields{index} 'is not a field of EEG.epoch' ]);
end
tmpepoch = EEG.epoch;
eval( [ 'Itriallow = find( [ tmpepoch(:).' ttfields{index} ' ] >= tt.' ttfields{index} '(1) );' ] );
eval( [ 'Itrialhigh = find( [ tmpepoch(:).' ttfields{index} ' ] <= tt.' ttfields{index} '(end) );' ] );
Itrialtmp = intersect_bc(Itriallow, Itrialhigh);
g.trial = intersect_bc( g.trial(:)', Itrialtmp(:)');
end
end
if isempty(g.trial)
error('Empty dataset, no trial');
end
if length(g.trial) ~= EEG.trials
fprintf('Removing %d trial(s)...\n', EEG.trials - length(g.trial));
end
if length(g.channel) ~= EEG.nbchan
fprintf('Removing %d channel(s)...\n', EEG.nbchan - length(g.channel));
end
try
% For AMICA probabilities...
%-----------------------------------------------------
if isfield(EEG.etc, 'amica') && ~isempty(EEG.etc.amica) && isfield(EEG.etc.amica, 'v_smooth') && ~isempty(EEG.etc.amica.v_smooth) && ~isfield(EEG.etc.amica,'prob_added')
if isfield(EEG.etc.amica, 'num_models') && ~isempty(EEG.etc.amica.num_models)
if size(EEG.data,2) == size(EEG.etc.amica.v_smooth,2) && size(EEG.data,3) == size(EEG.etc.amica.v_smooth,3) && size(EEG.etc.amica.v_smooth,1) == EEG.etc.amica.num_models
EEG = eeg_formatamica(EEG);
%-------------------------------------------
[EEG, com] = pop_select(EEG,args{:});
%-------------------------------------------
EEG = eeg_reformatamica(EEG);
EEG = eeg_checkamica(EEG);
return;
else
disp('AMICA probabilities not compatible with size of data, probabilities cannot be rejected')
disp('Resuming rejection...')
end
end
end
% ------------------------------------------------------
catch
warnmsg = strcat('your dataset contains amica information, but the amica plugin is not installed. Continuing and ignoring amica information.');
warning(warnmsg)
end
% recompute latency and epoch number for events
% ---------------------------------------------
if length(g.trial) ~= EEG.trials && ~isempty(EEG.event)
if ~isfield(EEG.event, 'epoch')
disp('Pop_epoch warning: bad event format with epoch dataset, removing events');
EEG.event = [];
else
if isfield(EEG.event, 'epoch')
keepevent = [];
for indexevent = 1:length(EEG.event)
newindex = find( EEG.event(indexevent).epoch == g.trial );% For AMICA probabilities...
%-----------------------------------------------------
try
if isfield(EEG.etc, 'amica') && ~isempty(EEG.etc.amica) && isfield(EEG.etc.amica, 'v_smooth') && ~isempty(EEG.etc.amica.v_smooth) && ~isfield(EEG.etc.amica,'prob_added')
if isfield(EEG.etc.amica, 'num_models') && ~isempty(EEG.etc.amica.num_models)
if size(EEG.data,2) == size(EEG.etc.amica.v_smooth,2) && size(EEG.data,3) == size(EEG.etc.amica.v_smooth,3) && size(EEG.etc.amica.v_smooth,1) == EEG.etc.amica.num_models
EEG = eeg_formatamica(EEG);
%-------------------------------------------
[EEG, com] = pop_select(EEG,args{:});
%-------------------------------------------
EEG = eeg_reformatamica(EEG);
EEG = eeg_checkamica(EEG);
return;
else
disp('AMICA probabilities not compatible with size of data, probabilities cannot be rejected')
disp('Resuming rejection...')
end
end
end
catch
warnmsg = strcat('your dataset contains amica information, but the amica plugin is not installed. Continuing and ignoring amica information.');
warning(warnmsg)
end;
% ------------------------------------------------------
if ~isempty(newindex)
keepevent = [keepevent indexevent];
if isfield(EEG.event, 'latency')
EEG.event(indexevent).latency = EEG.event(indexevent).latency - (EEG.event(indexevent).epoch-1)*EEG.pnts + (newindex-1)*EEG.pnts;
end
EEG.event(indexevent).epoch = newindex;
end
end
diffevent = setdiff_bc([1:length(EEG.event)], keepevent);
if ~isempty(diffevent)
disp(['Pop_select: removing ' int2str(length(diffevent)) ' unreferenced events']);
EEG.event(diffevent) = [];
end
end
end
end
% performing removal
% ------------------
if ~isempty(g.time) || ~isempty(g.notime)
if EEG.trials > 1
% select new time window
% ----------------------
try, tmpevent = EEG.event;
tmpeventlatency = [ tmpevent.latency ];
catch, tmpeventlatency = [];
end
alllatencies = 1-(EEG.xmin*EEG.srate); % time 0 point
alllatencies = linspace( alllatencies, EEG.pnts*(EEG.trials-1)+alllatencies, EEG.trials);
[EEG.data, tmptime, indices, epochevent]= epoch(EEG.data, alllatencies, ...
[g.time(1) g.time(2)]*EEG.srate, 'allevents', tmpeventlatency);
tmptime = tmptime/EEG.srate;
if g.time(1) ~= tmptime(1) && g.time(2)-1/EEG.srate ~= tmptime(2)
fprintf('pop_select(): time limits have been adjusted to [%3.3f %3.3f] to fit data points limits\n', tmptime(1), tmptime(2)+1/EEG.srate);
end
EEG.xmin = tmptime(1);
EEG.xmax = tmptime(2);
EEG.pnts = size(EEG.data,2);
alllatencies = alllatencies(indices);
% modify the event structure accordingly (latencies and add epoch field)
% ----------------------------------------------------------------------
allevents = [];
newevent = [];
count = 1;
if ~isempty(epochevent)
newevent = EEG.event(1);
for index=1:EEG.trials
for indexevent = epochevent{index}
newevent(count) = EEG.event(indexevent);
newevent(count).epoch = index;
newevent(count).latency = newevent(count).latency - alllatencies(index) - tmptime(1)*EEG.srate + 1 + EEG.pnts*(index-1);
count = count + 1;
end
end
end
EEG.event = newevent;
% erase event-related fields from the epochs
% ------------------------------------------
if ~isempty(EEG.epoch)
fn = fieldnames(EEG.epoch);
EEG.epoch = rmfield(EEG.epoch,{fn{strmatch('event',fn)}});
end
else
if isempty(g.notime)
if length(g.time) == 2 && EEG.xmin < 0
disp('Warning: negative minimum time; unchanged to ensure correct latency of initial boundary event');
end
g.notime = g.time';
g.notime = g.notime(:);
if g.notime(1) ~= 0, g.notime = [EEG.xmin g.notime(:)'];
else g.notime = [g.notime(2:end)'];
end
if g.time(end) == EEG.xmax, g.notime(end) = [];
else g.notime(end+1) = EEG.xmax;
end
for index = 1:length(g.notime)
if g.notime(index) ~= 0 && g.notime(index) ~= EEG.xmax
if mod(index,2), g.notime(index) = g.notime(index) + 1/EEG.srate;
else g.notime(index) = g.notime(index) - 1/EEG.srate;
end
end
end
g.notime = reshape(g.notime, 2, length(g.notime)/2)';
end
nbtimes = length(g.notime(:));
[points,flag] = eeg_lat2point(g.notime(:)', ones(1,nbtimes), EEG.srate, [EEG.xmin EEG.xmax]);
points = reshape(points, size(g.notime));
% fixing if last region is the same
if flag
if ~isempty(find((points(end,1)-points(end,2))== 0)), points(end,:) = []; end
end
EEG = eeg_eegrej(EEG, points);
end
end
% performing removal
% ------------------
if ~isequal(g.channel,1:size(EEG.data,1)) || ~isequal(g.trial,1:size(EEG.data,3))
eeglab_options;
if option_memmapdata
% this code below is preferred for memory mapped files
diff1 = setdiff_bc([1:size(EEG.data,1)], g.channel);
diff2 = setdiff_bc([1:size(EEG.data,3)], g.trial);
if ~isempty(diff1)
EEG.data(diff1, :, :) = [];
end
if ~isempty(diff2)
EEG.data(:, :, diff2) = [];
end
else
EEG.data = EEG.data(g.channel, :, g.trial);
end
end
if ~isempty(EEG.icaact), EEG.icaact = EEG.icaact(:,:,g.trial); end
if ~isempty(EEG.chanlocs)
if ~isfield(EEG.chaninfo, 'removedchans')
EEG.chaninfo.removedchans = [];
end
try
diff1 = setdiff_bc([1:EEG.nbchan], g.channel);
fields = fieldnames(EEG.chanlocs);
for iChan = diff1(:)'
EEG.chaninfo.removedchans(end+1).(fields{1}) = EEG.chanlocs(iChan).(fields{1});
for iField = 1:length(fields)
EEG.chaninfo.removedchans(end).(fields{iField}) = EEG.chanlocs(iChan).(fields{iField});
end
end
catch
disp('There was an issue storing removed channels in pop_select');
end
EEG.chanlocs = EEG.chanlocs(g.channel);
end
EEG.trials = length(g.trial);
EEG.pnts = size(EEG.data,2);
EEG.nbchan = length(g.channel);
if ~isempty(EEG.epoch)
EEG.epoch = EEG.epoch( g.trial );
end
if ~isempty(EEG.specdata)
if length(g.point) == EEG.pnts
EEG.specdata = EEG.specdata(g.channel, :, g.trial);
else
EEG.specdata = [];
fprintf('Warning: spectral data were removed because of the change in the number of points\n');
end
end
% ica specific
% ------------
if ~isempty(EEG.icachansind)
rmchans = setdiff_bc( EEG.icachansind, g.channel ); % channels to remove
% channel sub-indices
% -------------------
icachans = 1:length(EEG.icachansind);
for index = length(rmchans):-1:1
chanind = find(EEG.icachansind == rmchans(index));
icachans(chanind) = [];
end
% new channels indices
% --------------------
count = 1;
newinds = [];
for index = 1:length(g.channel)
if any(EEG.icachansind == g.channel(index))
newinds(count) = index;
count = count+1;
end
end
EEG.icachansind = newinds;
else
icachans = 1:size(EEG.icasphere,2);
end
if ~isempty(EEG.icawinv)
flag_rmchan = (length(icachans) ~= size(EEG.icawinv,1));
if isempty(EEG.icaweights) || flag_rmchan
EEG.icawinv = EEG.icawinv(icachans,:);
EEG.icaweights = pinv(EEG.icawinv);
EEG.icasphere = eye(size(EEG.icaweights,2));
end
end
if ~isempty(EEG.specicaact)
if length(g.point) == EEG.pnts
EEG.specicaact = EEG.specicaact(icachans, :, g.trial);
else
EEG.specicaact = [];
fprintf('Warning: spectral ICA data were removed because of the change in the number of points\n');
end
end
% check if only one epoch
% -----------------------
if EEG.trials == 1
if isfield(EEG.event, 'epoch')
EEG.event = rmfield(EEG.event, 'epoch');
end
EEG.epoch = [];
end
if isfield(EEG.reject, 'gcompreject') && isequal(g.channel,1:size(EEG.data,1))
tmpgcompreject = EEG.reject.gcompreject;
EEG.reject = [];
EEG.reject.gcompreject = tmpgcompreject;
else
EEG.reject = [];
end
EEG.stats = [];
EEG.reject.rejmanual = [];
% for stats, can adapt remove the selected trials and electrodes
% in the future to gain time -----------------------------------
EEG.stats.jp = [];
EEG = eeg_checkset(EEG, 'eventconsistency');
% generate command
% ----------------
if nargout > 1
com = sprintf('EEG = pop_select( EEG, %s);', vararg2str(args));
end
return;
% ********* OLD, do not remove any event any more
% ********* in the future maybe do a pack event to remove events not in the time range of any epoch
if ~isempty(EEG.event)
% go to array format if necessary
if isstruct(EEG.event), format = 'struct';
else format = 'array';
end
switch format, case 'struct', EEG = eventsformat(EEG, 'array'); end
% keep only events related to the selected trials
Indexes = [];
Ievent = [];
for index = 1:length( g.trial )
currentevents = find( EEG.event(:,2) == g.trial(index));
Indexes = [ Indexes ones(1, length(currentevents))*index ];
Ievent = union_bc( Ievent, currentevents );
end
EEG.event = EEG.event( Ievent,: );
EEG.event(:,2) = Indexes(:);
switch format, case 'struct', EEG = eventsformat(EEG, 'struct'); end
end