From d472f03c9addb7af5070194e9e30bd0a230b9c55 Mon Sep 17 00:00:00 2001 From: Luc Patiny Date: Mon, 13 May 2024 08:50:57 +0200 Subject: [PATCH] feat: add possitility to generate smarts and kekule isomeric smiles We never documented toIsomericSmiles(boolean) so I didn't do a breaking change --- __tests__/__snapshots__/library.js.snap | 4 ++++ __tests__/molecule.js | 17 ++++++++++++++++- .../research/gwt/minimal/JSMolecule.java | 19 ++++++++++++++++--- types.d.ts | 9 +++++++-- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/__tests__/__snapshots__/library.js.snap b/__tests__/__snapshots__/library.js.snap index 2199644b..eec44da4 100644 --- a/__tests__/__snapshots__/library.js.snap +++ b/__tests__/__snapshots__/library.js.snap @@ -296,6 +296,7 @@ exports[`prototype properties of Molecule 1`] = ` "toMolfile", "toMolfileV3", "toSVG", + "toSmarts", "toSmiles", "translateCoords", "validate", @@ -458,6 +459,9 @@ exports[`static properties of Molecule 1`] = ` "CANONIZER_TIE_BREAK_FREE_VALENCE_ATOMS", "FISCHER_PROJECTION_LIMIT", "FISCHER_PROJECTION_RING_LIMIT", + "MODE_CREATE_SMARTS", + "MODE_INCLUDE_MAPPING", + "MODE_KEKULIZED_OUTPUT", "STEREO_ANGLE_LIMIT", "VALIDATION_ERRORS_STEREO", "VALIDATION_ERROR_AMBIGUOUS_CONFIGURATION", diff --git a/__tests__/molecule.js b/__tests__/molecule.js index 8343bf83..4762696a 100644 --- a/__tests__/molecule.js +++ b/__tests__/molecule.js @@ -2,7 +2,7 @@ const fs = require('fs'); -const Molecule = require('../minimal').Molecule; +const { Molecule } = require('../minimal'); describe('from and to SMILES', () => { it.each(['C', 'COCOC', 'c1cc2cccc3c4cccc5cccc(c(c1)c23)c54'])( @@ -34,6 +34,21 @@ describe('from and to SMILES', () => { const mol = Molecule.fromSmiles(input); expect(mol.toIsomericSmiles()).toBe(output); }); + + it('smiles options', () => { + const mol = Molecule.fromSmiles('C1=CC=CC=C1'); + expect(mol.toSmiles()).toBe('C1(=CC=CC=C1)'); + expect(mol.toIsomericSmiles()).toBe('c1ccccc1'); + expect(mol.toIsomericSmiles(Molecule.MODE_KEKULIZED_OUTPUT)).toBe('C1=CC=CC=C1'); + expect(mol.toIsomericSmiles(Molecule.MODE_CREATE_SMARTS)).toBe('c1ccccc1'); + mol.setAtomMapNo(0, 1); + expect(mol.toIsomericSmiles(Molecule.MODE_INCLUDE_MAPPING)).toBe('c1cc[cH:1]cc1'); + + const fragment = Molecule.fromSmiles('C1=CC=CC=C1C'); + fragment.setFragment(true); + fragment.setAtomicNo(6, 1) + expect(fragment.toIsomericSmiles(Molecule.MODE_CREATE_SMARTS)).toBe('c1cc[c;!H0]cc1'); + }) }); describe('Molecule', () => { diff --git a/src/com/actelion/research/gwt/minimal/JSMolecule.java b/src/com/actelion/research/gwt/minimal/JSMolecule.java index be61a958..e4010aec 100644 --- a/src/com/actelion/research/gwt/minimal/JSMolecule.java +++ b/src/com/actelion/research/gwt/minimal/JSMolecule.java @@ -82,11 +82,17 @@ public native Object getOCL() }-*/; public String toSmiles() { + // we still allow to old code that do not care about stereo features and provide another SMILES return new SmilesCreator().generateSmiles(oclMolecule); } - public String toIsomericSmiles(boolean includeAtomMapping) { - return new IsomericSmilesCreator(oclMolecule, includeAtomMapping).getSmiles(); + public String toIsomericSmiles(int mode) { + return new IsomericSmilesCreator(oclMolecule, mode).getSmiles(); + } + + public String toSmarts() { + return new IsomericSmilesCreator(oclMolecule, IsomericSmilesCreator.MODE_CREATE_SMARTS) + .getSmiles(); } public String toMolfile() { @@ -293,7 +299,14 @@ public StereoMolecule getStereoMolecule() { return oclMolecule; } - // coming form Canonizer.java + // coming from IsomericSmilesCreator.java + public static final int MODE_CREATE_SMARTS = 1; + public static final int MODE_INCLUDE_MAPPING = 2; + public static final int MODE_KEKULIZED_OUTPUT = 4; // no lower case atom labels and single/double + // bonds to represent aromaticity + + + // coming from Canonizer.java public static final int CANONIZER_CREATE_SYMMETRY_RANK = 1; public static final int CANONIZER_CONSIDER_DIASTEREOTOPICITY = 2; public static final int CANONIZER_CONSIDER_ENANTIOTOPICITY = 4; diff --git a/types.d.ts b/types.d.ts index b0998879..7bf67701 100644 --- a/types.d.ts +++ b/types.d.ts @@ -93,6 +93,11 @@ export declare class Molecule { // based on JSMolecule.java you can do a regexp ".*static.* (int|long|double)(.*) = .*;" and replace with "$2: number;" + static MODE_CREATE_SMARTS = 1; + static MODE_INCLUDE_MAPPING = 2; + static MODE_KEKULIZED_OUTPUT = 4; // no lower case atom labels and single/double + // bonds to represent aromaticity + static CANONIZER_CREATE_SYMMETRY_RANK: number; static CANONIZER_CONSIDER_DIASTEREOTOPICITY: number; static CANONIZER_CONSIDER_ENANTIOTOPICITY: number; @@ -435,7 +440,7 @@ export declare class Molecule { */ getOCL(): any; - toSmiles(): string; + toSmiles(mode?: number): string; toIsomericSmiles(): string; @@ -1302,7 +1307,7 @@ export declare class Molecule { * @param mapNo * @param autoMapped */ - setAtomMapNo(atom: number, mapNo: number, autoMapped: boolean): void; + setAtomMapNo(atom: number, mapNo: number, autoMapped?: boolean): void; /** * Set atom to specific isotop or to have a natural isotop distribution