ntpstats.disciplines¶
Clock-discipline models for the research bench: ntpd's loop and Levine's NIST algorithms.
Like the ptp4l and sptp estimators, each model steers a clock in
closed loop on the free-running clock of a scenario: the steered clock reads
local + c(t), every measurement is seen as the residual
offset - c(t), and the correction c(t) at each measurement time is the
estimate of the offset (reference - local). Steering does not change the
measurement noise, so this is the closed loop exactly.
ntpd
The daemon clock discipline of the NTP reference implementation (ntpd
4.2.8, ntpd/ntp_loopfilter.c, without the kernel PLL): the clock
filter (minimum delay of the last eight samples, used only when newer than
the last update; among equal delays the newest, as the RFC's sort keeps
it first; during the startup clamp, when ntpd does not sort, the newest
sample; samples older than the Allan intercept ranked by delay plus their
grown dispersion), the popcorn spike suppressor of ntp_proto.c (a new
best sample whose offset differs from the previous one by more than three
times the filter jitter, less than two poll intervals after the last sample
used, is ignored), the state machine (NSET, FREQ, SYNC, SPIK; step
threshold 128 ms, stepout 300 s), the hybrid PLL/FLL frequency update and
the phase adjustment once per second, with the total slew (frequency plus
phase) bounded at 500 ppm as in adj_host_clock(). constants="rfc5905" uses the constants and
gain formulas of the RFC 5905 appendix (A.5.5.6, A.5.6.1) instead: PLL gain
65536, FLL gain 1/(18 - poll), Allan intercept 1500 s, stepout 900 s, the
phase adjusted by offset/(PLL min(2^poll, 1500 s)) per second, without
the 500 ppm bound on the slew (the appendix's clock_adjust() has none).
The clock filter, popcorn suppressor and state machine are ntpd's in both
cases. (The appendix's own suppressor, A.5.2, compares the interval in
seconds with twice the poll exponent and sums the squared offset
differences without averaging; ntpd's version is used instead.)
The time constant (poll exponent) is fixed at the measurement interval,
as with minpoll = maxpoll; popcorn=False turns the suppressor off.
lockclock
J. Levine's frequency-lock loop for the NIST time servers, as described in
J. Res. NIST 125:125008 (2020), section 6: a five-point majority vote on the
measurements of each cycle; time-adjustment mode while the residual
exceeds 3 sigma; otherwise a frequency estimate y = dx/T (Eq. 3) averaged
as ybar = (y + k ybar) / (k + 1) (Eq. 5) plus a phase correction that
removes dx over the next cycle; and the outlier rule of section 7 (the
frequency is not updated when its innovation exceeds three times the mean
innovation of the preceding cycles). Defaults are the paper's network
configuration: a cycle of about 1000 s and k = 1.
levine-kalman
LOCKCLOCK with the scalar Kalman time estimate of J. Levine, PTTI 2011
("Synchronizing computer clocks by the use of Kalman filters", Eq. 5): the
phase correction applies only the fraction sigma_o^2 / (sigma_o^2 +
sigma_t^2) of the residual, where sigma_t^2 is the variance of the
measurement (link) noise (the 1-sample deviation used by the vote) and
sigma_o^2 that of the clock's time dispersion over one cycle. As in the
paper, the Kalman filter estimates only the time state; the frequency
comes from the LOCKCLOCK loop (Eq. 3 then uses the time difference left
after the previous partial correction). Levine measured
sigma_o^2 = <(x_k - x_k^-)^2> (his Eq. 4) with a reference of negligible
noise; without one, the model estimates it online as the mean square of
the last eight cycle residuals (whose variance is sigma_o^2 + sigma_t^2)
minus sigma_t^2, unless sigma_o is given.
These are models written from the published code and papers, not the programs themselves.
ntpd_discipline(series, constants='ntpd', poll=None, initial_frequency=None, stages=8, popcorn=True)
¶
ntpd's clock discipline in closed loop (see the module docstring).
poll is the time constant exponent (log2 s; default: the measurement
interval). initial_frequency (s/s) starts in FSET state as if a drift
file existed; otherwise the loop starts in NSET and measures the frequency
directly after the stepout interval. popcorn enables ntpd's popcorn
spike suppressor.
lockclock(series, cycle=1024.0, k=1.0, sigma=None, points=5, max_rate=MAXFREQ, kalman=False, sigma_o=None)
¶
Levine's LOCKCLOCK frequency-lock loop (J. Res. NIST 2020, section 6), or with kalman=True its
scalar Kalman time estimate (PTTI 2011). See the module docstring.
cycle is the interval between frequency updates (s), k the averaging constant of Eq. 5, sigma
the 1-sample time deviation used by the vote and the 3-sigma tests (default: estimated robustly from the
first differences of the measurements), points the measurements voted on per cycle.
In time-adjustment mode the paper adjusts every second, so the clock's frequency error is negligible between adjustments. With the bench's longer measurement intervals it is not, so in that mode the model adjusts at every measurement and also estimates the frequency from successive residuals (Eq. 3 and 5); without that, a clock with a large frequency offset would never leave the time-adjustment mode.