@kent-tokyo/chematic 0.5.0 → 0.8.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.
@@ -1283,6 +1283,17 @@ export function mol_block_coords_json(mol_block: string): string;
1283
1283
  */
1284
1284
  export function mol_block_from_smiles(smiles: string): string;
1285
1285
 
1286
+ /**
1287
+ * Rejected wedge/hash stereocenters for a MOL V2000 block, as JSON.
1288
+ *
1289
+ * Companion to [`mol_from_sdf_block`]/[`mol_block_coords_json`] -- returns
1290
+ * `[{"atom_idx":N,"reason":"..."}]`, empty unless a wedge/hash bond was
1291
+ * present at some center and got rejected. See
1292
+ * `crates/chematic-py/src/formats.rs`'s `from_mol_block_with_diagnostics`
1293
+ * for the reason vocabulary (kept identical across bindings).
1294
+ */
1295
+ export function mol_block_stereo_diagnostics_json(mol_block: string): string;
1296
+
1286
1297
  /**
1287
1298
  * Only the first molecular fragment in the document is returned.
1288
1299
  * Returns a JS error if the document cannot be parsed.
@@ -1341,6 +1352,12 @@ export function mol_from_xyz(xyz: string): MolHandle;
1341
1352
  */
1342
1353
  export function mol_next_atom_idx(mol: MolHandle): number;
1343
1354
 
1355
+ /**
1356
+ * Rejected wedge/hash stereocenters for a MOL V3000 block, as JSON. Same
1357
+ * shape as [`mol_block_stereo_diagnostics_json`] but for V3000 input.
1358
+ */
1359
+ export function mol_v3000_stereo_diagnostics_json(block: string): string;
1360
+
1344
1361
  /**
1345
1362
  * Return a new `MolHandle` with one atom appended.
1346
1363
  *
@@ -1542,6 +1559,54 @@ export function predict_pka_json(smiles: string): string;
1542
1559
  */
1543
1560
  export function random_smiles_json(smiles: string, count: number, seed: bigint): string;
1544
1561
 
1562
+ /**
1563
+ * RDKit-bit-exact ECFP4 (radius=2, 2048 bits, `useChirality=false`, `useBondTypes=true`,
1564
+ * RDKit's default atom invariant) as a bit-packed byte vector (256 bytes = 2048 bits).
1565
+ *
1566
+ * Bit-for-bit identical to
1567
+ * `rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048).GetFingerprint(mol)`
1568
+ * for every input this preprocessing handles. **Not** the same bits as `ecfp4_bitvec`
1569
+ * (that path uses chematic's own FNV-1a hash and is not RDKit-bit-compatible by
1570
+ * design -- the two are never silently interchanged).
1571
+ *
1572
+ * Returns a JS error (its string carrying `RdkitMorganError`'s `Display` text, e.g.
1573
+ * `"rdkit-exact ecfp4: aromaticity: ..."`) if RDKit-parity aromaticity preprocessing
1574
+ * fails, never a silent fallback to `ecfp4_bitvec`'s Hückel-based engine -- the two
1575
+ * engines are not bit-compatible, so a silent substitution would look successful
1576
+ * while actually returning the wrong hash. See `docs/ecfp4_bitexact_api_rfc.md`.
1577
+ */
1578
+ export function rdkit_ecfp4_bitvec(mol: MolHandle): Uint8Array;
1579
+
1580
+ /**
1581
+ * Same fingerprint as `rdkit_ecfp4_bitvec`, plus the raw (unfolded) data behind it, as
1582
+ * JSON: `{"fingerprint":[u8,...],"sparseCounts":{"rawId":count,...},
1583
+ * "rawBitInfo":{"rawId":[[atomIdx,radius],...],...},
1584
+ * "foldedBitInfo":{"bit":[[atomIdx,radius],...],...}}`.
1585
+ *
1586
+ * Returns a JS error on the same preprocessing failures as `rdkit_ecfp4_bitvec`.
1587
+ */
1588
+ export function rdkit_ecfp4_detail_json(mol: MolHandle): string;
1589
+
1590
+ /**
1591
+ * RDKit-bit-exact Morgan/ECFP fingerprint at a caller-chosen radius/bit-width, as a
1592
+ * bit-packed byte vector (`nbits / 8` bytes, LSB-first).
1593
+ *
1594
+ * `radius` must be 0, 1, 2 (`rdkit_ecfp4_bitvec`'s ECFP4), or 3. `nbits` must be one
1595
+ * of 128, 256, 512, 1024, or 2048. Each of these 20 combinations is independently
1596
+ * re-verified against a live RDKit oracle (not assumed to generalize from
1597
+ * radius=2/2048 bits alone) -- see `validation/ecfp4_rdkit_stable_api_fixtures.json`.
1598
+ * An unsupported value returns a JS error rather than being silently coerced to the
1599
+ * nearest supported one.
1600
+ */
1601
+ export function rdkit_ecfp_config_bitvec(mol: MolHandle, radius: number, nbits: number): Uint8Array;
1602
+
1603
+ /**
1604
+ * Same fingerprint as `rdkit_ecfp_config_bitvec`, plus the raw (unfolded) data -- see
1605
+ * `rdkit_ecfp4_detail_json` for the JSON shape (identical, generalized to this
1606
+ * function's `radius`/`nbits`).
1607
+ */
1608
+ export function rdkit_ecfp_config_detail_json(mol: MolHandle, radius: number, nbits: number): string;
1609
+
1545
1610
  /**
1546
1611
  * Return a copy of the molecule with all explicit hydrogen atoms removed.
1547
1612
  */
@@ -1630,11 +1695,15 @@ export function sdf_from_records_json(smiles_json: string, names_json: string, p
1630
1695
  *
1631
1696
  * Each record has the shape:
1632
1697
  * ```json
1633
- * {"smiles":"CC(=O)O","name":"aspirin","properties":{"MW":"180.2","Activity":"high"}}
1698
+ * {"smiles":"CC(=O)O","name":"aspirin","properties":{"MW":"180.2","Activity":"high"},"stereo_diagnostics":[]}
1634
1699
  * ```
1635
1700
  *
1636
1701
  * Invalid records are represented as `null`. SD data fields are included in
1637
- * `properties`; multi-line values are joined with `\n`.
1702
+ * `properties`; multi-line values are joined with `\n`. `stereo_diagnostics`
1703
+ * is a list of `{"atom_idx":N,"reason":"..."}` objects, one per rejected
1704
+ * wedge/hash center (see [`mol_block_stereo_diagnostics_json`] for the
1705
+ * reason vocabulary) -- empty unless a wedge/hash bond was present at some
1706
+ * center and got rejected.
1638
1707
  */
1639
1708
  export function sdf_to_records_json(sdf: string): string;
1640
1709
 
@@ -2036,6 +2105,7 @@ export interface InitOutput {
2036
2105
  readonly mol2_to_smiles: (a: number, b: number) => [number, number];
2037
2106
  readonly mol_block_coords_json: (a: number, b: number) => [number, number, number, number];
2038
2107
  readonly mol_block_from_smiles: (a: number, b: number) => [number, number, number, number];
2108
+ readonly mol_block_stereo_diagnostics_json: (a: number, b: number) => [number, number, number, number];
2039
2109
  readonly mol_from_cdxml: (a: number, b: number) => [number, number, number];
2040
2110
  readonly mol_from_cml: (a: number, b: number) => [number, number, number];
2041
2111
  readonly mol_from_moljson: (a: number, b: number) => [number, number, number];
@@ -2044,6 +2114,7 @@ export interface InitOutput {
2044
2114
  readonly mol_from_v3000_block: (a: number, b: number) => [number, number, number];
2045
2115
  readonly mol_from_xyz: (a: number, b: number) => [number, number, number];
2046
2116
  readonly mol_next_atom_idx: (a: number) => number;
2117
+ readonly mol_v3000_stereo_diagnostics_json: (a: number, b: number) => [number, number, number, number];
2047
2118
  readonly mol_with_atom_added: (a: number, b: number, c: number) => [number, number, number];
2048
2119
  readonly mol_with_atom_charge: (a: number, b: number, c: number) => [number, number, number];
2049
2120
  readonly mol_with_atom_element: (a: number, b: number, c: number, d: number) => [number, number, number];
@@ -2141,6 +2212,10 @@ export interface InitOutput {
2141
2212
  readonly pharmacophore_fp_3d_summary: (a: number) => [number, number];
2142
2213
  readonly predict_pka_json: (a: number, b: number) => [number, number];
2143
2214
  readonly random_smiles_json: (a: number, b: number, c: number, d: bigint) => [number, number, number, number];
2215
+ readonly rdkit_ecfp4_bitvec: (a: number) => [number, number, number, number];
2216
+ readonly rdkit_ecfp4_detail_json: (a: number) => [number, number, number, number];
2217
+ readonly rdkit_ecfp_config_bitvec: (a: number, b: number, c: number) => [number, number, number, number];
2218
+ readonly rdkit_ecfp_config_detail_json: (a: number, b: number, c: number) => [number, number, number, number];
2144
2219
  readonly remove_hydrogens: (a: number) => number;
2145
2220
  readonly rgroup_decompose_json: (a: number, b: number, c: number, d: number) => [number, number, number, number];
2146
2221
  readonly ring_families_json: (a: number) => [number, number, number, number];
package/chematic_wasm.js CHANGED
@@ -3177,6 +3177,38 @@ export function mol_block_from_smiles(smiles) {
3177
3177
  }
3178
3178
  }
3179
3179
 
3180
+ /**
3181
+ * Rejected wedge/hash stereocenters for a MOL V2000 block, as JSON.
3182
+ *
3183
+ * Companion to [`mol_from_sdf_block`]/[`mol_block_coords_json`] -- returns
3184
+ * `[{"atom_idx":N,"reason":"..."}]`, empty unless a wedge/hash bond was
3185
+ * present at some center and got rejected. See
3186
+ * `crates/chematic-py/src/formats.rs`'s `from_mol_block_with_diagnostics`
3187
+ * for the reason vocabulary (kept identical across bindings).
3188
+ * @param {string} mol_block
3189
+ * @returns {string}
3190
+ */
3191
+ export function mol_block_stereo_diagnostics_json(mol_block) {
3192
+ let deferred3_0;
3193
+ let deferred3_1;
3194
+ try {
3195
+ const ptr0 = passStringToWasm0(mol_block, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
3196
+ const len0 = WASM_VECTOR_LEN;
3197
+ const ret = wasm.mol_block_stereo_diagnostics_json(ptr0, len0);
3198
+ var ptr2 = ret[0];
3199
+ var len2 = ret[1];
3200
+ if (ret[3]) {
3201
+ ptr2 = 0; len2 = 0;
3202
+ throw takeFromExternrefTable0(ret[2]);
3203
+ }
3204
+ deferred3_0 = ptr2;
3205
+ deferred3_1 = len2;
3206
+ return getStringFromWasm0(ptr2, len2);
3207
+ } finally {
3208
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
3209
+ }
3210
+ }
3211
+
3180
3212
  /**
3181
3213
  * Only the first molecular fragment in the document is returned.
3182
3214
  * Returns a JS error if the document cannot be parsed.
@@ -3308,6 +3340,33 @@ export function mol_next_atom_idx(mol) {
3308
3340
  return ret >>> 0;
3309
3341
  }
3310
3342
 
3343
+ /**
3344
+ * Rejected wedge/hash stereocenters for a MOL V3000 block, as JSON. Same
3345
+ * shape as [`mol_block_stereo_diagnostics_json`] but for V3000 input.
3346
+ * @param {string} block
3347
+ * @returns {string}
3348
+ */
3349
+ export function mol_v3000_stereo_diagnostics_json(block) {
3350
+ let deferred3_0;
3351
+ let deferred3_1;
3352
+ try {
3353
+ const ptr0 = passStringToWasm0(block, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
3354
+ const len0 = WASM_VECTOR_LEN;
3355
+ const ret = wasm.mol_v3000_stereo_diagnostics_json(ptr0, len0);
3356
+ var ptr2 = ret[0];
3357
+ var len2 = ret[1];
3358
+ if (ret[3]) {
3359
+ ptr2 = 0; len2 = 0;
3360
+ throw takeFromExternrefTable0(ret[2]);
3361
+ }
3362
+ deferred3_0 = ptr2;
3363
+ deferred3_1 = len2;
3364
+ return getStringFromWasm0(ptr2, len2);
3365
+ } finally {
3366
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
3367
+ }
3368
+ }
3369
+
3311
3370
  /**
3312
3371
  * Return a new `MolHandle` with one atom appended.
3313
3372
  *
@@ -3874,6 +3933,120 @@ export function random_smiles_json(smiles, count, seed) {
3874
3933
  }
3875
3934
  }
3876
3935
 
3936
+ /**
3937
+ * RDKit-bit-exact ECFP4 (radius=2, 2048 bits, `useChirality=false`, `useBondTypes=true`,
3938
+ * RDKit's default atom invariant) as a bit-packed byte vector (256 bytes = 2048 bits).
3939
+ *
3940
+ * Bit-for-bit identical to
3941
+ * `rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048).GetFingerprint(mol)`
3942
+ * for every input this preprocessing handles. **Not** the same bits as `ecfp4_bitvec`
3943
+ * (that path uses chematic's own FNV-1a hash and is not RDKit-bit-compatible by
3944
+ * design -- the two are never silently interchanged).
3945
+ *
3946
+ * Returns a JS error (its string carrying `RdkitMorganError`'s `Display` text, e.g.
3947
+ * `"rdkit-exact ecfp4: aromaticity: ..."`) if RDKit-parity aromaticity preprocessing
3948
+ * fails, never a silent fallback to `ecfp4_bitvec`'s Hückel-based engine -- the two
3949
+ * engines are not bit-compatible, so a silent substitution would look successful
3950
+ * while actually returning the wrong hash. See `docs/ecfp4_bitexact_api_rfc.md`.
3951
+ * @param {MolHandle} mol
3952
+ * @returns {Uint8Array}
3953
+ */
3954
+ export function rdkit_ecfp4_bitvec(mol) {
3955
+ _assertClass(mol, MolHandle);
3956
+ const ret = wasm.rdkit_ecfp4_bitvec(mol.__wbg_ptr);
3957
+ if (ret[3]) {
3958
+ throw takeFromExternrefTable0(ret[2]);
3959
+ }
3960
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
3961
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
3962
+ return v1;
3963
+ }
3964
+
3965
+ /**
3966
+ * Same fingerprint as `rdkit_ecfp4_bitvec`, plus the raw (unfolded) data behind it, as
3967
+ * JSON: `{"fingerprint":[u8,...],"sparseCounts":{"rawId":count,...},
3968
+ * "rawBitInfo":{"rawId":[[atomIdx,radius],...],...},
3969
+ * "foldedBitInfo":{"bit":[[atomIdx,radius],...],...}}`.
3970
+ *
3971
+ * Returns a JS error on the same preprocessing failures as `rdkit_ecfp4_bitvec`.
3972
+ * @param {MolHandle} mol
3973
+ * @returns {string}
3974
+ */
3975
+ export function rdkit_ecfp4_detail_json(mol) {
3976
+ let deferred2_0;
3977
+ let deferred2_1;
3978
+ try {
3979
+ _assertClass(mol, MolHandle);
3980
+ const ret = wasm.rdkit_ecfp4_detail_json(mol.__wbg_ptr);
3981
+ var ptr1 = ret[0];
3982
+ var len1 = ret[1];
3983
+ if (ret[3]) {
3984
+ ptr1 = 0; len1 = 0;
3985
+ throw takeFromExternrefTable0(ret[2]);
3986
+ }
3987
+ deferred2_0 = ptr1;
3988
+ deferred2_1 = len1;
3989
+ return getStringFromWasm0(ptr1, len1);
3990
+ } finally {
3991
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
3992
+ }
3993
+ }
3994
+
3995
+ /**
3996
+ * RDKit-bit-exact Morgan/ECFP fingerprint at a caller-chosen radius/bit-width, as a
3997
+ * bit-packed byte vector (`nbits / 8` bytes, LSB-first).
3998
+ *
3999
+ * `radius` must be 0, 1, 2 (`rdkit_ecfp4_bitvec`'s ECFP4), or 3. `nbits` must be one
4000
+ * of 128, 256, 512, 1024, or 2048. Each of these 20 combinations is independently
4001
+ * re-verified against a live RDKit oracle (not assumed to generalize from
4002
+ * radius=2/2048 bits alone) -- see `validation/ecfp4_rdkit_stable_api_fixtures.json`.
4003
+ * An unsupported value returns a JS error rather than being silently coerced to the
4004
+ * nearest supported one.
4005
+ * @param {MolHandle} mol
4006
+ * @param {number} radius
4007
+ * @param {number} nbits
4008
+ * @returns {Uint8Array}
4009
+ */
4010
+ export function rdkit_ecfp_config_bitvec(mol, radius, nbits) {
4011
+ _assertClass(mol, MolHandle);
4012
+ const ret = wasm.rdkit_ecfp_config_bitvec(mol.__wbg_ptr, radius, nbits);
4013
+ if (ret[3]) {
4014
+ throw takeFromExternrefTable0(ret[2]);
4015
+ }
4016
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
4017
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
4018
+ return v1;
4019
+ }
4020
+
4021
+ /**
4022
+ * Same fingerprint as `rdkit_ecfp_config_bitvec`, plus the raw (unfolded) data -- see
4023
+ * `rdkit_ecfp4_detail_json` for the JSON shape (identical, generalized to this
4024
+ * function's `radius`/`nbits`).
4025
+ * @param {MolHandle} mol
4026
+ * @param {number} radius
4027
+ * @param {number} nbits
4028
+ * @returns {string}
4029
+ */
4030
+ export function rdkit_ecfp_config_detail_json(mol, radius, nbits) {
4031
+ let deferred2_0;
4032
+ let deferred2_1;
4033
+ try {
4034
+ _assertClass(mol, MolHandle);
4035
+ const ret = wasm.rdkit_ecfp_config_detail_json(mol.__wbg_ptr, radius, nbits);
4036
+ var ptr1 = ret[0];
4037
+ var len1 = ret[1];
4038
+ if (ret[3]) {
4039
+ ptr1 = 0; len1 = 0;
4040
+ throw takeFromExternrefTable0(ret[2]);
4041
+ }
4042
+ deferred2_0 = ptr1;
4043
+ deferred2_1 = len1;
4044
+ return getStringFromWasm0(ptr1, len1);
4045
+ } finally {
4046
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
4047
+ }
4048
+ }
4049
+
3877
4050
  /**
3878
4051
  * Return a copy of the molecule with all explicit hydrogen atoms removed.
3879
4052
  * @param {MolHandle} mol
@@ -4087,11 +4260,15 @@ export function sdf_from_records_json(smiles_json, names_json, props_json) {
4087
4260
  *
4088
4261
  * Each record has the shape:
4089
4262
  * ```json
4090
- * {"smiles":"CC(=O)O","name":"aspirin","properties":{"MW":"180.2","Activity":"high"}}
4263
+ * {"smiles":"CC(=O)O","name":"aspirin","properties":{"MW":"180.2","Activity":"high"},"stereo_diagnostics":[]}
4091
4264
  * ```
4092
4265
  *
4093
4266
  * Invalid records are represented as `null`. SD data fields are included in
4094
- * `properties`; multi-line values are joined with `\n`.
4267
+ * `properties`; multi-line values are joined with `\n`. `stereo_diagnostics`
4268
+ * is a list of `{"atom_idx":N,"reason":"..."}` objects, one per rejected
4269
+ * wedge/hash center (see [`mol_block_stereo_diagnostics_json`] for the
4270
+ * reason vocabulary) -- empty unless a wedge/hash bond was present at some
4271
+ * center and got rejected.
4095
4272
  * @param {string} sdf
4096
4273
  * @returns {string}
4097
4274
  */
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.5.0",
8
+ "version": "0.8.0",
9
9
  "license": "MIT OR Apache-2.0",
10
10
  "repository": {
11
11
  "type": "git",