|
1 | 1 | function signal = flt_reref(varargin) |
2 | 2 | % Re-references the data to a new (set of) channel(s) or the average of all channels. |
3 | | -% Signal = flt_reref(Signal, ReferenceChannels, ExcludeChannels, KeepReference) |
| 3 | +% Signal = flt_reref(Signal, ReferenceChannels, ExcludeChannels, KeepReference, ReferenceType, HuberCutoff, HuberIterations) |
4 | 4 | % |
5 | 5 | % Re-referencing is a spatial filter in which the (instantaneous) mean signal of some "reference" |
6 | 6 | % channels is subtracted from the signal of each channel. This allows to dampen externally-induced |
|
12 | 12 | % re-referencing, since their spatial filters are adaptively optimized and effectively incorporate |
13 | 13 | % re-referencing to the degree that it is necessary. |
14 | 14 | % |
| 15 | +% This function also supports robust re-referencing, where artifacts in few channels will not affect |
| 16 | +% the outcome disproportionally. |
| 17 | +% |
15 | 18 | % In: |
16 | 19 | % Signal : Epoched or continuous data set. |
17 | 20 | % |
|
22 | 25 | % (default: []) |
23 | 26 | % |
24 | 27 | % KeepReference : Whether to keep the reference channel (default: false) |
| 28 | +% If true and multiple channels were selected, a new channel named CAR is |
| 29 | +% appended. |
| 30 | +% |
| 31 | +% ReferenceType : Type of referencing to apply, can be one of the following: |
| 32 | +% * 'mean': subtract average of reference channels (default) |
| 33 | +% * 'median': subtract median of reference channels |
| 34 | +% * 'huber': subtract robust mean (under the Huber loss) of reference channels; |
| 35 | +% |
| 36 | +% HuberCutoff : cutoff/transition parameter for huber loss; if [], this is set |
| 37 | +% to one (robust) standard deviation of the signal |
| 38 | +% |
| 39 | +% HuberIterations : number of iterations to compute the Huber fit; a larger number can tolerate |
| 40 | +% larger outliers (default: 100) |
25 | 41 | % |
26 | 42 | % Out: |
27 | 43 | % Signal : Re-referenced data set. |
|
45 | 61 | % Christian Kothe, Swartz Center for Computational Neuroscience, UCSD |
46 | 62 | % 2010-03-28 |
47 | 63 |
|
48 | | -% flt_reref_version<1.0> -- for the cache |
| 64 | +% flt_reref_version<1.01> -- for the cache |
49 | 65 |
|
50 | 66 | if ~exp_beginfun('filter') return; end |
51 | 67 |
|
52 | 68 | declare_properties('name',{'Rereferencing','ref'}, 'independent_channels',false,'independent_trials',true); |
53 | 69 |
|
54 | 70 | arg_define(varargin,... |
55 | 71 | arg_norep({'signal','Signal'}), ... |
56 | | - arg({'chn','ReferenceChannels'}, [], [], 'Cell array of reference channels. The signal data is be referenced to these, defaults to average reference if empty.','type','cellstr','shape','row'),... |
57 | | - arg({'exclude','ExcludeChannels'}, [], [], 'Cell array of channels to exclude.','type','cellstr','shape','row'),... |
58 | | - arg({'keepref','KeepReference'}, false, [], 'Keep the reference channel.')); |
| 72 | + arg({'ref_chn','ReferenceChannels','chn'}, [], [], 'Cell array of reference channels. The signal data is be referenced to these, defaults to average reference if empty.','type','cellstr','shape','row'),... |
| 73 | + arg({'exclude_chn','ExcludeChannels','exclude'}, [], [], 'Cell array of channels to exclude.','type','cellstr','shape','row'),... |
| 74 | + arg({'keepref','KeepReference'}, false, [], 'Keep the reference channel.'), ... |
| 75 | + arg({'ref_type','ReferenceType'}, 'mean', {'mean','median','huber'}, 'Type of reference. The traditional average reference operation uses the mean. If this is set to median, the median of the reference channels will be removed, and if set to huber the robust mean under the Huber loss will be removed (slower than median but closer to the mean).'), ... |
| 76 | + arg({'huber_cut','HuberCutoff'}, [], [], 'Cutoff for huber function. If left empty this is set to one (robust) standard deviation of the signal.','guru',true), ... |
| 77 | + arg({'huber_iters','HuberIterations'}, 100, [], 'Iterations for huber fitting. A larger number yields tolerance to larger outliers.','guru',true)); |
| 78 | + |
| 79 | +if ~isempty(ref_chn) |
| 80 | + ref_chns = set_chanid(signal,ref_chn); |
| 81 | +else |
| 82 | + ref_chns = 1:size(signal.data,1); |
| 83 | +end |
| 84 | + |
| 85 | +if ~isempty(exclude_chn) |
| 86 | + ref_chns = setdiff(ref_chns,set_chanid(signal,exclude_chn)); end |
| 87 | + |
| 88 | +switch ref_type |
| 89 | + case 'mean' |
| 90 | + ref_signal = mean(signal.data(ref_chns,:)); |
| 91 | + case 'median' |
| 92 | + ref_signal = median(signal.data(ref_chns,:)); |
| 93 | + case 'huber' |
| 94 | + if isempty(huber_cut) |
| 95 | + huber_cut = median(mad(signal.data,1,2))*1.4826; end |
| 96 | + ref_signal = robust_mean(signal.data(ref_chns,:)/huber_cut,1,huber_iters)*huber_cut; |
| 97 | + otherwise |
| 98 | + error('Unsupported reference type.'); |
| 99 | +end |
| 100 | + |
| 101 | +signal.data = bsxfun(@minus,signal.data,ref_signal); |
59 | 102 |
|
60 | | -signal = pop_reref(signal,set_chanid(signal,chn),'exclude',fastif(isempty(exclude),[],set_chanid(signal,exclude)),'keepref',fastif(keepref,'on','off')); %#ok<*NODEF> |
| 103 | +if ~keepref && ~isempty(ref_chn) |
| 104 | + signal = pop_select(signal,'nochannel',ref_chns); end |
| 105 | +if keepref && length(ref_chn)>1 |
| 106 | + signal.data(end+1,:) = ref_signal; |
| 107 | + signal.nbchan = size(signal.data,1); |
| 108 | + signal.chanlocs(end+1).labels = 'CAR'; |
| 109 | + signal.chanlocs(end).type = 'REF'; |
| 110 | +end |
61 | 111 |
|
62 | | -exp_endfun; |
| 112 | +exp_endfun('append_online',{'huber_cut',huber_cut}); |
0 commit comments