Contents
Signal Quality Assessment Demo
This demonstration script, which is part of DuraTools, is utilizing a vibration data base consisting of 102 vibration signals, test1 - test102. Data were recorded on different measurement points on a truck, driving by different speeds on different roads.
The task is to analyze the signals and find potentially bad measurements. We will show a few good tricks that can be made for assessing datac quality.
% Copyright (c) 2003-2006, Axiom EduTech AB, Ljusterö, Sweden. All rights reserved. % URL: http://www.vibratools.com Email: info@vibratools.com
Introduction
With many recorded signals, it is usually necessary to perform a signal data quality check. As a first test, we make a quality matrix for data using skewness and kurtosis. We sort the matrix after kurtosis size and plot the ten "worst" signals:
CurrDir=pwd;
cd DuraData
FontSize=10;
Calculate Quality Matrix
disp('Calculating Quality Matrix with skewness and kurtosis!') Q = qualitym('test',1,102,'wk'); % sort the matrix after kurtosis size [y,I] = sort(Q(:,3)); Q = Q(flipud(I),:); clc disp('The ten signals with highest kurtosis:') disp(' signal # skew kurtosis') disp(Q(1:10,:)) disp(' ') disp('Press any key to continue!')
Calculating Quality Matrix with skewness and kurtosis! The ten signals with highest kurtosis: signal # skew kurtosis 99.0000 -15.8565 942.0135 93.0000 5.4500 225.3094 87.0000 2.4807 56.1924 95.0000 -0.9698 54.3978 23.0000 0.5468 46.0364 27.0000 0.7321 26.1947 25.0000 0.6891 23.8230 37.0000 0.4559 23.5546 29.0000 0.6669 22.8375 21.0000 0.3464 21.6435 Press any key to continue!
Plot 10 Signals With Highest Kurtosis
load test1 fs = headfs(Header); for n = 1:10 figure(n) eval(['load test',int2str(Q(n,1))]); t = maketime(Data,fs); plot(t,Data,'k') set(gca,'FontSize',FontSize) xlabel(headxl(Header),'FontSize',FontSize) ylabel(headyu(Header),'FontSize',FontSize) title(['Time history ',headyl(Header)],'FontSize',FontSize) end
Check Problem Data
There seem to be (at least) two kinds of problems; spikes, as for test99 (and more) and bad contact as for test93 and test87. The typical shape is the result of a high-pass filtered step
Correlate With Found Bad Data
First, we try to find all signals behaving as test87.
disp('Testing for test87 behaviour') close all load test87 t = maketime(Data,fs); % % Pick Out a Typical Failure Part in the Signal x = sigtrunc(Data,fs,113,126); % correlate with test87 to get reference xc = xcorr(x,Data); scale = maximax(xc); % correlate this with all signals, save maximax % (maximax is max of absolute value) for n = 1:102 eval(['load test',int2str(n)]); xc = xcorr(x,Data); result(n,:) = [n maximax(xc)/scale]; home end % sort result % [y,I] = sort(result(:,2)); result = result(flipud(I),:); disp('Result of correlation') result(1:10,:) disp('It seems like we only have to cancel test87 and test 93!') % we start a black list % blacklist = [87 93]; % % For the spikes we look at test99 and test91. % Look at figure 1 and 2, the signals both looks spiky! % BUT, there is a huge difference, look at one second of % data in figures 3 and 4 % load test99 figure(1) t = maketime(Data,fs); plot(t,Data,'k') set(gca,'FontSize',FontSize) xlabel(headxl(Header),'FontSize',FontSize) ylabel(headyu(Header),'FontSize',FontSize) title(['Full Time history ',headyl(Header)],'FontSize',FontSize) figure(3) plot(t,Data,'k') axis([56.5 57.5 -250 50]) set(gca,'FontSize',FontSize) xlabel(headxl(Header),'FontSize',FontSize) ylabel(headyu(Header),'FontSize',FontSize) title(['One second Time history ',headyl(Header)],'FontSize',FontSize) drawnow % load test91 figure(2) t = maketime(Data,fs); plot(t,Data,'k') set(gca,'FontSize',FontSize) xlabel(headxl(Header),'FontSize',FontSize) ylabel(headyu(Header),'FontSize',FontSize) title(['Full Time history ',headyl(Header)],'FontSize',FontSize) figure(4) plot(t,Data,'k') axis([100 101 -60 60]) set(gca,'FontSize',FontSize) xlabel(headxl(Header),'FontSize',FontSize) ylabel(headyu(Header),'FontSize',FontSize) title(['One second Time history ',headyl(Header)],'FontSize',FontSize) drawnow %
Testing for test87 behaviour Result of correlation ans = 87.0000 1.0000 93.0000 0.9127 75.0000 0.0253 81.0000 0.0086 33.0000 0.0066 35.0000 0.0064 31.0000 0.0061 43.0000 0.0059 47.0000 0.0056 45.0000 0.0055 It seems like we only have to cancel test87 and test 93!
Look for Spikes
So, the "spikes" in test91 seems not to be in error, because they are symmetric and oscillating. But the spikes in test99 look like errors! We perform a test, looking for high frequency spikes. Let's filter in a 100 Hz 1/3 octave band filter and look at the kurtosis. We then arrange the result in order of kurtosis size
disp('testing for high frequency spikes') clear rrr [b,a] = tersfilt(fs,100); for n = 1:102 if isempty(find(n == blacklist)) == 1 eval(['load test',int2str(n)]); x = filter(b,a,Data); t = maketime(x,fs); [m,I] = max(abs(x)); rrr(n,:) = [n kurtosis(x) t(I)]; home; end end [m,I] = sort(rrr(:,2)); rrr = rrr(flipud(I),:); disp(' signal # kurtosis time for max') disp(rrr(1:10,:)) disp('By inspection we find that the method points out signals with spikes') % % We can inspect the worst signals, and we find that the method points out % high frequency spikes. % We add the first 8 in the list to our black list % blacklist = [blacklist rrr(1:8,1)']; blacklist = sort(blacklist); disp('We add the bad signals to our black list') disp(blacklist)
testing for high frequency spikes
signal # kurtosis time for max
99.0000 70.8247 259.2570
95.0000 18.4962 305.8600
34.0000 12.5338 162.2890
58.0000 10.5932 33.3710
36.0000 8.7628 164.8280
37.0000 7.9091 252.9120
79.0000 7.9026 218.2230
73.0000 7.6687 216.0180
75.0000 7.6358 63.2710
47.0000 7.0972 348.7210
By inspection we find that the method points out signals with spikes
We add the bad signals to our black list
34 36 37 58 73 79 87 93 95 99
Check High Skewness
Some signals have a very spectacular skewness, so we resort the Q matrix for skewness
disp('we resort the quality matrix after large skewness') [y,I] = sort(abs(Q(:,2))); Q = Q(flipud(I),:); disp(' signal # skew kurtosis') disp(Q(1:30,:)) disp('Add the worst ones to the black list') % Quality control can go on for ever, but here we stop, removing (rather % arbitrarely) all signals having an absolute skewness greater than 0.3 % % So we add to the black list % blacklist = [blacklist Q(find(abs(Q(:,2))>0.3),1)']; % % Finally, remove repetitions % blacklist = unique(blacklist); disp(blacklist) disp('QUALITY CHECK FINISHED!') cd(CurrDir) save blacklist blacklist
we resort the quality matrix after large skewness
signal # skew kurtosis
99.0000 -15.8565 942.0135
93.0000 5.4500 225.3094
87.0000 2.4807 56.1924
81.0000 1.8802 16.3026
75.0000 1.3780 18.1154
95.0000 -0.9698 54.3978
27.0000 0.7321 26.1947
25.0000 0.6891 23.8230
29.0000 0.6669 22.8375
39.0000 0.6184 19.9529
61.0000 0.5938 15.1037
23.0000 0.5468 46.0364
41.0000 0.5197 17.9191
49.0000 0.5169 15.8080
79.0000 0.5003 11.9982
73.0000 0.4715 12.6306
55.0000 0.4656 13.4765
19.0000 0.4590 21.1061
37.0000 0.4559 23.5546
67.0000 0.4259 12.5098
100.0000 0.3468 4.9242
15.0000 -0.3466 14.5037
21.0000 0.3464 21.6435
94.0000 0.3398 4.8794
45.0000 0.3116 17.1910
101.0000 -0.3075 15.7117
88.0000 0.2982 4.3745
47.0000 0.2922 18.8049
43.0000 0.2848 17.7868
32.0000 0.2846 6.3054
Add the worst ones to the black list
Columns 1 through 15
15 19 21 23 25 27 29 34 36 37 39 41 45 49 55
Columns 16 through 29
58 61 67 73 75 79 81 87 93 94 95 99 100 101
QUALITY CHECK FINISHED!