DreidTyper is a Rust library that turns a minimal MolecularGraph (atoms + bonds) into a fully typed, DREIDING-compatible topology. The pipeline is deterministic, aggressively validated, and designed for integrators who need trustworthy chemistry without shipping their own perception code.
At a high level the library walks through:
- Perception: six ordered passes (rings → Kekulé expansion → electron bookkeeping → aromaticity → resonance → hybridization) that upgrade raw connectivity into a rich
AnnotatedMolecule. - Typing: an iterative, priority-sorted rule engine that resolves the final DREIDING atom label for every atom.
- Building: a pure graph traversal that emits canonical bonds, angles, and torsions as a
MolecularTopology.
- Chemically faithful perception: built-in algorithms cover SSSR ring search, strict Kekulé expansion, charge/lone pair templates for heteroatoms, aromaticity categorization (including anti-aromatic detection), resonance propagation, and hybridization inference.
- Deterministic typing engine: TOML rules are sorted by priority and evaluated until a fixed point, making neighbor-dependent rules (e.g.,
H_HB) converge without guesswork. - Engine-agnostic topology: outputs canonicalized bonds, angles, proper and improper dihedrals ready for any simulator that consumes DREIDING-style terms.
- Extensible ruleset: ship with curated defaults (
resources/default.rules.toml) and load or merge custom rule files at runtime. - Rust-first ergonomics: zero
unsafe, comprehensive unit/integration tests, and precise error variants for validation, perception, and typing failures.
Add the crate to your Cargo.toml:
[dependencies]
dreid-typer = "0.2.1"Run the full pipeline from connectivity to topology:
use dreid_typer::{assign_topology, Element, MolecularGraph, MolecularTopology, BondOrder};
let mut graph = MolecularGraph::new();
let c1 = graph.add_atom(Element::C);
let c2 = graph.add_atom(Element::C);
let o = graph.add_atom(Element::O);
let h_o = graph.add_atom(Element::H);
let h_atoms: Vec<_> = (0..6).map(|_| graph.add_atom(Element::H)).collect();
graph.add_bond(c1, c2, BondOrder::Single).unwrap();
graph.add_bond(c2, o, BondOrder::Single).unwrap();
graph.add_bond(o, h_o, BondOrder::Single).unwrap();
for (carbon, chunk) in [c1, c2].into_iter().zip(h_atoms.chunks(3)) {
for &hydrogen in chunk {
graph.add_bond(carbon, hydrogen, BondOrder::Single).unwrap();
}
}
let topology: MolecularTopology = assign_topology(&graph).expect("perception + typing succeed");
assert_eq!(topology.atoms[c1].atom_type, "C_3");
assert_eq!(topology.atoms[c2].atom_type, "C_3");
assert_eq!(topology.atoms[o].atom_type, "O_3");
assert_eq!(topology.atoms[h_o].atom_type, "H_HB");Need custom chemistry? Parse a TOML file and run the same API:
use dreid_typer::{assign_topology_with_rules, rules, MolecularGraph};
let mut ruleset = rules::get_default_rules().to_vec();
let extra = std::fs::read_to_string("my_metals.rules.toml")?;
ruleset.extend(rules::parse_rules(&extra)?);
let topology = assign_topology_with_rules(&graph, &ruleset)?;- API Documentation - Comprehensive reference for all public types and functions.
- Architecture Documents - In-depth design and implementation details.
- Core Language: Rust
- Build System: Cargo
- Rule Format: TOML
This project is licensed under the MIT License - see the LICENSE file for details.