|
1 | | -function varargout = process_remove_drift_emd(varargin) |
2 | | -% PROCESS_REMOVE_DRIFT_EMD: Remove drift using Empirical Mode Decomposition (EMD) |
| 1 | +function varargout = process_detrend_emd( varargin ) |
| 2 | +% PROCESS_DETREND_EMD: Remove a non-linear trend in a signal with EMD |
3 | 3 | % |
4 | 4 | % This process: |
5 | 5 | % 1) Decomposes each channel into intrinsic mode functions using EMD |
6 | 6 | % 2) Estimates the characteristic frequency of each IMF |
7 | 7 | % 3) Keeps only modes above the selected cutoff frequency |
8 | 8 | % |
9 | 9 | % USAGE: |
10 | | -% OutputFiles = process_remove_drift_emd('Run', sProcess, sInputs) |
| 10 | +% OutputFiles = process_detrend_emd('Run', sProcess, sInputs) |
11 | 11 |
|
12 | 12 | % @============================================================================= |
13 | 13 | % This function is part of the Brainstorm software: |
|
28 | 28 | % =============================================================================@ |
29 | 29 | % |
30 | 30 | % Authors: Kenneth N. Taylor, 2020 |
31 | | -% John C. Mosher, 2020 |
| 31 | +% John C. Mosher, 2020 |
32 | 32 | % Chinmay Chinara, 2026 |
33 | 33 |
|
34 | 34 | eval(macro_method); |
35 | 35 | end |
36 | 36 |
|
| 37 | + |
37 | 38 | %% ===== GET DESCRIPTION ===== |
38 | 39 | function sProcess = GetDescription() %#ok<DEFNU> |
39 | | -% Description the process |
40 | | -sProcess.Comment = 'Remove drift using EMD'; |
41 | | -sProcess.FileTag = 'emd'; |
42 | | -sProcess.Category = 'Filter'; |
43 | | -sProcess.SubGroup = 'FAST graph'; |
44 | | -sProcess.Index = 1302; |
45 | | -sProcess.Description = 'https://neuroimage.usc.edu/brainstorm/Tutorials/FastGraph'; |
46 | | -% Definition of the input accepted by this process |
47 | | -sProcess.InputTypes = {'data'}; |
48 | | -sProcess.OutputTypes = {'data'}; |
49 | | -sProcess.nInputs = 1; |
50 | | -sProcess.nMinFiles = 1; |
51 | | -% EMD cutoff frequency |
52 | | -sProcess.options.cutoff.Comment = 'EMD cutoff frequency: '; |
53 | | -sProcess.options.cutoff.Type = 'value'; |
54 | | -sProcess.options.cutoff.Value = {2, 'Hz', 2}; |
| 40 | + % Description the process |
| 41 | + sProcess.Comment = 'Remove non-linear trend with EMD'; |
| 42 | + sProcess.FileTag = 'emd'; |
| 43 | + sProcess.Category = 'Filter'; |
| 44 | + sProcess.SubGroup = 'Pre-process'; |
| 45 | + sProcess.Index = 61.5; |
| 46 | + sProcess.Description = 'https://neuroimage.usc.edu/brainstorm/Tutorials/FastGraph'; |
| 47 | + % Definition of the input accepted by this process |
| 48 | + sProcess.InputTypes = {'raw', 'data', 'results', 'matrix'}; |
| 49 | + sProcess.OutputTypes = {'raw', 'data', 'results', 'matrix'}; |
| 50 | + sProcess.nInputs = 1; |
| 51 | + sProcess.nMinFiles = 1; |
| 52 | + % Default values for some options |
| 53 | + sProcess.processDim = 1; % Process channel by channel |
| 54 | + |
| 55 | + % Definition of the options |
| 56 | + % === Sensor types |
| 57 | + sProcess.options.sensortypes.Comment = 'Sensor types or names (empty=all): '; |
| 58 | + sProcess.options.sensortypes.Type = 'text'; |
| 59 | + sProcess.options.sensortypes.Value = 'MEG, EEG'; |
| 60 | + sProcess.options.sensortypes.InputTypes = {'data', 'raw'}; |
| 61 | + % === EMD cutoff frequency |
| 62 | + sProcess.options.emdcutoff.Comment = 'EMD cutoff frequency: '; |
| 63 | + sProcess.options.emdcutoff.Type = 'value'; |
| 64 | + sProcess.options.emdcutoff.Value = {2, 'Hz', 2}; |
55 | 65 | end |
56 | 66 |
|
| 67 | + |
57 | 68 | %% ===== FORMAT COMMENT ===== |
58 | 69 | function Comment = FormatComment(sProcess) %#ok<DEFNU> |
59 | 70 | Comment = sProcess.Comment; |
60 | 71 | end |
61 | 72 |
|
| 73 | + |
62 | 74 | %% ===== RUN ===== |
63 | 75 | function sInput = Run(sProcess, sInput) %#ok<DEFNU> |
64 | | - % Get process option values |
65 | | - CutoffFreq = sProcess.options.cutoff.Value{1}; |
66 | | - if CutoffFreq <= 0 |
67 | | - bst_report('Error', sProcess, [], 'EMD cutoff frequency must be positive.'); |
68 | | - return; |
69 | | - end |
| 76 | + % Get options |
| 77 | + if isfield(sProcess.options, 'emdcutoff') && isfield(sProcess.options.emdcutoff, 'Value') && iscell(sProcess.options.emdcutoff.Value) && ~isempty(sProcess.options.emdcutoff.Value) |
| 78 | + CutoffFreq = sProcess.options.emdcutoff.Value{1}; |
| 79 | + else |
| 80 | + CutoffFreq = []; |
| 81 | + end |
| 82 | + if isempty(CutoffFreq) || isequal(CutoffFreq, 0) |
| 83 | + bst_report('Error', sProcess, [], 'Invalid cutoff frequency value.'); |
| 84 | + sInput = []; |
| 85 | + return |
| 86 | + end |
70 | 87 |
|
71 | 88 | % Sampling frequency |
72 | 89 | Fs = 1 / mean(diff(sInput.TimeVector)); |
|
82 | 99 | end |
83 | 100 |
|
84 | 101 | % Add history comment |
85 | | - sInput.HistoryComment = sprintf('Removed drift using EMD: cutoff frequency = %.3f Hz', CutoffFreq); |
| 102 | + sInput.HistoryComment = sprintf('Removed non-linear trend with EMD: cutoff frequency = %.3f Hz', CutoffFreq); |
| 103 | + |
| 104 | + % Do not keep the Std field in the output |
| 105 | + if isfield(sInput, 'Std') && ~isempty(sInput.Std) |
| 106 | + sInput.Std = []; |
| 107 | + end |
86 | 108 | end |
87 | 109 |
|
| 110 | + |
88 | 111 | %% ===== IMF MODE STATISTICS ===== |
89 | 112 | function modeFreq = ImfStats(imf, Fs) |
90 | 113 | % IMF matrix is expected as [time x modes] |
|
0 commit comments