# How to count active faults in a specific time interval

1 view (last 30 days)

Show older comments

### Accepted Answer

Mathieu NOE
on 20 Apr 2022

hello

try this code ; it select segments of data above a given threshold and longer than min_contiguous_samples samples;

% dummy data

samples=10000;

time= 3*(0:samples-1)/samples;

dt = mean(diff(time));

data = max(0,0.03*time+ sin(6*time.^2 -0.5));

fault_signal = zeros(size(time));

%% parameters

min_contiguous_samples = 400; % select segments only if they are at least this length => faulty signal = 1

threshold = 0.5; % 1 = max (100%) of data value

%% main loop %%%%

ind = (data>threshold*max(data)); % find data above threshold

% now define start en end point of segments above threshold

[begin,ends] = find_start_end_group(ind);

length_ind = ends - begin;

ind2= length_ind>min_contiguous_samples; % check if their length is valid (above min_contiguous_samples value)

begin = begin(ind2); % selected points

ends = ends(ind2); % selected points

time2 = time(ind);

data2 = data(ind);

% define the begin / ending x, y values of raw data

time2_begin = time(begin);

data_begin = interp1(time,data,time2_begin);

time2_ends = time(ends);

data_ends = interp1(time,data,time2_ends);

for ci = 1:length(begin)

ind = (time>=time2_begin(ci) & time<=time2_ends(ci));

fault_signal(ind) = 1;

end

figure(1),

subplot(211),plot(time,data,'k',time2,data2,'.r',time2_begin,data_begin,'*c',time2_ends,data_ends,'*m','MarkerSize',12);

xlabel('time');

ylabel('amplitude');

legend('signal',['signal above ' num2str(threshold*100) ' % threshold'] ,'begin points','end points');

subplot(212),plot(time,fault_signal,'k');

xlabel('time');

ylabel('amplitude');

legend('fault signal');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [begin,ends] = find_start_end_group(ind)

% This locates the beginning /ending points of data groups

D = diff([0,ind,0]);

begin = find(D == 1);

ends = find(D == -1) - 1;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function x_rms = my_rms(x)

x_rms = sqrt(mean(x.^2));

end

### More Answers (1)

Jon
on 20 Apr 2022

Edited: Jon
on 20 Apr 2022

Here is another approach (uses repelem trick from @Jan https://www.mathworks.com/matlabcentral/answers/382011-how-to-count-the-number-of-consecutive-identical-elements-in-both-the-directions-in-a-binary-vecto?s_tid=srchtitle)

% set up a small example

thresh = 0.5 % threshold for fault

minCount = 2; % min number of repeated values to be considered a fault

r = rand(1,10) % example vector of residuals

% make logical array with values of residual greater than threshold set

% true

f = r > thresh

% mark beginning and ends of consecutive runs of zeros and ones

d = [true,diff(f)~=0,true]

% find run lengths

n = diff(find(d))

% make vector with run length corresponding to each element

runLength = repelem(n,n);

% just keep run lengths where it is over threshold

runLength = runLength.*f

% assign logical indices for points that are considered faults

isFault = runLength >= minCount

% illustrative plots

idx = 1:numel(r);

plot(idx,r,idx(~isFault),r(~isFault),'og',idx(isFault),r(isFault),'*r')

##### 5 Comments

Mathieu NOE
on 21 Apr 2022

hello again

there are "home made" alternatives to repelem if you don't have it :

see in the code below (expanded)

% set up a small example

thresh = 0.5; % threshold for fault

minCount = 5; % min number of repeated values to be considered a fault

r = rand(1,100) % example vector of residuals

% make logical array with values of residual greater than threshold set

% true

f = r > thresh;

% mark beginning and ends of consecutive runs of zeros and ones

d = [true,diff(f)~=0,true];

% find run lengths

n = diff(find(d));

% make vector with run length corresponding to each element

% runLength = repelem(n,n);

runLength = my_repelem1(n,n); % alternative #1

% runLength = my_repelem2(n,n); % alternative #2

% just keep run lengths where it is over threshold

runLength = runLength.*f;

% assign logical indices for points that are considered faults

isFault = runLength >= minCount;

% illustrative plots

idx = 1:numel(r);

plot(idx,r,idx(~isFault),r(~isFault),'og',idx(isFault),r(isFault),'*r')

%%%%%%%%%%%%%%%%%%%%%% alternatives to repelem %%%%%%%%%%%%%%%%%%%%%

function out = my_repelem1(A,R)

% B = my_repelem1(A, R), returns an array with each element of A

% repeated according to R.

out = cell2mat(arrayfun(@(a,r)repmat(a,1,r),A,R,'uni',0));

end

%%%%%%%%%%%%%%%%%%%%%%

function out = my_repelem2(A,R)

% B = my_repelem1(A, R), returns an array with each element of A

% repeated according to R.

out = cell(1,length(R)) ;

for i = 1:length(R)

out{i} = ones(1,R(i))*A(i) ;

end

out = [out{:}];

end

### See Also

### Categories

### Products

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!