Data Flow & Runtime Architecture

  1. Loading: OrbitronServices::loader() wraps the IO pipeline (io/pipelines/src/lib.rs) to parse source files into SceneGraph instances. The loader records provenance tags and infers covalent bonds via orbitron_backbone::infer_covalent_bonds.

  2. Bundle format (core/orbpack): the canonical document, the .orbpack container, and the conversion to a SceneGraph. Split out of io/pipelines because that crate carries HDF5, memory mapping, directories and clap and can never build for wasm32, while the browser viewer has to read bundles. Parsing source files, the on-disk cache, and writing bundles stay in io/pipelines, where those dependencies belong. io/pipelines re-exports the crate, so crate::canonical::… paths are unchanged.

  3. Scene Backbone: SceneGraph (immutable, persistent) stores snapshots of atoms, bonds, trajectories, metadata, parsed electronic-structure evidence, and an optional editable MolecularElectronicState. The latter records builder charge and multiplicity without rewriting results parsed from a calculation. The GUI and CLI work against SceneGraph plus derived render data (RenderSceneData).

  4. Query & Selection: Expressions parsed by orbitron-query::parse_expression are evaluated via SelectionProgram inside orbitron-selection-engine. Cached outputs and selection scoring drive the viewer highlights and CLI results.

  5. Rendering: orbitron-render::Renderer translates RenderSceneData into GPU draw commands (instanced atoms/bonds, text overlays). Camera control lives in ui/shell/src/camera.rs, but the renderer crate is UI-agnostic.

  6. Services Layer: OrbitronServices coordinates loader/analyzer/exporter/renderer operations and abstracts data sources. It owns the generic load/analyze/export/render path and is the single front door for opening a file into a scene. Format-specific parsing (format sniffers, companion-file parsers, per-format run-summaries) is used directly from io/pipelines, which is a shared layer rather than a hidden internal; the desktop additionally keeps its own background streaming loader (ui/shell/.../path_loader.rs) for local files with progress/cancel.

  7. Editing: orbitron-edit wraps a SceneGraph in an EditableScene and applies EditCommands against it, keeping the undo/redo stacks the desktop exposes. Its geometry/ module is the molecular builder: build templates and generated rings for placement, a pure planner per geometry command, coordination-sphere assessment, 3D embedding from a flat connection table, bounded conformer search, and residue mutation. smiles.rs imports the supported SMILES subset through Yowl and returns an explicit-H scene or fragment. Minimisation is a separate crate, orbitron-forcefield (UFF), so the planner and the minimiser stay independently testable. Its fixed-cell periodic path carries explicit lattice images in every interaction while retaining one Cartesian coordinate per base atom.

  8. Frontends: The GUI viewer (ui/shell) embeds the renderer and services within an egui event loop (viewer_loop::ViewerLoop). The CLI and TUI use the same services for loading, analysis, and export, so a behaviour added in a core crate reaches all three.

  9. External APIs: Downstream tools integrate via OrbitronServices (Rust) or the Python bridge (Orbitron class). Core behavior is shared, but each frontend still owns command wiring, presentation, and error reporting. A new core feature therefore needs an explicit surface and test in every frontend that claims to expose it.

Binary scene and trajectory compatibility

SceneGraph::to_bytes and Trajectory::to_bytes use named MessagePack so adding a defaulted field does not shift positional data. Trajectory bytes begin with ORBITRON_TRAJECTORY_MSGPACK_V1\0; Trajectory::from_bytes retains a read-only fallback for the former bincode layout. New writers must not emit the legacy form.