{"id":37073368,"url":"https://github.com/lode-org/readcon-core","last_synced_at":"2026-05-10T22:06:07.187Z","repository":{"id":305245455,"uuid":"999216744","full_name":"lode-org/readcon-core","owner":"lode-org","description":"Oxidized rewrite of readCon","archived":false,"fork":false,"pushed_at":"2026-03-27T19:19:25.000Z","size":687,"stargazers_count":1,"open_issues_count":9,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-02T08:38:20.800Z","etag":null,"topics":["chemistry","parser"],"latest_commit_sha":null,"homepage":"https://lode-org.github.io/readcon-core/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lode-org.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-09T23:27:03.000Z","updated_at":"2026-03-27T19:19:29.000Z","dependencies_parsed_at":"2025-07-19T21:15:43.837Z","dependency_job_id":null,"html_url":"https://github.com/lode-org/readcon-core","commit_stats":null,"previous_names":["lode-org/readcon-rs","lode-org/readcon-core"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/lode-org/readcon-core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lode-org%2Freadcon-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lode-org%2Freadcon-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lode-org%2Freadcon-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lode-org%2Freadcon-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lode-org","download_url":"https://codeload.github.com/lode-org/readcon-core/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lode-org%2Freadcon-core/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32031070,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chemistry","parser"],"created_at":"2026-01-14T08:36:44.845Z","updated_at":"2026-05-10T22:06:07.174Z","avatar_url":"https://github.com/lode-org.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Table of Contents\n\n1.  [About](#org6c05cb6)\n    1.  [Features](#orgdaee6f9)\n    2.  [Install](#org6030511)\n    3.  [Tutorial](#org396efa6)\n    4.  [Design Decisions](#org9e2ac18)\n        1.  [FFI Layer](#org821878d)\n    5.  [Specification](#orgdd36a00)\n        1.  [CON format](#org5e88f7d)\n        2.  [convel format](#org4b3e8e7)\n    6.  [Why use this over readCon?](#org7a9436c)\n    7.  [Citation](#org4154b3e)\n2.  [License](#org45415ab)\n\n\n\u003ca id=\"org6c05cb6\"\u003e\u003c/a\u003e\n\n# About\n\nOxidized rust re-implementation of [readCon](https://github.com/HaoZeke/readCon).\n\nReads and writes both `.con` (coordinate-only) and `.convel` (coordinates\nplus velocities) simulation configuration files used by [eOn](https://theory.cm.utexas.edu/eon/).\n\n\n\u003ca id=\"orgdaee6f9\"\u003e\u003c/a\u003e\n\n## Features\n\n-   **CON and convel support:** Parses both coordinate-only and velocity-augmented files. Velocity sections are auto-detected without relying on file extensions.\n-   **Lazy iteration:** `ConFrameIterator` parses one frame at a time for memory-efficient trajectory processing.\n-   **Performance:** Uses [fast-float2](https://github.com/aldanor/fast-float-rust) (Eisel-Lemire algorithm) for the f64 parsing hot path and [memmap2](https://docs.rs/memmap2) for large trajectory files.\n-   **Parallel parsing:** Optional rayon-based parallel frame parsing behind the `parallel` feature gate.\n-   **Language bindings:** Python (PyO3), Julia (ccall), C (cbindgen FFI), and C++ (RAII header-only wrapper), following the hourglass design from [Metatensor](https://github.com/metatensor/metatensor).\n-   **Spec-v2 metadata helpers:** Rust, Python, Julia, C, and C++ bindings all expose typed helpers for common JSON metadata keys like `energy`, `frame_index`, `time`, `timestep`, `neb_bead`, and `neb_band`, while still allowing raw JSON metadata when needed.\n-   **Spec-v2 validation:** `validate=true` enforces finite numeric values, reserved metadata schema, physical header geometry, exact component labels, valid symbols, declared section presence, and matching per-atom identity columns.\n-   **Force and constraint fidelity:** Writers preserve velocities, forces, original atom ids, and per-axis fixed masks across Rust, Python, Julia, C, and C++.\n-   **RPC serving:** Optional Cap'n Proto RPC interface (`rpc` feature) for network-accessible parsing.\n\n\n\u003ca id=\"org6030511\"\u003e\u003c/a\u003e\n\n## Install\n\n\u003ctable border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\"\u003e\n\n\n\u003ccolgroup\u003e\n\u003ccol  class=\"org-left\" /\u003e\n\n\u003ccol  class=\"org-left\" /\u003e\n\u003c/colgroup\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth scope=\"col\" class=\"org-left\"\u003eLanguage\u003c/th\u003e\n\u003cth scope=\"col\" class=\"org-left\"\u003eInstall command\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd class=\"org-left\"\u003eRust\u003c/td\u003e\n\u003ctd class=\"org-left\"\u003e\u003ccode\u003ecargo add readcon-core\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd class=\"org-left\"\u003ePython\u003c/td\u003e\n\u003ctd class=\"org-left\"\u003e\u003ccode\u003epip install readcon\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd class=\"org-left\"\u003eJulia\u003c/td\u003e\n\u003ctd class=\"org-left\"\u003e\u003ccode\u003ejulia --project=julia/ReadCon -e 'using Pkg; Pkg.instantiate()'\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd class=\"org-left\"\u003eC / C++ system\u003c/td\u003e\n\u003ctd class=\"org-left\"\u003e\u003ccode\u003ecargo cinstall --release --prefix /usr/local\u003c/code\u003e (installs \u003ccode\u003elibreadcon_core.{so,a}\u003c/code\u003e, \u003ccode\u003ereadcon-core.h\u003c/code\u003e, \u003ccode\u003ereadcon-core.hpp\u003c/code\u003e, and a pkg-config file)\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003ctd class=\"org-left\"\u003eC / C++ via meson subproject\u003c/td\u003e\n\u003ctd class=\"org-left\"\u003edrop the repository under \u003ccode\u003esubprojects/readcon-core/\u003c/code\u003e and link against the \u003ccode\u003ereadcon_core_dep\u003c/code\u003e dependency\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\nThe C/C++ headers require a C99 (`readcon-core.h`) or C++17 (`readcon-core.hpp`, for `std::optional` and `std::filesystem`) compiler.\n\n\n\u003ca id=\"org396efa6\"\u003e\u003c/a\u003e\n\n## Tutorial\n\nA copy-pasteable walkthrough that parses a multi-frame trajectory, inspects metadata, builds a new frame, and writes it back. Run it as-is.\n\n    cargo run --example rust_usage -- resources/test/tiny_multi_cuh2.con\n\nThe example above iterates lazily over every frame, prints atom counts plus the per-frame energy if present, and exits. Equivalent flows in the other bindings:\n\n    import readcon\n    \n    # Read every frame; the iterator yields PyConFrame objects\n    for frame in readcon.iter_frames(\"resources/test/tiny_multi_cuh2.con\"):\n        print(frame.natms_per_type, frame.energy())  # energy() is None when absent\n    \n    # Build and write a new frame\n    b = readcon.ConFrameBuilder(cell=[10.0, 10.0, 10.0], angles=[90.0, 90.0, 90.0])\n    b.set_energy(-42.5).add_atom(\"Cu\", 0.0, 0.0, 0.0, 1, 63.546)\n    b.write(\"out.con\")\n\n    using ReadCon\n    for frame in iter_frames(\"resources/test/tiny_multi_cuh2.con\")\n        println(frame.natms_per_type, \" \", energy(frame))\n    end\n\n    #include \u003creadcon-core.hpp\u003e\n    #include \u003ciostream\u003e\n    \n    int main() {\n        readcon::ConFrameIterator it(\"resources/test/tiny_multi_cuh2.con\");\n        for (const auto \u0026frame : it) {\n            std::cout \u003c\u003c frame.atoms().size() \u003c\u003c \" atoms\";\n            if (auto e = frame.energy_opt()) std::cout \u003c\u003c \" E=\" \u003c\u003c *e;\n            std::cout \u003c\u003c \"\\n\";\n        }\n    }\n\n    #include \u003creadcon-core.h\u003e\n    #include \u003cstdio.h\u003e\n    \n    int main(void) {\n        uintptr_t n = 0;\n        RKRConFrame **frames = rkr_read_all_frames(\"resources/test/tiny_multi_cuh2.con\", \u0026n);\n        for (uintptr_t i = 0; i \u003c n; ++i) {\n            printf(\"frame %zu energy=%f\\n\", i, rkr_frame_energy(frames[i]));\n        }\n        free_rkr_frame_array(frames, n);\n    }\n\n\n\u003ca id=\"org9e2ac18\"\u003e\u003c/a\u003e\n\n## Design Decisions\n\nThe library is designed with the following principles in mind:\n\n-   **Lazy Parsing:** The `ConFrameIterator` allows for lazy parsing of frames, which can be more memory-efficient when dealing with large trajectory files.\n\n-   **Interoperability:** The FFI layer makes the core parsing logic accessible from other programming languages, increasing the library's utility. Currently, a `C` header is auto-generated along with a hand-crafted `C++` interface, following the hourglass design from [Metatensor](https://github.com/metatensor/metatensor).\n\n\n\u003ca id=\"org821878d\"\u003e\u003c/a\u003e\n\n### FFI Layer\n\nA key challenge in designing an FFI is deciding how data is exposed to the C-compatible world. This library uses a hybrid approach to offer both safety and convenience:\n\n1.  **Opaque Pointers (The Handle Pattern):** The primary way to interact with\n    frame data is through an opaque pointer, represented as `RKRConFrame*` in C.\n    The C/C++ client holds this \"handle\" but cannot inspect its contents\n    directly. Instead, it must call Rust functions to interact with the data\n    (e.g., `rkr_frame_get_header_line(frame_handle, ...)`). This is the safest\n    and most flexible pattern, as it completely hides Rust's internal data\n    structures and memory layout, preventing ABI breakage if the Rust code is\n    updated.\n\n2.  **Transparent `#[repr(C)]` Structs (The Data Extraction Pattern):** For\n    convenience and performance in cases where only the core atomic data is\n    needed, the library provides a function (`rkr_frame_to_c_frame`) to extract a\n    \"lossy\" but transparent `CFrame` struct from an opaque handle. The C/C++\n    client can directly read the fields of this struct (e.g.,\n    `my_c_frame-\u003enum_atoms`). The client takes ownership of this extracted struct\n    and is responsible for freeing its memory.\n\nThis hybrid model provides the best of both worlds: the safety and\nforward-compatibility of opaque handles for general use, and the performance of\ndirect data access for the most common computational tasks.\n\n\n\u003ca id=\"orgdd36a00\"\u003e\u003c/a\u003e\n\n## Specification\n\nSee [docs/orgmode/spec.org](docs/orgmode/spec.md) (or the [published HTML build](https://lode-org.github.io/readcon-core/spec.html)) for the full specification. A summary follows.\n\n\n\u003ca id=\"org5e88f7d\"\u003e\u003c/a\u003e\n\n### CON format\n\n-   A 9-line header (comments, cell dimensions, cell angles, atom type/count/mass metadata)\n-   Line 2 is reserved for spec-v2 JSON metadata\n-   Per-type coordinate blocks (symbol, label, atom lines with x y z fixed atomID)\n-   Optional spec-v2 `sections` and `validate` metadata for declared per-atom sections and strict validation\n-   Multiple frames are concatenated directly with no separator\n\n\n\u003ca id=\"org4b3e8e7\"\u003e\u003c/a\u003e\n\n### convel format\n\nSame as CON, with an additional velocity section after each frame's coordinates:\n\n-   A blank separator line\n-   Per-type velocity blocks (symbol, label, atom lines with vx vy vz fixed atomID)\n\n\n\u003ca id=\"org7a9436c\"\u003e\u003c/a\u003e\n\n## Why use this over [readCon](https://github.com/HaoZeke/readCon)?\n\nSpeed, correctness, and multi-language bindings.\n\n\n\u003ca id=\"org4154b3e\"\u003e\u003c/a\u003e\n\n## Citation\n\nIf you use `readcon-core` in academic work, please cite it via the metadata in [CITATION.cff](CITATION.cff). The Zenodo DOI tracks the latest release.\n\n\n\u003ca id=\"org45415ab\"\u003e\u003c/a\u003e\n\n# License\n\nMIT.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flode-org%2Freadcon-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flode-org%2Freadcon-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flode-org%2Freadcon-core/lists"}