readcon-core 0.14.5

An oxidized single and multiple CON file reader and writer with FFI bindings for ergonomic C/C++ usage.
Documentation

Table of Contents

  1. About
    1. Features
    2. Migrate onto CON
    3. Install
    4. Tutorial
    5. Design Decisions
      1. FFI Layer
    6. Specification
      1. CON format
      2. convel format
    7. Capabilities
    8. Citation
  2. License

About

readcon-core is the reference implementation of versioned .con / .convel. This stack puts CON everywhere: every optimizer, potential driver, analysis tool, campaign store, and ML hand-off that needs a durable atomic configuration with constraints, forces, and identity.

CON is human-readable and complete on one frame: cell, type-grouped coordinates, per-direction fixed masks, column-5 atom_id, optional per-atom sections (velocities, forces, energies, charges, spins, magmoms), and JSON metadata (spec v2–v3, docs/orgmode/spec.org). That payload is why saddle, dimer, and NEB codes already work on CON; the library exists so the rest of the atomistic stack adopts the same file.

Already on that path: rare-event clients, rgpot, rgpycrumbs, ASE adapters, amsel, campaign stores, and anything that takes DLPack or metatensor blocks.

Rust rewrite of readCon. Chemfiles owns format diversity at the edge; this crate owns CON fidelity on the wire and in memory.

Measurements: Cachegrind I-refs (examples/cachegrind_harness.rs); Python ASV + spyglass on PRs (benchmarks/); CON peers via benches/compare_readers.py (and other scripts under benches/). See docs/orgmode/benchmarks.org.

Features

  • CON and convel: Coordinates; optional sections declared in sections (velocities, forces, energies, charges, spins, magmoms). Velocities also auto-detect on legacy .convel without a sections key.
  • Lazy iteration: ConFrameIterator; next_with_raw_span keeps the on-disk blob for corpus ingest.
  • Hot path: fast-float2, memmap2, Cachegrind-tracked scenarios.
  • Parallel frames: Rayon behind the parallel Cargo feature.
  • Bindings: Python (PyO3), Julia (ccall), C (shipped header), C++ (RAII header), Fortran (fpm); hourglass ABI patterned on metatensor.
  • Metadata helpers: Typed energy, frame_index, time, timestep, neb_bead, neb_band across bindings; raw JSON still available.
  • Validation: validate=true enforces finiteness, reserved keys, geometry, labels, symbols, section presence, identity columns.
  • Fidelity: atom_id, per-direction fixed masks, and declared optional sections round-trip through the core reader/writer.
  • Campaigns: Pair with readcon-db (CON-text indexes, dedup, multi-reader; docs · docs.rs).
  • RPC: Cap'n Proto behind the rpc feature.

Migrate onto CON

Why switch: use a real frame API and multi-language library instead of hand-rolling XYZ and a private atoms object.

  • API: parse/write, builders, metadata, validation, compression, lazy multi-frame iteration

  • Payload: constraints, atom_id, optional sections, versioned JSON on one frame

  • Selection: select_atoms / rkr_frame_select (name H, bonds/angles when topology is present)

  • Languages: hourglass rkr_* in Fortran / C / C++ / Python / Julia / Rust (same semantics when you add a language)

  • Campaigns: readcon-db on CON text (energy / formula / sections, dedup, multi-reader; docs · docs.rs)

  • Plotting: chemparseplot (+ rgpycrumbs) on the same files

  • Measurements: Cachegrind I-refs; PR ASV + spyglass; peer scripts in benches/benchmarks.org

    foreign → CON (needs --features chemfiles)

    cargo run --release --features chemfiles -- convert structure.xyz structure.con

    Python (readcon-chemfiles or maturin --features python,chemfiles)

    python -c "import readcon; readcon.convert_to_con('structure.xyz','structure.con')"

How-to: docs/orgmode/migrate.org. Chemfiles path (CI-run): chemfiles-notebook. Campaigns: readcon-db docs · docs.rs/readcon-db. Plotting: chemparseplot.

Install

The C/C++ headers are shipped (include/readcon-core.h). cbindgen is a maintainer tool, not a consumer dependency. C99 (readcon-core.h) or C++17 (readcon-core.hpp) compiler. FetchContent URL: readcon-core-cxx-$VERSION.tar.gz on the GitHub Release. Full matrix: getting-started.

Tutorial

One Good Tutorial (Diátaxis): install, read a multi-frame fixture, inspect atom_id, write a round-trip, build a frame with energy. Full steps: docs/orgmode/tutorial.org (or the published HTML tutorial page).

Short Python path from the repository root:

import readcon

for frame in readcon.iter_con("resources/test/tiny_multi_cuh2.con"):
    print(frame.cell, len(frame), frame.energy)

frames = readcon.read_con("resources/test/tiny_multi_cuh2.con")
readcon.write_con("out.con", frames)

atoms = [readcon.Atom("Cu", 0.0, 0.0, 0.0, atom_id=0, mass=63.546)]
frame = readcon.ConFrame(cell=[10.0, 10.0, 10.0], angles=[90.0, 90.0, 90.0], atoms=atoms)
frame.set_energy(-42.5)
frame.write_con("built.con")

Rust smoke (same fixture):

cargo run --example rust_usage -- resources/test/tiny_multi_cuh2.con

Other languages and task recipes: docs/orgmode/howto.org. Conversion from XYZ/PDB/GRO: chemfiles-tutorial.

Design Decisions

  • Lazy parsing: ConFrameIterator parses one frame at a time for large trajectories.
  • Hourglass FFI: shipped C header plus a hand-written C++ RAII wrapper, same pattern as metatensor. CMake FetchContent, Meson wrap, and readcon-core.pc do not run cbindgen.

FFI Layer

Two exposure modes:

  1. Opaque handles (RKRConFrame*): client calls Rust accessors (rkr_frame_get_header_line, …). Hides layout; ABI can evolve behind the handle.
  2. Transparent #[repr(C)] extract (rkr_frame_to_c_frameCFrame): client owns a flat atom table for hot loops and frees it with free_c_frame.

Specification

See docs/orgmode/spec.org (or the published HTML build) for the full specification. A summary follows.

CON format

  • A 9-line header (comments, cell dimensions, cell angles, atom type/count/mass metadata)
  • Line 2 is reserved for spec-v2 JSON metadata
  • Per-type coordinate blocks (symbol, label, atom lines with x y z fixed atomID)
  • Optional spec-v2 sections and validate metadata for declared per-atom sections and strict validation
  • Multiple frames are concatenated directly with no separator

convel format

Same as CON, with an additional velocity section after each frame's coordinates:

  • A blank separator line
  • Per-type velocity blocks (symbol, label, atom lines with vx vy vz fixed atomID)

Capabilities

Predecessor: readCon.

Citation

If you use readcon-core in academic work, please cite it via the metadata in CITATION.cff. The Zenodo DOI tracks the latest release.

License

MIT.