Automation Interfaces

9.1 CLI (automation/cli)

  • automation/cli/src/cli.rs defines the Clap command enums (enum Commands, enum AnalyzeCommands); main.rs is a thin entry point that parses them and dispatches. Key subcommands:
    • info: prints metadata/JSON summary (OrbitronServices::analyzer).
    • resources (visible alias resource): reads file metadata plus one bounded source prefix and reports the shared source estimate, count hints, memory snapshot, and policy verdict without parsing. Its JSON schema is orbitron.resources/1. A block verdict is report data and does not change the command’s successful exit status; source inspection failures do.
    • pack: takes a subcommand. pack periodic (visible alias vasp, from when it only handled VASP) writes a bundle directory for a periodic run — canonical JSON, band/DOS figures and CSVs, and the raw assets.
    • select: compiles a DSL expression and prints matching atom IDs.
    • analyze: groups specialised analysis modules (md, geometry, orbitals, populations, bond-orders, vibrations). Periodic packaging goes through pack periodic.
    • view: launches the GUI (--features gui) or TUI (--tui) viewer, accepts --freq for vibrational data, --select for initial highlights, and --blank to open an empty session.
    • convert, inspect, measure, canonical, batch: wrap exporter, task summary, measurement, and canonicalisation utilities. inspect includes molecular dipoles, generic task provenance and SCF histories, plus first-zone topology and folded k-path details for periodic runs. Its canonical-output path lives in handlers/commands/inspect/mod.rs; standalone MOLDEN, NWChem companion, and DIRAC checkpoint inspection lives in inspect/companion.rs.
    • smiles, inchi, identify: emit chemical identifiers for a loaded structure.
    • from-smiles: build an explicit-H scene from the supported SMILES subset and export XYZ, PDB, MOL, SDF, or scene bytes. It uses the shared orbitron-edit importer rather than a CLI-specific parser. Tetrahedral and non-ring alkene stereo are constrained during 3D generation. scripts/differential_smiles.py compares the same corpus independently under RDKit (myrdkit) or Open Babel (myopenbabel) and records agreement, disagreement, and each refusal class separately.
    • render: produce headless image renders.
    • orbital: render a molecular orbital isosurface to an image (NWChem via a companion .movecs), with --mo/--spin/--iso/--grid controls.
    • fs, config, completions: inspect data roots, persist loader thresholds, and emit shell completion scripts.
  • Global flags (all global = true, so they work before or after the subcommand): --log-level, --cell-cubic and --pbc, --data-root, --max-file-size, --max-memory, --allow-large, --no-progress, --quiet, and --stdin-format. The CLI activates tracing via tracing_subscriber::EnvFilter and loads OrbitronConfig before merging command-line overrides; environment variables still take precedence if present.
  • Resource inspection uses capacity::inspect_file_open once, then calls the pure capacity::project function with the sampled memory snapshot and configured cap. It must not call the enforcing gate or start canonical parsing. This keeps the 64 KiB ceiling meaningful and leaves JSON stdout free of prompts and warnings.
  • capacity::inspect_file_resources assembles the common source report, memory snapshot, verdict, and hard-cap field used by both the CLI command and Python’s Orbitron.resources(). Frontends validate their path policy before calling it and decide how to present the serializable result.
  • capacity::DEFAULT_TERMINAL_RESULT_LIMIT is the shared default for potentially large terminal tables. Computed bond orders, program tasks, state-energy lists, SCF cycles, SCF task sections, and CLI trajectory-frame and selection rows use it. Molpro’s specialized task, correlated-stage, multistate-energy, and XML-sidecar printers also use it; otherwise they can bypass the generic task limit. NWChem .civecs human state rows use it while JSON retains the full state array. Molcas module, diagnostic, and root lists, plus the specialized NWChem, DIRAC, and QE task summaries, use the same limit. Explicit Molpro, Molcas, and DIRAC task selectors bypass presentation truncation so users can still address later records. All omission notices report exact counts and point to complete CLI JSON. Metadata tags, element and coordination summaries, run reports, and warning lists also use the shared limit. Bond-order commands accept --limit N and require --all before printing every human-readable row or analysis. Ordinary scene bonds are reported as counts and statistics, not expanded into a raw bond list.

9.2 Terminal UI (automation/tui)

  • A keyboard-first, pane-focused inspector that shares loader/selection logic with the GUI. At any moment one pane is focused and owns the contextual keys; Tab cycles focus between the panes that exist for the loaded file (focus.rs defines Focus::{View, Atoms, Analysis, Sequence, Vibrations, Slice}).
  • The six panes: View (3D molecule, rotate/zoom), Atoms (navigable atom list), Analysis (dipole, computed bond orders, tasks, SCF, and periodic summaries plus highlight actions), Sequence (trajectory frames, Gaussian stages, NWChem tasks, read-only polymer sequences, unresolved-residue markers, and non-polymer component counts), Vibrations (normal modes and their animation), and Slice (a 2D ASCII orbital/density contour on a plane through 3 measured atoms).
  • panels/properties.rs reports editable molecular charge/multiplicity, electron count, spin parity, and atomic-formal-charge agreement. It does not expose mutation because the TUI remains an inspector rather than an editing surface.
  • State, rendering, and panes are organised as directories (state/, render/, panels/). Analysis data is cached in state/analysis_cache.rs; task and SCF rendering lives in panels/analysis/tasks.rs, bond orders in panels/analysis/bond_orders.rs, and reciprocal-space summaries in panels/analysis/periodic.rs. Other features include vibration animation (state/vibrations.rs, panels/vibrations.rs), geometry measurements (state/measurement.rs), and the 2D slice (slice.rs, state/slice_ops.rs, panels/slice_view.rs). Input handling lives in input.rs, translating key events into actions dispatched per focused pane.
  • Biological summaries are cached in state/residues.rs whenever the active scene changes. They use orbitron_backbone::residue_sequence; do not rebuild residue identity independently in a panel. Non-polymer counts include the source _chem_comp.name in parentheses when mmCIF supplies it.
  • The TUI is especially useful for headless servers where a GPU backend is unavailable; it reuses OrbitronServices with Backend::Headless.

9.3 MD analysis automation

automation/cli/src/handlers/commands/analyze.rs maps analyze md arguments onto orbitron_services::MdAnalysisRequest. The services engine processes all requested outputs in one frame pass, uses online coordinate statistics for RMSF, and calls the existing query crate for residue contacts, explicit-H hydrogen bonds, and cross-chain interfaces. Keep atom numbering conversion at the CLI/report boundary: service requests carry AtomId, while JSON and CSV use one-based scene positions.

The engine returns a complete in-memory report before write_md_report touches the destination. A progress callback can cancel after any complete frame. This ordering is part of the file contract: cancellation must not leave a final CSV or JSON that looks complete.

The persistent numerical reference is scripts/gromacs_md_analysis_differential.py. Its 11 cases cover triclinic unfitted/fitted RMSD, RMSD against a separately loaded structure, atom RMSF, mass-weighted radius of gyration, orthorhombic raw/minimum-image boundary distances, and non-empty residue-contact and hydrogen-bond occupancies. The occupancy cases compare exact frame counts and identity present-frame counts. Each case must report agree, disagree, tool_refused, or reference_refused; an empty reference table is never a pass.

External RMSD references are selected and loaded through the normal guarded scene path. The CLI preserves scene order, then passes coordinates, atomic numbers, source path, SHA-256 digest, and one-based reference atom numbers to the services engine. The engine refuses count and element-order mismatches before processing frames.

core/services/examples/xtc_render_profile.rs measures a real XTC through indexing and hashing, cold frame decode, native render-data construction, first GPU upload/draw/readback, and cached-buffer draw/readback. Generate a repeatable water box with scripts/generate_gromacs_scale_gro.py, convert the concatenated GRO to XTC with GROMACS, then run the example in release mode.