%% Measure Pulse and Transition Characteristics of Streaming Signals
% This example measures the pulse and transition metrics of a noisy rectangular pulse. Pulse metrics include rise time, fall time, pulse width, and pulse period. Transition metrics include middle-cross events, overshoot, and undershoot of the posttransition aberration regions of the noisy rectangular pulse.
%% Generate a Rectangular Pulse
% Generate a noisy rectangular pulse. The noise is a white Gaussian noise with zero mean and a standard deviation of 0.1. Store the data in rectData.

t = 0:.01:9.99;   % time vector 
w = 1; % pulse width
d = w/2:w*2:10; % delay vector
y2 = pulstran(t,d,'rectpuls',w); 
rectData = y2'+0.1*randn(1000,1); % rectangular pulse with noise
plot(rectData);
xlabel('Samples');
ylabel('Level (volts)');

%
%% Measure State Levels
% The dsp.StateLevels System object uses the histogram method to estimate the state levels of a bilevel waveform. The histogram method involves the following steps:
% Determine the maximum and minimum amplitudes of the data.
% For the specified number of histogram bins, determine the bin width, which is the ratio of the amplitude range to the number of bins.
% Sort the data values into the histogram bins.
% Identify the lowest indexed histogram bin and the highest indexed histogram bin with nonzero counts.
% Divide the histgram into two subhistograms.
% Compute the state levels by determining the mode or mean of the upper and lower histograms.
% Plot the state levels of the rectangular pulse.

sLevel = dsp.StateLevels;
levels = sLevel(rectData);
figure(1);
plot(sLevel);

%
%% Compute Pulse Metrics
% Using the dsp.PulseMetrics System object, you can compute metrics such as the rise time, fall time, pulse width, and pulse period of the rectangular pulse. Plot the pulse with the state levels and reference levels.

pMetrics = dsp.PulseMetrics('StateLevels',levels,'CycleOutputPort',true);
[pulse,cycle] = pMetrics(rectData);
plot(pMetrics);
xlabel('Samples');

%
% Rise Time is the duration between the instants where the rising transition of each pulse crosses from the lower to the upper reference levels. View the rise time of each pulse.

pulse.RiseTime

%
% Fall time is the duration between the instants where the falling transition of each pulse crosses from the upper to the lower reference levels. View the fall time of each pulse.

pulse.FallTime

%
% Width is the duration between the mid-reference level crossings of the first and second transitions of each pulse. View the width of each pulse.

pulse.Width

%
% Period is the duration between the first transition of the current pulse and the first transition of the next pulse. View the period of each pulse.

cycle.Period

%
%% Polarity
% The Polarity property of the pMetrics object is set to 'Positive'. The object therefore computes the pulse metrics starting from the first positive transition.
%% Running Metrics
% If the RunningMetrics property is set to true, the object treats the data as a continuous stream of running data. If there is an incomplete pulse at the end, the object returns the metrics of the last pulse in the next process step, once it has enough data to complete the pulse. If the  RunningMetrics property is set to false, the object treats each call to process independently. If the last pulse is incomplete, the object computes whatever metrics it can return with the available data. For example, if the pulse is half complete, the object can return the rise time of the last pulse, but not the pulse period.
% Given that the polarity is positive and the running metrics are set to false, the rectangular pulse has:
% The first positive transition at 200 seconds
% Three complete pulses and two incomplete pulses (first and the last)
% Four positive transitions and four negative transitions
% Depending on the metric, the number of elements in the metric vector is equal to either the number of transitions or the number of complete pulses. The rise time vector has four elements, which matches the number of transitions. The cycle period has three elements, which matches the number of complete pulses.
% Set the RunningMetrics property to true.

release(pMetrics);
pMetrics.RunningMetrics = true;
[pulse,cycle] = pMetrics(rectData);
plot(pMetrics);
xlabel('Samples');

% The pMetrics object has three positive transitions and three negative transitions. The object waits to complete the last pulse before it returns the metrics for the last pulse.
%
% Divide the input data into two frames with 500 samples in each frame. Compute the pulse metrics of the data in running mode. The number of iteration loops correspond to the number of data frames processed.

release(pMetrics);
framesize = 500;
for i = 1:2
    data = rectData((((i-1)*framesize)+1):i*framesize);
    [pulse,cycle] = pMetrics(data);
    pulse.RiseTime
end

% The first frame contains one complete pulse and 2 incomplete pulses. The rise time value displayed in the first iteration step corresponds to the rising transition in this complete pulse. The rise time of the last complete pulse is not displayed in this iteration step. The algorithm waits to complete the pulse data. The second data frame contains the remaining part of this pulse and another complete pulse. The rise time vector in the second iteration step has two elements - first value corresponds to the rising transition of the incomplete pulse in the previous step, and the second value corresponds to the rising transition of the complete pulse in the current step.
%
%% Compute Transition Metrics
% The transition metrics correspond to the metrics of the first and second transitions. Using the dsp.TransitionMetrics System object, you can determine the middlecross events, and compute the post-overshoot and post-undershoot of the rectangular pulse. To measure the postshoot metrics, set the PostshootOutputPort property of  dsp.TransitionMetrics to true.

tMetrics = dsp.TransitionMetrics('StateLevels',levels,'PostshootOutputPort',true);
[transition,postshoot] = tMetrics(rectData);
plot(tMetrics);
xlabel('Samples');

%
% Middle-cross events are instants in time where the pulse transitions cross the middle reference level. View the middle-cross events of the pulse.

transition.MiddleCross

%
% Overshoots and undershoots are expressed as a percentage of the difference between state levels. Overshoots and undershoots that occur after the posttransition aberration region are called post-overshoots and post-undershoots. The overshoot value of the rectangular pulse is the maximum of the overshoot values of all the transitions. View the post-overshoots of the pulse.

postshoot.Overshoot

%
% The undershoot value of the rectangular pulse is the minimum of the undershoot values of all the transitions.

postshoot.Undershoot

% Copyright 2012 The MathWorks, Inc.