1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! A high-performance, pure Rust library for automated DREIDING force field parameterization.
//! It orchestrates structure repair, topology perception, and partial atomic charge calculation
//! to produce simulation-ready inputs for both biological macromolecules and arbitrary chemical systems.
//!
//! # Features
//!
//! - **Atom typing** — Automatic assignment of DREIDING atom types based on
//! element, hybridization, and local bonding environment
//! - **Flexible charge calculation** — Global QEq, hybrid (classical + QEq), or
//! embedded QEq with environment polarization for ligands in protein complexes
//! - **Parameter generation** — Bond, angle, torsion, inversion, van der Waals,
//! and hydrogen bond potentials with multiple functional forms
//! - **Flexible I/O** — Read/write PDB, mmCIF, MOL2, SDF formats; export to BGF
//!
//! # Quick Start
//!
//! The main entry point is the [`forge`] function, which takes a [`System`] and
//! [`ForgeConfig`] and produces a fully parameterized [`ForgedSystem`]:
//!
//! ```
//! use dreid_forge::{System, Atom, Bond, Element, BondOrder};
//! use dreid_forge::{forge, ForgeConfig, ForgeError};
//!
//! // Build an ethanol molecule (C₂H₅OH)
//! let mut system = System::new();
//!
//! // Atoms: C1 (methyl), C2 (methylene), O, and hydrogens
//! system.atoms.push(Atom::new(Element::C, [-1.270, 0.248, 0.000])); // C1
//! system.atoms.push(Atom::new(Element::C, [ 0.139, -0.308, 0.000])); // C2
//! system.atoms.push(Atom::new(Element::O, [ 1.036, 0.789, 0.000])); // O
//! system.atoms.push(Atom::new(Element::H, [-1.317, 0.885, 0.883])); // H on C1
//! system.atoms.push(Atom::new(Element::H, [-1.317, 0.885, -0.883])); // H on C1
//! system.atoms.push(Atom::new(Element::H, [-2.030, -0.533, 0.000])); // H on C1
//! system.atoms.push(Atom::new(Element::H, [ 0.358, -0.920, 0.876])); // H on C2
//! system.atoms.push(Atom::new(Element::H, [ 0.358, -0.920, -0.876])); // H on C2
//! system.atoms.push(Atom::new(Element::H, [ 1.939, 0.473, 0.000])); // H on O
//!
//! // Bonds
//! system.bonds.push(Bond::new(0, 1, BondOrder::Single)); // C1-C2
//! system.bonds.push(Bond::new(1, 2, BondOrder::Single)); // C2-O
//! system.bonds.push(Bond::new(0, 3, BondOrder::Single)); // C1-H
//! system.bonds.push(Bond::new(0, 4, BondOrder::Single)); // C1-H
//! system.bonds.push(Bond::new(0, 5, BondOrder::Single)); // C1-H
//! system.bonds.push(Bond::new(1, 6, BondOrder::Single)); // C2-H
//! system.bonds.push(Bond::new(1, 7, BondOrder::Single)); // C2-H
//! system.bonds.push(Bond::new(2, 8, BondOrder::Single)); // O-H
//!
//! // Parameterize with default settings
//! let forged = forge(&system, &ForgeConfig::default())?;
//!
//! // Atom types: C_3 (sp³ carbon), O_3 (sp³ oxygen), H_, H_HB (H-bond donor)
//! assert_eq!(forged.atom_types.len(), 4);
//! assert!(forged.atom_types.contains(&"C_3".to_string()));
//! assert!(forged.atom_types.contains(&"O_3".to_string()));
//! assert!(forged.atom_types.contains(&"H_HB".to_string()));
//!
//! // Per-atom properties: charge, mass, type index
//! assert_eq!(forged.atom_properties.len(), 9);
//!
//! // Bond potentials: C-C, C-O, C-H, O-H
//! assert_eq!(forged.potentials.bonds.len(), 8);
//!
//! // Angle potentials: all angles around sp³ centers
//! assert_eq!(forged.potentials.angles.len(), 13);
//!
//! // Torsion potentials: H-C-C-H, H-C-C-O, C-C-O-H, H-C-O-H
//! assert_eq!(forged.potentials.torsions.len(), 12);
//!
//! // Inversion potentials: none for all-sp³ molecule
//! assert!(forged.potentials.inversions.is_empty());
//!
//! // VdW pair potentials: n(n+1)/2 = 4×5/2 = 10 pairs
//! assert_eq!(forged.potentials.vdw_pairs.len(), 10);
//!
//! // H-bond potential: O_3 as donor/acceptor with H_HB
//! assert_eq!(forged.potentials.h_bonds.len(), 1);
//! # Ok::<(), ForgeError>(())
//! ```
//!
//! # Module Organization
//!
//! - [`io`] — File I/O for molecular structures (PDB, mmCIF, MOL2, SDF, BGF)
//! - [`forge`] — Main parameterization function
//! - [`ForgeConfig`] — Configuration for potential types and charge methods
//!
//! # Data Types
//!
//! ## Input Structures
//!
//! - [`System`] — Molecular system with atoms, bonds, and optional metadata
//! - [`Atom`] — Single atom with element and Cartesian coordinates
//! - [`Bond`] — Bond between two atoms with bond order
//! - [`Element`] — Chemical element (H through Og)
//! - [`BondOrder`] — Bond order (Single, Double, Triple, Aromatic)
//!
//! ## Output Structures
//!
//! - [`ForgedSystem`] — Fully parameterized system ready for simulation
//! - [`AtomParam`] — Per-atom charge, mass, and type index
//! - [`Potentials`] — Collection of all potential energy functions
//! - [`BondPotential`] — Harmonic or Morse bond stretching
//! - [`AnglePotential`] — Cosine-harmonic, cosine-linear, or theta-harmonic bending
//! - [`TorsionPotential`] — Periodic torsion potentials
//! - [`InversionPotential`] — Planar or umbrella out-of-plane terms
//! - [`VdwPairPotential`] — Lennard-Jones or Buckingham dispersion
//! - [`HBondPotential`] — Directional hydrogen bond terms
//!
//! ## Configuration
//!
//! - [`ChargeMethod`] — None, QEq, or Hybrid charge equilibration
//! - [`QeqConfig`] — QEq solver settings (total charge, convergence)
//! - [`HybridConfig`] — Hybrid biological/QEq charge assignment settings
//! - [`BondPotentialType`] — Harmonic vs Morse selection
//! - [`AnglePotentialType`] — Cosine vs theta-harmonic selection
//! - [`VdwPotentialType`] — Lennard-Jones vs Buckingham selection
//!
//! ## Biological Metadata
//!
//! - [`BioMetadata`] — Per-atom PDB/mmCIF annotations
//! - [`AtomResidueInfo`] — Residue name, chain, sequence number
//! - [`StandardResidue`] — Standard amino acids and nucleotides
//! - [`ResidueCategory`] — Standard, hetero, or ion classification
//! - [`ResiduePosition`] — Terminal position (N/C-terminal, 5'/3'-end)
pub use Atom;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use Error as ForgeError;