Skip to content

ntpstats.trace

Delay traces: real per-direction network delays that drive the simulator.

The synthetic paths of :mod:ntpstats.simulate (a floor plus exponential queueing) are a model. A trace is the delay a real network imposed: extract it from a capture or a log, then replay it under a simulated clock whose true offset is known, so that estimators are scored on real network behaviour (#29).

Extraction

Every two-way exchange (NTP or PTP, from a capture or a daemon log) gives the measured offset θm (reference − local) and the round-trip delay δ. The raw one-way delays are δ/2 + θm (local to reference) and δ/2 − θm (reference to local). They still contain the true offset θ between the two clocks, which moves as the clocks wander, so θ is estimated and removed ("detrended"):

  • floor (default): in each window, the exchange with the smallest round trip is taken as symmetric, its offset is θ; θ is interpolated between windows. This follows the clock's wander and is how the NTP clock filter and Huygens-style estimators reason.
  • linear: one straight line (Theil–Sen) through those minimum-delay offsets, for clocks with a steady frequency offset.
  • none: θ = 0, for captures where both ends were synchronised (for example a capture host disciplined by PTP or GNSS).

The absolute asymmetry of a path cannot be measured from two-way timestamps alone; the trace assumes equal floor delays unless asymmetry (forward floor − backward floor) is given. The queueing variation (PDV) and its correlation between directions are kept.

Replay

:class:TracePath feeds a trace to the simulator, either in time order (replay, looping if the run is longer) or as a moving-block bootstrap (bootstrap) that draws random blocks of block seconds, keeping the short-term correlation and both directions together, so every seed sees a different but statistically similar network.

DelayTrace dataclass

One-way delays of a path, seconds; NaN marks a lost exchange.

to_ref is local → reference (the client → server direction of NTP, slave → master of PTP); from_ref is the other direction. t is seconds from the start of the trace.

stats()

Floors, percentiles and PDV of both directions, loss and the assumptions made.

to_series(epoch=0.0)

As a series: offset (reference − local) is what a perfect clock would have measured.

to_csv()

CSV (unix_time,offset,delay,to_ref,from_ref) that :func:load_trace reads back.

TracePath dataclass

A :class:DelayTrace as the network of a simulated scenario (both directions together).

mode="replay" plays the trace in time order (looping); bootstrap concatenates random blocks of block seconds (default: 64 exchanges or the trace duration / 8, whichever is shorter), a moving-block bootstrap that keeps short-term correlation. scale multiplies the queueing part (delay above each direction's floor), to ask "what if the network were twice as loaded?".

delays(rel, rng)

One-way delays (to_ref, from_ref) at simulation times rel (s from the start); NaN = lost.

from_series(series, detrend='floor', window=None, asymmetry=0.0, name=None)

Extract a :class:DelayTrace from any series with an offset and a round-trip delay column.

Works for NTP and PTP captures, chrony measurements.log, ntpd peerstats/rawstats and simulator output. A series that already has to_ref/from_ref columns (an exported trace) is taken as is.

load_trace(path, peer=None, fmt='auto', detrend='floor', window=None, asymmetry=0.0)

Load a capture or log (any format with two-way exchanges) and extract its delay trace.

trace_path_from_dict(d, base_dir='.')

[trace] table of a scenario file: file, peer, mode, block, scale, detrend, window, asymmetry (a relative file is relative to the scenario file).