1
$\begingroup$

I am new to signal processing and I am sure this is a very rudimentary question. However I have done various searches and I cannot find an explanation (possibly because my knowledge is insufficient to even ask the question).

I have a light intensity signal, which is sampled at 2hz. I would like to apply 0.1hz lowpass fir filter. Using the gsignal package, I create the filter with the following code:

  fs = 2
  h <- gsignal::fir1(20, 0.1/(fs / 2), "low")

I am using a value of 20 for the order, because I am trying to emulate a software that employs "Lowpass Fir Filter 20 Order Hamming".

Edit: The coefficients of the filter are as follows:

[1] 0.0001146817 0.0017498427 0.0056848703 0.0138813218
 [5] 0.0275824834 0.0467267921 0.0696939138 0.0934923321
 [9] 0.1143658981 0.1286667204 0.1337545106 0.1286667204
[13] 0.1143658981 0.0934923321 0.0696939138 0.0467267921
[17] 0.0275824834 0.0138813218 0.0056848703 0.0017498427
[21] 0.0001146817

/edit

Then I employ the filter as follows:

xf <- gsignal::filter(h, x1)

The issue I have is visible in the plot below:

black = original signal, red = filtered signal

The black line is the original signal and the red line is the "filtered" signal. As can be seen, after applying the filter, all of the values have been increased by what seems to be a constant value. This appears to be affected by the order value. As such, I am not even sure that the filter is doing anything at all.

After googling to try to understand this, I have tried using the filtfilt() function without success. I have also managed to set initial values for my fir filter, so the "drop" at the beginning of the signal does not happen.

I am willing to study and learn more about this to solve my issue. If someone could point my in the right direction as to what I am not understanding, I would be very appreciative.

Thanks.

Edit #2: I believe the issue might be solved now, thanks to a comment below. I will add my working code for anyone with a similar question in the future:

  fs = 2
  h <- gsignal::fir1(20, 0.1/(fs / 2), "low") # create filter
  hn <- h / sum(h) # scale the filter by dividing by the sum of coefficients
  myzi <- gsignal::filter_zi(hn) # create the starting point values
  
  # apply filter with initial value
  x2 <- gsignal::filter(hn, x1, myzi * x1[1])
  
 # find the filter delay so it can be compensated for
  gd <- grpdelay(hn)
  npts <- length(x1)
  delay <- mean(gd$gd)
  x3 <- c(x2$y[(delay +1):npts], rep(NA, delay)) # filtered data with delay compensation applied
  
# plot the data for visual inpection 

  plot(t, x1, type = "l", xlab ="", ylab = "")
  lines(t, x2$y, col = "blue")
  lines(t, x3, col = "red")
  

This results in the following , where the black line is the original signal, blue line is filtered signal and red line is filtered signal with delay compensation:

fir filter with scaled coefficients and delay compensation

$\endgroup$
2
  • $\begingroup$ Can you show the coefficients for the filter? If their sum is not 1 or around that value, then the program calculates them differently. $\endgroup$ Jul 20, 2022 at 10:26
  • $\begingroup$ Thanks for taking the time to respond. I have edited the post and added the coefficients from the filter. $\endgroup$
    – Chris
    Jul 20, 2022 at 10:40

1 Answer 1

1
$\begingroup$

Your filter has a DC gain of 1.1377. The gain at 0Hz is simply the sum of all FIR coefficients and that's not 1 for your filter (which it should be). Since your signal has a very large DC component (or bias) that generates fixed offset.

I'm not fluent in R but at a casual glance your code looks ok to me. Maybe something is wrong with gsignal::fir1() or it's not used as intended?

You could fix it by dividing all coefficients by the sum of the coefficients, but it's probably better to deep dive into gsignal::fir1() and find out why it's not behaving as expected.

$\endgroup$
2
  • $\begingroup$ Thanks very much for the response. This is very helpful. In my searching to understand this, I had come to suspect that the filter applies a gain to the signal, and you have confirmed to me that the gain is the result of the summed coefficients. At least I can use this information to keep investigating my problem. It could indeed be the case that I am creating the filter incorrectly, so I will keep looking. I won't mark the question as solved just yet, in case someone with experience of this R package is able to comment on my application of the fir function. $\endgroup$
    – Chris
    Jul 20, 2022 at 14:02
  • $\begingroup$ Thanks to your comment, I believe I have now managed to solve my problem. Your advice was much appreciated, thank you! $\endgroup$
    – Chris
    Jul 20, 2022 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.