Skip to content

Commit

Permalink
v2.0 (#1)
Browse files Browse the repository at this point in the history
* new functions

* update to readme

* update README

* bug fix

* remove R

* del r

* minor text fix

* update README

* move maxmin readme

* minor link fix

* minor README fix

* update README

* update maxmin readme

* final fix

* final fix to maxmin readme
  • Loading branch information
mattansb authored May 7, 2018
1 parent 096d1ec commit df588a5
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 81 deletions.
157 changes: 110 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,71 +1,134 @@

# TBT


[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1241518.svg)](https://doi.org/10.5281/zenodo.1241518)

This EEGLAB plugin allows for the automatic rejection and interpolation of channels on an epoch-by-epoch basis.

It also comes with an additional method for rejecting epochs - max-minus-min threshold.
It also comes with an additional method for rejecting epochs - max-minus-min threshold [(see here for more info)](./doc/Using_eegmaxmin.md).

## Downloading

- You can download TBT through EEGLAB's data-processing extension GUI (_File > Manage EEGLAB Extensions > Data-Processing Extensions_).
- Or as a `.zip` file from EEGLABS's servers [(TBT v1.5)](http://sccn.ucsd.edu/eeglab/plugins/TBT1.5.zip).
- Or as a `.zip` file from the GitHub page [(TBT v1.5)](https://github.com/mattansb/TBT/releases).
- You can download TBT through EEGLAB's data-processing extension GUI (*File > Manage EEGLAB Extensions > Data-Processing Extensions*).
- Or as a `.zip` file from EEGLABS's servers [(TBT v1.5)](http://sccn.ucsd.edu/eeglab/plugins/TBT1.5.zip).
- Or as a `.zip` file from the GitHub page [(TBT)](https://github.com/mattansb/TBT/releases).

## Using `pop_TBT`
### List of included functions
- `eegplugin_TBT` - EEGLAB plugin function.
- `tbt_bcr` - epoch-by-epoch channel interpolation, based on any rejection method used by EEGLAB, or a manual cell-array listing which channels to interpolate in which epochs.
- `pop_TBT` - call from EEGLAB menu of `tbt_bcr`. If no parameters are specified, pops a GUI window
## List of included functions

### TBT GUI
- `eegplugin_TBT` - EEGLAB plugin function.
- `tbt_bcr` - epoch-by-epoch channel interpolation, based on any rejection method used by EEGLAB, or a manual cell-array listing which channels to interpolate in which epochs.
- `tbt_bool2cell` - converts a boolean channel-by-trial matrix to a tbt ready cell-list (see bellow).
- `tbt_cell2bool` - converts a tbt ready cell-list a boolean channel-by-trial matrix (see bellow).
- `pop_TBT` - call from EEGLAB menu of `tbt_bcr`. If no parameters are specified, pops a GUI window.

![pop_TBT](doc/TBT_eg.png)
## TBT GUI

### Scripting
```matlab
Use the menu *Tools > Epoch by Epoch Rejection/Interpolation*, or type into the command line:

``` matlab
[EEG, com, badlist] = pop_TBT(EEG); % pop-up interactive window mode
```

![](doc/TBT_eg.png)

You will be asked to select a rejection method, and set its parameters, and also to set the following:
1. **The maximum percent of bad trials per channel.** If a channel is bad on more then this percent of the trials, the channel will be removed across the whole data-set.
2. **The maximum number of bad channels per trial.** If a trial has more than this number of bad channels, the trial will be removed.
3. Whether to plot the marked channels and trials before rejecting and interpolating the marked channels.

![](doc/tbt_plot.png)

## Scripting

Scripting takes to general following form:

``` matlab
% Use some rejection method:
EEG = pop_eegmaxmin(EEG);
% Send the 'rejE' matrix to pop_TBT:
my_bads = EEG.reject.rejmaxminE;
EEG = pop_TBT(EEG,my_bads,0.3,10);
% to get more info, type 'help pop_TBT' in the command line.
```

Scripting gives two major additional not available in the gui:

1. Supplying a cell-list for rejection
2. interpolating additional missing channels (thus making TBT an optional last step in pre-processing)

### Supplying a cell-list

EEG = pop_TBT(EEG,bads,badsegs,badchans,plot_bads);
% EEG - input dataset
% bads - a boolean 2-d matrix (channels * trials) specifying "bad
% channels" for each epoch. OR
% a x-by-2 cell list, with the first column specifying the
% epochs, and the second column specifying the bad channels
% in those epochs. e.g.: {1,{'E12'};[13 28],{'E22'}} will
% remove E12 from the 1st epoch, and E22 from epochs 13 and
% 28.
% badsegs - Number of max bad channels per epoch. If an epoch has
% more than this number of bad channels, the epoch is
% removed.
% badchans - Proportion (e.g., 0.3) of max bad epochs per channel. If
% a channel was found to be bad on more than this percent
% of trials, it is removed.
% plot_bads - [0|1] plot before executing. When plotting, will also ask
% to confirm. If no plotting, will execute immediately.
A cell list can be manually created to mark bad channels in specific trials. For example, if we wish to remove E12 and E45 from the 1st epoch, and E22 from epochs 13 and 28, we would create a cell list to be used this list as input for `pop_TBT`:

``` matlab
my_bads = {...
1,{'E12','E45'};...
[13 28],{'E22'};...
}
EEG = pop_TBT(EEG,my_bads,0.3,10);
```
## Using `pop_eegmaxmin`

### List of included functions
This method can also be combined with other `rejE` methods using the `tbt_cell2bool` function:

- `eegmaxmin` - new rejection method, based on max-min amplitude differences (available only for channel data, not IC activation).
- `pop_eegmaxmin` - call from EEGLAB menu of `eegmaxmin`. If no parameters are specified, pops a GUI window:
``` matlab
% Specify cell-list
my_bads = {...
1,{'E12','E45'};...
[13 28],{'E22'};...
}
### Max-Min Threshold GUI
% transforms the cell-list into a 'rejE'-like matrix.
my_bads = tbt_cell2bool(my_bads,EEG);
![pop_eegmaxmin](doc/maxmin_eg.png)
% combine with automatic method:
EEG = pop_eegmaxmin(EEG);
### Scripting
```matlab
[EEG, com] = pop_eegmaxmin(EEG); % pop-up interactive window mode
EEG = pop_eegmaxmin(EEG,chanRange,timeRange,minmaxThresh,winSize,stepSize);
% EEG - input dataset.
% chanRange - [1:EEG.nbchan] indecies for channels.
% timeRange - [1:EEG.xmax*1000] range for inspection in ms.
% minmaxThresh- Threshold for the difference between max and min.
% winSize - size of moving window (in ms).
% stepSize - step size for moving window (in ms).
% maW - moving average window size [default 0].
my_bads = my_bads | EEG.reject.rejmaxminE;
EEG = pop_TBT(EEG,my_bads,0.3,10);
```
The `tbt_bool2cell` function is the reverse of `tbt_cell2bool`, converting a boolean `rejE` matrix to a tbt-ready cell-list. For example:

```Matlab
EEG = pop_eegmaxmin(EEG);
tbt_bool2cell(EEG.reject.rejmaxminE, EEG)
>> ans =
>>
>> 70ª2 cell array
>>
>> [ 2] {'E64' 'E90'}
>> [ 3] {'E63' 'E64' 'E68' 'E90' 'E99'}
>> [ 5] {'E68' 'E73'}
>> ...
```

### Intepolating all missing channels

By default, trial-by-trial interpolation interpolates *only* the channels that are marked on a single-trial basis. i.e., channels marked as bad across the whole data-set will not be re-added by interpolation. If you wish to add them back (or any other channel that may have been removed in any previous processing step), channel locations can be added to `pop_tbt`:

``` matlab
% To add back all channels from the input EEG data-set:
EEG = pop_eegmaxmin(EEG);
my_bads = EEG.reject.rejmaxminE;
EEG = pop_TBT(EEG,my_bads,0.3,10,[],EEG.chanlocs); % or any other chanloc struct
```

This makes TBT an ideal 'last step' in preprocessing - providing a clean data-set with all missing channels interpolated.

Author
------

- **Mattan S. Ben-Shachar** \[aut, cre\] \<mattanshm at post.bgu.ac.il\>
25 changes: 25 additions & 0 deletions doc/Using_eegmaxmin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

<!-- README.md is generated from README.Rmd. Please edit that file -->
eegmaxmin
=========

Using `pop_eegmaxmin`
---------------------

### List of included functions

- `eegmaxmin` - new rejection method, based on max-min amplitude differences (available only for channel data, not IC activation).
- `pop_eegmaxmin` - call from EEGLAB menu of `eegmaxmin`. If no parameters are specified, pops a GUI window:

### Max-Min Threshold GUI

![pop\_eegmaxmin](maxmin_eg.png)

### Scripting

``` matlab
[EEG, com] = pop_eegmaxmin(EEG); % pop-up interactive window mode
EEG = pop_eegmaxmin(EEG,chanRange,timeRange,minmaxThresh,winSize,stepSize,maW);
% to get more info, type 'help pop_eegmaxmin' in the command line.
```
Binary file added doc/tbt_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 16 additions & 13 deletions tbt/pop_TBT.m
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
% pop_TBT() - Rejects and iterpolates channels on a epoch by epoch basis.
%
% Usage:
% >> EEG = pop_TBT(EEG,bads,badsegs,badchans,plot_bads);
% >> EEG = pop_TBT(EEG,bads,badsegs,badchans,plot_bads,chanlocs);
%
% only interpolate channels according to `bads`:
% >> EEG = pop_TBT(EEG,bads,EEG.nbchan,1,plot_bads);
% >> EEG = pop_TBT(EEG,bads,EEG.nbchan,1,plot_bads,chanlocs);
%
% pop-up interative window mode:
% >> [EEG, com, badlist] = pop_TBT(EEG);
Expand Down Expand Up @@ -41,6 +41,12 @@
% of trials, it is removed.
% plot_bads - [0|1] plot before executing. When plotting, will also ask
% to confirm. If no plotting, will execute immediately.
% chanlocs - [optional] a chanlocs struct (e.g., EEG.chanlocs). If
% provided, missing channels will be interpolated according
% to this struct, and not the input EEG. NOTE that if not
% provided, channel that have been rejected across the
% dataset (according to the badchans critirion) will not be
% interpolated back in.
%
% Outputs:
% EEG - output dataset. Note that due to the fucntion of
Expand All @@ -64,7 +70,7 @@
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

function [EEG, com, badlist] = pop_TBT(EEG,bads,badsegs,badchans,plot_bads)
function [EEG, com, badlist] = pop_TBT(EEG,bads,badsegs,badchans,plot_bads,chanlocs)

com = '';

Expand Down Expand Up @@ -157,12 +163,14 @@
eval([comrej]);
eval([comtbt]);
end
elseif nargin < 5
[EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,1);
badlist.nbadchan = nbadchan;
badlist.nbadtrial = nbadtrial;
else
[EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,plot_bads);
if ~exist('plot_bads','var'), plot_bads = 1; end
if exist('chanlocs','var')
[EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,plot_bads,chanlocs);
else
[EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,plot_bads);
end

badlist.nbadchan = nbadchan;
badlist.nbadtrial = nbadtrial;
end
Expand All @@ -184,8 +192,3 @@ function get_help(x,y)

end






45 changes: 24 additions & 21 deletions tbt/tbt_bcr.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
% tbt_bcr() - Rejects and iterpolates channels on a epoch by epoch basis.
%
% Usage:
% >> [EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,plot_bads);
% >> [EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,plot_bads,chanlocs);
%
% Inputs:
% EEG - input dataset
Expand All @@ -16,6 +16,12 @@
% of trials, it is removed.
% plot_bads - [0|1] plot before executing. When plotting, will also ask
% to confirm. If no plotting, will execute immediately.
% chanlocs - [optional] a chanlocs struct (e.g., EEG.chanlocs). If
% provided, missing channels will be interpolated according
% to this struct, and not the input EEG. NOTE that if not
% provided, channel that have been rejected across the
% dataset (according to the badchans critirion) will not be
% interpolated back in.
%
% Outputs:
% EEG - output dataset
Expand All @@ -40,19 +46,12 @@
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


function [EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,plot_bads)
function [EEG, nbadchan, nbadtrial] = tbt_bcr(EEG,bads,badsegs,badchans,plot_bads,chanlocs)

%% convert bads from cell to array
if iscell(bads)
fprintf('pop_TBT(): Converting cell-array.')
bads_array = zeros([size(EEG.data,1) size(EEG.data,3)]);
for r = 1:size(bads,1)
% identift channels
chan_i = cellfun(@(x) any(strcmpi(x,bads{r,2})),{EEG.chanlocs.labels});
epoch_i = bads{r,1};
bads_array(chan_i,epoch_i) = 1;
end
bads = bads_array;
bads = tbt_cell2bool(bads,EEG);
fprintf('.. done.\n')
end

Expand Down Expand Up @@ -104,7 +103,7 @@


if plot_bads==0
%% Remove bad channels and trials
%% Remove bad channels and trials
% Remove bad channels
fprintf('\n')
if ~isempty(bChan_lab) % if any bad channels
Expand All @@ -126,15 +125,15 @@

%% Interpolate bad channels (trial by trial)
EEG_old = EEG; % need the old channlocs an events for later

tbt = {[],{}}; % make empty list
for tr = 1:size(bads,2) % each trial
if any(bads(:,tr)) % if has any bad channels
tbt{end+1,1} = tr; % list trial number
tbt{end,2} = {EEG.chanlocs(bads(:,tr)==1).labels}; % list bad channels in current trial
end
if ~exist('chanlocs','var')
interp_all = true;
chanlocs = EEG_old.chanlocs;
else
interp_all = false;
end
tbt = tbt(2:end,:); % remove first empty row

% convert bool array to n-by-2 cell-list
tbt = tbt_bool2cell(bads,EEG);

if size(tbt,1)~=0
fprintf('pop_TBT(): Splitting data')
Expand All @@ -160,8 +159,8 @@
for t = 1:length(NEWEEG)
if ~mod(t,5), fprintf('.'); end
% Interpolate:
evalc('NEWEEG(t) = pop_interp(NEWEEG(t), EEG_old.chanlocs, ''spherical'');');
% NEWEEG(t) = pop_interp(NEWEEG(t), EEG_old.chanlocs, 'spherical');
evalc('NEWEEG(t) = pop_interp(NEWEEG(t), chanlocs, ''spherical'');');
% NEWEEG(t) = pop_interp(NEWEEG(t), chanlocs, 'spherical');

clear missing
end
Expand Down Expand Up @@ -190,6 +189,10 @@
EEG.urevent = EEG_old.urevent;

fprintf([repmat('\b',[1 28]) '... done.\n'])
elseif interp_all
fprintf('pop_TBT(): Interpolating missing channels')
evalc('EEG = pop_interp(EEG, chanlocs, ''spherical'');');
fprintf('.. done.\n')
end

EEG = eeg_checkset(EEG);
Expand Down
12 changes: 12 additions & 0 deletions tbt/tbt_bool2cell.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function tbt = tbt_bool2cell(bads,EEG)

tbt = {[],{}}; % make empty list
for tr = 1:size(bads,2) % each trial
if any(bads(:,tr)) % if has any bad channels
tbt{end+1,1} = tr; % list trial number
tbt{end,2} = {EEG.chanlocs(bads(:,tr)==1).labels}; % list bad channels in current trial
end
end
tbt = tbt(2:end,:); % remove first empty row

end
12 changes: 12 additions & 0 deletions tbt/tbt_cell2bool.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function bads_array = tbt_cell2bool(bads,EEG)

bads_array = zeros([size(EEG.data,1) size(EEG.data,3)]);

for r = 1:size(bads,1)
% identift channels
chan_i = cellfun(@(x) any(strcmpi(x,bads{r,2})),{EEG.chanlocs.labels});
epoch_i = bads{r,1};
bads_array(chan_i,epoch_i) = 1;
end

end

0 comments on commit df588a5

Please sign in to comment.