OMM interface overhaul: full-fidelity dicts, file/text loaders, TLE conversion, one parser for Rust and Python - #173
Open
ssmichael1 wants to merge 1 commit into
Open
OMM interface overhaul: full-fidelity dicts, file/text loaders, TLE conversion, one parser for Rust and Python#173ssmichael1 wants to merge 1 commit into
ssmichael1 wants to merge 1 commit into
Conversation
…onversion, one parser for Rust and Python Python - omm_from_url returns every field the source provided (metadata, COMMENT, Space-Track extras such as OBJECT_TYPE / RCS_SIZE / TLE_LINE1, XML USER_DEFINED parameters) instead of 17 keys, with numbers as numbers - new omm_from_file / omm_from_text (JSON or XML, detected from content); the xmltodict workaround in the tests and tutorial is gone - TLE.from_omm / TLE.to_omm convert between the representations - sgp4 dict inputs go through the same serde parser as Rust: quoted numbers, null / empty optionals, case-insensitive MEAN_ELEMENT_THEORY / TIME_SYSTEM, any level of an xmltodict tree, EPOCH as str / time / datetime, and an error that names the expected keys - propagation rejects EPHEMERIS_TYPE 4 (SGP4-XP) instead of silently running classic SGP4 on it - OMMDict TypedDict (runtime module python/satkit/_types.py) in the stubs; sgp4 signature documents list[TLE | OMMDict] Rust - OMM.epoch is an Instant (was a String; epoch_instant() deprecated) - OMM derives Serialize (absent optionals skipped, EPOCH as RFC 3339) - from_mean_elements constructor replaces the invalid Default - from_tle / to_tle (+ From impls), from_json_value, from_text, from_file, reset_cache; from_json_string accepts a bare object - one generic tolerant scalar parser shared by the JSON and XML paths - XML: COMMENT lines, CREATION_DATE, spacecraftParameters, and userDefinedParameters are read; OBJECT_NAME / OBJECT_ID default to UNKNOWN - omm::Error is #[non_exhaustive]; InvalidFloat/InvalidInt/InvalidFloatField collapse into InvalidField; new UnsupportedEphemerisType, UnexpectedJsonShape, UnrecognizedFormat Tests: Space-Track ships TLE lines with each OMM, so both parsers are now checked against each other (Rust and Python); XML vs JSON parity on the Space-Track corpus; serialize round-trip; TLE round-trip; rejection cases. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTxc7VmUFyqdpobZkg7Rb7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the OMM interface review. Closes the gaps between the Rust and Python OMM paths and exposes what Rust already parsed.
Python
omm_from_urlis no longer lossy. It returns every field the source provided: version, originator,COMMENT,CENTER_NAME/REF_FRAME/TIME_SYSTEM/MEAN_ELEMENT_THEORY,GM, mass/areas/coefficients,BTERM/AGOM, and all extras (Space-Track'sOBJECT_TYPE,RCS_SIZE,LAUNCH_DATE,TLE_LINE1, …; XMLUSER_DEFINEDparameters). Numbers come back as numbers,EPOCHas RFC 3339.omm_from_file(path)andomm_from_text(text), JSON or XML detected from content. The tests and the OMM tutorial no longer needxmltodict(dropped from thetestextra anddocs/requirements.txt).TLE.from_omm(dict)/TLE.to_omm().sgp4dict inputs are flattened to JSON and handed to the same serde parser as Rust, replacing ~130 lines of hand-rolled field code. Verified behaviours: quoted numbers,None/""optionals,sgp4/utcmetadata accepted, any level of an xmltodict tree (omm,body,segment,datanode),EPOCHasstr/satkit.time/datetime, numpy scalars, and an error that names the expected keys instead of a bare "OMM epoch is required".EPHEMERIS_TYPE: 4raises instead of running classic SGP4 silently.OMMDictTypedDict(runtime modulesatkit/_types.py, re-exported at top level) documents the keys and units;sgp4is typedTLE | OMMDict | list[TLE | OMMDict]. stubtest passes.omm_from_urlreleases the GIL during the fetch.Rust (breaking, for 0.22)
OMM.epoch: Instant(wasString;epoch_instant()kept as deprecated). No reparse per call, noInstant::INVALIDfallback.OMMderivesSerialize(absent optionals skipped,EPOCHwritten as RFC 3339, extras written back).Defaultremoved;OMM::from_mean_elements(epoch, n, e, i, Ω, ω, M)replaces it.OMM::from_tle/OMM::to_tleplusFrom<&TLE>/From<&OMM>impls;OBJECT_ID↔ international designator conversion.from_json_value,from_text,from_file,reset_cache;from_json_stringaccepts a bare object (thefrom_urlstring hack is gone).de_opt_*and fourparse_optional_*helpers.COMMENTlines (header, metadata, data),CREATION_DATE,spacecraftParameters, anduserDefinedParametersare read, so Space-Track XML and JSON now yield identical messages.OBJECT_NAME/OBJECT_IDdefault toUNKNOWN(trimmed dicts).omm::Erroris#[non_exhaustive];InvalidFloat/InvalidInt/InvalidFloatFieldcollapse intoInvalidField { field, message }; newUnsupportedEphemerisType,UnexpectedJsonShape,UnrecognizedFormat.Not done: KVN parsing, covariance block, and a Python
OMMclass (dicts stay the Python representation on purpose).Tests
TLE_LINE1/2with each OMM, so both parsers are checked against each other over the corpus (Rust: 200 records, Python: 100) — within 10 m at epoch + 3 h (the TLE epoch's 0.864 ms resolution bounds the difference; worst case seen 2 m).to_2lineidentical), tolerant scalars, rejection cases, cache-reset behaviour, xmltodict shapes,EPOCHvariants.cargo test --lib305 passed,cargo test --doc omm4 passed,pytest python/test/197 passed, stubtest clean, clippy-D warningsclean, notebook cells executed.🤖 Generated with Claude Code
https://claude.ai/code/session_01GTxc7VmUFyqdpobZkg7Rb7