MATLAB: Finding runs of a signal where enabling conditions are met.


Dear all,
I have two long data vectors which are slightly delayed.
I am trying to find the delay time each time, a third variable of TRUE (1). In the picture below a screenshot of the data, where the grey signal is slightly delayed, and the pink signal the enabling condition.
To find the delay time, I am thinking of finding the gradient of the two signals and compare them. I then want to find the maximum value of the signal and find the 63% value which will give me tau.
Finding the gradient of the signals:
signal_1_gradient = diff(signal_1)./diff(time)
signal_2_gradient = diff(signal_1)./diff(time)
For filtering the gradient signal:
b = (1/6)*ones(1,6);
a = 1;
signal_1_gradient_filt = filter(b,a,signal_1);
signal_2_gradient_filt = filter(b,a,signal_2);
And finding the index where enabling conditions are met:
index = find(enabling_conditions == 1)
signal_1_gradient_filt = signal_1_gradient_filt(index)
signal_1_gradient_filt = signal_1_gradient_filt(index)
It would be easiest for me, if I get multiple short vectors (in a structure) with all the periods where the enabling conditions were met. But I cannot find out how to split the vectors once I found the total index where enabling conditions were met.
From this I think it's not so hard to find the gradients for each phase.
Thanks a lot, and please ask me if something is not clear.

Best Answer

  • First, in your example, you don't need the find. A logical array would work just as well:
    index = enabling_conditions == 0; %shouldn't it be == 1?
    If I understood correctly, you want to find the start and end of each run of 1 (or is it 0?) in your enabling_conditions, and split the signals arrays into each run:
    transitions = diff([0 enabling_conditions 0]); %assuming enabling_conditions is a row vector, and you want to find the runs of 1
    %transitions is 1 when going from false to true and -1 when going from true to false. 0 otherwise
    startruns = find(transitions == 1);
    endruns = find(transitions == -1);
    %because enabling_conditions was flanked with 0 in the diff, startruns and endruns are guaranteed to have the same number of elements.
    %now split the signal according to start and end of each run:
    subsignals_1 = arrayfun(@(s, e) signal_1_gradient_filt(s:e), startruns, endruns, 'UniformOutput', false)
    subsignals_2 = arrayfun(@(s, e) signal_2_gradient_filt(s:e), startruns, endruns, 'UniformOutput', false)
    Note that I put the vectors into a cell array rather than a structure. I think it makes more sense. You can convert the cell array into a structure with cell2struct but naming the fields is going to be an issue.