{"id":19252277,"url":"https://github.com/sccn/cleanline","last_synced_at":"2025-04-21T13:30:48.610Z","repository":{"id":56661333,"uuid":"225720153","full_name":"sccn/cleanline","owner":"sccn","description":"Clean Line","archived":false,"fork":false,"pushed_at":"2025-02-07T17:33:18.000Z","size":919,"stargazers_count":16,"open_issues_count":3,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-01T13:38:08.773Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"MATLAB","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sccn.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-03T21:30:50.000Z","updated_at":"2025-03-19T12:06:03.000Z","dependencies_parsed_at":"2024-07-25T23:06:51.826Z","dependency_job_id":"087a7167-3574-40b2-aa53-45c26ccc3061","html_url":"https://github.com/sccn/cleanline","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sccn%2Fcleanline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sccn%2Fcleanline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sccn%2Fcleanline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sccn%2Fcleanline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sccn","download_url":"https://codeload.github.com/sccn/cleanline/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250064541,"owners_count":21368922,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T18:26:13.421Z","updated_at":"2025-04-21T13:30:48.602Z","avatar_url":"https://github.com/sccn.png","language":"MATLAB","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Screenshot 2024-08-02 at 09 14 11](https://github.com/user-attachments/assets/4e5be390-d091-4bdf-9ddc-e6fff8b692bb)\n\n# CleanLine\n\nWelcome to the CleanLine plugin for EEGLAB! \n\nThis plugin adaptively estimates and removes sinusoidal (e.g. line) noise from your ICA components\nor scalp channels using multi-tapering and a Thompson F-statistic.\n\nCleanLine is written by Tim Mullen (tim@sccn.ucsd.edu) with thanks to Makoto Miyakoshi for beta \ntesting. CleanLine makes use of functions modified from the Mitra Lab's Chronux \nToolbox (www.chronux.org).\n\nCleanLine also makes use of the arg() functionality from Christian Kothe's BCILAB toolbox \n(sccn.ucsd.edu/wiki/BCILAB)\n\n# Instalation\n\nInstallation of CleanLine is simple:\n\n1) download CleanLine (if you are reading this, you have probably already completed this step)\n\n2) Unzip the package and copy to \u003ceeglabroot\u003e/plugins/. Start eeglab from the Matlab command line.\n   Alternately, you may add CleanLine (with subfolders) to your path and ensure EEGLAB is present \n   in the path.\n\n3) If using the EEGLAB GUI you may start CleanLine from Tools--\u003eCleanLine.\n   Alternately, you can start CleanLine from the command line\n\n```matlab\nEEGclean = pop_cleanline(EEG);\n```\n\n   See \"Command-line example\" section below for command-line example and other parameters\n   \n5) For Help, type\n\n```matlab\ndoc cleanline\n```\n\n   Or, hold mouse over any textbox, checkbox, etc in the GUI for tooltip help text.\n\n\n# Theory\n\nSinusoidal noise can be a prominent artifact in recorded electrophysiological data. This can stem \nfrom AC power line fluctuations (e.g. 50/60 Hz line noise + harmonics), power suppliers (e.g. in \nmedical equipment), fluorescent lights, etc. Notch filtering is generally undesirable due to \ncreation of band-holes, and significant distortion of frequencies around the notch frequency (as well \nas phase distortion at other frequencies and Gibbs rippling in the time-domain). Other approaches for\nsinusoidal (\"line\") noise reduction include adaptive regressive filtering approaches (e.g. RLS, LMS),\nbut these typically require a reference signal (e.g. externally-recorded noise reference), which is \noften unavailable. Blind-source separation approaches such as ICA may help mitigate line noise, but  \noften fail to completely remove the noise due to spatiotemporal non-stationarities in the  noise. \n\nCleanLine uses an approach for line noise removal advocated by Partha Mitra and Hemant Bokil in \n\"Observed Brain Dynamics\" (2007), Chapter 7.3.4. \n\nIn brief, the data is traversed by a sliding window. Within each window, the signal is transformed to \nthe frequency domain using a multi-taper FFT. The complex amplitude (amplitude and phase) is thus\nobtained for each frequency. Under the assumption of a deterministic sinusoid embedded in white \nnoise, we can set up a regression of the multi-taper transform (spectrum) of this sinusoidal signal \nonto the multitaper spectrum of the original data at a given frequency. The regression coefficient \nis a complex number representing the complex amplitude (phase and amplitude) of the deterministic \nsinusoid. From this, a time-domain representation of the sinusoid may be constructed and subtracted \nfrom the data to remove the line.\n\nTypically, one does not know the exact line frequency. For instance, in the U.S.A., power line noise \nis not guaranteed to be at exactly 60 Hz (or even to have constant phase over a given period of time).\nTo ameliorate this problem a Thompson F-Test may be applied to determine the statistical significance\nof a non-zero coefficient in the above regression (indicating a sinusoid with significantly non-zero \namplitude). We can then search within a narrow band around the expected location of the line for the \nfrequency which maximizes this F-statistic above a significance threshold (e.g. p=0.05).\n\nLine frequency scanning can be enabled/disabled using the 'ScanForLines' option.\n\nOverlapping short (e.g. 2-4 second) windows can be used to adaptively estimate the frequency, phase,\nand amplitude of the sinusoidal noise components (which typically change over the course of a recording \nsession). The discontinuity at the point of window overlap can be smoothed using a sigmoidal function.\nThe example below demonstrates such a function for different smoothing factors (slope of the sigmoid).\n\n```matlab\nwinsize = 4;                        % window length in seconds\nwinstep = 2;                        % window step in seconds (50% overlap)\nFs      = 128;                      % sampling rate\ntau     = [1 10 100]';              % smoothing factors\noverlap = winsize-winstep;\ntoverlap = -overlap/2:(1/Fs):overlap/2;\n\n% specify the smoothing function\nfoverlap = 1-1./(1+exp(-repmat(tau,1,length(toverlap)).*repmat(toverlap,length(tau),1)/overlap));\n\n% define some colours\nyellow  = [255, 255, 25]/255;\nred     = [255 0 0]/255;\nh       = zeros(1,3+length(tau));\n\n% plot the figure\nfigure;\naxis([-winsize+overlap/2 winsize-overlap/2 0 1]); set(gca,'ColorOrder',[0 0 0; 0.7 0 0.8; 0 0 1],'fontsize',11);\nhold on\nh(1)=hlp_vrect([-winsize+overlap/2 -overlap/2], 'yscale',[0 1],'patchProperties',{'FaceColor',yellow,        'FaceAlpha',1,'EdgeColor','none','EdgeAlpha',0.5}); \nh(2)=hlp_vrect([overlap/2 winsize-overlap/2],   'yscale',[0 1],'patchProperties',{'FaceColor',red,           'FaceAlpha',1,'EdgeColor','none','EdgeAlpha',0.5});\nh(3)=hlp_vrect([-overlap/2 overlap/2],          'yscale',[0 1],'patchProperties',{'FaceColor',(yellow+red)/2,'FaceAlpha',1,'EdgeColor','none','EdgeAlpha',0.5});\nh(4:end) = plot(toverlap,foverlap,'linewidth',2);\nplot(toverlap,1-foverlap,'linewidth',1,'linestyle','--');\nhold off;\nxlabel('Time (sec)'); ylabel('Smoothing weight'); \ntitle('Plot of window overlap smoothing function vs. time for different smoothing factors');\nlegend(h,[{'Window 1','Window 2','Overlap'},cellstr(num2str(tau))']);\n```\n\nThe smoothing factor is determined by the 'SmoothingFactor' parameter in cleanline().\n\nCleanLine allows you to specify the multi-taper frequency resolution by the 'Bandwidth' parameter. \nThis is the width of a peak in the spectrum for a sinusoid at given frequency. Due to the time-frequency \nuncertainty principle, decreasing bandwidth increases the necessary length of the sliding window in \norder to obtain a reasonable frequency decomposition. The number of tapers, K, used by CleanLine is \ngiven by K=2TW-1 where T is the temporal resolution in seconds (window length) and W is the frequency \nresolution (Bandwidth) in Hz. CleanLine fixes T to be the sliding window length, so W (Bandwidth) is the\nonly required parameter. If the 'Verbosity' option is set to 1, then CleanLine will display the multi-taper\nparameters in the command line on execution of the function.\n\n\n# Tips on running CleanLine\n\nThe default options should work quite well, but parameters may need to be tweaked depending on the setup. \nIf you have multiple epochs you need to make sure that your window size and step size exactly divides the \nepoch length. In other words, you do not want any sliding windows to overlap two epochs since line noise \nphase and amplitude may shift at that point, making it impossible to perform the time-domain line subtraction.\nIf you have relatively short epochs (e.g. \u003c 5 sec) it is best if each window is taken to be the length\nof the epoch and the step size is equal to the window length. In this way, the lines are estimated and \nremoved for each epoch individually. When using the GUI, the default values for window length and step size\nare automatically set to the epoch length.\n\nIf cleaning continuous, un-epoched data, then you may wish to use sliding windows of 3-4 seconds with 50% \noverlap.\n\nIf using the EEGLAB GUI, commands are stored in EEG.history so that the eegh() command will return the \ncommand-line function call corresponding to the last GUI execution of CleanLine.\n\nYou might find it useful to try the option ('PlotFigures',true) on a subset of channels/components to get a\nsense of the performance of CleanLine for difference parameter choices (and also to identify where the most\nsignificant lines lie in the spectrum) and then, once you are satisfied with the parameters, turn this option\noff before cleaning all the remaining channels/components. NOTE: CleanLine is *considerably slower* if PlotFigures \nis enabled. If you don't care to see the visualize the final results of the cleaning operation, you may also\nwish to set ('ComputeSpectralPower',false) which will speed up computation considerably.\n\n\n# Typical command-line example (Multiple trials)\n\n```matlab\n% This will run cleanline on all channels, scanning for lines +/- 1 Hz around the 60 and 120 Hz frequencies. \n% Each epoch will be cleaned individually and epochs containing lines that are significantly sinusoidal at \n% the p\u003c=0.01 level will be cleaned. \n\nEEG = pop_cleanline(EEG, 'Bandwidth',2,'ChanCompIndices',[1:EEG.nbchan] ,'SignalType','Channels','ComputeSpectralPower',true,'LineFrequencies',[60 120] ,'NormalizeSpectrum',false,'LineAlpha',0.01,'PaddingFactor',2,'PlotFigures',false,'ScanForLines',true,'SmoothingFactor',100,'VerbosityLevel',1,'SlidingWinLength',EEG.pnts/EEG.srate,'SlidingWinStep',EEG.pnts/EEG.srate);\n```\n\n# Help for cleanline.m (These can also be passed to pop_cleanline)\n\n## Function input\n  **LineFrequencies:**      Line noise frequencies to remove                                                                      \n                        Input Range  : Unrestricted                                                                           \n                        Default value: 60  120                                                                                \n                        Input Data Type: real number (double)                                                                 \n                                                                                                                              \n  **ScanForLines:**         Scan for line noise                                                                                   \n                        This will scan for the exact line frequency in a narrow range around the specified LineFrequencies    \n                        Input Range  : [true false]                                                                           \n                        Default value: true                                                                                      \n                        Input Data Type: boolean                                                                              \n                                                                                                                              \n  **LineAlpha:**            p-value for detection of significant sinusoid                                                                        \n                        Input Range  : [0  1]                                                                                 \n                        Default value: 0.01                                                                                   \n                        Input Data Type: real number (double)                                                                 \n                                                                                                                              \n  **Bandwidth:**            Bandwidth (Hz)                                                                                        \n                        This is the width of a spectral peak for a sinusoid at fixed frequency. As such, this defines the     \n                        multi-taper frequency resolution.                                                                     \n                        Input Range  : Unrestricted                                                                           \n                        Default value: 1                                                                                      \n                        Input Data Type: real number (double)                                                                 \n                                                                                                                              \n  **SignalType:**          Type of signal to clean                                                                               \n                        Cleaned ICA components will be backprojected to channels. If channels are cleaned, ICA activations    \n                        are reconstructed based on clean channels.                                                            \n                        Possible values: 'Components','Channels'                                                              \n                        Default value  : 'Components'                                                                         \n                        Input Data Type: string                                                                               \n                                                                                                                              \n  **ChanCompIndices:**      IDs of Chans/Comps to clean                                                                           \n                        Input Range  : Unrestricted                                                                           \n                        Default value: 1:152                                                                                  \n                        Input Data Type: any evaluable Matlab expression.                                                     \n                                                                                                                              \n  **SlidingWinLength:**     Sliding window length (sec)                                                                           \n                        Default is the epoch length.                                                                          \n                        Input Range  : [0  4]                                                                                 \n                        Default value: 4                                                                                      \n                        Input Data Type: real number (double)                                                                 \n                                                                                                                              \n  **SlidingWinStep:**       Sliding window step size (sec)                                                                        \n                        This determines the amount of overlap between sliding windows. Default is window length (no           \n                        overlap).                                                                                             \n                        Input Range  : [0  4]                                                                                 \n                        Default value: 4                                                                                      \n                        Input Data Type: real number (double)                                                                 \n                                                                                                                              \n  **SmoothingFactor:**      Window overlap smoothing factor                                                                       \n                        A value of 1 means (nearly) linear smoothing between adjacent sliding windows. A value of Inf means   \n                        no smoothing. Intermediate values produce sigmoidal smoothing between adjacent windows.               \n                        Input Range  : [1  Inf]                                                                               \n                        Default value: 100                                                                                    \n                        Input Data Type: real number (double)                                                                 \n                                                                                                                              \n  **PaddingFactor:**        FFT padding factor                                                                                    \n                        Signal will be zero-padded to the desired power of two greater than the sliding window length. The    \n                        formula is NFFT = 2^nextpow2(SlidingWinLen*(PadFactor+1)). e.g. For SlidingWinLen = 500, if PadFactor = -1,    \n                        we do not pad; if PadFactor = 0, we pad the FFT to 512 points, if PadFactor=1, we pad to 1024 points etc.                                                                                                  \n                        Input Range  : [-1  Inf]                                                                              \n                        Default value: 2                                                                                      \n                        Input Data Type: real number (double)                                                                 \n                                                                                                                              \n  **ComputeSpectralPower:** Visualize Original and Cleaned Spectra                                                                \n                        Original and clean spectral power will be computed and visualized at end of processing                             \n                        Input Range  : [true false]                                                                           \n                        Default value: true                                                                                      \n                        Input Data Type: boolean                                                                              \n                                                                                                                              \n  **NormalizeSpectrum:**    Normalize log spectrum by detrending (not generally recommended)                                                                     \n                        Input Range  : [true false]                                                                            \n                        Default value: false                                                                                      \n                        Input Data Type: boolean                                                                              \n                                                                                                                              \n  **VerboseOutput:**        Produce verbose output                                                                                \n                        Input Range  : [true false]                                                                           \n                        Default value: true                                                                                      \n                        Input Data Type: boolean                                                                \n                                                                                                                              \n  **PlotFigures:**          Plot Individual Figures                                                                               \n                        This will generate figures of F-statistic, spectrum, etc for each channel/comp while processing       \n                        Input Range  : [true false]                                                                            \n                        Default value: false                                                                                      \n                        Input Data Type: boolean  \n \n##  Output                Information\n  **EEG**                   Cleaned EEG dataset\n  \n  **Sorig**                 Original multitaper spectrum for each component/channel\n  \n  **Sclean**                Cleaned multitaper spectrum for each component/channel\n  \n  **f**                     Frequencies at which spectrum is estimated in Sorig, Sclean\n  \n  **amps**                  Complex amplitudes of sinusoidal lines for each window (line time-series for window i can be reconstructed by creating a sinuoid with frequency f{i} and complex\namplitude amps{i})\n\n  **freqs**                 Exact frequencies at which lines were removed for each window (cell array)\n  \n  **g**                     Parameter structure. Function call can be replicated exactly by calling \u003e\u003e cleanline(EEG,g);\n\n\n# CleanLine versions\nV1 - Original version by Tim Mullen\n\nV2 - Include a rewrite by Kay Robbins with integration by Arnaud Delorme and \ntesting by Makoto Miyakoshi\n\nV2.1 - Fix menu returning automatically in EEGLAB 2024.0 and 2024.1\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsccn%2Fcleanline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsccn%2Fcleanline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsccn%2Fcleanline/lists"}