bio-forge-wasm 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,132 @@
1
+ <h1><img src="https://raw.githubusercontent.com/TKanX/bio-forge/main/assets/logo.svg" alt="BioForge Logo" width="50em"> BioForge</h1>
2
+
3
+ **BioForge** is a pure-Rust toolkit for automated preparation of biological macromolecules. It reads experimental structures (PDB/mmCIF), reconciles them with high-quality residue templates, repairs missing atoms, assigns hydrogens and termini, builds topologies, and optionally solvates the system with water and ions—all without leaving the Rust type system.
4
+
5
+ ## Highlights
6
+
7
+ - **Template-driven accuracy** – Curated TOML templates for standard amino acids, nucleotides, and water guarantee reproducible coordinates, charges, and bonding.
8
+ - **High performance** – Multithreaded processing (via rayon) handles million-atom systems in milliseconds; single-pass parsing, in-place mutation, and zero-copy serialization minimize overhead.
9
+ - **Rich structure model** – Lightweight `Atom`, `Residue`, `Chain`, and `Structure` types backed by `nalgebra` make geometric operations trivial.
10
+ - **Format interoperability** – Buffered readers/writers for PDB, mmCIF, and MOL2 plus error types that surface precise parsing diagnostics.
11
+ - **Preparation pipeline** – Cleaning, repairing, protonating, solvation, coordinate transforms, and topology reconstruction share a common `ops::Error` so workflows compose cleanly.
12
+ - **WebAssembly support** – Full-featured WASM bindings for modern JavaScript bundlers (Vite, webpack, Rollup); ideal for browser-based molecular viewers and web applications.
13
+ - **Rust-first ergonomics** – No FFI, no global mutable state beyond the lazily-loaded template store, and edition 2024 guarantees modern language features.
14
+
15
+ ## Processing Pipeline
16
+
17
+ ```
18
+ Load → Clean → Repair → Hydrogenate → Solvate → Topology → Write
19
+ ```
20
+
21
+ 1. **Load** – `io::read_pdb_structure` or `io::read_mmcif_structure` parses coordinates with `IoContext` alias resolution.
22
+ 2. **Clean** – `ops::clean_structure` removes waters, ions, hetero residues, or arbitrary residue names via `CleanConfig`.
23
+ 3. **Repair** – `ops::repair_structure` realigns residues to templates and rebuilds missing heavy atoms (OXT on C-termini, OP3 on 5'-phosphorylated nucleic acids).
24
+ 4. **Hydrogenate** – `ops::add_hydrogens` infers protonation states (configurable pH and histidine strategy) and reconstructs hydrogens from template anchors.
25
+ 5. **Solvate** – `ops::solvate_structure` creates a periodic box, packs water on a configurable lattice, and swaps molecules for ions to satisfy a target charge.
26
+ 6. **Topology** – `ops::TopologyBuilder` emits bond connectivity with peptide-link detection, nucleic backbone connectivity, and disulfide heuristics.
27
+ 7. **Write** – `io::write_pdb_structure` / `io::write_mmcif_structure` serialize the processed structure; `write_*_topology` helpers emit CONECT or `struct_conn` records.
28
+
29
+ ## Quick Start
30
+
31
+ ### For CLI Users
32
+
33
+ Install the latest BioForge CLI binary from the [releases page](https://github.com/TKanX/bio-forge/releases) or via `cargo`:
34
+
35
+ ```bash
36
+ cargo install bio-forge
37
+ ```
38
+
39
+ Once the `bioforge` binary is installed, you can repair a structure in a single step:
40
+
41
+ ```bash
42
+ bioforge repair -i input.pdb -o repaired.pdb
43
+ ```
44
+
45
+ Explore the complete preparation pipeline in the [user manual](MANUAL.md) and browse the [examples directory](https://github.com/TKanX/bio-forge/tree/main/examples) for runnable walkthroughs.
46
+
47
+ ### For Library Developers (Rust)
48
+
49
+ BioForge is also available as a library crate. Add it to your `Cargo.toml` dependencies:
50
+
51
+ ```toml
52
+ [dependencies]
53
+ bio-forge = "0.3.0"
54
+ ```
55
+
56
+ #### Example: Preparing a PDB Structure
57
+
58
+ ```rust
59
+ use std::{fs::File, io::{BufReader, BufWriter}};
60
+
61
+ use bio_forge::{
62
+ io::{
63
+ read_pdb_structure,
64
+ write_pdb_structure,
65
+ write_pdb_topology,
66
+ IoContext,
67
+ },
68
+ ops::{
69
+ add_hydrogens, clean_structure, repair_structure, solvate_structure,
70
+ CleanConfig, HydroConfig, SolvateConfig, TopologyBuilder,
71
+ },
72
+ };
73
+
74
+ fn main() -> Result<(), Box<dyn std::error::Error>> {
75
+ let ctx = IoContext::new_default();
76
+ let input = BufReader::new(File::open("input.pdb")?);
77
+ let mut structure = read_pdb_structure(input, &ctx)?;
78
+
79
+ clean_structure(&mut structure, &CleanConfig::water_only())?;
80
+ repair_structure(&mut structure)?;
81
+ add_hydrogens(&mut structure, &HydroConfig::default())?;
82
+ solvate_structure(&mut structure, &SolvateConfig::default())?;
83
+
84
+ let topology = TopologyBuilder::new().build(structure.clone())?;
85
+
86
+ write_pdb_structure(BufWriter::new(File::create("prepared.pdb")?), &structure)?;
87
+ write_pdb_topology(BufWriter::new(File::create("prepared-topology.pdb")?), &topology)?;
88
+ Ok(())
89
+ }
90
+ ```
91
+
92
+ > Prefer mmCIF? Swap in `read_mmcif_structure` / `write_mmcif_structure`. Need to process ligands? Parse them via `io::read_mol2_template` and feed the resulting `Template` into `TopologyBuilder::add_hetero_template`.
93
+
94
+ ### For Library Developers (JavaScript/TypeScript)
95
+
96
+ Install via npm:
97
+
98
+ ```bash
99
+ npm install bio-forge-wasm
100
+ ```
101
+
102
+ Prepare a structure with the following code:
103
+
104
+ ```typescript
105
+ import { Structure } from "bio-forge-wasm";
106
+
107
+ const pdb = await fetch("https://files.rcsb.org/view/1UBQ.pdb").then((r) =>
108
+ r.text()
109
+ );
110
+ const structure = Structure.fromPdb(pdb);
111
+
112
+ structure.clean({ removeWater: true });
113
+ structure.repair();
114
+ structure.addHydrogens({ hisStrategy: "network" });
115
+
116
+ const topology = structure.toTopology();
117
+ console.log(`Bonds: ${topology.bondCount}`);
118
+ ```
119
+
120
+ ## Documentation
121
+
122
+ | Resource | Description |
123
+ | ----------------------------------------------------------------- | ------------------------------ |
124
+ | [CLI Manual](MANUAL.md) | Command-line usage and options |
125
+ | [JS/TS API](https://github.com/TKanX/bio-forge/blob/main/API.md) | WebAssembly bindings reference |
126
+ | [Rust API](https://docs.rs/bio-forge) | Library documentation |
127
+ | [Architecture](ARCHITECTURE.md) | Internal design and algorithms |
128
+ | [Examples](https://github.com/TKanX/bio-forge/tree/main/examples) | Runnable walkthroughs |
129
+
130
+ ## License
131
+
132
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,319 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * Configuration for structure cleaning operations.
5
+ */
6
+ export interface CleanConfig {
7
+ /**
8
+ * Remove water molecules (HOH). Default: `false`
9
+ */
10
+ removeWater?: boolean;
11
+ /**
12
+ * Remove ion residues. Default: `false`
13
+ */
14
+ removeIons?: boolean;
15
+ /**
16
+ * Remove hydrogen atoms. Default: `false`
17
+ */
18
+ removeHydrogens?: boolean;
19
+ /**
20
+ * Remove hetero residues (ligands). Default: `false`
21
+ */
22
+ removeHetero?: boolean;
23
+ /**
24
+ * Specific residue names to remove. Default: `[]`
25
+ */
26
+ removeResidueNames?: string[];
27
+ /**
28
+ * Specific residue names to keep (overrides other rules). Default: `[]`
29
+ */
30
+ keepResidueNames?: string[];
31
+ }
32
+
33
+ /**
34
+ * Per-chain information.
35
+ */
36
+ export interface ChainInfo {
37
+ /**
38
+ * Chain identifier.
39
+ */
40
+ id: string;
41
+ /**
42
+ * Number of residues in this chain.
43
+ */
44
+ residueCount: number;
45
+ /**
46
+ * Number of atoms in this chain.
47
+ */
48
+ atomCount: number;
49
+ /**
50
+ * Polymer classifications present in this chain.
51
+ * Possible values: `\"protein\"`, `\"nucleic\"`, `\"solvent\"`, `\"hetero\"`.
52
+ * An empty array indicates an empty chain.
53
+ */
54
+ polymerTypes: Array<"protein" | "nucleic" | "solvent" | "hetero">;
55
+ }
56
+
57
+ /**
58
+ * Configuration for solvation.
59
+ */
60
+ export interface SolvateConfig {
61
+ /**
62
+ * Margin around solute (Å). Default: `10.0`
63
+ */
64
+ margin?: number;
65
+ /**
66
+ * Water grid spacing (Å). Default: `3.1`
67
+ */
68
+ waterSpacing?: number;
69
+ /**
70
+ * Minimum solvent-solute distance (Å). Default: `2.4`
71
+ */
72
+ vdwCutoff?: number;
73
+ /**
74
+ * Remove existing solvent before solvating. Default: `true`
75
+ */
76
+ removeExisting?: boolean;
77
+ /**
78
+ * Cation species: `\"Na\"`, `\"K\"`, `\"Mg\"`, `\"Ca\"`, `\"Li\"`, `\"Zn\"`. Default: `[\"Na\"]`
79
+ */
80
+ cations?: Array<"Na" | "K" | "Mg" | "Ca" | "Li" | "Zn">;
81
+ /**
82
+ * Anion species: `\"Cl\"`, `\"Br\"`, `\"I\"`, `\"F\"`. Default: `[\"Cl\"]`
83
+ */
84
+ anions?: Array<"Cl" | "Br" | "I" | "F">;
85
+ /**
86
+ * Target net charge after solvation. Default: `0`
87
+ */
88
+ targetCharge?: number;
89
+ /**
90
+ * Random seed for reproducible placement.
91
+ */
92
+ rngSeed?: number | undefined;
93
+ }
94
+
95
+ /**
96
+ * Comprehensive structure information.
97
+ */
98
+ export interface StructureInfo {
99
+ /**
100
+ * Number of chains.
101
+ */
102
+ chainCount: number;
103
+ /**
104
+ * Total number of residues.
105
+ */
106
+ residueCount: number;
107
+ /**
108
+ * Total number of atoms.
109
+ */
110
+ atomCount: number;
111
+ /**
112
+ * Box dimensions `[a, b, c]` in Å, if present.
113
+ */
114
+ boxLengths: [number, number, number] | undefined;
115
+ /**
116
+ * Box angles `[α, β, γ]` in degrees, if present.
117
+ */
118
+ boxAngles: [number, number, number] | undefined;
119
+ /**
120
+ * Per-chain information.
121
+ */
122
+ chains: ChainInfo[];
123
+ }
124
+
125
+ /**
126
+ * Configuration for topology building.
127
+ */
128
+ export interface TopologyConfig {
129
+ /**
130
+ * Disulfide bond cutoff (Å). Default: `2.2`
131
+ */
132
+ disulfideCutoff?: number;
133
+ }
134
+
135
+ /**
136
+ * Configuration for hydrogen addition.
137
+ */
138
+ export interface HydroConfig {
139
+ /**
140
+ * Target pH for protonation state decisions. Default: `undefined` (neutral)
141
+ */
142
+ targetPh?: number | undefined;
143
+ /**
144
+ * Remove existing hydrogens before adding new ones. Default: `true`
145
+ */
146
+ removeExistingH?: boolean;
147
+ /**
148
+ * Histidine tautomer strategy: `\"hid\"`, `\"hie\"`, `\"random\"`, `\"network\"`. Default: `\"network\"`
149
+ */
150
+ hisStrategy?: "hid" | "hie" | "random" | "network";
151
+ }
152
+
153
+
154
+ export class Structure {
155
+ private constructor();
156
+ free(): void;
157
+ [Symbol.dispose](): void;
158
+ /**
159
+ * Parses an mmCIF string into a Structure.
160
+ */
161
+ static fromMmcif(content: string): Structure;
162
+ /**
163
+ * Centers the center of mass at the origin.
164
+ */
165
+ centerMass(): void;
166
+ /**
167
+ * Builds a Topology from this structure.
168
+ */
169
+ toTopology(config?: TopologyConfig | null, templates?: Template[] | null): Topology;
170
+ /**
171
+ * Rotates using Euler angles (XYZ convention, all in radians).
172
+ */
173
+ rotateEuler(x: number, y: number, z: number): void;
174
+ /**
175
+ * Serializes to PDB format as bytes.
176
+ */
177
+ toPdbBytes(): Uint8Array;
178
+ /**
179
+ * Adds hydrogen atoms.
180
+ */
181
+ addHydrogens(config?: HydroConfig | null): void;
182
+ /**
183
+ * Parses a PDB byte array into a Structure.
184
+ */
185
+ static fromPdbBytes(content: Uint8Array): Structure;
186
+ /**
187
+ * Serializes to mmCIF format as bytes.
188
+ */
189
+ toMmcifBytes(): Uint8Array;
190
+ /**
191
+ * Centers the geometric centroid at the origin.
192
+ */
193
+ centerGeometry(): void;
194
+ /**
195
+ * Creates a deep copy of the structure.
196
+ */
197
+ clone(): Structure;
198
+ /**
199
+ * Parses an mmCIF byte array into a Structure.
200
+ */
201
+ static fromMmcifBytes(content: Uint8Array): Structure;
202
+ /**
203
+ * Returns comprehensive structure statistics.
204
+ */
205
+ info(): StructureInfo;
206
+ /**
207
+ * Removes unwanted components (water, ions, hydrogens, hetero residues).
208
+ */
209
+ clean(config?: CleanConfig | null): void;
210
+ /**
211
+ * Reconstructs missing atoms from templates.
212
+ */
213
+ repair(): void;
214
+ /**
215
+ * Serializes to PDB format.
216
+ */
217
+ toPdb(): string;
218
+ /**
219
+ * Solvates the structure with water and ions.
220
+ */
221
+ solvate(config?: SolvateConfig | null): void;
222
+ /**
223
+ * Parses a PDB string into a Structure.
224
+ */
225
+ static fromPdb(content: string): Structure;
226
+ /**
227
+ * Rotates around the X axis (angle in radians).
228
+ */
229
+ rotateX(radians: number): void;
230
+ /**
231
+ * Rotates around the Y axis (angle in radians).
232
+ */
233
+ rotateY(radians: number): void;
234
+ /**
235
+ * Rotates around the Z axis (angle in radians).
236
+ */
237
+ rotateZ(radians: number): void;
238
+ /**
239
+ * Serializes to mmCIF format.
240
+ */
241
+ toMmcif(): string;
242
+ /**
243
+ * Translates all atoms by the given vector (x, y, z in Å).
244
+ */
245
+ translate(x: number, y: number, z: number): void;
246
+ /**
247
+ * Returns the number of atoms.
248
+ */
249
+ readonly atomCount: number;
250
+ /**
251
+ * Returns the number of chains.
252
+ */
253
+ readonly chainCount: number;
254
+ /**
255
+ * Returns the number of residues.
256
+ */
257
+ readonly residueCount: number;
258
+ }
259
+
260
+ export class Template {
261
+ private constructor();
262
+ free(): void;
263
+ [Symbol.dispose](): void;
264
+ /**
265
+ * Parses a MOL2 byte array into a Template.
266
+ */
267
+ static fromMol2Bytes(content: Uint8Array): Template;
268
+ /**
269
+ * Parses a MOL2 string into a Template.
270
+ */
271
+ static fromMol2(content: string): Template;
272
+ /**
273
+ * Returns the template name (residue code).
274
+ */
275
+ readonly name: string;
276
+ }
277
+
278
+ export class Topology {
279
+ private constructor();
280
+ free(): void;
281
+ [Symbol.dispose](): void;
282
+ /**
283
+ * Serializes to PDB format as bytes.
284
+ */
285
+ toPdbBytes(): Uint8Array;
286
+ /**
287
+ * Creates a Topology from a Structure.
288
+ */
289
+ static fromStructure(structure: Structure, config?: TopologyConfig | null, templates?: Template[] | null): Topology;
290
+ /**
291
+ * Serializes to mmCIF format as bytes.
292
+ */
293
+ toMmcifBytes(): Uint8Array;
294
+ /**
295
+ * Serializes to PDB format with CONECT records.
296
+ */
297
+ toPdb(): string;
298
+ /**
299
+ * Serializes to mmCIF format with struct_conn records.
300
+ */
301
+ toMmcif(): string;
302
+ /**
303
+ * Returns the number of bonds.
304
+ */
305
+ readonly bondCount: number;
306
+ /**
307
+ * Returns a copy of the underlying structure.
308
+ */
309
+ readonly structure: Structure;
310
+ }
311
+
312
+ /**
313
+ * Initializes panic hook for better error messages in browser console.
314
+ *
315
+ * This function is automatically called when the WASM module is loaded.
316
+ * It sets up `console_error_panic_hook` to provide readable panic messages
317
+ * in the browser's developer console instead of cryptic WASM error codes.
318
+ */
319
+ export function init(): void;
@@ -0,0 +1,5 @@
1
+ import * as wasm from "./bio_forge_wasm_bg.wasm";
2
+ export * from "./bio_forge_wasm_bg.js";
3
+ import { __wbg_set_wasm } from "./bio_forge_wasm_bg.js";
4
+ __wbg_set_wasm(wasm);
5
+ wasm.__wbindgen_start();