@kent-tokyo/chematic 0.1.3 → 0.1.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/README.md CHANGED
@@ -2,38 +2,66 @@
2
2
 
3
3
  WebAssembly bindings for [chematic](https://github.com/kent-tokyo/chematic), a pure-Rust cheminformatics library.
4
4
 
5
- This crate exposes `#[wasm_bindgen]` bindings so that chematic can be used directly from JavaScript and TypeScript in the browser or Node.js.
5
+ Published to npm as [`@kent-tokyo/chematic`](https://www.npmjs.com/package/@kent-tokyo/chematic).
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm install @kent-tokyo/chematic
11
+ ```
6
12
 
7
13
  ## Features
8
14
 
9
15
  - Parse SMILES strings into molecule handles
10
- - Compute molecular descriptors: molecular weight, TPSA, formula, heavy atom count, H-bond donors/acceptors
16
+ - Molecular descriptors: MW, TPSA, LogP, Fsp3, QED, exact mass, rotatable bonds, HBD/HBA, aromatic ring count
11
17
  - Lipinski Rule-of-Five check
12
18
  - Canonical SMILES generation
13
- - ECFP4 fingerprints and Tanimoto similarity
19
+ - ECFP4, AtomPair, and Topological Torsion fingerprints with Tanimoto similarity
20
+ - BRICS fragment count
14
21
 
15
22
  ## Usage
16
23
 
17
- Build with [wasm-pack](https://rustwasm.github.io/wasm-pack/):
24
+ ```js
25
+ import init, {
26
+ parse_smiles,
27
+ tanimoto_ecfp4,
28
+ tanimoto_atom_pair,
29
+ tanimoto_torsion,
30
+ brics_fragment_count,
31
+ } from '@kent-tokyo/chematic';
18
32
 
19
- ```sh
20
- wasm-pack build --target web
21
- ```
33
+ await init();
22
34
 
23
- Then in JavaScript/TypeScript:
35
+ const mol = parse_smiles('CC(=O)Oc1ccccc1C(=O)O'); // aspirin
24
36
 
25
- ```js
26
- import init, { parse_smiles, tanimoto_ecfp4 } from './pkg/chematic_wasm.js';
37
+ // Descriptors
38
+ console.log(mol.atom_count()); // 13
39
+ console.log(mol.molecular_weight()); // ~180.16
40
+ console.log(mol.formula()); // "C9H8O4"
41
+ console.log(mol.tpsa()); // ~63.6
42
+ console.log(mol.logp_crippen()); // ~1.2
43
+ console.log(mol.fsp3()); // ~0.111
44
+ console.log(mol.qed()); // drug-likeness score [0, 1]
45
+ console.log(mol.exact_mass()); // ~180.042
46
+ console.log(mol.hbd_count()); // 1
47
+ console.log(mol.hba_count()); // 4
48
+ console.log(mol.rotatable_bond_count()); // 3
49
+ console.log(mol.aromatic_ring_count()); // 1
50
+ console.log(mol.lipinski_passes()); // true
51
+ console.log(mol.canonical_smiles()); // canonical SMILES string
27
52
 
28
- await init();
53
+ // BRICS fragmentation
54
+ console.log(brics_fragment_count(mol)); // ≥ 2
29
55
 
30
- const mol = parse_smiles('c1ccccc1');
31
- console.log(mol.atom_count()); // 6
32
- console.log(mol.molecular_weight()); // ~78.11
33
- console.log(mol.formula()); // "C6H6"
34
- console.log(mol.lipinski_passes()); // true
56
+ // Fingerprint similarity
57
+ const caffeine = parse_smiles('Cn1cnc2c1c(=O)n(c(=O)n2C)C');
58
+ console.log(tanimoto_ecfp4(mol, caffeine)); // ECFP4 Tanimoto
59
+ console.log(tanimoto_atom_pair(mol, caffeine)); // AtomPair Tanimoto
60
+ console.log(tanimoto_torsion(mol, caffeine)); // Torsion Tanimoto
61
+ ```
62
+
63
+ ## Building from source
35
64
 
36
- const aspirin = parse_smiles('CC(=O)Oc1ccccc1C(=O)O');
37
- const sim = tanimoto_ecfp4(mol, aspirin);
38
- console.log(sim); // < 1.0
65
+ ```sh
66
+ wasm-pack build --target bundler --release
39
67
  ```
@@ -9,6 +9,10 @@ export class MolHandle {
9
9
  private constructor();
10
10
  free(): void;
11
11
  [Symbol.dispose](): void;
12
+ /**
13
+ * Number of aromatic rings (all ring atoms aromatic).
14
+ */
15
+ aromatic_ring_count(): number;
12
16
  /**
13
17
  * Number of heavy atoms (explicit atoms in the graph; does not count implicit H).
14
18
  */
@@ -21,10 +25,36 @@ export class MolHandle {
21
25
  * Canonical SMILES string.
22
26
  */
23
27
  canonical_smiles(): string;
28
+ /**
29
+ * 2D SVG depiction of the molecule (CPK coloring).
30
+ */
31
+ depict_svg(): string;
32
+ /**
33
+ * Returns `true` if the molecule passes Egan's absorption criteria
34
+ * (TPSA ≤ 131.6 Ų and LogP ≤ 5.88).
35
+ */
36
+ egan_passes(): boolean;
37
+ /**
38
+ * Monoisotopic (exact) mass.
39
+ */
40
+ exact_mass(): number;
41
+ /**
42
+ * Sum of formal charges.
43
+ */
44
+ formal_charge_sum(): number;
24
45
  /**
25
46
  * Molecular formula string (Hill notation: C first, H second, then alphabetical).
26
47
  */
27
48
  formula(): string;
49
+ /**
50
+ * Fraction of sp3 carbons (Fsp3).
51
+ */
52
+ fsp3(): number;
53
+ /**
54
+ * Returns `true` if the molecule passes Ghose's drug-likeness filter
55
+ * (MW 160–480, LogP −0.4–5.6, HeavyAtoms 20–70, MR 40–130).
56
+ */
57
+ ghose_passes(): boolean;
28
58
  /**
29
59
  * Number of hydrogen bond acceptors (Lipinski: all N and O atoms).
30
60
  */
@@ -41,16 +71,84 @@ export class MolHandle {
41
71
  * Returns `true` if the molecule satisfies Lipinski's Rule of Five.
42
72
  */
43
73
  lipinski_passes(): boolean;
74
+ /**
75
+ * Crippen–Wildman octanol/water partition coefficient (LogP).
76
+ */
77
+ logp_crippen(): number;
78
+ /**
79
+ * Wildman–Crippen molar refractivity (MR).
80
+ */
81
+ molar_refractivity(): number;
44
82
  /**
45
83
  * Average molecular weight (Da).
46
84
  */
47
85
  molecular_weight(): number;
86
+ /**
87
+ * Number of non-aromatic rings containing at least one heteroatom.
88
+ */
89
+ num_aliphatic_heterocycles(): number;
90
+ /**
91
+ * Number of aromatic rings containing at least one heteroatom (N, O, S, …).
92
+ */
93
+ num_aromatic_heterocycles(): number;
94
+ /**
95
+ * Number of bridgehead atoms (shared by ≥2 rings with ≥3 ring bonds).
96
+ */
97
+ num_bridgehead_atoms(): number;
98
+ /**
99
+ * Number of heteroatoms (non-C, non-H heavy atoms).
100
+ */
101
+ num_heteroatoms(): number;
102
+ /**
103
+ * Number of fully saturated rings containing at least one heteroatom.
104
+ */
105
+ num_saturated_heterocycles(): number;
106
+ /**
107
+ * Number of spiro atoms (sole shared atom between exactly 2 rings).
108
+ */
109
+ num_spiro_atoms(): number;
110
+ /**
111
+ * Number of assigned stereocenters (R/S).
112
+ */
113
+ num_stereocenters(): number;
114
+ /**
115
+ * Returns `true` if the molecule has no PAINS structural alerts.
116
+ */
117
+ pains_passes(): boolean;
118
+ /**
119
+ * Quantitative Estimate of Drug-likeness (QED); range [0, 1].
120
+ */
121
+ qed(): number;
122
+ /**
123
+ * Returns `true` if the molecule passes the REOS (Rapid Elimination Of Swill) filter.
124
+ */
125
+ reos_passes(): boolean;
126
+ /**
127
+ * Total number of rings (SSSR count).
128
+ */
129
+ ring_count(): number;
130
+ /**
131
+ * Number of rotatable bonds.
132
+ */
133
+ rotatable_bond_count(): number;
48
134
  /**
49
135
  * Topological polar surface area (Ų).
50
136
  */
51
137
  tpsa(): number;
138
+ /**
139
+ * Returns `true` if the molecule passes Veber's oral bioavailability criteria
140
+ * (TPSA ≤ 140 Ų and rotatable bonds ≤ 10).
141
+ */
142
+ veber_passes(): boolean;
52
143
  }
53
144
 
145
+ /**
146
+ * Number of BRICS fragments produced by fragmenting the molecule.
147
+ *
148
+ * Returns 1 if no BRICS-breakable bonds exist (whole molecule is one fragment).
149
+ */
150
+ export function brics_fragment_count(mol: MolHandle): number;
151
+
54
152
  /**
55
153
  * Compute the ECFP4 fingerprint as a bit-packed byte vector (256 bytes = 2048 bits).
56
154
  */
@@ -63,7 +161,22 @@ export function ecfp4_bitvec(mol: MolHandle): Uint8Array;
63
161
  */
64
162
  export function parse_smiles(s: string): MolHandle;
65
163
 
164
+ /**
165
+ * Tanimoto similarity between two molecules using AtomPair fingerprints.
166
+ */
167
+ export function tanimoto_atom_pair(a: MolHandle, b: MolHandle): number;
168
+
66
169
  /**
67
170
  * Tanimoto similarity between two molecules using ECFP4 fingerprints.
68
171
  */
69
172
  export function tanimoto_ecfp4(a: MolHandle, b: MolHandle): number;
173
+
174
+ /**
175
+ * Tanimoto similarity between two molecules using FCFP4 fingerprints (pharmacophore-based).
176
+ */
177
+ export function tanimoto_fcfp4(a: MolHandle, b: MolHandle): number;
178
+
179
+ /**
180
+ * Tanimoto similarity between two molecules using Topological Torsion fingerprints.
181
+ */
182
+ export function tanimoto_torsion(a: MolHandle, b: MolHandle): number;
package/chematic_wasm.js CHANGED
@@ -5,5 +5,5 @@ import { __wbg_set_wasm } from "./chematic_wasm_bg.js";
5
5
  __wbg_set_wasm(wasm);
6
6
  wasm.__wbindgen_start();
7
7
  export {
8
- MolHandle, ecfp4_bitvec, parse_smiles, tanimoto_ecfp4
8
+ MolHandle, brics_fragment_count, ecfp4_bitvec, parse_smiles, tanimoto_atom_pair, tanimoto_ecfp4, tanimoto_fcfp4, tanimoto_torsion
9
9
  } from "./chematic_wasm_bg.js";
@@ -19,6 +19,14 @@ export class MolHandle {
19
19
  const ptr = this.__destroy_into_raw();
20
20
  wasm.__wbg_molhandle_free(ptr, 0);
21
21
  }
22
+ /**
23
+ * Number of aromatic rings (all ring atoms aromatic).
24
+ * @returns {number}
25
+ */
26
+ aromatic_ring_count() {
27
+ const ret = wasm.molhandle_aromatic_ring_count(this.__wbg_ptr);
28
+ return ret >>> 0;
29
+ }
22
30
  /**
23
31
  * Number of heavy atoms (explicit atoms in the graph; does not count implicit H).
24
32
  * @returns {number}
@@ -51,6 +59,47 @@ export class MolHandle {
51
59
  wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
52
60
  }
53
61
  }
62
+ /**
63
+ * 2D SVG depiction of the molecule (CPK coloring).
64
+ * @returns {string}
65
+ */
66
+ depict_svg() {
67
+ let deferred1_0;
68
+ let deferred1_1;
69
+ try {
70
+ const ret = wasm.molhandle_depict_svg(this.__wbg_ptr);
71
+ deferred1_0 = ret[0];
72
+ deferred1_1 = ret[1];
73
+ return getStringFromWasm0(ret[0], ret[1]);
74
+ } finally {
75
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
76
+ }
77
+ }
78
+ /**
79
+ * Returns `true` if the molecule passes Egan's absorption criteria
80
+ * (TPSA ≤ 131.6 Ų and LogP ≤ 5.88).
81
+ * @returns {boolean}
82
+ */
83
+ egan_passes() {
84
+ const ret = wasm.molhandle_egan_passes(this.__wbg_ptr);
85
+ return ret !== 0;
86
+ }
87
+ /**
88
+ * Monoisotopic (exact) mass.
89
+ * @returns {number}
90
+ */
91
+ exact_mass() {
92
+ const ret = wasm.molhandle_exact_mass(this.__wbg_ptr);
93
+ return ret;
94
+ }
95
+ /**
96
+ * Sum of formal charges.
97
+ * @returns {number}
98
+ */
99
+ formal_charge_sum() {
100
+ const ret = wasm.molhandle_formal_charge_sum(this.__wbg_ptr);
101
+ return ret;
102
+ }
54
103
  /**
55
104
  * Molecular formula string (Hill notation: C first, H second, then alphabetical).
56
105
  * @returns {string}
@@ -67,6 +116,23 @@ export class MolHandle {
67
116
  wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
68
117
  }
69
118
  }
119
+ /**
120
+ * Fraction of sp3 carbons (Fsp3).
121
+ * @returns {number}
122
+ */
123
+ fsp3() {
124
+ const ret = wasm.molhandle_fsp3(this.__wbg_ptr);
125
+ return ret;
126
+ }
127
+ /**
128
+ * Returns `true` if the molecule passes Ghose's drug-likeness filter
129
+ * (MW 160–480, LogP −0.4–5.6, HeavyAtoms 20–70, MR 40–130).
130
+ * @returns {boolean}
131
+ */
132
+ ghose_passes() {
133
+ const ret = wasm.molhandle_ghose_passes(this.__wbg_ptr);
134
+ return ret !== 0;
135
+ }
70
136
  /**
71
137
  * Number of hydrogen bond acceptors (Lipinski: all N and O atoms).
72
138
  * @returns {number}
@@ -99,6 +165,22 @@ export class MolHandle {
99
165
  const ret = wasm.molhandle_lipinski_passes(this.__wbg_ptr);
100
166
  return ret !== 0;
101
167
  }
168
+ /**
169
+ * Crippen–Wildman octanol/water partition coefficient (LogP).
170
+ * @returns {number}
171
+ */
172
+ logp_crippen() {
173
+ const ret = wasm.molhandle_logp_crippen(this.__wbg_ptr);
174
+ return ret;
175
+ }
176
+ /**
177
+ * Wildman–Crippen molar refractivity (MR).
178
+ * @returns {number}
179
+ */
180
+ molar_refractivity() {
181
+ const ret = wasm.molhandle_molar_refractivity(this.__wbg_ptr);
182
+ return ret;
183
+ }
102
184
  /**
103
185
  * Average molecular weight (Da).
104
186
  * @returns {number}
@@ -107,6 +189,102 @@ export class MolHandle {
107
189
  const ret = wasm.molhandle_molecular_weight(this.__wbg_ptr);
108
190
  return ret;
109
191
  }
192
+ /**
193
+ * Number of non-aromatic rings containing at least one heteroatom.
194
+ * @returns {number}
195
+ */
196
+ num_aliphatic_heterocycles() {
197
+ const ret = wasm.molhandle_num_aliphatic_heterocycles(this.__wbg_ptr);
198
+ return ret >>> 0;
199
+ }
200
+ /**
201
+ * Number of aromatic rings containing at least one heteroatom (N, O, S, …).
202
+ * @returns {number}
203
+ */
204
+ num_aromatic_heterocycles() {
205
+ const ret = wasm.molhandle_num_aromatic_heterocycles(this.__wbg_ptr);
206
+ return ret >>> 0;
207
+ }
208
+ /**
209
+ * Number of bridgehead atoms (shared by ≥2 rings with ≥3 ring bonds).
210
+ * @returns {number}
211
+ */
212
+ num_bridgehead_atoms() {
213
+ const ret = wasm.molhandle_num_bridgehead_atoms(this.__wbg_ptr);
214
+ return ret >>> 0;
215
+ }
216
+ /**
217
+ * Number of heteroatoms (non-C, non-H heavy atoms).
218
+ * @returns {number}
219
+ */
220
+ num_heteroatoms() {
221
+ const ret = wasm.molhandle_num_heteroatoms(this.__wbg_ptr);
222
+ return ret >>> 0;
223
+ }
224
+ /**
225
+ * Number of fully saturated rings containing at least one heteroatom.
226
+ * @returns {number}
227
+ */
228
+ num_saturated_heterocycles() {
229
+ const ret = wasm.molhandle_num_saturated_heterocycles(this.__wbg_ptr);
230
+ return ret >>> 0;
231
+ }
232
+ /**
233
+ * Number of spiro atoms (sole shared atom between exactly 2 rings).
234
+ * @returns {number}
235
+ */
236
+ num_spiro_atoms() {
237
+ const ret = wasm.molhandle_num_spiro_atoms(this.__wbg_ptr);
238
+ return ret >>> 0;
239
+ }
240
+ /**
241
+ * Number of assigned stereocenters (R/S).
242
+ * @returns {number}
243
+ */
244
+ num_stereocenters() {
245
+ const ret = wasm.molhandle_num_stereocenters(this.__wbg_ptr);
246
+ return ret >>> 0;
247
+ }
248
+ /**
249
+ * Returns `true` if the molecule has no PAINS structural alerts.
250
+ * @returns {boolean}
251
+ */
252
+ pains_passes() {
253
+ const ret = wasm.molhandle_pains_passes(this.__wbg_ptr);
254
+ return ret !== 0;
255
+ }
256
+ /**
257
+ * Quantitative Estimate of Drug-likeness (QED); range [0, 1].
258
+ * @returns {number}
259
+ */
260
+ qed() {
261
+ const ret = wasm.molhandle_qed(this.__wbg_ptr);
262
+ return ret;
263
+ }
264
+ /**
265
+ * Returns `true` if the molecule passes the REOS (Rapid Elimination Of Swill) filter.
266
+ * @returns {boolean}
267
+ */
268
+ reos_passes() {
269
+ const ret = wasm.molhandle_reos_passes(this.__wbg_ptr);
270
+ return ret !== 0;
271
+ }
272
+ /**
273
+ * Total number of rings (SSSR count).
274
+ * @returns {number}
275
+ */
276
+ ring_count() {
277
+ const ret = wasm.molhandle_ring_count(this.__wbg_ptr);
278
+ return ret >>> 0;
279
+ }
280
+ /**
281
+ * Number of rotatable bonds.
282
+ * @returns {number}
283
+ */
284
+ rotatable_bond_count() {
285
+ const ret = wasm.molhandle_rotatable_bond_count(this.__wbg_ptr);
286
+ return ret >>> 0;
287
+ }
110
288
  /**
111
289
  * Topological polar surface area (Ų).
112
290
  * @returns {number}
@@ -115,9 +293,31 @@ export class MolHandle {
115
293
  const ret = wasm.molhandle_tpsa(this.__wbg_ptr);
116
294
  return ret;
117
295
  }
296
+ /**
297
+ * Returns `true` if the molecule passes Veber's oral bioavailability criteria
298
+ * (TPSA ≤ 140 Ų and rotatable bonds ≤ 10).
299
+ * @returns {boolean}
300
+ */
301
+ veber_passes() {
302
+ const ret = wasm.molhandle_veber_passes(this.__wbg_ptr);
303
+ return ret !== 0;
304
+ }
118
305
  }
119
306
  if (Symbol.dispose) MolHandle.prototype[Symbol.dispose] = MolHandle.prototype.free;
120
307
 
308
+ /**
309
+ * Number of BRICS fragments produced by fragmenting the molecule.
310
+ *
311
+ * Returns 1 if no BRICS-breakable bonds exist (whole molecule is one fragment).
312
+ * @param {MolHandle} mol
313
+ * @returns {number}
314
+ */
315
+ export function brics_fragment_count(mol) {
316
+ _assertClass(mol, MolHandle);
317
+ const ret = wasm.brics_fragment_count(mol.__wbg_ptr);
318
+ return ret >>> 0;
319
+ }
320
+
121
321
  /**
122
322
  * Compute the ECFP4 fingerprint as a bit-packed byte vector (256 bytes = 2048 bits).
123
323
  * @param {MolHandle} mol
@@ -148,6 +348,19 @@ export function parse_smiles(s) {
148
348
  return MolHandle.__wrap(ret[0]);
149
349
  }
150
350
 
351
+ /**
352
+ * Tanimoto similarity between two molecules using AtomPair fingerprints.
353
+ * @param {MolHandle} a
354
+ * @param {MolHandle} b
355
+ * @returns {number}
356
+ */
357
+ export function tanimoto_atom_pair(a, b) {
358
+ _assertClass(a, MolHandle);
359
+ _assertClass(b, MolHandle);
360
+ const ret = wasm.tanimoto_atom_pair(a.__wbg_ptr, b.__wbg_ptr);
361
+ return ret;
362
+ }
363
+
151
364
  /**
152
365
  * Tanimoto similarity between two molecules using ECFP4 fingerprints.
153
366
  * @param {MolHandle} a
@@ -160,6 +373,32 @@ export function tanimoto_ecfp4(a, b) {
160
373
  const ret = wasm.tanimoto_ecfp4(a.__wbg_ptr, b.__wbg_ptr);
161
374
  return ret;
162
375
  }
376
+
377
+ /**
378
+ * Tanimoto similarity between two molecules using FCFP4 fingerprints (pharmacophore-based).
379
+ * @param {MolHandle} a
380
+ * @param {MolHandle} b
381
+ * @returns {number}
382
+ */
383
+ export function tanimoto_fcfp4(a, b) {
384
+ _assertClass(a, MolHandle);
385
+ _assertClass(b, MolHandle);
386
+ const ret = wasm.tanimoto_fcfp4(a.__wbg_ptr, b.__wbg_ptr);
387
+ return ret;
388
+ }
389
+
390
+ /**
391
+ * Tanimoto similarity between two molecules using Topological Torsion fingerprints.
392
+ * @param {MolHandle} a
393
+ * @param {MolHandle} b
394
+ * @returns {number}
395
+ */
396
+ export function tanimoto_torsion(a, b) {
397
+ _assertClass(a, MolHandle);
398
+ _assertClass(b, MolHandle);
399
+ const ret = wasm.tanimoto_torsion(a.__wbg_ptr, b.__wbg_ptr);
400
+ return ret;
401
+ }
163
402
  export function __wbg___wbindgen_throw_1506f2235d1bdba0(arg0, arg1) {
164
403
  throw new Error(getStringFromWasm0(arg0, arg1));
165
404
  }
Binary file
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "kent-tokyo <kent-tokyo@users.noreply.github.com>"
6
6
  ],
7
7
  "description": "WebAssembly bindings for chematic — use chematic from JavaScript/TypeScript",
8
- "version": "0.1.3",
8
+ "version": "0.1.5",
9
9
  "license": "MIT OR Apache-2.0",
10
10
  "repository": {
11
11
  "type": "git",
@@ -26,11 +26,9 @@
26
26
  ],
27
27
  "keywords": [
28
28
  "cheminformatics",
29
- "chemistry",
30
- "smiles",
31
29
  "wasm",
32
- "rdkit",
33
- "fingerprints",
34
- "tanimoto"
30
+ "webassembly",
31
+ "smiles",
32
+ "chemistry"
35
33
  ]
36
34
  }