Hello,
A very technical issue:
Apparently, Mokka has options to (zero-lag, bidirectionally) filter the analog data in a C3D using a Butterworth filter. As Mokka is based on BTK, I was interested in how this could be done efficiently in BTK and checked the code (see below)
I noticed that Mokka nicely changes the order and cutoff frequency when zero-lag filtering is selected (using the formula's in Winter's book). However, I noticed that Mokka uses the order of the filter instead of the number of passes when calculating the scaling/compensation factor.
Is this correct? When looking at Winter's book, the cutoff frequency correction should only be based on the number of passes... Unless I am mistaking, this would mean that zero-lag filtering in Mokka only works for 2nd order BW filters.
Regards,
Ben van Basten
Motek
PS. I posted this on the BTK forum as well, but from my experience, this forum is very inactive, so I would like to consult the bm-l community as well.
A very technical issue:
Apparently, Mokka has options to (zero-lag, bidirectionally) filter the analog data in a C3D using a Butterworth filter. As Mokka is based on BTK, I was interested in how this could be done efficiently in BTK and checked the code (see below)
I noticed that Mokka nicely changes the order and cutoff frequency when zero-lag filtering is selected (using the formula's in Winter's book). However, I noticed that Mokka uses the order of the filter instead of the number of passes when calculating the scaling/compensation factor.
Is this correct? When looking at Winter's book, the cutoff frequency correction should only be based on the number of passes... Unless I am mistaking, this would mean that zero-lag filtering in Mokka only works for 2nd order BW filters.
Regards,
Ben van Basten
Motek
PS. I posted this on the BTK forum as well, but from my experience, this forum is very inactive, so I would like to consult the bm-l community as well.
Code:
[FONT=Arial]FilterAnalog.cpp: const double hfs = data->acquisition()->analogFrequency() / 2.0; int n = dialog.orderSpinBox->value(); bool zeroLagFilter = (dialog.zeroLagComboBox->currentIndex() == 0); if (dialog.typeComboBox->currentIndex() == 0) { double wn = dialog.lowerCutOffSpinBox->value() / hfs; if (zeroLagFilter) btkEigen::adjustZeroLagButterworth(n, wn); btkEigen::butter(&b, &a, n, wn, btkEigen::LowPass); } IIRFilterDesign.h: void adjustZeroLagButterworth(int& n, double& wn) { const double c = 1.0 / std::pow(std::pow(2,1.0/static_cast<double>(n))-1.0, 0.25); //BEN: n should be 2 (number of passes) wn *= c; [FONT=Arial] n /= 2;[/FONT] };[/FONT]