How to extract event start and finish indices by finding rising edges and falling edges of an array?
110 views (last 30 days)
Show older comments
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;
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.
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);
%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);
%now you're guaranteed to have matching startlocs and endlocs.
More Answers (0)
Find more on Number Theory in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!Start Hunting!