How to implement a matched filter - matlab

I have a template. I compute the impulse response of the matched filter by taking the inverse Fourier Transform of the conjugate of the Fourier transform of my template. And I would like to perform the matched filtering operation on one of my available EEG channels using the 'filter' command in Matlab. Using the filter command the coefficient 'b' is my impulse response? Moreover, I would like to implement Matlab code to threshold the output of the matched filter to detect peaks.How can I achieve it?

Here is a start for you,
% A template is given
temp = randn(100,1);
% Create a matched filter based on the template
b = flipud(temp(:));
% For testing the matched filter, create a random signal which
% contains a match for the template at some time index
x = [randn(200,1); temp(:); randn(300,1)];
n = 1:length(x);
% Process the signal with the matched filter
y = filter(b,1,x);
% Set a detection threshold (exmaple used is 90% of template)
thresh = 0.9
% Compute normalizing factor
u = temp.'*temp;
% Find matches
matches = n(y>thresh*u);
% Plot the results
plot(n,y,'b', n(matches), y(matches), 'ro');
% Print the results to the console
display(matches);
As Andreas mentions in his answer, there is no need for the fourier transform. If you have a time-domain template, then its matched filter is simply a time-reversed version of itself (which I achieve with flipud). As you go along, you will find that there are many nuances to be worked out. This code works great because I am in control from start to finish, but once you start working with real data, things get much more complicated. Choosing an appropriate threshold value for example will require some knowledge about the data that you will be working with.
In truth, peak detection can be a very non-trivial task depending on the nature of your signals, etc. In my case, peak detection was easy because my signal was completely uncorrelated with the template, except at the point in the middle, and I also knew exactly what amplitude I was expecting to see. All of these assumptions are over-simplifications of the problem which I used to demonstrate the concepts.

Practically, you do this
y = filter( h, 1, x )
with h the impuse response and x and y input and output signals.
The matched filter is nothing else than a correlator that correlates with a given signal pattern.
It has a impulse response which is just the time reverse of the signal pattern you try to look for.
So by the way: If you have a measured signal pattern, reverse it and set this as impulse response of a FIR filter. There is no need to do this in the frequency domain if you have measurement in the time domain (both approaches are equivalent but one is more error prone then the other)

Related

Using Matlab digitalfilter object from lowpass() in filter()

I need to perform a lowpass filtering operation many times (same cutoff frequency and sampling frequency each time).
It seems that lowpass() is a slow operation and I can speed it up if I reuse the filter object that is created. The help for lowpass() says that:
[Y,D] = lowpass(...) returns the digital filter, D, used to filter the signal. [...] Call filter(D,X) to filter data.
However when I try to use the filter object in this way I get different results to what lowpass() returns. I expect lp1 and lp2 to be identical in this example:
% Test input data
x = rand([200,1]);
% Lowpass filter, and save the filter object to df:
[lp1, df] = lowpass(x,50,1000);
% Reuse the filter object:
lp2 = filter(df, x);
% Plot to show that they are clearly different results
figure;plot(lp1);hold on;plot(lp2);
I have also tried using filtfilt() but this does not produce an identical result.
Quick trick to reuse filter object df if you want the same output as from lowpass IN THIS SPECIFIC SCENARIO and if time's not on your side: lp3 = conv(x, df.Coefficients, 'same');
Explanation: the filter you designed using lowpass.m is a finite impulse response filter (FIR) which shifts phases. Look again at the two curves in the figure your code snippet produces and you'll realize that the curve produced by filter.m is essentially a right-shifted version of the version produced by lowpass.m. You could try to correct for that, see https://de.mathworks.com/help/signal/ug/compensate-for-the-delay-introduced-by-an-fir-filter.html. The surprising part, though, is that lowpass.m corrects for the delay automatically, which a cursory reading of the docs didn't reveal.
filtfilt.m performs filtering twice, once in the forward direction, then in the reverse, and additionally '...minimizes start-up and ending transients...'. Because this to and fro filtering essentially cancels the delays but also filters harder, the results will by definition be different from those of either lowpass.m and filter.m.
In the long term, you will be best off investing some time into designing your filters from the bottom up (the Matlab docs are excellent in this regard), not using relatively new convenience wrapper functions like lowpass which seemingly do things unasked for in the background.
% Test input data
x = rand([200,1]);
t = 1:200;
% Lowpass filter, and save the filter object to df:
[lp1, df] = lowpass(x,50,1000);
% Reuse the filter object:
lp2 = filter(df, x);
% Convolution of time series with filter coefficients
lp3 = conv(x, df.Coefficients, 'same');
% Plot
figure(1), clf;
subplot(2,1,1)
% Plot lp3 with a tiny offset so we can discern it from lp1
plot(t, lp1, t, lp2, t, lp3+0.01)
legend('lowpass.m','filter.m','convolution')
% Use filtfilt to obtain zero-lag, doubly filtered version (for comparison)
lp4 = filtfilt(df, x);
subplot(2,1,2)
plot(t, lp1, t, lp4)
legend('lowpass.m','filtfilt.m')

Applying low pass filter

I want to simulate an interpolator in MATLAB using upsampling followed by a low pass filter. First I have up-sampled my signal by introducing 0's.
Now I want to apply a low pass filter in order to interpolate. I have designed the following filter:
The filter is exactly 1/8 of the normalized frequency because I need to downsample afterward. (it's a specific excersise to upsample interpolate and downsample in this particular order.)
However when I apply this filter to my data using the function filter(myfilter, data) the following signal is generated:
I really don't know what is happening to my signal because in theory I know an interpolated signal should appear. This is the first time I'm working in MATLAB with filters because till now we only had the theory and had to assume ideal filters and analytical solutions.
Can someone give me an indication what might be wrong? I use the following code:
clear all; close all;
% Settings parameters
fs=10e6;
N=10;
c=3/fs;
k=3;
M=8;
% Settings time and signal
t=0:fs^-1:N*fs^-1;
x=exp(-(t.^2)./(2.*c.^2)); % Gaussian signal
% Upsampling
tu=0:(fs*M)^-1:N*fs^-1;
xu=zeros(1,size(tu,2));
sample_range=1:M:size(xu,2);
for i=1:size(x,2);
xu(sample_range(i))=x(i);
end;
%% Direct Method
xf=filter(lpf5mhz,xu);
As suggested by hotpaw2's answer, the low-pass filter needs some time to ramp up to the input signal values. This is particularly obvious with signal with sharp steps such as yours (the signal implicitly includes a large step at the first sample since past samples are assumed to be zeros by the filter call). Also, with your design parameters the delay of the filter is greater than the maximum time range shown on your output plot (1e-6), and correspondingly the output remains very small for the time range shown.
To illustrate the point, we can take a look at the filtered output with smaller filter lengths (and correspondingly smaller delays), using filters generated with fir1(length,0.125):
Given a signal with a smoother transition such as a Gaussian pulse which has been sufficiently time delayed:
delay = 10/fs;
x=exp(-((t-delay).^2)./(2.*c.^2)); % Gaussian signal
the filter can better ramp up to the signal value:
The next thing you may noticed, is that the filtered output has 1/Mth the amplitude as the unfiltered signal. To get an interpolated signal with similar amplitude as the unfiltered signal you would have to scale the filter output with:
xf=M*filter(lpf5mhz,1,xu);
Finally, the signal is delayed by the filtering operation. So for comparison purposes you may want plot a time shifted version with:
filter_delay = (1/(M*fs))*(length(lpf5mhz)-1)/2;
plot(tu-(1/(M*fs))*(length(b)-1)/2, xf);
A low-pass filter only helps interpolate signals that are much longer than the length of the impulse response of the low-pass filter. Otherwise the output can be dominated by the filter transient.

Simple low/high filtering matlab

can someone help me with another matlab project:
Is it possible to create a simple low pass filter like in RC circuits? For instance if we create a sine wave like y=10*sin(2*pift).
Can i just filter the signal with a cutoff frequency to be able to see how the filtered signal looks like(for the amplitude decay)?
So when i enter some information for example f = cutoff and plot the filtered signal this must reduce the amplitude somewhere at 30% from the input signal ?
I've been looking for the functions like butter and cheby but they seem to do other kind of filtering like removing the noise from a signal. I just want some simple plots(input and output) which will show the principle of RC, RL low and high pass filters.
An RC circuit is a fist-order filter. To approximate a first order hardware filter, I generally use a IIR filter. A butterworth filter is usually my first choice for IIR, but for a first-order response, it doesn't really matter.
Here's an example with the cutoff frequency being the same as the signal frequency, so the filtered signal should be 3 dB down...
%first, make signal
fs = 1000; %your sample rate, Hz
dur_sec = 1; %what is the duration of your signal, seconds
t_sec = ([1:dur_sec*fs]-1)/fs; %here is a vctor of time
freq_Hz = 25; %what frequency do you want your sign wave
y = sin(2*pi*freq_Hz*t_sec); %make your sine wave
%Second, make your filter
N = 1; %first order
cutoff_Hz = 25; %should be 3dB down at the cutoff
[b,a]=butter(N,cutoff_Hz/(fs/2),'lowpass'); %this makes a lowpass filter
%Third, apply the filter
y_filt = filter(b,a,y);
%Last, plot the results
figure;
plot(t_sec,y,t_sec,y_filt);
xlabel('Time (sec)');
ylabel('Amplitude');
ylim([-1 1]);
legend('Raw','Filtered');
title(['1st-Order Filter with Cutoff at ' num2str(cutoff_Hz) ' Hz']);
As an alternative to using the built-in filter design functions such as butter, you could choose model the circuit itself. A simple first order RC (or RL) circuit would result a first order differential equation. For an RC circuit, you'd then integrate the equation through time, given your sine wave as stimulation. That would work fine, but could be more of a hassle, depending upon your background.
For a simple, first-order hardware filter that is properly buffered by an op-amp on either end of the RC, I think that you'd find that the result using the first order butter filter is going to be awfully close (the same?) as modeling the circuit. The butter filter is way easier to implement in software (because i just gave you the code above), so I'd go that route.
When you move to 2nd order hardware filters, however, that's where you have to be more careful. You have a few options:
1) Continue to model your 2nd order hardware using one of the built-in filter functions. A second order butter is trivial to implement (alter the N in the code above), but this might not model the specific hardware filter that you've created. You'll have to choose the right kind of IIR filter to match the architecture of your hardware filter.
2) If you haven't picked your architecture for your hardware filter, you could choose the architecture to follow one of the canonical filter types, just so that it is easy to model via butter, cheby1, or whatever.
3) You could go back to modeling the circuit with differential equations. This would let you model any filter circuit, whether it followed a canonical type or not. You could also put non-linear effects in here, if you wanted.
For the first order RC filter, though, I think that any of the built-in filter types will be a decent enough model for an RC filter. I'd suggest that you play with my example code above. I think that it will satisfy your need.
Chip

Filters performance analysis

I am working on some experimental data which, at some point, need to be time-integrated and then high-pass filtered (to remove low frequency disturbancies introduced by integration and unwanted DC component).
The aim of my work is not related to filtering, but still I would like to analyze more in detail the filters I am using to give some justification (for example to motivate why I chosed to use a 4th order filter instead of a higher/lower one).
This is the filter I am using:
delta_t = 1.53846e-04;
Fs = 1/delta_t;
cut_F = 8;
Wn = cut_F/(Fs/2);
ftype = 'high';
[b,a] = butter(4,Wn,ftype);
filtered_signal = filtfilt(b,a,signal);
I already had a look here: High-pass filtering in MATLAB to learn something about filters (I never had a course on signal processing) and I used
fvtool(b,a)
to see the impulse response, step response ecc. of the filter I have used.
The problem is that I do not know how to "read" these plots.
What do I have to look for?
How can I understand if a filter is good or not? (I do not have any specification about filter performances, I just know that the lowest frequency I can admit is 5 Hz)
What features of different filters are useful to be compared to motivate the choice?
I see you are starting your Uni DSP class on filters :)
First thing you need to remember is that Matlab can only simulate using finite values, so the results you see are technically all discrete. There are 4 things that will influence your filtering results(or tell you if your filter is good or bad) which you will learn about/have to consider while designing a Finite response filter:
1, the Type of the filter (i.e. Hamming, Butterworth (the one you are using), Blackman, Hanning .etc)
2, the number of filter Coefficients (which determines your filter resolution)
3, the sampling frequency of the original signal (ideally, if you have infinite sampling frequency, you can have perfect filters; not possible in Matlab due to reason above, but you can simulate its effect by setting it really high)
4, the cut-off frequency
You can play around with the 4 parameters so that your filter does what you want it to.
So here comes the theory:
There is a trade-off in terms of the width of your main lobe vs the spectrum leakage of your filter. The idea is that you have some signal with some frequencies, you want to filter out the unwanted (i.e. your DC noise) and keep the ones you want, but what if your desired signal frequency is so low that it is very close to the DC noise. If you have a badly designed filter, you will not be able to filter out the DC component. In order to design a good filter, you will need to find the optimal number for your filter coefficients, type of filter, even cut-off frequency to make sure your filter works as you wanted.
Here is a low-pass filter that I wrote back in the days, you can play around with filters a lot by filtering different kinds of signals and plotting the response.
N = 21; %number of filter coefficients
fc = 4000; %cut-off frequency
f_sampling = fs; %sampling freq
Fc = fc/f_sampling;
n = -(N-1)/2:(N-1)/2;
delta = [zeros(1,(N-1)/2) 1 zeros(1,(N-1)/2)];
h = delta - 2*Fc*sinc(2*n*Fc);
output = filter(h,1,yoursignal);
to plot the response, you want to plot your output in the frequency domain using DFT or FFT(in Matlab) and see how the signal has been distorted due to the leakage and etc.
NFFT=256; % FFT length
output=1/N*abs(fft(output,NFFT)).^2; % PSD estimate using FFT
this gives you what is known as a periodigram, when you plot, you might want to do the 10*log10 to it, so it looks nicer
Hope you do well in class.

Linearity of filtering system on concatenated signals

I have a signal s[n] and a bandpass filter that filters out very low and very high frequency components of the signal. I want to store the signal into an Matlab array and put it through the filter.
However, I cannot store s[n] in Matlab because the allocated memory is not sufficient to contain such long signal. I decided to split the signal into N segments, and put each segment through that bandpass filter, and lastly assemble them after filtering.
I am wondering if there is any linearity issue with this approach. If this is not valid, then is there any other method that can achieve what I want? Thanks.
If you are using an FIR filter you can using convolution:
x = rand(1000,1)
b = fir1(100, 0.5)
y1 = zeros(1100, 1)
% compute the response using the first 400 points of x
y1(1:500) = conv(x(1:400),b)
% compute the response using the last 600 points of x
y1(401:1100) = y1(401:1100) + conv(x(401:1000),b)
% compute the whole response just to compare
y2 = conv(x,b)
Note that the length of conv(a,b) is length(a) + lenght(b) - 1
But the total response will have the same length of your approach, you are probably going to have the same memory problem.
Overlap-add and overlap-save are methods to deal with segmented windows of data when doing FFT fast convolution, but should work with segmented direct linear convolution with (finite) FIR filter kernels as well.
When doing IIR filtering, you need to save and restore the internal filter state across segment boundaries.
If you don't do the above, then you will usually end up with transient clicks at the block boundaries.