Skip to content

API reference

The full public surface of gmat_czml. Every name here is importable from the top-level package (for example from gmat_czml import to_czml).

Conversion

to_czml

to_czml(
    ephemeris: TrajectorySource,
    *,
    style: Style | None = None,
    playback_seconds: float = 60.0,
    ground_track: bool = False,
    contacts: Sequence[Contact] | None = None,
    maneuvers: Iterable[Maneuver] | None = None,
    attitude: Attitude | None = None,
) -> CzmlDocument

Convert a canonical trajectory into a CzmlDocument.

ephemeris is a canonical state-series DataFrame, an orbit-formats Ephemeris, or an iterable of either (one trajectory per object) — whatever gmat_czml.schema.normalize_inputs accepts. style selects the visual style; None uses the default. playback_seconds sets the document clock's default speed: the whole trajectory plays back in roughly that many seconds of wall-clock time (floored at 1x). The document is assembled entirely in memory.

ground_track adds each object's sub-satellite geodetic polyline (one packet per contiguous segment, split at the antimeridian). It is off by default: the ground track is the only path that loads the Earth-orientation rotation (and astropy, transitively, for an inertial source), so the core ephemeris path stays free of it unless a ground track is asked for (D6).

contacts adds, per Contact, an observer entity at its geodetic position and an observer → satellite link shown only during each access window. Each distinct observer is placed once, and each contact's target must be one of the rendered objects.

maneuvers adds, per orbit-formats Maneuver, a marker on the orbit at the burn: an impulsive burn becomes a point + label pinned at the burn epoch (shown from then on); a finite burn becomes an orange arc over the burn span plus a companion marker. The marker position is interpolated from the trajectory, so maneuvers attach to the one rendered object — passing them for a multi-object document raises AmbiguousManeuverTargetError.

attitude adds, from an Attitude (a CCSDS-AEM quaternion history), a sampled orientation on a child entity that references the object's position and carries a schematic body box, so the object's axes animate over the trajectory. The orientation is composed into Cesium's body→Earth-fixed convention (the source attitude's reference frame is rotated to ECEF per epoch), so an inertial-referenced attitude renders correctly. Like maneuvers it attaches to the one rendered object — passing it for a multi-object document raises AmbiguousAttitudeTargetError.

Raises a SchemaError (the typed family) for a malformed input, naming exactly what is wrong, UnsupportedCentralBodyError for a ground track about a non-Earth body, UnknownContactTargetError / ContactEntityCollisionError for a contact that targets a missing object or collides with another entity, AmbiguousManeuverTargetError for maneuvers on a multi-object document, ManeuverOutsideTrajectoryError for a burn outside the trajectory's time span, AmbiguousAttitudeTargetError for an attitude on a multi-object document, UnsupportedAttitudeTypeError / AttitudeFrameError for a non-quaternion or unresolvable-frame attitude, or ValueError if playback_seconds is not positive.

Documents

CzmlDocument

CzmlDocument(document: Document)

A handle on an assembled CZML document.

Wraps the czml3 Document the converters produce. The three accessors are the public surface:

  • to_json — the document as a CZML JSON string;
  • to_dict — the same document as parsed JSON (CZML's top level is a JSON array of packets, so this is a list);
  • save — write the JSON to a file, byte-for-byte identical to to_json.

The wrapped czml3 object is available as document for callers that need the model.

document property

document: Document

The wrapped czml3 Document.

to_json

to_json() -> str

The document as a CZML JSON string — a JSON array whose first element is the preamble.

to_dict

to_dict() -> list[Any]

The document as a list of packet dicts, parsed from to_json.

Parsing the serialized JSON (rather than walking the model) guarantees the dict form and the string form describe exactly the same document.

save

save(path: str | Path) -> Path

Write the document to path (UTF-8) and return the path it was written to.

The file holds exactly what to_json returns — no trailing newline is added — so a saved document and an in-memory to_json() are byte-for-byte identical.

Input schema

The canonical input boundary — see the schema reference for the contract these validate.

validate

validate(df: DataFrame) -> CanonicalInput

Validate a single-object canonical DataFrame and return a CanonicalInput.

Checks the gmat-czml guards (required columns, a recognised frame, a required-and-recognised time scale, well-formed units), then delegates the array / spine parsing to Ephemeris.from_dataframe. A position-only frame (no VX, VY, VZ) is accepted; the velocity is filled with NaN and CanonicalInput.has_velocity is False.

Raises a specific SchemaError for each malformed case, naming what is wrong rather than surfacing a bare KeyError / ValueError.

normalize_inputs

normalize_inputs(source: object) -> list[CanonicalInput]

Validate one trajectory or a collection of them into a list of CanonicalInput.

Accepts a single canonical DataFrame, a single upstream Ephemeris, or an iterable of either (the multi-object contract: one trajectory per object, identity from attrs['object_name']). Returns one CanonicalInput per object. Object names, when declared, must be unique across the collection.

recognised_frame

recognised_frame(name: str) -> str | None

The canonical frame id for name, or None if it is outside the recognised set.

Case- and whitespace-insensitive. Defers to orbit-formats' shared frame alias table and supplements it with GMAT's own EarthMJ2000Eq / EarthFixed spellings, so the two libraries agree on every name they share and a GMAT-tagged state is recognised too. The returned id is the orbit-formats canonical frame id the downstream frame mapping consumes.

CanonicalInput dataclass

CanonicalInput(
    ephemeris: Ephemeris, frame: str, has_velocity: bool
)

A validated single-object trajectory ready for conversion.

ephemeris is the parsed upstream canonical object (epochs, positions, velocities, and the metadata spine); frame is the recognised canonical frame id (e.g. "EME2000" / "ITRF"); has_velocity records whether real velocity columns were supplied, since the schema makes velocity optional and a position-only source carries NaN velocities.

object_name property

object_name: str | None

The object's identity, from attrs['object_name'] (None when undeclared).

central_body property

central_body: str | None

The central body (e.g. "Earth"), from attrs['central_body'] if declared.

time_scale property

time_scale: str

The time scale (one of UTC TAI TT TDB GPS UT1), from attrs['time_scale'].

Unlike object_name / central_body, the scale is required: validation resolves it (falling back to attrs['epoch_scales']['Epoch']) and rejects an absent or unrecognised one, so a constructed CanonicalInput always carries a recognised, non-None scale. The cast records that established guarantee for the type checker.

Contacts

The contact record gmat-czml owns — an observer's placement and the access windows it sees a satellite over. See the contacts conversion for what each becomes in CZML.

GroundStation dataclass

GroundStation(
    name: str,
    latitude: float,
    longitude: float,
    height: float = 0.0,
)

An observer's identity and geodetic placement.

name is the observer's id (and label text); latitude and longitude are geodetic degrees (east-positive longitude); height is kilometres above the WGS84 ellipsoid (scaled to the metres CZML cartographic height uses). Equality is structural, so the same station may appear in several Contact records (one per satellite it tracks) and is placed once — but two differently-placed stations sharing a name are rejected.

Contact dataclass

Contact(
    observer: GroundStation,
    target: str,
    windows: Sequence[tuple[datetime, datetime]],
)

Access windows between one observer and one target satellite.

observer is the ground station; target is the target satellite's object name — it must match a rendered object's entity id (its declared name, or its object-<index> positional fallback). windows is the access intervals, each a (start, end) pair of datetime; the link is shown only during them. Times are UTC — a naive datetime is read as UTC and an aware one is converted. A contact with no windows still places its observer but emits no link.

Styling

Style dataclass

Style(
    name: str = "sat-default",
    marker: PointStyle | ImageBillboard = PointStyle(),
    label: LabelStyle = LabelStyle(),
    path: PathStyle = PathStyle(),
    track: TrackStyle = TrackStyle(),
    maneuver: ManeuverStyle = ManeuverStyle(),
    contact: ContactStyle = ContactStyle(),
    attitude: AttitudeStyle = AttitudeStyle(),
)

The visual style applied to one rendered object and its annotation layers.

name is the style's identity (the preset name a preset lookup returns). The satellite-layer fields drive the object's own geometry:

  • marker — the object's glyph, either a coloured PointStyle (the default) or an ImageBillboard image, exactly one of the two;
  • label — the name LabelStyle;
  • path — the orbit-trail PathStyle;
  • track — the ground-TrackStyle.

The annotation-layer fields style the optional annotations, each with its own default look:

  • maneuver — the ManeuverStyle for burn markers and arcs (orange);
  • contact — the ContactStyle for observers and lines of sight (cyan);
  • attitude — the AttitudeStyle for the body-orientation box (translucent cyan).

The defaults are sat-default, so Style() is the baked-in look gmat_czml.to_czml applies when given no style. Build a custom style by overriding any field — Style(marker=PointStyle(color=(0, 255, 0, 255)), path=PathStyle(width=3.0)) — or resolve a named preset with preset. The palette presets recolour only the satellite layer; the annotation layers keep their semantic colours unless you override them.

PointStyle dataclass

PointStyle(
    color: RGBA = (255, 255, 0, 255),
    pixel_size: float = 10.0,
    outline_color: RGBA = (0, 0, 0, 255),
    outline_width: float = 1.0,
)

The marker glyph as a coloured point — a filled dot with an outline.

color fills the dot and outline_color / outline_width draw its border; pixel_size is the dot's screen size in pixels. Channels are 0-255. The defaults are the sat-default marker: a yellow dot with a thin black outline.

ImageBillboard dataclass

ImageBillboard(image: str, scale: float = 1.0)

The marker glyph as an image billboard — a screen-facing image in place of the point.

image is the image source: any URI a Cesium client can load, including an http(s) URL or a data: URI with the image inlined (gmat-czml ships no asset pipeline, so the caller supplies the image). scale multiplies the image's native pixel size. Setting a Style's marker to an ImageBillboard replaces the coloured point with the billboard.

LabelStyle dataclass

LabelStyle(
    color: RGBA = (255, 255, 255, 255),
    font: str = "11pt Lucida Console",
)

The object's name label — its fill colour and font.

color is the text fill (channels 0-255) and font is a CSS-style font string. The label's layout (its offset clear of the marker and its anchoring) is fixed by the converter, not styled here. The defaults are the sat-default label: white text in a small monospace font.

PathStyle dataclass

PathStyle(
    color: RGBA = (255, 255, 0, 255), width: float = 1.5
)

The orbit trail — its line colour and width.

color (channels 0-255) and width (pixels) draw the trailing orbit path behind the object. The defaults are the sat-default trail: a thin yellow line.

TrackStyle dataclass

TrackStyle(
    color: RGBA = (255, 255, 0, 255), width: float = 2.0
)

The ground track — its line colour and width.

color (channels 0-255) and width (pixels) draw the sub-satellite ground-track polyline. The defaults are the sat-default track: the orbit trail's yellow, a touch heavier so it reads against the globe.

LineStyle dataclass

LineStyle(color: RGBA, width: float)

A line — its colour and width.

color (channels 0-255) and width (pixels) draw a generic line: the maneuver burn arc and the contact line of sight. Unlike PathStyle / TrackStyle, which name the satellite's own orbit trail and ground track, this is the neutral line style the annotation layers reuse.

ManeuverStyle dataclass

ManeuverStyle(
    marker: PointStyle = (
        lambda: PointStyle(
            color=(255, 140, 0, 255), pixel_size=11.0
        )
    )(),
    label: LabelStyle = LabelStyle(),
    arc: LineStyle = (
        lambda: LineStyle(
            color=(255, 140, 0, 255), width=3.0
        )
    )(),
)

The maneuver annotation layer — its marker, label, and burn-arc styles.

A maneuver renders as a marker (a point + label, for an impulsive burn or a finite burn's companion) and, for a finite burn, a burn arc. marker styles the point, label the text, and arc the finite-burn line. The defaults are the baked-in maneuver look: an orange marker and arc with a white label, drawn as their own layer distinct from the satellite.

ContactStyle dataclass

ContactStyle(
    observer: PointStyle = (
        lambda: PointStyle(
            color=(0, 255, 255, 255), pixel_size=8.0
        )
    )(),
    label: LabelStyle = LabelStyle(),
    link: LineStyle = (
        lambda: LineStyle(
            color=(0, 255, 255, 255), width=1.0
        )
    )(),
)

The contact annotation layer — its observer marker, label, and line-of-sight styles.

A contact renders an observer entity (a point + label at the ground station) and an observer -> satellite link. observer styles the point, label the text, and link the line of sight. The defaults are the baked-in contact look: a cyan observer and link with a white label, drawn as the ground / line-of-sight layer distinct from the satellite.

AttitudeStyle dataclass

AttitudeStyle(
    box_fill_color: RGBA = (0, 200, 255, 110),
    box_outline_color: RGBA = (0, 200, 255, 255),
    box_outline_width: float = 1.0,
)

The attitude annotation layer — the body box's fill and outline colours.

The attitude marker is a schematic body box; box_fill_color fills it (channels 0-255, with a translucent alpha by default) and box_outline_color / box_outline_width draw its edges. The box's dimensions are fixed by the converter (three distinct, exaggerated axes so the orientation reads), not styled here. The defaults are the baked-in translucent-cyan body box.

preset

preset(name: str) -> Style

The named preset Style, or raise UnknownStyleError.

name must be one of PRESET_NAMES (sat-default plus the colour palette). The preset is resolved, never guessed: an unrecognised name is rejected with the recognised set rather than silently falling back to the default.

Errors

Every error gmat-czml raises on purpose descends from GmatCzmlError; the schema-validation failures additionally descend from SchemaError, which is also a ValueError.

errors

The typed error hierarchy the public surface raises.

Every error gmat-czml raises on purpose descends from GmatCzmlError, so a caller can catch the whole family with one except. The schema-validation failures all descend from SchemaError, which is also a ValueError — a malformed canonical input is a bad value, and existing except ValueError handlers keep working. Each subclass names exactly what is wrong (a missing column, an unrecognised frame, an absent time scale, malformed unit metadata) so a producer never has to read a bare KeyError traceback to learn what its DataFrame got wrong.

GmatCzmlError

Bases: Exception

Base class for every error gmat-czml raises deliberately.

UnmappableFrameError

UnmappableFrameError(frame: str, mappable: Iterable[str])

Bases: GmatCzmlError

A recognised frame that has no CZML reference-frame mapping.

Raised by the frame mapping for a canonical frame id that validation recognised but the converter cannot render in a CZML reference frame (INERTIAL / FIXED). Distinct from UnknownFrameError, which rejects a name outside the recognised set at the input boundary: the input here was valid, so this descends from GmatCzmlError directly rather than SchemaError. frame is the offending id and mappable the ids that do map.

UnsupportedCentralBodyError

UnsupportedCentralBodyError(central_body: str)

Bases: GmatCzmlError

A ground track requested for a trajectory about a body other than Earth.

The sub-satellite projection is WGS84 / Earth-fixed throughout (D1, D5), so the ground track is Earth-only. Raised by the ground-track converter when attrs['central_body'] is declared as something other than Earth; an undeclared body is accepted, since every recognised frame is an Earth frame already. Like UnmappableFrameError, the input was a valid trajectory — the limitation is at render time — so this descends from GmatCzmlError directly rather than SchemaError. central_body is the offending value.

UnknownInterpolationError

UnknownInterpolationError(
    algorithm: str, recognised: Iterable[str]
)

Bases: GmatCzmlError

A declared interpolation algorithm with no CZML equivalent.

Raised by the ephemeris converter when attrs['interpolation'] carries a name outside the set CZML understands (LAGRANGE / HERMITE / LINEAR). The interpolation hint is read at the converter layer, not validated as part of the schema contract, so — like UnmappableFrameError — this descends from GmatCzmlError directly rather than SchemaError. The algorithm is mapped, never guessed: an undeclared algorithm defaults, but an unrecognised one is rejected. algorithm is the offending name and recognised the names that map.

UnknownStyleError

UnknownStyleError(name: str, recognised: Iterable[str])

Bases: GmatCzmlError

A style preset name that is not in the recognised set.

Raised by gmat_czml.preset when asked for a preset outside the registry (sat-default plus the colour palette). The preset is resolved, never guessed — an unrecognised name is rejected rather than silently falling back to the default — so this, like UnknownInterpolationError, is a render-time choice that descends from GmatCzmlError directly rather than SchemaError. name is the offending value and recognised the preset names that resolve.

UnknownContactTargetError

UnknownContactTargetError(
    target: str, known: Iterable[str]
)

Bases: GmatCzmlError

A contact names a target satellite that is not an object in the document.

The observer → satellite link is a CZML polyline whose endpoints reference the observer's and the target's position properties, so the target must be one of the rendered objects (its entity id is the object's name, or its positional fallback). A contact naming a target no input trajectory provides would emit a link with a dangling reference a Cesium client cannot resolve, so it is rejected. Like UnmappableFrameError, the trajectory input was valid — the mismatch is in the contacts argument — so this descends from GmatCzmlError directly rather than SchemaError. target is the offending name and known the object ids a contact may target.

ContactEntityCollisionError

ContactEntityCollisionError(entity_id: str)

Bases: GmatCzmlError

A contact would emit a CZML entity whose id collides with another entity.

Contacts introduce their own entities — one observer per ground station and one observer-to-satellite link per contact — each with its own packet id (the observer's name, and <observer>-to-<target> for the link). That id must be unique across the whole document: a Cesium client silently merges two packets sharing an id into one entity. This is raised when an observer name collides with an object (satellite) id, when one observer name is declared with two different placements, or when two contacts share the same observer and target. Like UnknownContactTargetError, the trajectory input was valid, so this descends from GmatCzmlError directly. entity_id is the colliding id.

ManeuverOutsideTrajectoryError

ManeuverOutsideTrajectoryError(
    epoch: datetime, span: tuple[datetime, datetime]
)

Bases: GmatCzmlError

A maneuver whose ignition (or finite-burn cut-off) falls outside the trajectory's time span.

A maneuver carries no position of its own, so the converter interpolates the marker location from the trajectory at the burn epoch. A burn before the first state or after the last has no orbit beneath it to pin to, so it is rejected rather than clamped to an endpoint. Like UnknownContactTargetError, the trajectory input was valid — the mismatch is in the maneuvers argument — so this descends from GmatCzmlError directly rather than SchemaError. epoch is the offending ignition time (UTC) and span the trajectory's (start, end) it must fall within.

AmbiguousManeuverTargetError

AmbiguousManeuverTargetError(count: int)

Bases: GmatCzmlError

Maneuvers were supplied for a document with more than one object.

A Maneuver names neither a position nor a target craft, so gmat-czml attributes the maneuvers to the single rendered trajectory; with more than one object it cannot tell which craft each burn acts on, and refuses to guess. Like ManeuverOutsideTrajectoryError, the inputs were individually valid — the ambiguity is in pairing them with the maneuvers argument — so this descends from GmatCzmlError directly. count is the number of objects in the document.

AmbiguousAttitudeTargetError

AmbiguousAttitudeTargetError(count: int)

Bases: GmatCzmlError

An attitude was supplied for a document with more than one object.

An attitude history orients one object: its sampled orientation attaches to that object's position, so with more than one rendered object gmat-czml cannot tell which craft the attitude belongs to, and refuses to guess. Like AmbiguousManeuverTargetError, the inputs were individually valid — the ambiguity is in pairing them with the attitude argument — so this descends from GmatCzmlError directly. count is the number of objects in the document.

UnsupportedAttitudeTypeError

UnsupportedAttitudeTypeError(
    attitude_type: str, supported: Iterable[str]
)

Bases: GmatCzmlError

An attitude whose representation the converter does not render.

The attitude converter emits a sampled orientation from a quaternion history; the canonical Attitude also models Euler-angle and spin attitudes, which are not rendered (rather than converted on a guess). Like UnmappableFrameError, the attitude was a valid canonical object — the limitation is at render time — so this descends from GmatCzmlError directly. attitude_type is the offending type and supported the types that render.

AttitudeFrameError

AttitudeFrameError(
    frame_a: str | None, frame_b: str | None
)

Bases: GmatCzmlError

An attitude whose two frames do not resolve to one external reference plus one body frame.

An AEM names two frames; rendering the orientation requires exactly one to be a recognised external reference (e.g. EME2000 / ITRF, which body→ECEF composition rotates through) and the other to be the body frame (e.g. SC_BODY, which is not a recognised external frame). This is raised when neither frame is recognised (no external reference to compose against) or both are (no identifiable body frame). Like UnmappableFrameError, the attitude was a valid canonical object — the limitation is at render time — so this descends from GmatCzmlError directly. frame_a and frame_b are the offending frame names.

EmptyAttitudeError

Bases: GmatCzmlError

An attitude history with no samples — there is no orientation to render.

SchemaError

Bases: GmatCzmlError, ValueError

A canonical input that does not satisfy the schema contract.

Base for every validation failure. Also a ValueError, so the typed family stays catchable as the broad value error a malformed input naturally is.

MissingColumnError

MissingColumnError(columns: Iterable[str])

Bases: SchemaError

A required state column is absent from the DataFrame.

columns holds the missing column names. Epoch, X, Y, Z are always required; velocity is optional, but declaring it partially (some of VX, VY, VZ but not all three) is a malformed declaration and reported here too.

MissingFrameError

MissingFrameError()

Bases: SchemaError

No coordinate_system is declared on DataFrame.attrs.

The reference frame is load-bearing for the CZML reference frame, so it is required rather than guessed.

UnknownFrameError

UnknownFrameError(frame: str, recognised: Iterable[str])

Bases: SchemaError

A declared coordinate_system that is not in the recognised set.

frame is the offending value and recognised the names gmat-czml accepts.

MissingTimeScaleError

MissingTimeScaleError()

Bases: SchemaError

No time scale is declared on DataFrame.attrs.

Read from time_scale, falling back to epoch_scales['Epoch']; when neither is present the scale is required rather than assumed, since the CZML clock is built in UTC.

UnknownTimeScaleError

UnknownTimeScaleError(
    time_scale: str, recognised: Iterable[str]
)

Bases: SchemaError

A declared time scale that is not one of the recognised scales.

time_scale is the offending value and recognised the scales gmat-czml accepts.

InvalidUnitsError

InvalidUnitsError(detail: str)

Bases: SchemaError

The units metadata is malformed.

attrs['units'] must be a mapping whose recognised keys (length / speed / angle / time) carry non-empty unit strings. detail describes what was wrong.

EmptyTrajectoryError

Bases: SchemaError

There is nothing to convert — a state series with no samples, or no inputs at all.

DuplicateObjectNameError

DuplicateObjectNameError(name: str)

Bases: SchemaError

Two inputs in a multi-object collection share the same object_name.

Object identity comes from attrs['object_name'], so two trajectories carrying the same name are ambiguous. name is the colliding value.

MalformedStateError

Bases: SchemaError

The state arrays could not be parsed.

Non-numeric values, an unparseable epoch, or a shape the canonical layer rejects. Wraps the upstream ValueError (available as the exception __cause__) so the failure surfaces as a typed gmat-czml error rather than a bare parse error.

gmat-run adapter

The optional one-hop bridge from a gmat-run Results to a document — see the gmat-run adapter guide. It lives in its own module because gmat-run is an optional dependency, imported only inside these functions.

gmat_run

Turn a gmat-run Results into a CZML document, in one hop.

gmat-run runs a GMAT mission headlessly and returns a Results whose ephemerides and contacts are already keyed pandas.DataFrame views over the run's output files. A GMAT ephemeris DataFrame is gmat-czml's canonical state series — same Epoch, X, Y, Z[, VX, VY, VZ] columns and the same attrs spine (object_name / coordinate_system / central_body / time_scale / interpolation …) — so a trajectory flows into gmat_czml.to_czml with no reshaping. This adapter is the thin convenience that bundles a whole Results into one document without the caller wiring each piece by hand.

gmat-run stays optional. It is imported inside these functions, never at module load, so importing gmat-czml (and the minimal install) never needs it; calling the adapter without it installed raises a clear, actionable ImportError naming the install. The type annotations reference gmat_run.Results only under typing.TYPE_CHECKING.

What maps, and what does not. A Results is the run's output, which bounds what the adapter can reach:

  • Ephemerides map directly — results_to_trajectories returns one canonical DataFrame per EphemerisFile resource (naming the object after the resource when the source declared no OBJECT_NAME), and to_czml_from_results renders them as a multi-object document.
  • Contacts map to gmat-czml GroundStation / Contact records, but a GMAT ContactLocator report names its observer without its geodetic position — that lives on the GroundStation resource in the mission script, not in the run output. So the caller supplies each observer's placement via a stations mapping; the adapter pairs it with the access windows it reads from the report (results_to_contacts).
  • Maneuvers and attitude are not reachable from a bare Results. gmat-run surfaces no maneuver output at all, and attitude lives on Mission.attitude_inputs, not Results. To annotate a document with either, read the source .opm / .aem through orbit-formats and pass the resulting Maneuver / Attitude to gmat_czml.to_czml directly.

The adapter's own typed errors (MissingStationError, UnsupportedContactFormatError) descend from GmatCzmlError, so they are catchable with the rest of the family, but live here rather than in the core error module — they are concepts only this optional adapter raises. Errors from the conversion itself (an unknown contact target, a duplicate object name, an empty trajectory) propagate from gmat_czml.to_czml unchanged.

MissingStationError

MissingStationError(
    observers: Iterable[str], provided: Iterable[str]
)

Bases: GmatCzmlError

A contact observer has no geodetic placement in the supplied stations mapping.

A GMAT ContactLocator report names its observer but not its position — the observer's longitude / latitude / height live on the GroundStation resource in the mission script, not in the run output — so the adapter cannot place the observer without a caller-supplied placement. observers are the unplaced names and provided the station keys that were supplied.

UnsupportedContactFormatError

UnsupportedContactFormatError(
    report_format: str, resource: str
)

Bases: GmatCzmlError

A contact resource whose ReportFormat carries no access-window columns.

The adapter builds each contact's windows from the Start / Stop columns the window-bearing ContactLocator formats emit (Legacy, ContactRangeReport, the SiteView variants). The per-tick AzimuthElevationRange variants report one Time per sample rather than an interval, so there are no windows to map. report_format is the offending variant and resource the contact resource name.

to_czml_from_results

to_czml_from_results(
    results: Results,
    *,
    ephemerides: Sequence[str] | None = None,
    stations: Mapping[str, GroundStation] | None = None,
    contact_resources: Sequence[str] | None = None,
    style: Style | None = None,
    playback_seconds: float = 60.0,
    ground_track: bool = False,
) -> CzmlDocument

Convert a gmat-run Results into a CzmlDocument in one hop.

Every EphemerisFile resource becomes one object in the document; pass ephemerides to render a subset (a sequence of resource names, in the order given) instead of all of them. style, playback_seconds, and ground_track are forwarded to gmat_czml.to_czml unchanged.

When stations is given ({observer name: GroundStation}), the run's ContactLocator resources are mapped to observer entities and per-window links; contact_resources selects a subset of them (default: all). Every observer named in a mapped report must have a placement in stations — the report does not carry one (see MissingStationError). Without stations no contacts are rendered, and passing contact_resources without stations is an error.

Maneuvers and attitude are not rendered here: a Results carries no maneuver output, and attitude lives on Mission, not Results — read the source .opm / .aem through orbit-formats and pass the result to gmat_czml.to_czml directly.

Raises ImportError if gmat-run is not installed, EmptyTrajectoryError if the Results has no ephemerides, MissingStationError / UnsupportedContactFormatError for the contact-mapping failures, and whatever gmat_czml.to_czml raises for the conversion itself (e.g. a duplicate object name, or a contact targeting an object not in the document).

results_to_trajectories

results_to_trajectories(
    results: Results, *, names: Sequence[str] | None = None
) -> list[DataFrame]

The Results ephemerides as canonical state-series DataFrames, one per resource.

names selects a subset of EphemerisFile resources (in the order given); the default is every ephemeris in the run, in its insertion order. Each DataFrame is the gmat-run-parsed canonical frame, returned as-is when the source declared an OBJECT_NAME and otherwise with the resource name set as attrs['object_name'] (so the object has a stable, unique id). The caller's DataFrames are never mutated — the fallback is applied on a shallow copy.

Raises ImportError if gmat-run is absent, KeyError if names references an unknown resource, and EmptyTrajectoryError if the selection is empty.

results_to_contacts

results_to_contacts(
    results: Results,
    stations: Mapping[str, GroundStation],
    *,
    names: Sequence[str] | None = None,
) -> list[Contact]

The Results contacts as gmat-czml Contact records.

stations places each observer ({observer name: GroundStation}); names selects a subset of ContactLocator resources (default: all). For each mapped report, the target satellite is read from the report and one Contact is produced per observer, its windows the report's (Start, Stop) access intervals (UTC). The returned contacts are in resource order, then observer order within each resource.

Raises ImportError if gmat-run is absent, KeyError if names references an unknown resource, UnsupportedContactFormatError for a report with no window columns, and MissingStationError for an observer with no placement in stations.