# How to estimate the period of a pulse train?

I am trying to find the period of a pulse train like signal.

I have reviewed the following questions but I did not find a clear-cut answer to the problem, 12892, 16502, 6260.

I do not know the period nor the pulse width. I work with windows that will contain between 2 and 16 pulses. Pulses may vary in length but will usually be shorter than half the period. The signal may be noisy, although I would be happy with a solution for the case of the (relatively) clean signal. I can work out a minimal pulse width if it helps.

Here are plots of the type of signal I am working with.  I am primarily interested in the period of the signal. The analysis needs not to be online.

For the first example, I'm looking to find a result of about 136.5.

My first attempt was to look at the signal in the frequency domain. But a pulse train in time domain is also a pulse train in frequency domain. I got this plot for the clean signal. Next I tried autocorrelation. I got the following: It is much better. I need to get the value automatically though, and I'm not too sure how to find that second local maxima without introducing too much ad-hoc thresholds that may fail when there are more or less peaks in the window. Additionally, I'm looking for a floating point result. Also, the autocorrelation for the noisy signal was much less clear cut, even after smoothing the input.

There is probably another approach by detecting the rising edges in time domain?

Question:

• Is there a standard way to estimate the period of a pulse train?
• If autocorrelation is the right approach, how to automatically find the floating point coordinate of the peak from the autocorrelation result without too many assumptions?
• In case you will choose 'detecting the rising edges in time domain' approach. This post contains some filtering techniques, you may be interested in. – Nikolai Popov Apr 8 '15 at 9:08

If all you need to estimate is the period of your pulse train then you can threshold the original waveform and work on the clean one by detecting the rising and falling edges.

An FFT based approach would return an average estimate of its "frame of observation" anyway whose accuracy would depend on the length of the frame. (that is, an average estimate of the buffer that is passed at its input)

If you are concerned about the noise, use a short moving average filter (for instance a length 3 or length 5) to smooth the curve prior to estimating and applying the threshold. If absolute timings are essential for your application don't forget to take into account the group delay of the filter.

# Is there a standard way to estimate the period of a pulse train?

I have no answer to this part of the question. But I hope the algorithm, described below can be useful.

# If autocorrelation is the right approach, how to automatically find the floating point coordinate of the peak from the autocorrelation result without too many assumptions?

Consider next input signal: and its autocorrelation function $f[n]$: It can be described as $f[n] = s[n] + b[n]$, where $s[n]$ is the sequence of noisy peaks and $b[n]$ is base line: Using this model we can do the following:
1. Extract $b[n]$ from $f[n]$ using morphological opening (see appendix) with flat structuring element. (The width of the structuring element should be greater, than maximum possible width of the autocorrelation function's peak). 2. Estimate $s[n] = f[n] - b[n]$.
3. Calculate mean $m$ and standard deviation $\sigma$ of $s[n]$.
4. Define threshold $t = m + 2\sigma$ (or something just above noisy zero level).
5. Apply threshold $t$ to $s[n]$. 6. Find second ($p_{2}$) and third ($p_{3}$) points of intersection $s[n]$ with $t$.
7. Find perdiod $T$ (in samples) as index of the max element between $p_{2}$ and $p_{3}$.

# Appendix. Morphological opening.

Opening ($\circ$) of a function $f: D\subset{\rm I\!R}\to{\rm I\!R}$ is defined as:

$f \circ g_{s} = (f \ominus g_{s}) \oplus g_{s}$,

where $g_{s}: G_{s}\subset {\rm I\!R}\to{\rm I\!R}$ is a structuring element of length $s$ and the $\oplus$ (dilation) and $\ominus$ (erosion) operations are defined as:

Dilation: $(f \oplus g_{s})(x) = \max_{ t\in(G_{s}\cap D_{x})} (f(x-t) + g_{s}(t))$
Erosion: $(f \ominus g_{s})(x) = \min_{ t\in(G_{s}\cap D_{x})} (f(x+t) - g_{s}(t))$

where $D_{x}$ is $D$ translated by $x$.

I can offer the following algorithm:

1. Calculate the autocorrelation of signal.
2. Find the positions of the maximums in the autocorrelation - $t_i$. Rejecting false peaks by some algorithms (by threshold?)
3. Ideally it must be $t_i=i*T$, where $T$ is period of pulse train. Your data has some errors, so use linear regression to calculate $T$ and to estimate errors.

I think you can use standart method of fitting data to Straight Line. See for example explanation in 15.2 of "Numerical Recipes in C" http://apps.nrbook.com/c/index.html (page 661-662)