MATLAB Answers

How to extract event start and finish indices by finding rising edges and falling edges of an array?

99 views (last 30 days)
Luna
Luna on 14 Jan 2020
Commented: Luna on 16 Jan 2020
Hi dear community,
I have a state array doesn't matter what value inside it but for example I only want to find array == 6 as a logical array. (State 6 means something to me.). So my array becomes array = [1 1 1 0 0 0 1 1 ... etc].
I detected its rising and falling edges so that I want to find each event started in a point and finished in another point. My data resampled so I am working in sample base.
I want to find the intervals of these event all the array long because I will evaluate another array's values along these events.
For example if I find event rising edges = [7000 9000] and falling edges = [7300 9100] that means I have 2 events and first event between 7000:7300 and second is 9000:9100. So my another array's values between 7000:7300.
Here is example code:
array = [0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0];
another_array = 1:18; % just for example it will have equal size with state array
sample_time = 0.1;
loc = (array >= 0.5);
d_loc = [false ; diff(loc)];
rising_edges_index = find(d_loc == 1);
loc = (array <= 0.5);
d_loc = [false ; diff(loc)];
falling_edges_index = find(d_loc == 1);
another_array_mean_vals = [];
for i = 1:numel(rising_edges_index)
another_array_mean_vals = [another_array_mean_vals, another_array(rising_edges_index(i):falling_edges_index(i))]; % for example each interval I want to get mean values and save it
event_duration_in_seconds = (falling_edges_index(i) - rising_edges_index(i))*sample_time;
end
The problem is sometimes rising_edges_index and falling_edges_index sizes are not equal! Because it starts with falling edge but there were no rising edge for corresponding event. Other way around sometimes there is a rising edge but no corresponding falling edge at the end of the array. Or both sometimes starts with falling edge and ends with rising edge.
How to handle this situation? Would you remove those inappropriate events or add zero to the beginning and pretend like the event started at the beginning of the state signal?
Just a sample visual for the situation. You can think it as a square wave which has no constant period.
example_event_triggers.png

  4 Comments

Show 1 older comment
Luna
Luna on 15 Jan 2020
Actually I am interested in two things: First, rising edges and corresponding falling edges locations.The second is the parts I want to extract as events for example:
Between first rising edge and first falling edge my event is Event 1, the second is Event 2. So I will calculate some other things according to these events.
For example I have array2, array3, array4. For Event 1; I will find the value of array2 when event started(rising edge location), I will find value of array3 when event end(falling edge location), and I will find mean value of array4 during the event. So I will create a table like below:
Event Names EventStart EventEnd Mean
Event 1 12.52 13.25 55.36
Event 2 .... ..... .....
.
.
The states are numbers for example: state_array = [9 9 9 9 3 3 3 3 5 5 5 5 6 6 6 6 3 3 3 3].
So I am interested in this array when only state array is 6 for any duration.
Guillaume
Guillaume on 15 Jan 2020
This may only be a matter of semantic, but if you're interested in the location and duration between a rising edges and corresponding falling edge, what you're actually interested in is the state (high), not the edges. This semantic matters for the actual algorithm.
if the signal starts or ends in a high state, do you want to detect it or ignore it?
Luna
Luna on 15 Jan 2020
I want to ignore it because I will never know when it has been started so the true detection of start and end times are important for me.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 15 Jan 2020
I think you've answered your own question. "How to handle this situation? Would you remove those inappropriate events". Yes, you'd remove them. It's only a small variation on your code:
%The following code works with row or column vectors (your code only work with column vectors).
isevent = statevector == 6; %only care about state of value 6.
startlocs = find(diff(isevent) == 1) + 1; %location of 1st high value in each run
endlocs = find(diff(isevent) == -1); %location of last high value in each run. Guaranteed to be different from startlocs.
%now detect an end before the 1st start. Also detects a single transition to high state with no end. Either way remove that 1st end
if ~isempty(endlocs) && (isempty(startlocs) || endlocs(1) < startlocs(1)) %this line relies on the short-circuiting behaviour of && and ||. The order of operations is critical
endlocs = endlocs(2:end);
end
%now detect a start after the last end. Also detects a single transition to low state with no start. Either way remove that last start
if ~isempty(startlocs) && (isempty(endlocs) || startlocs(end) > endlocs(end)) %this line relies on the short-circuiting behaviour of && and ||. The order of operations is critical
startlocs = startlocs(1:end-1);
end
%now you're guaranteed to have matching startlocs and endlocs.

More Answers (0)

Sign in to answer this question.

Products


Release

R2018b