Apply filtfilt on successive blocks with initial conditions (to avoid discontinuity)
Asked Answered
L

0

0

We have two lowpass filters with a different cutoff value:

b, a = signal.butter(2, 0.125)
b2, a2 = signal.butter(2, 0.140) 

When applying the first filter to x[0:10000] and the second to x[10000:20000] with lfilter, we have to use initial conditions for the output to be "continuous", as seen here in the answer of Continuity issue when applying an IIR filter on successive time-frames:

zi = lfilter_zi(b, a)
x[0:10000], zi = lfilter(b, a, x[0:10000], zi=zi)
x[10000:20000], zi = lfilter(b2, a2, x[10000:20000], zi=zi)

Question: how to do the same when applying filtfilt (forward and backwards filtering), to ensure continuity when using filters on consecutive blocks, as there is no zi initial conditions parameter?

Loats answered 25/9, 2018 at 16:31 Comment(7)
I don't think that the implementation of filtfilt lends itself to block-processing, unfortunately. You may have to search for a specialized implementation or implement something yourself.Bondon
Could you elaborate why you need acausal filtering? Maybe there's another solution for your problem...Bondon
@Bondon When using lfilter (that has the zi initial condition parameter, so this one works well for block-processing) there is a delay delta for a step function (Heavyside) to reach, say, 95% of the final value. I noticed filtfilt compensates this delay (to the price of a pre-ringing), that's why I was using it. I could also use lfilter and shift the time-axis by delta/2 to avoid the too-big latency caused by lfilter. How is called this delta for a filter? Is there a way to compute it?Loats
Yes, that's what an acausal filter does, it takes input values "from the future" to calculate the current output value. But why is it important to you? You can achieve the same by shifting the timestamps of the output signal relative to the input signal. What you call delta is usually called the time constant of the step response and is denoted by the greek letter tau.Bondon
@Bondon It's important because my input signal x is separated into several signals x = x1 + x2 + x3. Then I'm applying modifications (filtering, etc.) on x1, this gives x1_modified. Then I'm resumming x_modified = x1_modified + x2 + x3. If there is some delay in x1's modification, it will be weird when resumming with x2 and x3 which are not delayed. That's why I was looking for delay compensation, and that's why I was using filtfilt instead of lfilter.Loats
@Bondon Moreover as x1 has to be modified with a cutoff that varies along time (thus this question), I have to do it "by blocks". Thus this problem filtfilt + continuity when doing block processing! This is the full picture :)Loats
Let us continue this discussion in chat.Bondon

© 2022 - 2024 — McMap. All rights reserved.