ntpstats.estimators¶
Pluggable clock-offset estimators for benchmarking synchronisation algorithms.
An estimator turns noisy measurements into an estimate of the true offset (reference - local) at the measurement times::
class MyEstimator(Estimator):
name = "mine"
def fit(self, series): # TimeSeries -> TimeSeries
...
register(MyEstimator())
Third-party packages can expose estimators through the entry-point group
ntpstats.estimators (value: an :class:Estimator instance, class or
factory); they are picked up by :func:available and ntpstats bench.
Multi-server estimators set multi = True and receive a list of series
(one per server); they return one combined series.
Built-in reference algorithms
raw the measurements themselves
kalman two-state Kalman filter (no delay information)
kalman-dw Kalman filter with delay-weighted measurement noise
rts-dw RTS smoother, delay weighted (offline optimum for the model)
mindelay NTP clock filter: minimum delay of the last 8 samples (RFC 5905 s10)
regression chrony-style weighted linear regression over a window sized
by a runs test on the residuals
feedforward RADclock-style: rate from long-baseline low-RTT packets,
offset from a quality-weighted recent window
rfc5905 (multi) clock filter + selection (intersection), cluster and
combine algorithms of RFC 5905 s11
median (multi) median of the servers' clock-filter outputs
regression(series, max_samples=64, min_samples=6, sigma=None)
¶
Causal weighted linear regression per sample, chrony style.
Weights are 1 / (sigma^2 + q^2) with q the queueing error bound;
the window shrinks (dropping the oldest half) while the residual signs
fail a runs test, i.e. while a straight line no longer describes the
recent phase (frequency change).
feedforward(series, rate_window=6 * 3600, offset_window=16, e_star=None)
¶
Feed-forward estimator in the spirit of RADclock (Veitch, Ridoux et al.).
- rate: slope between low-RTT packets separated by a long baseline
(causal, up to
rate_windowseconds back), robust to queueing; - offset: for each sample, quality-weighted average of the last
offset_windowrate-corrected offsets, weightsexp(-(q / E*)^2).
rfc5905_combine(series_list, nmin=1, maxclock=3, dispersion=0.001)
¶
Selection, cluster and combine (RFC 5905 s11.2) over several servers.
At each epoch (times of the first server) the latest clock-filter output
of every server gives an offset and a root distance
lambda = delay/2 + dispersion + jitter. The intersection algorithm
keeps the truechimers, the cluster algorithm prunes outliers by selection
jitter down to maxclock survivors, and the survivors are combined
weighted by 1/lambda.