How to apply butterworth filter to data in cells? filter went wrong

4 views (last 30 days)
Hi all,
I have signals of diffrent lengths located in cells (attached), that when plotted over one plot looks like this.
My aim is to:
  1. interpolate all cells to 101 data points
  2. apply butterworth filter to data in all cells
load 'cells'
% Interpolate data
force_y_l_cycle = cellfun(@(x) interpft(x,101), force_y_l_cycle, 'uni', 0);
% Filter data
SampRate=1000;
Wn=SampRate/2;
order=2;
cutoff=6;
[b,a] = butter(order,cutoff/Wn,'low');
for k = 1:length(force_y_l_cycle)
force_y_l_cycle{k} = filtfilt(b, a, force_y_l_cycle{k});
end
% Plot
hold on
for i = 1:length(force_y_l_cycle)
plot(force_y_l_cycle{i},'r') ;
xlabel('% of cycle'); ylabel('force y l (N)'); box off; axis tight;
end
This results in:
Interpolated:
Filtered results is this.
If I chnage the order so first filtering and then interpolation I get this, which is better but still the last data poits shoudl be closer to 0.
I wonder where do I make a mistake in my approach ? Can you help please?

Accepted Answer

William Rose
William Rose on 15 Jul 2022
This appears to be a record of vertical ground reaction force for 7 steps on an instrumented treadmill, from a subject weighing approximately 70 kilos.
The first approach to filtering, in which you interpolate and then filter, does not give the desired result, because you tell butter() that the sampling rate is 1000 Hz. But that is not correct, because the original records, which were 0.68 to 0.84 seconds long, have been interpolated to 101 samples. Therefore the effective sampling rate is approximately 101 samples/0.76 seconds = 133 samples/second. The exact sampling rate of each nterpolated step is different for each step, since the individual steps had different durations, and they were all interpolated to 101 points.
The second approach to filtering, in which you filter and then interpolate, is much better. However, the final point of each filtered record is not as close to zero as you would expect. I think this is a consquence of the initial and final conditions used by the filtfilt() function. These initial and final conditions are chosen based on the algorithm published here.
You have several options. Here are two:
  1. Interpolated the unfiltered steps to 101 samples and take the average of them. This will result in a smoothed average ground reaction force for one typical step. Do not filter it after that.
  2. Suppose the record lengths which you show above are [680, 710, 740, 770, 800, 820, 840] points. Add 10 zeros before and after each unfiltered record, so that the record lengths are [700, 730, 760, 790, 820, 840, 860]. Filter each signal with filtfilt(), using [b,a] from butter() with a sampling rate of 1000 Hz. Then chop off ten points from each end of each filtered record. Then interpolate to 101 points per step. You will probably find some overshoot/undershoot in the filitered signals, around the transitions to zero. If this is a problem, try a Bessel filter instead of Butterworth. Bessel has a lot less overshoot and undershoot.
Good luck with your research!
  1 Comment
Tomaszzz
Tomaszzz on 18 Jul 2022
Hi @William Rose. Many thanks for such a detailed response and explanation. Indeed, this is data from walking. Thanks for pointing out my mistake regarding the first approach. I guess option 1 you suggested will do the job. Cheers, always a pleasure to learn from colleagues in the field!

Sign in to comment.

More Answers (1)

William Rose
William Rose on 18 Jul 2022
@Tomaszzz, You're welcome. Good lcuk with your research.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!