Services Layer

7.1 Using OrbitronServices (Rust API)

use orbitron_services::{OrbitronServices, ServicesConfig, Backend};

fn main() -> anyhow::Result<()> {
    // Configure headless services (suitable for CLI tools or batch jobs).
    let config = ServicesConfig {
        enable_gpu: false,
        max_file_size: 2 * 1024 * 1024 * 1024, // 2 GiB cap
        max_atoms: 0,                          // 0 = unlimited
        max_bonds: 0,                          // 0 = unlimited
        verbose: true,
        render_backend: Backend::Headless,
        data_root: Some(std::env::current_dir()?),
    };

    let services = OrbitronServices::new(config)?;
    let scene = services.load("fixtures/benzene.xyz")?;

    // Measurements and derived data
    let distance = services.distance(&scene, 0, 1)?;
    let bbox = services.analyzer().bounding_box(&scene)?;

    // Export / render
    services.export(&scene, "benzene.pdb")?;
    services
        .renderer()
        .render_to_file(&scene, "benzene.png", 1920, 1080, None)?;

    Ok(())
}
  • Prefer the façade methods (load, distance, export) for convenience. The sub-services stay accessible via getters if you need finer control (services.loader().load_frequencies).
  • Swap in a remote data source via OrbitronServices::with_data_source and SftpDataSource::connect("[user@]host:/root"); the CLI and Python bridge follow this pattern.
  • Persistent configuration (the remote scp-style spec) lives in config.rs. OrbitronConfig resolves the platform-specific config directory via directories::ProjectDirs; both the CLI and GUI load it on start and merge it with per-run flags or environment overrides.
  • Use renderer_mut() when you need to mutate renderer options (e.g., toggling lighting presets before drawing headless renders).
  • streaming::TrajectoryStream integrates with async runtimes—feed frames into custom analysis loops without blocking the UI. The viewer uses it to stream long trajectories while rendering.