Klokloggegevensformaten
src/clock_log.rs leest een gemeten klokloggegevensbestand in tot één genormaliseerde fasereeks: een uniform raster van samples (time_s, phase_s), met het steekproefinterval tau0 opgegeven of gevonden, elk hiaat geteld en de eenheden van het log benoemd. Er worden acht formaten gelezen, elk een gedocumenteerde deelverzameling. Alles buiten die deelverzameling wordt geweigerd met een fout die benoemt wat is aangetroffen, in plaats van bij benadering te worden gelezen.
Afkortingen. RINEX is het Receiver Independent Exchange Format. TICC is de tijdintervalteller van TAPR (Tucson Amateur Packet Radio). ADEV is de overlappende Allan-deviatie, TDEV de tijdsdeviatie en MTIE de maximale tijdintervalfout. tau0 is het steekproefinterval in seconden.
Waar een log kan worden gebruikt#
telecom-timing:[series.clock_log]in plaats vanseries.samplesofseries.csv_path. De fase van het log, in ns, is de tijdfoutreeks die aan de maskers wordt getoetst, en het rapport krijgt een blokclock_logdat zegt hoe het is gelezen.- Het type clock: een tabel
[clock_log]voegt een blokmeasuredaan de run toe: hoe het log is gelezen, de SHA-256 van de tabel (input_sha256; descenario_hashvan de run omvat de tabel niet) en van de fasesamples, en de overlappende ADEV, TDEV en MTIE bij octaafmiddelingsfactoren. Hiervoor isruns = 1nodig. De gesimuleerde holdover is ongewijzigd.
Zonder de tabel worden beide typen geparst, gehasht en gerapporteerd zoals voorheen.
[clock_log] # or [series.clock_log] in a telecom-timing scenario
format = "ticc" # "rinex-clk", "timelab", "ticc", "ptp4l", "phc2sys", "ts2phc",
# "chrony-tracking" or "chrony-statistics"
path = "logs/ticc.txt" # or text = "..." inline (the only choice in WebAssembly)
channel = "chA" # TICC: needed when the log holds more than one channel
gaps = "linear" # "refuse" (default), "longest" or "linear"
# clock = "G08" # RINEX, linuxptp, chrony: needed when the log holds more than one clock or source
# tau0_s = 1.0 # overrides a header and the detected spacing
# units = "ns" # TimeLab phase units: s (default), ms, us, ns, ps
# data = "phase" # TimeLab: phase (default) or frequency
De formaten#
rinex-clk: RINEX-klokbestanden, versies 2,00 en 3,00 tot 3,04 (inclusief het naamveld van negen tekens van 3,04). Het record RINEX VERSION / TYPE wordt gecontroleerd en elke andere versie wordt geweigerd, met de gevonden versie genoemd: IGS publiceert het klokformaat (rinex_clock300.txt, 302, 304) tot 3,04, en de documenten van RINEX 4,00, 4,01 en 4,02 definiëren alleen observatie-, navigatie- en meteorologische bestanden, dus er is geen versie 4,00 van het klokbestand om te lezen. De header wordt alleen gelezen voor zijn TIME SYSTEM ID en overgeslagen tot END OF HEADER. Van de datarecords worden alleen de records AS (satelliet) en AR (ontvanger of station) van één klok, op naam gekozen, bewaard. Hun eerste waardeveld, de klokbias in seconden, is de fase. Vervolgregels en de records CR, DR en MS worden overgeslagen. Epochen zijn de kalendervelden van het record, als seconden vanaf 1980-01-06 00:00:00 in het eigen tijdsysteem van het bestand, zonder omzetting.
timelab: ASCII-fase- of frequentielogs in TimeLab-stijl, de platte tekstvorm die TimeLab exporteert en die de ASCII-import ervan en Stable32 lezen. Er staat één meting per regel: ofwel één kolom met een uniforme tau0, ofwel twee kolommen time value. Kolommen kunnen worden gescheiden door witruimte, komma's of puntkomma's.
- Regels die beginnen met
#,;of%zijn commentaar. Een commentaar van de vormkey = value(ofkey: value) stelttau0(s),units(s,ms,us,nsofps, voor fase),data(phaseoffrequency) oftime_units(sofmjd, voor de eerste van twee kolommen) in. - Eén voorafgaande niet-numerieke regel wordt als kolomkop beschouwd.
- Frequentiegegevens (fractionele frequentie) worden alleen als enkele kolom geaccepteerd. Ze worden geïntegreerd tot fase als
x[i+1] = x[i] + y[i]·tau0(NIST SP 1065, 2008, §4,1). - De binaire en
.tim-projectbestanden van TimeLab worden niet gelezen.
ticc: logs van de TAPR TICC-teller (TICC Operation Manual, revisies van 23 november 2016 en 15 december 2025, "measurement modes"). Elk gegevensveld is seconden met 12 decimalen (11 standaard vanaf firmware 20251101: elk aantal tot 15 wordt gelezen). Een tijdstempel wordt uit zijn decimale tekst gelezen als een geheel aantal femtoseconden, niet als binaire float, zodat de fase van een log die dagen na het starten van de teller is genomen de eigen resolutie van de teller behoudt: een f64-tijdstempel bij 3.0e5 s heeft een afstand van 5.8e-11 s, ongeveer de 60 ps van de teller.
- Regels in timestampmodus (
<seconds> chA,<seconds> chB) en het pseudo-timestampkanaal van de TimeLab-modus (chC) zijn tijdstempels van gebeurtenissen. De fase van het gekozen kanaal is zijn tijdstempel min de nominale tik:x[k] = t[k] − t[0] − n[k]·tau0, waarbijn[k]het gehele aantaltau0sinds de eerste gebeurtenis is. Een gemiste gebeurtenis is een hiaat. - Regels in intervalmodus (
<seconds> TI(A->B), of elk label dat metTIbegint) worden rechtstreeks als fase gelezen, één meting pertau0. Het scenario moettau0_sopgeven, omdat de regel geen tijd bevat. - De modus Paired Timestamp drukt dezelfde regels af in kanaalvolgorde en wordt gelezen als modus Timestamp; de modus 3-Corner Hat voegt het gesynthetiseerde
chCtoe, gelezen zoals hierboven. - Uitvoer van de modi Period en Debug wordt geweigerd. Een kanaal waarvan de metingen niet oplopen wordt gemeld als modus Period. De binaire modus Timestamp is geen tekst, en een bestand ervan wordt geweigerd met een melding die dat zegt.
- Regels die met
#beginnen en regels die niet<number> <label>zijn (zoals het opstartmenu) worden overgeslagen en geteld.
logs van linuxptp en chrony#
Deze vijf formaten lezen wat een draaiende tijddaemon over zijn eigen klok schrijft. Ze dienen om achteraf een tijdsynchronisatieketen te controleren (een boundary clock, de PHC van een grandmaster, een chrony-client) met dezelfde schatters als de andere logs. Ze lezen geen configuratie van een daemon, en niets hier communiceert met een daemon.
ptp4l, phc2sys, ts2phc: de servoregels van linuxptp, waarbij elk formaat alleen regels van zijn eigen programma leest. Een meting is een regel van de vorm
ptp4l[5003.000]: master offset 40 s2 freq +1480 path delay 497
phc2sys[7000.000]: CLOCK_REALTIME phc offset -30 s2 freq +100 delay 1200
ts2phc[8000.000]: /dev/ptp0 offset 3 s2 freq -2
- De tijdstempel is de eerste
[seconds.fraction]in de regel (de monotone klok van de daemon). Hij wordt ook gelezen na een syslog-voorvoegsel, waarbij een proces-id zoalsptp4l[812]:geen fractie heeft en niet wordt overgenomen. - De fase is de gelogde
offset, in nanoseconden, omgerekend naar seconden. Het is de door de daemon gemeten tijdfout van zijn slave-klok ten opzichte van zijn referentie, zoals gelogd: positief als de slave voorloopt. Het is de fout die onder servoregeling overblijft, niet de drift van een vrijlopende klok. - De woorden tussen de tijdstempel en
offsetbenoemen de bron (master,eth0 mastervoor een voorvoegsel[eth0],CLOCK_REALTIME phc,/dev/ptp0). Een log met meer dan één bron heeftclock = "<that text>"nodig; de fout somt ze op. - Metingen voordat de servo voor het eerst
s2(vergrendeld) meldt, worden weggelaten en geteld inn_skipped_lines:s0ens1zijn de ontgrendelde toestand en de staptoestand, waarvan de offsets overgangsverschijnselen bij het invangen zijn. Een servo dies2nooit bereikt, wordt geweigerd. Een regel zonder toestandsveld wordt gelezen zoals hij is. - Samenvattingsregels (
rms ... max ...), berichtendelayenselected best masteren regels van andere programma's worden overgeslagen en geteld. - Tijdstempels die teruglopen (een herstarte daemon) worden geweigerd; splits het log.
chrony-tracking, chrony-statistics: de bestanden log tracking en log statistics van chrony, gelezen op kolompositie. Een meting is een regel met ten minste 14 kolommen (tracking) of 13 (statistics) die begint met een UTC-datum en -tijd van de vorm YYYY-MM-DD HH:MM:SS. De regel met kolomkoppen wordt overgeslagen en geteld; de ====-lijn eronder wordt overgeslagen zonder te worden geteld.
- Tracking: kolom 7, de lokale offset bij de klokupdate, in seconden. Het IP-adres of de referentie-id verandert met de geselecteerde bron, dus zonder
clockwordt elke regel als één lokale klok gelezen.clock = "<id>"houdt één referentie-id aan. - Statistics: kolom 5, de geschatte offset van een bron, in seconden. Er is één reeks per bronadres, en het log heeft
clock = "<address>"nodig als het er meer dan één bevat. - Tijdstippen zijn seconden vanaf 1980-01-06 00:00:00 UTC, zonder verwerking van schrikkelseconden. Chrony schrijft een regel per update of per bronsample, dus de tussenruimte is niet uniform.
tau0is de mediane tussenruimte; een meting binnen een halvetau0na de laatst bewaarde wordt weggelaten en geteld inn_duplicates, en een grotere tussenruimte is een hiaat, datgaps = "refuse"meldt. Geeftau0_sengaps = "linear"op voor een log met een vast pollinginterval.
De kolommen van chrony en de regelindelingen van linuxptp zijn die uit de openbare documentatie van de daemons. De fixtures in tests/fixtures/clock_log/linuxptp_chrony/ zijn voor Kshana geschreven met verzonnen waarden (zie de NOTICE.md ervan); er is geen echt log gelezen, dus een indeling die tussen daemonversies verschilt, kan nog steeds worden geweigerd of verkeerd gelezen. Een regel die niet overeenkomt, wordt overgeslagen en geteld, nooit geraden.
tau0 en hiaten#
Als het log tijdstempels bevat en er geen tau0 is opgegeven, is tau0 de mediane tussenruimte van opeenvolgende tijdstempels, afgerond op vier significante cijfers, en wordt de bron gemeld als median-spacing. De tussenruimte van een teller wijkt van de nominale af met de frequentie-offset van de referentie, ten hoogste delen op 10^6. Een tau0_s in het scenario wint altijd (bron input), daarna een commentaar tau0 in de header (bron header).
Samples worden op het raster t0 + i·tau0 geplaatst, en een ontbrekend tijdstip is een hiaat. Metingen die meer dan 1 % van tau0 naast het raster liggen, worden weggelaten en geteld, evenals duplicaten (de eerste blijft). Het hiaatbeleid is een van de volgende:
refuse(de standaard): elk hiaat is een fout die de hiaten telt;longest: houd de langste hiaatvrije reeks;linear: vul interne hiaten door lineaire interpolatie en meld het aantal gevulde.
De schatters hebben een hiaatvrije opname nodig, en daarom worden hiaten hier opgelost.
Uw eigen klok#
Een tabel [clock_log] bij de soort klok meldt hoe stabiel uw eigen klok was, naast de simulatie: scenarios/clock-measured-log.toml (kshana example clock-measured-log) is clock-holdover.toml met een uittreksel van 96 metingen van een IGS-satellietklok als inline TimeLab-log. Vervang text door path en format voor uw eigen bestand. Het blok measured in het resultaat bevat hoe de log is gelezen (formaat, tau0 en waar hij vandaan komt, elke onderbreking) en zijn ADEV, TDEV en MTIE; het wijzigt de simulatie niet.
De holdover aansturen met uw eigen klok: [clock_fit]#
[clock_log] # the measured series, as above
format = "ticc"
path = "my-clock.txt"
channel = "chA"
[clock_fit]
replaces = "classical" # or "quantum": the simulated clock whose noise the log replaces
De log wordt gefit met de apparaatkaartprocedure van src/clock_library/card.rs (conditionering, kwadratische component verwijderd, ruisidentificatie met lag-1, gewogen kleinste kwadraten in witte PM, witte FM, flicker-FM en random-walk-FM bij de middelingstijden met ten minste 30 vrijheidsgraden). De genoemde klok neemt dan q_wf = h_0 / 2, q_rw = 2 pi^2 h_-2, flicker_floor = sqrt(2 ln 2 h_-1) en de gefitte drift over; y0 blijft zoals het scenario het heeft, omdat een log de offset van zijn referentie draagt, niet van de klok na sturing. Witte faseruis wordt gefit en gerapporteerd maar niet gesimuleerd. Het resultaat krijgt een blok fitted (de coëfficiënten, de fitpunten, de waarden die de run gebruikte, wat is weggelaten, de SHA-256 van de log) en de klok draagt de id measured:<12 hex of the phase hash>. Met runs > 1 trekt het ensemble uit de gefitte klok (het blok measured vereist runs = 1). Een fit zonder frequentieruis, een log die te kort is om te fitten en een replaces anders dan quantum of classical zijn fouten die dat zeggen. scenarios/clock-fitted-log.toml is een voorbeeld (6 uur van een IGS-satellietklok).
Wat de vergelijking op bekende ruis (tests/fixtures/clock_fit/RESULTS.md) laat zien, en wat u in gedachten moet houden:
- Gehaald: het niveau van de witte FM wordt binnen 5 % teruggevonden op elk synthetisch record dat het heeft; de gefitte kaart reproduceert de ware Allan-deviatie binnen een factor 1,35 bij elke middelingstijd waarbij is gefit; de ruisexponent die de fit identificeert is gelijk aan die van allantools in elk punt (op het record van de 5071A, zodra de fasesprong die de conditionering verwijdert ook uit de invoer van allantools is verwijderd).
- Niet gehaald, en vastgezet door de test: random-walk-FM wordt alleen teruggevonden wanneer die de langste middelingstijden van het record domineert, en zelfs dan in één van de drie records van een reeks van 131.072 s met een kruising bij 3.000 s heeft de fit hem aan flicker-FM en aan de drift toegekend. De scheiding tussen random-walk-FM en flicker-FM is uit één record niet betrouwbaar. De run reproduceert de stabiliteit van de log over de middelingstijden die de log dekt; daarbuiten lopen de twee keuzes uiteen (flicker-FM is een constante bodem, random-walk-FM groeit als de wortel van de middelingstijd).
- MODELLED: een wat-als voor de ruis van die klok zoals de log hem toont, geen kalibratie van de klok en geen voorspelling van zijn toekomstige gedrag.
Een misvormde log is een fout die noemt wat is aangetroffen (de regel, de versie, de ontbrekende selector), nooit een gedeeltelijk resultaat: tests/clock_log_real_allantools.rs legt 24 van zulke gevallen vast.
Bewijs#
MODELLED. Dit is een parser, en zijn uitvoer voedt schatters die elders tegen allantools zijn gevalideerd. De unittests in src/clock_log.rs gebruiken kleine met de hand geschreven logs, en voor de formaten linuxptp en chrony de fixtures in tests/fixtures/clock_log/linuxptp_chrony/. tests/clock_log_allantools.rs voert de vergelijking uit die vooraf is vastgelegd in tests/fixtures/clock_log/PREREGISTRATION.md: drie synthetische logs met seed, een per formaat, teruggelezen door een onafhankelijke lezer die door dezelfde auteur uit deze pagina is geschreven, met de ADEV, TDEV en MTIE gecontroleerd tegen allantools 2024,6; die vergelijking dekt alleen de eerste drie formaten, en de lezers van linuxptp en chrony hebben parsertests maar geen vergelijking met een onafhankelijke referentie. De logs van die vergelijking zijn synthetisch, dus niets daarvan beschrijft een echte klok of teller; de vergelijking op gemeten reeksen wordt hieronder beschreven.
Op gemeten data#
tests/clock_log_real_allantools.rs voert de vergelijking uit die vooraf is vastgelegd in tests/fixtures/clock_log_real/PREREGISTRATION.md (vastgelegd vóór elke fixture of run) op vier gemeten reeksen: de Stable32 PHASE.DAT, de eerste 65.536 metingen van een 5071A-cesiumklok tegen een waterstofmaser, en de klokken van IGS-satelliet G01 (30 s) en station ABMF (300 s) uit de definitieve IGS-klok van 2026-08-02, als meegeleverde snede met zijn NOTICE. De eerste twee dragen geen toestemming voor herdistributie: de logs die ervan zijn geschreven staan in de door git genegeerde realdata-cache/ (scripts/gen_clock_log_real_ref.py), en de test zegt dat en slaagt wanneer ze ontbreken tenzij KSHANA_REQUIRE_REALDATA=1. Elke log wordt gelezen door de engine en door een onafhankelijke lezer, en ADEV, TDEV en MTIE worden vergeleken met allantools 2024,6. Vastgelegd in tests/fixtures/clock_log_real/RESULTS.md: bij de uitgeleverde lezer faalden de TICC-logs, de headerversie en vijf foutmeldingen de vooraf vastgelegde drempels; ze zijn hersteld en de vergelijking is ongewijzigd opnieuw uitgevoerd. Gehaald, op één paar na: de MTIE van een frequentielog wijkt af van die van allantools, omdat allantools de frequentie min zijn gemiddelde integreert (vastgezet als NOT MET; de gelijkwaardige vergelijking is gehaald). De rij blijft MODELLED: de TICC-logs zijn gemeten klokdata die door ons script opnieuw in de indeling van de teller zijn gecodeerd (er is geen echte TICC-opname gevonden), en de referentielezer heeft dezelfde auteur als die van de engine.