Code covered by the BSD License  

Highlights from
Wavelet denoising of vaginal pulse amplitude

image thumbnail
from Wavelet denoising of vaginal pulse amplitude by Nicole Prause
Uses an automated wavelet algorithm to remove noise components from the vaginal PA

sigclean=waveclean(signal)
function sigclean=waveclean(signal)
%waveclean=WAVELET-USING FUNCTION CLEANER
%function to automatically clean a function using wavelets, function
%should be length 2^J, where J is a positive integer
% 
% Appropriate citation:
% Prause, N., Williams, K., & Bosworth, K. (2009). Wavelet denoising of
% vaginal pulse amplitude. Psychophysiology, in press.
%
%USAGE:
%           sigclean=waveclean(signal)
%INPUTS:
%           signal=the original signal to be cleaned
%OUTPUTS:
%           sigclean=the cleaned signal
%
%NOTES: will automatically lengthen if length does not equal 2^J, but this
%           introduces inaccuracies and is not recommended
%       will not work for anything but SPAN-lab, for now...

%length 2^J, find J
J=log2(length(signal));

%test for proper length
if J ~= round(J)
    %adjust length to next 2^J; mirror 
    %NOTE: *Avoid having a length that is not a power of two if at all
    %       possible*
    J=ceil(J);
    signal_extension=length(signal);
    signal(signal_extension+1:2^J)=signal(signal_extension:-1:2*signal_extension-2^J+1);
end

%wavelet: Coiflet works well for this data
wavelet_filter=MakeONFilter('Coiflet',5);

%stationary wavelet transform
signal_fwtstat=fwt_stat(signal,1,wavelet_filter);

%remove the noise and unneeded constituent signals
signal_fwtstat(:,1:J-7)=0;
signal_fwtstat(:,J-4:J)=0;

%soft threshholding for signals we want to keep
for o=J-6:J-5
    signal_fwtstat_o=signal_fwtstat(:,o);
    To=2*median(abs(signal_fwtstat_o));
    %while the max is outside To, find where the max is
    %multiply by the 'smoothmult' function, where the radius is the
    %distance to the nearest point arbitrarily close to 0 (<=To/16)
    while max(abs(signal_fwtstat_o)) > To*23/16
        maxsignal_fwtstat_o=find(abs(signal_fwtstat_o) == max(abs(signal_fwtstat_o)));
        zerosignal_fwtstat_o=find(abs(signal_fwtstat_o) <= To/8); 
        smoothmult_radius=min(abs(zerosignal_fwtstat_o-maxsignal_fwtstat_o(1,1)));
        smoothmult_mid=maxsignal_fwtstat_o;
        signal_fwtstat_omax=signal_fwtstat_o(maxsignal_fwtstat_o(1,1));
        %if maxsignal_fwtstat_o is on boundaries, only smoothmult on one side, not both
        if maxsignal_fwtstat_o == 1
            signal_fwtstat_o=smoothmultR(signal_fwtstat_o,To/signal_fwtstat_omax,smoothmult_mid(1,1),smoothmult_radius(1,1));
        elseif maxsignal_fwtstat_o == length(signal_fwtstat_o)
            signal_fwtstat_o=smoothmultL(signal_fwtstat_o,To/signal_fwtstat_omax,smoothmult_mid(1,1),smoothmult_radius(1,1));
        else
            %if boundary(s) within smoothmult_radius 
            if abs(maxsignal_fwtstat_o-1) < smoothmult_radius
                smoothmult_radius=abs(maxsignal_fwtstat_o-1);
            elseif abs(maxsignal_fwtstat_o-length(signal_fwtstat_o)) < smoothmult_radius
                smoothmult_radius=abs(maxsignal_fwtstat_o-length(signal_fwtstat_o));
            end   
            signal_fwtstat_o=smoothmult(signal_fwtstat_o,To/signal_fwtstat_omax,smoothmult_mid(1,1),smoothmult_radius(1,1));
        end
    end
    signal_fwtstat(:,o)=signal_fwtstat_o;
end

%inverse wavelet transform
sigclean=iwt_stat(signal_fwtstat,wavelet_filter);

%plot original and clean signals
figure(12)
subplot(2,1,1)
plot(signal)
ylabel('Original signal')
subplot(2,1,2)
plot(sigclean,'r')
ylabel('Cleaned signal')

Contact us at files@mathworks.com