@molcrafts/molrs 0.0.1 → 0.0.5

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/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2025, MolCrafts
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md CHANGED
@@ -1,175 +1,86 @@
1
- # molrs-wasm: WASM bindings for molrs
1
+ # @molcrafts/molrs
2
2
 
3
- Object-oriented WASM bindings for molrs using FFI handle-based architecture.
3
+ [![npm](https://img.shields.io/npm/v/@molcrafts/molrs.svg)](https://www.npmjs.com/package/@molcrafts/molrs)
4
4
 
5
- ## Quick Start
5
+ WebAssembly bindings for the [molrs](https://github.com/MolCrafts/molrs) molecular modeling toolkit.
6
6
 
7
- ```javascript
8
- import init, { Frame, XyzReader } from './pkg/molrs.js';
7
+ ## Install
9
8
 
10
- await init();
11
-
12
- // Create a new frame
13
- const frame = new Frame();
14
- const atoms = frame.createBlock("atoms");
15
-
16
- // Set column data
17
- atoms.setColumnF32("x", new Float32Array([1.0, 2.0, 3.0]));
18
- const data = atoms.getColumnF32("x");
19
-
20
- // Read from file
21
- const reader = new XyzReader(fileContent);
22
- const loadedFrame = reader.read(0);
23
- ```
24
-
25
- ## API Reference
26
-
27
- ### Frame
28
-
29
- The main container for molecular data.
30
-
31
- ```javascript
32
- const frame = new Frame();
33
-
34
- // Create a block
35
- const atoms = frame.createBlock("atoms");
36
-
37
- // Get an existing block
38
- const atomsAgain = frame.getBlock("atoms");
39
-
40
- // Remove a block
41
- frame.removeBlock("atoms");
42
-
43
- // Clear all blocks
44
- frame.clear();
45
-
46
- // Drop the frame (invalidates all blocks)
47
- frame.drop();
9
+ ```bash
10
+ npm install @molcrafts/molrs
48
11
  ```
49
12
 
50
- ### Block
13
+ ## Quick start
51
14
 
52
- A block contains columnar data with consistent row counts.
15
+ ```js
16
+ import init, { parseSMILES, generate3D, writeFrame } from "@molcrafts/molrs";
53
17
 
54
- ```javascript
55
- const block = frame.createBlock("atoms");
56
-
57
- // Set column data
58
- const positions = new Float32Array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
59
- const shape = new Uint32Array([2, 3]); // 2 atoms, 3 coordinates each
60
- block.setColumnF32("positions", positions, shape);
61
-
62
- // Set integer columns (e.g., atom ids or bond indices)
63
- const ids = new BigInt64Array([1n, 2n, 3n]);
64
- block.setColumnI64("id", ids);
65
-
66
- // Get column data (returns copy)
67
- const data = block.getColumnF32("positions"); // Float32Array
68
- const idData = block.getColumnI64("id"); // BigInt64Array
69
-
70
- // Get column with shape info
71
- const { data, shape } = block.getColumnF32WithShape("positions");
18
+ await init();
72
19
 
73
- // Query block info
74
- const keys = block.keys(); // ["positions"]
75
- const nrows = block.nrows(); // 2
20
+ // Parse SMILES → 3D coordinates → XYZ string
21
+ const ir = parseSMILES("CCO");
22
+ const frame = ir.toFrame();
23
+ const mol3d = generate3D(frame, "fast");
24
+ console.log(writeFrame(mol3d, "xyz"));
76
25
  ```
77
26
 
78
- ## File I/O
27
+ ## API
79
28
 
80
- ### Reading Files
29
+ ### Data model
81
30
 
82
- ```javascript
83
- // XYZ files
84
- const xyzReader = new XyzReader(fileContent);
85
- const frameCount = xyzReader.len();
86
- const frame = xyzReader.read(0); // Read frame 0
31
+ - **`Frame`** — container mapping string keys (`"atoms"`, `"bonds"`) to `Block`s
32
+ - **`Block`** — column store with typed arrays (`Float32Array`, `Int32Array`, `Uint32Array`, `string[]`)
33
+ - **`Box`** simulation box with periodic boundary conditions
87
34
 
88
- // PDB files
89
- const pdbReader = new PdbReader(pdbContent);
90
- const frame2 = pdbReader.read(0);
35
+ ### I/O
91
36
 
92
- // LAMMPS data files
93
- const lammpsReader = new LammpsReader(lammpsContent);
94
- const frame3 = lammpsReader.read(0);
95
- ```
37
+ - `parseSMILES(smiles)` `SmilesIR` → `.toFrame()`
38
+ - `XYZReader`, `PDBReader`, `LAMMPSReader` — file format parsers
39
+ - `writeFrame(frame, "xyz" | "pdb")` — serialize to string
40
+ - `SimulationReader` — Zarr V3 trajectory reader
96
41
 
97
- ### Writing Files
42
+ ### 3D generation
98
43
 
99
- ```javascript
100
- // TODO: Writer API needs implementation
101
- // const output = writeFrame(frame, "xyz");
102
- ```
44
+ - `generate3D(frame, speed?)` — MMFF94 coordinate generation (`"fast"` | `"normal"` | `"thorough"`)
103
45
 
104
- ## TypeScript Example
46
+ ### Analysis
105
47
 
106
- ```typescript
107
- import init, { Frame, Block, XyzReader } from './pkg/molrs.js';
48
+ ```js
49
+ import { LinkedCell, RDF } from "@molcrafts/molrs";
108
50
 
109
- await init();
51
+ const lc = new LinkedCell(5.0); // cutoff = 5.0 A
52
+ const nlist = lc.build(frame); // self-query (unique pairs i < j)
53
+ const cross = lc.query(refFrame, other); // cross-query
110
54
 
111
- // Create frame and block
112
- const frame: Frame = new Frame();
113
- const atoms: Block = frame.createBlock("atoms");
114
-
115
- // Set positions
116
- const positions = new Float32Array([
117
- 0.0, 0.0, 0.0, // atom 1
118
- 1.0, 0.0, 0.0, // atom 2
119
- 0.0, 1.0, 0.0, // atom 3
120
- ]);
121
- atoms.setColumnF32("x", positions);
122
-
123
- // Query data
124
- const nAtoms = atoms.nrows(); // 3
125
- const x = atoms.getColumnF32("x");
126
- console.log(x[0]); // 0.0
127
-
128
- // Read from file
129
- const reader = new XyzReader(fileContent);
130
- const loadedFrame = reader.read(0);
131
- if (loadedFrame) {
132
- const loadedAtoms = loadedFrame.getBlock("atoms");
133
- if (loadedAtoms) {
134
- console.log(`Loaded ${loadedAtoms.nrows()} atoms`);
135
- }
136
- }
55
+ const rdf = new RDF(100, 5.0);
56
+ const result = rdf.compute(frame, nlist);
57
+ console.log(result.binCenters(), result.rdf());
137
58
  ```
138
59
 
139
- ## Handle Invalidation
60
+ - **`LinkedCell`** — cell-list neighbor search (`build()` for self-query, `query()` for cross-query)
61
+ - **`RDF`** — radial distribution function (periodic and free-boundary)
62
+ - **`MSD`** — mean squared displacement
63
+ - **`Cluster`** — distance-based cluster analysis
140
64
 
141
- Handles follow strict invalidation rules:
65
+ Frames without a simulation box are supported — a non-periodic bounding box is auto-generated.
142
66
 
143
- - **Block handles** become invalid when:
144
- - The parent frame is dropped
145
- - The block is removed from the frame
146
- - The frame is cleared
67
+ ### Block column conventions
147
68
 
148
- - **Frame handles** become invalid when:
149
- - `frame.drop()` is called
69
+ | Block | Column | Type | Description |
70
+ |-------|--------|------|-------------|
71
+ | `atoms` | `symbol` | `string` | Element symbol |
72
+ | `atoms` | `x`, `y`, `z` | `f32` | Cartesian coordinates |
73
+ | `atoms` | `mass` | `f32` | Atomic mass |
74
+ | `atoms` | `charge` | `f32` | Partial charge |
75
+ | `bonds` | `i`, `j` | `u32` | Atom indices |
76
+ | `bonds` | `order` | `f32` | Bond order (1.0, 1.5, 2.0, 3.0) |
150
77
 
151
- Attempting to use an invalid handle will throw an error.
152
-
153
- ## Architecture
154
-
155
- This WASM layer is a thin wrapper around `molrs-ffi`, which provides:
156
- - Stable handle-based references (no raw pointers)
157
- - Explicit invalidation semantics
158
- - Consistent behavior across Python and WASM
159
-
160
- The API is designed to be:
161
- - **Object-oriented**: Natural class hierarchy (Frame → Block)
162
- - **Type-safe**: Clear ownership and lifetime semantics
163
- - **Explicit**: No hidden copies or implicit conversions
164
- - **Simple**: Store is hidden - Frame is the main entry point
165
-
166
- ## Testing
78
+ ## Build from source
167
79
 
168
80
  ```bash
169
- cargo test -p molrs-wasm --lib
81
+ wasm-pack build --target bundler --scope molcrafts --out-name molrs
170
82
  ```
171
83
 
172
- For WASM-specific tests:
173
- ```bash
174
- wasm-pack test --node wasm
175
- ```
84
+ ## License
85
+
86
+ BSD-3-Clause