Count impulses into sequence of impulses and segments of sequences of impulses from signal

2 views (last 30 days)
For example I have signal of current:
And I count the all of impulses such same:
numberOfPulses = nnz(diff(outSig_1_curr > 1) > 0);
But I don't know how to count numbers of marked sequences of impulses in signal and count nums of impulses for each sample (markes as black rectangle on png)?
So, the some of signals contain the such abnormal samples (sequences of impulses)
How can I count this abnormal samples and impulses for each abnormal samples?
Maybe I could findpeaks function, but I don't know ho to separate each samples at the other impulses in signal..
Signals .mat files available in GDrive: Google Drive
Thanks in advance for your help!
  2 Comments
Alex Milns
Alex Milns on 12 Jul 2022
1/ sampling freq - 1 000 000 Hz
2/ wich portion of the data are you showing ?
I demonstrate time fragment from signals (all signal available in Google Drive). First screen - sig1 data, Second screen - sig16 data

Sign in to comment.

Accepted Answer

Mathieu NOE
Mathieu NOE on 12 Jul 2022
hello again
so this is my attempt... not maybe the shortest and most efficienct code , but seems to do what I wanted
so we can slect blocks of data based on two selection parameters :
  • the minimal window length (in samples) where we want peaks : here 1000 samples = 1 ms
  • the min distance between blocks of data : here we want separation above 400 samples = 0.4 ms
The code shows here 3 blocks of data which contains this amount of peaks :
number_of_peaks = 18 111 15
hope it helps
code
clc
clearvars
load('sig1.mat') % outSig_1_curr2 32800000x1
samples = numel(outSig_1_curr2);
Fs = 1000000; % Hz
dt = 1/Fs;
t = (0:samples-1)*dt;
% extract signal between t = 21.9112 and t = 21.94 s
ind1 = round(21.9112*Fs);
ind2 = round(21.94*Fs);
t = t(ind1:ind2);
outSig_1_curr2 = outSig_1_curr2(ind1:ind2);
%% find peaks
% find positive local maxima
[tf, P] = islocalmax(outSig_1_curr2,'MinProminence',200);
t_peak = t(tf);
outSig_1_peak = outSig_1_curr2(tf);
%% localize / extract valid data blocks
blocks_distance_samples = 100; % select data blocks that are distant above value = blocks_distance_samples (in samples)
min_contiguous_samples = 1000; % select data blocks that are contiguous with min amount of samples = min_contiguous_samples
detect_signal = zeros(size(t))+0.5; % initialisation
% now define start en end point of segments above threshold
%%%%%%%%%%
% This locates the beginning /ending points of data groups
ind = find(tf); % logical to index conversion
D = diff([0;ind;0]);
ind_ends = find(D > blocks_distance_samples) - 1;
ends = ind(ind_ends);
begin = ind(ind_ends+1);
% remove incorrect begin / ends points (like end point before begin point and vice versa)
ends = ends(ends>begin(1));
begin = begin(begin<ends(end));
m = min(numel(begin),numel(ends));
ends = ends(1:m);
begin = begin(1:m);
%%%%%%%%%%
length_ind = ends - begin; % compute block length
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
t_peak2 = t(ind);
outSig_1_peak2 = outSig_1_curr2(ind);
% define the begin / ending x, y values of raw data
t_peak2_begin = t(begin);
outSig_1_curr2_begin = outSig_1_curr2(begin);
t_peak2_ends = t(ends);
outSig_1_curr2_ends = outSig_1_curr2(ends);
for ci = 1:length(begin)
ind = (t>=t_peak2_begin(ci) & t<=t_peak2_ends(ci));
detect_signal(ind) = 200;
% include here your code if you want to extract the data blocks
% individually
ind4 = (t_peak>=t_peak2_begin(ci) & t_peak<=t_peak2_ends(ci));
number_of_peaks(ci) = numel(find(ind4));
end
number_of_peaks
% plot
figure(1)
plot(t,outSig_1_curr2,t_peak,outSig_1_peak,'dr',t(begin),outSig_1_curr2(begin),'dg',t(ends),outSig_1_curr2(ends),'dk',t,detect_signal,'k');
legend('signal',' peaks ','begin points','end points','selected signal')
  19 Comments
Alex Milns
Alex Milns on 18 Jul 2022
Hello, Mathieu NOE!
It's very very cool solution to the counting problem. Thus, the first code can be used to count the working impulses, and this code even does an excellent job for the entire duration of the signal (the program will run for about 3 minutes)! Thank you very much for such great help!

Sign in to comment.

More Answers (1)

Karim
Karim on 12 Jul 2022
Edited: Karim on 12 Jul 2022
If the rectangles were drawn using matlab, then you know the start and stop time.
Thus, if this works for the total number of pulses:
numberOfPulses = nnz(diff(outSig_1_curr > 1) > 0);
then you can add an extra logic operation to only count in a time interval:
numberOfPulses = nnz( [0 diff(outSig_1_curr > 1)] > 0 & t>=t_start & t<=t_stop);
note that I added a 0 to the first logic check, this is since the diff(outSig) will contain 1 element less than the time vector due to the diff operation.
also, note that you can add .mat files directly to your question by using the paperclip symbol
  2 Comments
Alex Milns
Alex Milns on 12 Jul 2022
Edited: Alex Milns on 12 Jul 2022
This signal extract from TDMS file, AE and Current sensor, this signal is random, and all I know, more precisely, I assume that the duration of each pulse is 5 microseconds, but the number of pulses in each block, and the number of such blocks, I still do not know how to calculate. Moreover, it can be seen that some fragments (sequences of pulses are located above the midline)
The mat file 252 mb, so I attach link!
This fragmets has diffirent length and arbitrary start and end time!
Alex Milns
Alex Milns on 12 Jul 2022
So I understand, that in my situation I should set 200 threshold value.
numberOfPulses = nnz(diff(outSig_1_curr > 200) > 0);
And I consider, that I use logical indexing for mark sequences of impulses, and count this numbers segments:
idx1 = [0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0];
diffs = diff([0 idx1 0]);
% find start index of the blocks
loc = find(diffs == 1);
% calc block lengths by subtracting end - start indices
Ns = find(diffs == -1) - loc;
C = mat2cell([loc' Ns'],ones(size(loc)))
4×1 cell array
{[ 4 3]}
{[ 9 3]}
{[16 6]}
{[29 3]}
And I have a idea create two idx for count normal and abnormal segments, and count pulse for each segments, but I don't have idea for separate normal and abnormal fragments..
So this method not working:
numberOfPulses = nnz( [0 diff(outSig_1_curr > 1)] > 0 & t>=t_start & t<=t_stop);
Error using horzcat
Dimensions of arrays being concatenated are not consistent.

Sign in to comment.

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!