Skip to content

Return original molecule from StereoisomerEnumerator when no unspecified stereocenters are available#8924

Merged
greglandrum merged 2 commits intordkit:masterfrom
phonglam3103:Improve_StereoisomerEnumerator
Nov 11, 2025
Merged

Return original molecule from StereoisomerEnumerator when no unspecified stereocenters are available#8924
greglandrum merged 2 commits intordkit:masterfrom
phonglam3103:Improve_StereoisomerEnumerator

Conversation

@phonglam3103
Copy link
Copy Markdown
Contributor

What does this implement/fix? Explain your changes.

The current implementation of rdEnumerateStereoisomers with the tryEmbedding option enabled attempts to embed the input molecule even when no stereoisomer flipping has occurred.

For example:

from rdkit import Chem
from rdkit.Chem import rdEnumerateStereoisomers


mol = Chem.MolFromSmiles(r'C1C\C=C\CCC[C@H]1C(=O)Nc2ccc(cc2)C[C@@H](C(=O)[O-])[NH3+]')
smiles = set()
opts = rdEnumerateStereoisomers.StereoEnumerationOptions()
opts.tryEmbedding=True
enum = rdEnumerateStereoisomers.StereoisomerEnumerator(mol, opts)
while True:
    iso = enum.next()
    if iso is None:
        break
    smiles.add(Chem.MolToSmiles(iso))
print(len(smiles), 'stereoisomers found:')
for smi in smiles:
    print(smi)

returns:

0 stereoisomers found:
[08:22:18] [NH3+][C@@H](Cc1ccc(NC(=O)[C@H]2CC/C=C/CCC2)cc1)C(=O)[O-]     failed to embed.

As a result, the input molecule disappears after enumeration.

By contrast, the original Python implementation of EnumerateStereoisomers returns the input molecule unchanged when no “flippers” (stereocenters to invert) are present:

from rdkit import Chem
from rdkit.Chem import AllChem

opts = AllChem.StereoEnumerationOptions(tryEmbedding=True)
mol = Chem.MolFromSmiles(r'C1C\C=C\CCC[C@H]1C(=O)Nc2ccc(cc2)C[C@@H](C(=O)[O-])[NH3+]')
isomers = tuple(AllChem.EnumerateStereoisomers(mol, options=opts))
print(f'Found {len(isomers)} stereoisomers:')
for iso in isomers:
    print(Chem.MolToSmiles(iso))

returns:

Found 1 stereoisomers:
[NH3+][C@@H](Cc1ccc(NC(=O)[C@H]2CC/C=C/CCC2)cc1)C(=O)[O-]

This PR updates the C++ StereoisomerEnumerator so that it behaves consistently with the Python version. Specifically, it skips embedding when the d_flippers vector is empty (i.e., no new stereoisomers are generated). This ensures that the input molecule is preserved and avoids unnecessary embedding attempts, improving both correctness and performance.

…ippers are available and add test for embedding behavior with input acceptance.
@phonglam3103
Copy link
Copy Markdown
Contributor Author

Hi @DavidACosgrove, it would be nice if you can have a look on this PR

Copy link
Copy Markdown
Collaborator

@DavidACosgrove DavidACosgrove left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@DavidACosgrove
Copy link
Copy Markdown
Collaborator

Hi @DavidACosgrove, it would be nice if you can have a look on this PR

Sorry, that I missed that one. One of the maintainers will have to review it also, however, before it can be accepted and merged.

Co-authored-by: Greg Landrum <greg.landrum@gmail.com>
@greglandrum greglandrum changed the title StereoisomerEnumerator with Embedding to return original molecule when no unspecified stereocenters are available Return original molecule from StereoisomerEnumerator when no unspecified stereocenters are available Nov 11, 2025
@greglandrum greglandrum added this to the 2025_09_3 milestone Nov 11, 2025
Copy link
Copy Markdown
Member

@greglandrum greglandrum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@greglandrum greglandrum merged commit c41513e into rdkit:master Nov 11, 2025
12 checks passed
@greglandrum
Copy link
Copy Markdown
Member

Thanks @phonglam3103 !

greglandrum added a commit that referenced this pull request Nov 28, 2025
…ied stereocenters are available (#8924)

* Enhance StereoisomerEnumerator to return original molecule when no flippers are available and add test for embedding behavior with input acceptance.

* Use std::make_unique for ROMol construction

Co-authored-by: Greg Landrum <greg.landrum@gmail.com>

---------

Co-authored-by: Greg Landrum <greg.landrum@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants