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

조회 수: 75(최근 30일)
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
Alex Milns
Alex Milns 2022년 7월 12일
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

댓글을 달려면 로그인하십시오.

채택된 답변

Mathieu NOE
Mathieu NOE 2022년 7월 12일
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

댓글을 달려면 로그인하십시오.

추가 답변(1개)

Karim
Karim 2022년 7월 12일
편집: Karim 2022년 7월 12일
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
Alex Milns
Alex Milns 2022년 7월 12일
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.

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

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

Start Hunting!

Translated by