Skip to content

ntpstats.hat

Separate the stability of each clock (or server) from pairwise differences.

With three or more sources and no better reference, only differences are observable. A client that measures several NTP servers gets o_i = x_i - x_client; in o_i - o_j the client's own noise cancels, so the same methods apply to ntpstats monitor logs.

  • Three-cornered hat (Gray & Allan 1974): σ²_A = (σ²_AB + σ²_AC - σ²_BC) / 2. Negative results are possible when the sources' noise levels differ a lot or are correlated; they are flagged, not hidden.
  • N-cornered hat: least squares over all pairs (σ²_ij = σ²_i + σ²_j).
  • Groslambert covariance (Vernotte, Lantz et al.): σ²_A is the cross-covariance of the Allan-filtered differences AB and AC, averaged over all pairs of other sources. For three sources and the same terms the estimate equals the three-cornered hat exactly (polarisation identity; see Vernotte, Calosso & Rubiola, IFCS 2016). What differs is the uncertainty: the covariance view gives an interval that holds its coverage when one source dominates, where propagating pairwise variances does not.

Confidence intervals propagate the variance of each pairwise estimate (2σ⁴/EDF, EDF as in :mod:ntpstats.edf) or, for the covariance, Var(z₁z₂) = E[z₁²]E[z₂²] + E[z₁z₂]² with the same effective number of terms; correlation between pairs is neglected, so they are approximate.

HatResult dataclass

dev property

Individual ADEV; NaN where the variance estimate is negative.

align(series, tau0=None, max_gap=3.0)

Common uniform grid over the overlap; NaN where a source has no sample within max_gap intervals.

hat(X, tau0, names=None, method='gcov', taus='octave', ci=0.683)

Individual Allan variances of the N sources in the rows of X (phase, s; NaN = gap).

hat_series(series, method='gcov', tau0=None, max_gap=3.0, taus='octave', ci=0.683)

:func:hat on offset series measured by one client (or against one reference).