# [Eeglablist] eeglab causal filtering: impacts and applications?

Andreas Widmann widmann at uni-leipzig.de
Tue Feb 2 03:52:06 PST 2021

```Hi Cedric,

> Do N taps = filter order = filter length?
N taps = filter length = filter order + 1.

> If so, for an order of 1650 (i.e. for a transition bandwidth of 1 Hz as estimated by the pop_firws function; minimum recommended) and a sampling rate of 500 Hz, I get a delay of 1.649 ms.
Unit is samples or seconds! Order = 1650 -> N = 1651 samples -> group delay = (N - 1) / 2 samples and sampling rate fs = 500 samples / second -> group delay = (N - 1) / 2 / fs seconds (the equation is the same as from your dspguru webpage, just written differently). Thus, the delay of the order 1650 filter is 1.65 seconds.

> Following your formula to calculate the phase shift when using a causal filter (shift = order-1)/gp_delay), I get 1000 independently of the order (which makes sense as the gd_delay changes as a function of the order). I haven't worked much on phase so I am not sure if that corresponds to a big shift or not.
Sorry, not sure whether I understand the question? Which formula do you refer to? Phase shift is frequency dependent. Typically, the question is whether it is linear or not and can therefore be corrected or not.

>> b_high = minphaserceps( firws( 10, 1/5, 'high' ) ); % minimum-phase non-linear high-pass
>
> Is this the same as using your pop_firws? e.g. [EEG, com, b] = pop_firws(EEG, 'forder', 10, 'fcutoff', 1/5, 'ftype', 'highpass', 'wtype', 'hamming', 'minphase', true);
Yes, BUT: pop_firws is the high level wrapper. Unit for fcutoff is Hz! firws is a low-level function. Unit for f is pi rad / sample (i.e. normalized to Nyquist, this is the MATLAB standard for this kind of functions). 0.2 pi rad / sample * fs / 2 with fs = 500 samples / second -> 50 seconds^-1 or Hz.

> What about your firfilt function that automatically corrects the group-delay if I choose to do the non-causal linear filter? No need to apply correction on EEG.times with this method, right?
Yes, firfilt automatically corrects for the group delay, that is, implements a zero-phase FIR filter. But firfilt is a low-level function and you should know what you are doing when using it. If you want to do this on the command line I would rather recommend using fir_filterdcpadded. There is a 'causal‘ flag and you can do causal and non-causal (linear phase only) filtering. fir_filterdcpadded must be used with continuous segments only. firfilt also works with boundaries. firfilt was designed long time ago when memory was a limited resource and is memory optimized but complex. It will be sooner than later be fully replaced by fir_filterdcpadded (as in Fieldtrip) which is simple and fast but memory consuming.

> Interestingly, they found an effect at 24 ms before stimulus, and filtered with a second-order filter 1–40 Hz bandpass backward–forward. I wonder if that could be a smearing effect from post-stimulus activity.
Note, that you cannot delay correct an IIR filter (the impulse response is infinite and the phase response non-linear) and order has a very different meaning. Indeed, backward-forward filtering will result in a non-causal zero-phase filter (actually, the order of backward-forward or forward-backward doesn’t matter). As an IIR filter is used there is no temporal limit for non-causal effects (here post-stimulus on pre-stimulus time ranges) as with FIR filters. I cannot comment whether this affects the conclusions without reading and understanding in detail.

Hope this helps! Best,
Andreas

> Am 02.02.2021 um 02:39 schrieb Cedric Cannard <ccannard at protonmail.com>:
>
> Hi Andreas,
>
> Thank you so much for the thorough response and examples, this is very helpful.
>
> Because this analysis is exploratory (looking at the whole 1.5 s period before stimulus), I cannot know whether the signal of interest is further away from stimulus onset than the group delay. Other studies on pre-stimulus EEG do not provide much on this topic surprisingly (e.g. https://urldefense.com/v3/__https://www.frontiersin.org/articles/10.3389/fnhum.2020.00182/full__;!!Mih3wA!XvTZMQW-HAOS-0brWhhQ3MxL38_oEd5FVdHGyNbYHJfz1g5lWxfujc9QDsJT-037KfkNfg\$ ). Interestingly, they found an effect at 24 ms before stimulus, and filtered with a second-order filter 1–40 Hz bandpass backward–forward. I wonder if that could be a smearing effect from post-stimulus activity.
>
> I tried assessing what the delay would be for a linear-phase filter on my data with: (N – 1)/(2 * sample_freq) from https://urldefense.com/v3/__https://dspguru.com/dsp/faqs/fir/properties/*:*:text=has*20no*20mate.)-,2.1.,1*20kHz)*3D10*20milliseconds__;I34lJSUlJQ!!Mih3wA!XvTZMQW-HAOS-0brWhhQ3MxL38_oEd5FVdHGyNbYHJfz1g5lWxfujc9QDsJT-02fz36Ufw\$ .
> Do N taps = filter order = filter length?
> If so, for an order of 1650 (i.e. for a transition bandwidth of 1 Hz as estimated by the pop_firws function; minimum recommended) and a sampling rate of 500 Hz, I get a delay of 1.649 ms.
> For order = 132 (transition bandwidth = 12.5 Hz as with default pop_eegfiltnew), a delay of 0.131 ms.
> And for order = 3300 (transition bandwidth = 0.5 Hz), a delay of 16.499 ms.
> Following your formula to calculate the phase shift when using a causal filter (shift = order-1)/gp_delay), I get 1000 independently of the order (which makes sense as the gd_delay changes as a function of the order). I haven't worked much on phase so I am not sure if that corresponds to a big shift or not.
>
> If this is correct, then the delay is very small and should not be a problem regarding latency shifts as I am looking at a large window of 1500 ms, right? If there is only a few ms of shift, using a linear-phase non-causal filter would be preferable to preserve spectral/phase information.
> Visual inspection with vis_artifacts comparing raw data before and after shows very minimal shifts from the linear filtering.
>
> Now I understand that I can't correct a causal filter without making it non-causal, thanks!
>
> Side note:
>> b_high = minphaserceps( firws( 10, 1/5, 'high' ) ); % minimum-phase non-linear high-pass
>> fsig_high = filter( b_high, 1, sig ); % causal filter
>
> Is this the same as using your pop_firws? e.g. [EEG, com, b] = pop_firws(EEG, 'forder', 10, 'fcutoff', 1/5, 'ftype', 'highpass', 'wtype', 'hamming', 'minphase', true);
>
> What about your firfilt function that automatically corrects the group-delay if I choose to do the non-causal linear filter? No need to apply correction on EEG.times with this method, right?
>
> Cedric
>
> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
> On Sunday, January 31, 2021 12:57 PM, Andreas Widmann <widmann at uni-leipzig.de> wrote:
>
>> Hi Cedric,
>>
>> in general most of your reasoning is correct and reasonable: Non-linear causal filters typically should only be used if the application explicitly requires this, for example is causality matters as in the detection of onset latencies (even if the problem is overestimated as it mainly affects ultra-sharp transients typically not observed in EEG/ERP), the analysis of small fast components before large slow components (e.g. if higher high-pass cutoff frequencies are required), or in the analysis of pre-stimulus activity, that is, your case.
>>
>> There is, however, one problematic aspect in your reasoning which if resolved might possibly help you finding the right answer for you : You cannot delay correct a causal filter (linear or non-linear). This would make it automatically non-causal and break causality and there is no way around this.
>>
>> Now you still have to decide whether to apply a linear or a non-linear filter. The difference between a linear causal and linear non-causal filter is exclusively the time axis. The output of the non-causal filter equals the delay corrected output of the causal filter. It is sufficient to change the EEG.times time axis. That is, if your signal of interest is further away from stimulus onset than the group delay you can simply use a linear non-causal filter.
>>
>> % Example:
>> sig = [ 0 0 0 0 0 1 0 0 0 0 0 ]; % test signal (impulse)
>> b = [ 1 1 1 1 1 ] / 5; % some crude boxcar filter for demonstration purposes only, linear-phase, length = 5, order = 4, group delay = 2
>> fsig = filter( b, 1, sig ); % causal filter
>> plot( -5:5, [ sig; fsig ]', 'o' ) % the filtered impulse in the output does not start before the impulse in the input
>>
>> fsig = filter( b, 1, [ sig 0 0 ] ) % padded causal filter
>> fsig = fsig( 3:end ); % delay correction by group delay, this is what makes the filter non-causal and zero-phase
>> plot( -5:5, [ sig; fsig ]', 'o' ) % the filtered impulse in the output starts before the impulse in the input BUT everything before x = -2 is unaffected
>>
>> If the (group) delay is too large for your purpose you must reduce the delay and thus use a non-linear filter, e.g. minimum phase. Non-linear filters delay different frequencies by a different amount (and due to this difference you cannot easily delay correct the output of non-linear filters even if non-causality would be acceptable). Therefore, you must not interpret the shape of the waveform in ERPs as it is distorted to some extent and also not interpret cross-frequency relationships of amplitude or phase in ERSPs. But on the other hand you can be certain that your pre-stimulus data are not contaminated by post-stimulus activity.
>>
>>> 2.  Can I use the standard linear zero-phase filter for low-pass filtering after a causal filter as the paper showed that low-pass filtering using causal filters introduces large delays?
>>>    My tests did not show any difference on the ERP plots compared to using only the causal filter without low-pass filtering but I haven't run more thorough tests.
>>>
>>
>> No, I do not think that this is a valid strategy. The output of the non-linear high-pass in the first step (if I correctly understand your question) would only introduce a small delay. The non-causal effects of the zero-phase (delay corrected) low-pass will in most cases exceed the delay introduced by the high-pass. Thus, you have a non-linear and non-causal filter output.
>>
>> % Check:
>> b_high = minphaserceps( firws( 10, 1/5, 'high' ) ); % minimum-phase non-linear high-pass
>> fsig_high = filter( b_high, 1, sig ); % causal filter
>> plot( -5:5, [ sig; fsig_high ]', 'o' ) % Causality preserved :)
>>
>> fsig_high_low = filter( b, 1, [ fsig_high 0 0 ] ); % the low-pass from above
>> fsig_high_low = fsig_high_low( 3:13 ); % delay correction/zero-phase
>> plot( -5:5, [ sig; fsig_high_low ]', 'o' ) % Causality violated :(
>>
>>> 3.  the minimum-phase filter is called "beta" in eeglab GUI, can I confidently use it for my analysis and publication?
>>
>> I didn’t notice or hear of any known errors in the last years. I would consider it safe for productive use.
>>
>>> 4.  If I need to apply a delay correction (for either causal filter), how can I do it?
>>
>> You cannot without making the filter non-causal, see above.
>>
>> Side note: I recommend not to use the legacy filter. It is broken. It would be relatively simple to use the new filter for causal linear filtering on the command line (just take the filter coefficients and use the regular MATLAB filter command; see above).
>>
>> Hope this helps! Best,
>> Andreas
>>
>>> Am 29.01.2021 um 22:05 schrieb Cedric Cannard ccannard at protonmail.com:
>>> Hi all,
>>> I am analyzing 64-channel EEG data of the pre-stimulus period [-1500 0] ms (3 conditions from 3 types of images being presented) and results will be obtained using LIMO on the ERP and ERSP data. I have been reading Andreas Widmann's papers on filtering (e.g. https://urldefense.com/v3/https://www.frontiersin.org/articles/10.3389/fpsyg.2012.00233/full;!!Mih3wA!VNo4GYqFILb305TK2eZbXRZWcQcgOnHzFo8Zfb510jeSOjaJCydWh45s-vE0funMJm7jiA\$ ; https://urldefense.com/v3/https://home.uni-leipzig.de/biocog/eprints/widmann_a2015jneuroscimeth250_34.pdf;!!Mih3wA!VNo4GYqFILb305TK2eZbXRZWcQcgOnHzFo8Zfb510jeSOjaJCydWh45s-vE0fukqNL9gVw\$ ), but I am still unsure I fully understand whether I should use the legacy causal FIR filter and apply a delay correction or the new minimum-phase causal filter instead. I also found this eeglablist discussion (https://sccn.ucsd.edu/pipermail/eeglablist/2013/006638.html) but it is from 2013 and there is now a beta minimum-phase causal filter available in EEGLAB, so
>>> I wonder what the new recommendations would be.
>>> I am pretty clear about using a non-linear/causal filter and not linear/non-causal filter to avoid "introducing non-causally smeared artificial or artificially enhanced components after high-pass filtering (Fig 7D; see Acunzo et al., 2012 for discussion), or smearing post-stimulus oscillations into the pre-stimulus interval leading to spurious interpretations of pre-stimulus phase (Zoefel and Heil, 2013)."
>>> However, regarding the causal filtering, I read: "zero-phase (non-causal) filters preserve peak latencies, while causal filters necessarily shift the signal in time. If a causal filter is needed, a non-linear minimum-phase filter should be considered as it introduces only the minimum possible delay at each frequency for a given magnitude response but distorting broadband or complex signals due to non-linearity (see Fig. 2). Causal high-pass minimum-phase (and other non-linear) filters introduce rather small delays (Fig. 2F and G) while causal low-pass (and band-pass and band-stop) filters introduce larger delays even with minimum-phase property (Fig. 2A and B), which is why they are not recommended in electrophysiology (Rousselet, 2012)."
>>> --> This suggests I should use the minimum-phase for high-pass filtering (1 Hz) but not for low-pass filtering (50 Hz).
>>> But further in the paper the authors say: "However, as FIR filter coefficients necessarily must be symmetric (or antisymmetric) for the filter to have linear-phase characteristic (Rabiner and Gold, 1975; Ifeachor and Jervis, 2002), this reduction of filter delay comes at the cost of a non-linear phase response and the introduction of a systematic delay in the signal (which can not easily be compensated due to non-linear phase). The recommendation for minimum-phase causal FIR filtering, thus, should be strictly limited to the detection of onset latencies and applications where causality is required for theoretical con
>>> siderations."
>>> --> This suggests the minimum-phase filter not only introduces delays that are harder to compensate for compared to the causal FIR filter, but also that it distort complex and broadband signals? Does this mean the minimum-phase filtering might not necessarily be better than the legacy causal FIR filter for ERP/ERSP analyses?? My tests comparing the two during high-pass 1 Hz show extreme differences in the ERP plots for the same subject, obviously.
>>>
>>> 1.  Which one should I use for ERP and ERSP analyses of the pre-stimulus period?
>>> 2.  Can I use the standard linear zero-phase filter for low-pass filtering after a causal filter as the paper showed that low-pass filtering using causal filters introduces large delays?
>>>    My tests did not show any difference on the ERP plots compared to using only the causal filter without low-pass filtering but I haven't run more thorough tests.
>>>
>>> 3.  the minimum-phase filter is called "beta" in eeglab GUI, can I confidently use it for my analysis and publication?
>>> 4.  If I need to apply a delay correction (for either causal filter), how can I do it?
>>>
>>> Thanks in advance to anyone that could bring me more clarity on this topic.
>>> Cedric
>>>
>>> Eeglablist page: http://sccn.ucsd.edu/eeglab/eeglabmail.html
>>> To unsubscribe, send an empty email to eeglablist-unsubscribe at sccn.ucsd.edu
>>> For digest mode, send an email with the subject "set digest mime" to eeglablist-request at sccn.ucsd.edu
>
>
> _______________________________________________
> Eeglablist page: http://sccn.ucsd.edu/eeglab/eeglabmail.html
> To unsubscribe, send an empty email to eeglablist-unsubscribe at sccn.ucsd.edu
> For digest mode, send an email with the subject "set digest mime" to eeglablist-request at sccn.ucsd.edu

```