function [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value)
% % find_previous_crossing: finds previous crossing above or below p_value
% %
% % Syntax:
% %
% % [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value);
% %
% % **********************************************************************
% %
% % Description
% %
% % The program "find_previous_crossing" will find the index of the data
% % point preceeding the data point wher the data array crosses p_value.
% %
% % Finds the previous crossing above or below p_value given a
% % multichannel input data time series p and a starting index p_index.
% %
% % The time record p has size [num_samples, num_channels]. The p_index is
% % the starting point
% %
% %
% %
% %
% % **********************************************************************
% %
% % Input variables
% %
% % p=randn(100000, 10); % time record of data samples
% % % default value is p=randn(100000, 1);
% %
% % p_index % index of starting point for
% % % finding previous crossing of p_value.
% % %
% % % default value is [maxy, p_index]=max(y, [], 1);
% %
% % p_value=0; % Threshold value for the crossing.
% % % default value is p_value=0;
% %
% %
% % **********************************************************************
% %
% % Output variables
% %
% % pc_ix is the index of the data sample before the previous crossing.
% %
% % pc_int is the interpolated fractional index of the previous crossing.
% %
% %
% % **********************************************************************
%
% Example='1';
%
% p=[1:0.1:10]; % time record of data samples
%
% p_index=5; % index of starting point for
% % finding previous crossing of p_value.
%
% p_value=2.01; % Threshold value for the crossing.
% % default value is p_value=0;
%
% [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value);
%
%
%
% Example='2';
%
% p=[10:-0.1:-100]; % time record of data samples
%
% p_index=80; % index of starting point for
% % finding previous crossing of p_value.
%
% p_value=2.56; % Threshold value for the crossing.
% % default value is p_value=0;
%
% [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value);
%
%
%
% % **********************************************************************
% %
% % find_previous_crossing was written by Edward L. Zechmann.
% %
% % date 6 August 2010
% %
% % modified 9 August 2010 Made program work with multiple
% % channels. Updated Comments
% %
% %
% %
% % **********************************************************************
% %
% % Please feel free to modify this code.
% %
% % See also: rise_time, find_previous_crossing, find_previous_ncrossings,
% % find_next_crossing, find_next_ncrossings
% % A_duration, B_mil_1474D_duration, B_Duration,
% % C_Duration, D_Duration
% %
if (nargin < 1 || isempty(p)) || ~isnumeric(p)
warning('need at least 1 input: using random numbers as input data');
p=randn(100000, 1);
end
% Make the data have the correct data type and size
[p]=convert_double(p);
% Make sure the matrix y is oriented correctly.
% Transpose if necessary.
[num_samples, num_channels]=size(p);
if num_samples < num_channels
p=p';
[num_samples, num_channels]=size(p);
end
if (nargin < 2 || isempty(p_index)) || any(~isnumeric(p_index))
[maxy, p_index]=max(y, [], 1);
end
p_index(p_index > num_samples)=num_samples;
p_index(p_index < 1)=1;
if (nargin < 3 || isempty(p_value)) || ~isnumeric(p_value)
p_value=0;
end
pc_ix=zeros(num_channels, 1);
pc_int=zeros(num_channels, 1);
for e1=1:num_channels;
% Set value of p2 for channel e1
p2=p(:, e1);
% Select p_value for channel e1
if length(p_value) >= e1
p_value_buf=p_value(e1);
else
p_value_buf=p_value(end);
end
% Shift p2 for channel e1
if p2(p_index) < p_value_buf
p2=-p2+p_value_buf;
else
p2=p2-p_value_buf;
end
% Select p_index for channel e1
if length(p_index) >= e1
pc_ix_buf=p_index(e1);
else
pc_ix_buf=p_index(end);
end
% make sure that p_index_buf is in range
if pc_ix_buf > length(p2)
pc_ix_buf=length(p2);
end
if pc_ix_buf < 1
pc_ix_buf=1;
end
% find start time for A-duration, which is the first zero-crossing before
% the peak pressure
flag1=0;
while (flag1 == 0) && (pc_ix_buf > 1)
pc_ix_buf = pc_ix_buf-1;
if p2(pc_ix_buf) <= 0
flag1=1;
end
end
% interpolate to find better begin time
if isequal(flag1, 0)
pc_ix_buf=[];
pc_int_buf=[];
else
if abs(p2(pc_ix_buf)-p2(pc_ix_buf+1)) >= 10^-12
pc_int_buf = (0-p2(pc_ix_buf))/(p2(pc_ix_buf+1)-p2(pc_ix_buf))+pc_ix_buf;
else
pc_int_buf=pc_ix_buf;
end
end
if ~isempty(pc_ix_buf)
pc_ix(e1)=pc_ix_buf;
pc_int(e1)=pc_int_buf;
end
end