Strojový překlad, nekontrolovaný rodilým mluvčím. Referenční je anglická verze.

ČasováníUpravit na GitHubuZdroj: docs/CLOCK-LOG-FORMATS.md

Formáty záznamů hodin

src/clock_log.rs čte změřený záznam hodin do jedné normalizované fázové řady: rovnoměrné mřížky vzorků (time_s, phase_s), s uvedeným nebo zjištěným intervalem vzorků tau0, se započítanou každou mezerou a s pojmenovanými jednotkami záznamu. Čte se osm formátů, každý jako zdokumentovaná podmnožina. Cokoli mimo podmnožinu se odmítne chybou, která uvádí, co bylo nalezeno, místo aby se to četlo přibližně.

Zkratky. RINEX je Receiver Independent Exchange Format. TICC je čítač časových intervalů TAPR (Tucson Amateur Packet Radio). ADEV je překrývající se Allanova odchylka, TDEV časová odchylka a MTIE maximální chyba časového intervalu. tau0 je interval vzorků v sekundách.

Kde lze záznam použít#

  • telecom-timing: [series.clock_log] místo series.samples nebo series.csv_path. Fáze záznamu v ns je řada časové chyby kontrolovaná proti maskám a zpráva získává blok clock_log, který říká, jak byl záznam přečten.
  • Druh clock: tabulka [clock_log] přidává k běhu blok measured: jak byl záznam přečten, SHA-256 tabulky (input_sha256; scenario_hash běhu tabulku nepokrývá) a fázových vzorků a překrývající se ADEV, TDEV a MTIE při oktávových faktorech průměrování. Vyžaduje runs = 1. Simulovaný holdover se nemění.

Bez tabulky se oba druhy zpracovávají, hashují a uvádějí přesně jako dříve.

[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

Formáty#

rinex-clk: soubory hodin RINEX, verze 2,00 a 3,00 až 3,04 (včetně devítiznakového pole jména ve verzi 3,04). Záznam RINEX VERSION / TYPE se kontroluje a každá jiná verze je odmítnuta s uvedením nalezené verze: IGS zveřejňuje formát hodin (rinex_clock300.txt, 302, 304) až do 3,04 a dokumenty RINEX 4,00, 4,01 a 4,02 definují jen soubory pozorování, navigace a meteorologické, takže verze 4,00 souboru hodin ke čtení neexistuje. Hlavička se čte jen kvůli TIME SYSTEM ID a přeskakuje se až po END OF HEADER. Z datových záznamů se ponechávají jen záznamy AS (družice) a AR (přijímač nebo stanice) jedněch hodin vybraných podle jména. Jejich první hodnotové pole, předpětí hodin v sekundách, je fáze. Pokračovací řádky a záznamy CR, DR a MS se přeskakují. Epochy jsou kalendářní pole záznamu, jako sekundy od 1980-01-06 00:00:00 ve vlastní časové soustavě souboru, bez převodu.

timelab: ASCII záznamy fáze nebo frekvence ve stylu TimeLab, prostá textová forma, kterou TimeLab exportuje a kterou čtou jeho import ASCII a Stable32. Na řádku je jedno čtení: buď jediný sloupec s rovnoměrným tau0, nebo dva sloupce time value. Sloupce mohou být odděleny mezerami, čárkami nebo středníky.

  • Řádky začínající #, ; nebo % jsou komentáře. Komentář ve tvaru key = value (nebo key: value) nastavuje tau0 (s), units (s, ms, us, ns nebo ps, pro fázi), data (phase nebo frequency) nebo time_units (s nebo mjd, pro první ze dvou sloupců).
  • Jeden úvodní nečíselný řádek se bere jako záhlaví sloupců.
  • Frekvenční data (relativní frekvence) se přijímají pouze jako jediný sloupec. Integrují se na fázi jako x[i+1] = x[i] + y[i]·tau0 (NIST SP 1065, 2008, §4,1).
  • Binární soubory TimeLab a projektové soubory .tim se nečtou.

ticc: záznamy čítače TAPR TICC (TICC Operation Manual, revize z 23. listopadu 2016 a 15. prosince 2025, „measurement modes“). Každé datové pole jsou sekundy s 12 desetinnými místy (výchozí 11 od firmwaru 20251101: čte se libovolný počet až 15). Časové razítko se čte z desetinného textu jako celé číslo femtosekund, nikoli jako binární číslo s plovoucí řádovou čárkou, takže fáze záznamu pořízeného dny po spuštění čítače zachovává vlastní rozlišení čítače: časové razítko f64 při 3.0e5 s má rozestup 5.8e-11 s, asi 60 ps čítače.

  • Řádky režimu Timestamp (<seconds> chA, <seconds> chB) a kanál pseudočasových značek režimu TimeLab (chC) jsou časové značky událostí. Fáze vybraného kanálu je jeho časová značka minus nominální tik: x[k] = t[k] − t[0] − n[k]·tau0, kde n[k] je celý počet tau0 od první události. Zmeškaná událost je mezera.
  • Řádky režimu Interval (<seconds> TI(A->B) nebo jakýkoli štítek začínající TI) se čtou přímo jako fáze, jedno čtení na tau0. Scénář musí uvést tau0_s, protože řádek nenese čas.
  • Režim Paired Timestamp tiskne stejné řádky v pořadí kanálů a čte se jako režim Timestamp; režim 3-Corner Hat přidává syntetizovaný chC, čtený jak je uvedeno výše.
  • Výstup režimů Period a Debug je odmítnut. Kanál, jehož odečty neroste, je hlášen jako režim Period. Binární režim Timestamp není text a soubor v něm je odmítnut se zprávou, která to říká.
  • Řádky začínající # a řádky, které nemají tvar <number> <label> (například úvodní nabídka), se přeskakují a počítají.

Záznamy linuxptp a chrony#

Těchto pět formátů čte, co běžící démon času zapisuje o svých vlastních hodinách. Slouží ke zpětné kontrole časovacího řetězce (hraniční hodiny, PHC grandmastera, klient chrony) týmiž estimátory jako ostatní záznamy. Nečtou konfiguraci démona a nic zde s démonem nekomunikuje.

ptp4l, phc2sys, ts2phc: servořídicí řádky linuxptp, přičemž každý formát čte jen řádky vlastního programu. Čtení je řádek ve tvaru

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
  • Časová značka je první [seconds.fraction] na řádku (monotónní hodiny démona). Čte se i za předponou syslogu, kde identifikátor procesu jako ptp4l[812]: nemá zlomek a nebere se.
  • Fáze je zaznamenaný offset v nanosekundách, převedený na sekundy. Je to změřená časová chyba podřízených hodin démona vůči jeho referenci, tak jak byla zaznamenána: kladná, když podřízené hodiny předbíhají. Je to chyba zbývající pod servořízením, nikoli drift volně běžících hodin.
  • Slova mezi časovou značkou a offset pojmenovávají zdroj (master, eth0 master pro předponu [eth0], CLOCK_REALTIME phc, /dev/ptp0). Záznam s více než jedním zdrojem vyžaduje clock = "<that text>"; chyba je vypíše.
  • Čtení před tím, než servo poprvé ohlásí s2 (uzamčeno), se vynechávají a počítají v n_skipped_lines: s0 a s1 jsou stavy neuzamčeno a skok, jejichž offsety jsou přechodové jevy při náběhu. Servo, které s2 nikdy nedosáhne, se odmítne. Řádek bez pole stavu se čte tak, jak je.
  • Souhrnné řádky (rms ... max ...), zprávy delay a selected best master a řádky jiných programů se přeskakují a počítají.
  • Časové značky, které jdou zpět (restartovaný démon), se odmítají; záznam rozdělte.

chrony-tracking, chrony-statistics: soubory log tracking a log statistics programu chrony, čtené podle pozice sloupce. Čtení je řádek s alespoň 14 sloupci (tracking) nebo 13 (statistics), který začíná datem a časem UTC ve tvaru YYYY-MM-DD HH:MM:SS. Řádek záhlaví sloupců se přeskakuje a počítá; čára ==== pod ním se přeskakuje bez započtení.

  • Tracking: sloupec 7, místní offset při aktualizaci hodin, v sekundách. IP adresa nebo id reference se mění s vybraným zdrojem, takže bez clock se každý řádek čte jako jedny místní hodiny. clock = "<id>" ponechá jedno id reference.
  • Statistics: sloupec 5, odhadnutý offset zdroje, v sekundách. Na adresu zdroje připadá jedna řada a záznam potřebuje clock = "<address>", pokud jich obsahuje více.
  • Epochy jsou sekundy od 1980-01-06 00:00:00 UTC, bez zpracování přestupných sekund. Chrony zapisuje řádek na každou aktualizaci nebo vzorek zdroje, takže rozestup není rovnoměrný. tau0 je mediánový rozestup; čtení méně než půl tau0 po uchovaném předchozím se zahodí a započítá do n_duplicates a delší rozestup je mezera, kterou hlásí gaps = "refuse". U záznamu s ustáleným intervalem dotazování zadejte tau0_s a gaps = "linear".

Sloupce chrony a rozvržení řádků linuxptp odpovídají veřejné dokumentaci démonů. Fixtures v tests/fixtures/clock_log/linuxptp_chrony/ byly pro Kshana napsány s vymyšlenými hodnotami (viz jeho NOTICE.md); žádný skutečný záznam se nečetl, takže rozvržení lišící se mezi verzemi démonů může být stále odmítnuto nebo špatně přečteno. Řádek, který neodpovídá, se přeskočí a započítá, nikdy se nehádá.

tau0 a mezery#

Když záznam nese časové značky a není zadáno tau0, je tau0 mediánový rozestup po sobě jdoucích časových značek zaokrouhlený na čtyři platné číslice a zdroj se uvádí jako median-spacing. Rozestup čítače se od nominálního liší o frekvenční offset reference, o 10^6 dílů nebo méně. tau0_s ve scénáři vždy vyhrává (zdroj input), poté komentář záhlaví tau0 (zdroj header).

Vzorky se umísťují na mřížku t0 + i·tau0 a chybějící epocha je mezera. Čtení vzdálenější od mřížky než 1 % z tau0 se zahodí a započítá, stejně jako duplicity (první se ponechá). Politika mezer je jedna z těchto:

  • refuse (výchozí): jakákoli mezera je chyba, která mezery spočítá;
  • longest: ponechat nejdelší souvislý úsek bez mezer;
  • linear: doplnit vnitřní mezery lineární interpolací a uvést počet doplněných.

Estimátory potřebují záznam bez mezer, a proto se mezery řeší zde.

Vaše vlastní hodiny#

Tabulka [clock_log] u druhu clock uvádí, jak stabilní byly vaše vlastní hodiny, vedle simulace: scenarios/clock-measured-log.toml (kshana example clock-measured-log) je clock-holdover.toml s výřezem 96 odečtů hodin družice IGS jako vloženým záznamem TimeLab. Nahraďte text hodnotami path a format pro svůj soubor. Blok measured ve výsledku obsahuje, jak byl záznam přečten (formát, tau0 a odkud pochází, každá mezera) a jeho ADEV, TDEV a MTIE; simulaci nemění.

Řízení holdoveru vlastními hodinami: [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

Záznam se fituje postupem karty zařízení z src/clock_library/card.rs (úprava, odstranění kvadratické složky, identifikace šumu s lagem 1, vážené nejmenší čtverce v bílém PM, bílém FM, flicker FM a random-walk FM při časech průměrování s alespoň 30 stupni volnosti). Pojmenované hodiny pak přebírají q_wf = h_0 / 2, q_rw = 2 pi^2 h_-2, flicker_floor = sqrt(2 ln 2 h_-1) a nafitovaný drift; y0 zůstává, jak jej má scénář, protože záznam nese ofset své reference, nikoli hodin po disciplinaci. Bílý fázový šum se fituje a uvádí, ale nesimuluje. Výsledek získává blok fitted (koeficienty, body fitu, hodnoty, které běh použil, co bylo vynecháno, SHA-256 záznamu) a hodiny nesou id measured:<12 hex of the phase hash>. S runs > 1 čerpá soubor běhů z nafitovaných hodin (blok measured potřebuje runs = 1). Fit bez frekvenčního šumu, záznam příliš krátký na fit a replaces jiný než quantum nebo classical jsou chyby, které to říkají. scenarios/clock-fitted-log.toml je příklad (6 hodin hodin družice IGS).

Co ukazuje srovnání na známém šumu (tests/fixtures/clock_fit/RESULTS.md) a co mít na paměti:

  • Splněno: úroveň bílého FM se obnoví do 5 % na každém syntetickém záznamu, který jej má; nafitovaná karta reprodukuje skutečnou Allanovu odchylku v rozmezí faktoru 1,35 při každém času průměrování, pro který byla fitována; exponent šumu, který fit identifikuje, se rovná exponentu z allantools v každém bodě (na záznamu 5071A poté, co je fázový skok, který úprava odstraní, odstraněn i ze vstupu allantools).
  • Nesplněno a zafixováno testem: random-walk FM se obnoví jen tehdy, když dominuje nejdelším časům průměrování záznamu, a i tehdy jen u jednoho ze tří záznamů řady o 131 072 s s překřížením při 3 000 s; fit jej přiřadil flicker FM a driftu. Rozdělení mezi random-walk FM a flicker FM není z jednoho záznamu spolehlivé. Běh reprodukuje stabilitu záznamu v časech průměrování, které záznam pokrývá; za nimi se obě volby rozcházejí (flicker FM je konstantní podlaha, random-walk FM roste jako druhá odmocnina času průměrování).
  • MODELLED: scénář „co kdyby“ pro šum těchto hodin tak, jak jej záznam ukazuje, nikoli kalibrace hodin ani předpověď jejich budoucího chování.

Chybně utvořený záznam je chyba, která uvádí, co bylo nalezeno (řádek, verzi, chybějící volič), nikdy částečný výsledek: tests/clock_log_real_allantools.rs zafixovává 24 takových případů.

Důkazy#

MODELLED. Toto je parser a jeho výstup krmí odhadovače, které jsou jinde validovány proti allantools. Jednotkové testy v src/clock_log.rs používají malé ručně psané záznamy a pro formáty linuxptp a chrony fixtury v tests/fixtures/clock_log/linuxptp_chrony/. tests/clock_log_allantools.rs spouští srovnání předregistrované v tests/fixtures/clock_log/PREREGISTRATION.md: tři syntetické záznamy se seedem, po jednom na formát, načtené zpět nezávislou čtečkou napsanou podle této stránky týmž autorem, s ADEV, TDEV a MTIE zkontrolovanými proti allantools 2024,6; toto srovnání pokrývá jen první tři formáty a čtečky linuxptp a chrony mají testy parseru, ale žádné srovnání s orákulem. Záznamy tohoto srovnání jsou syntetické, takže nic z toho nepopisuje skutečné hodiny ani čítač; srovnání na změřených řadách je popsáno níže.

Na změřených datech#

tests/clock_log_real_allantools.rs spouští srovnání předregistrované v tests/fixtures/clock_log_real/PREREGISTRATION.md (odevzdané před jakoukoli fixturou či během) na čtyřech změřených řadách: PHASE.DAT ze Stable32, prvních 65 536 odečtů cesiových hodin 5071A proti vodíkovému maseru a hodinách družice IGS G01 (30 s) a stanice ABMF (300 s) z finálních hodin IGS ze 2026-08-02, jako vendorovaný výřez s jeho NOTICE. První dvě nenesou povolení k redistribuci: záznamy z nich zapsané jsou v realdata-cache/ ignorovaném gitem (scripts/gen_clock_log_real_ref.py) a test to uvádí a při jejich nepřítomnosti projde, pokud není KSHANA_REQUIRE_REALDATA=1. Každý záznam čte engine i nezávislá čtečka a ADEV, TDEV a MTIE se porovnávají s allantools 2024,6. Zaznamenáno v tests/fixtures/clock_log_real/RESULTS.md: u dodávané čtečky selhaly na předregistrovaných prazích záznamy TICC, verze hlavičky a pět chybových zpráv; byly opraveny a srovnání bylo znovu spuštěno beze změny. Splněno kromě jednoho páru: MTIE frekvenčního záznamu se liší od allantools, protože allantools integruje frekvenci minus její střední hodnotu (zafixováno jako NOT MET; srovnání na stejném základě je splněno). Řádek zůstává MODELLED: záznamy TICC jsou změřená data hodin překódovaná naším skriptem do rozvržení čítače (žádný skutečný záznam z TICC nebyl nalezen) a referenční čtečka má stejného autora jako ta v enginu.