Skip to content

Commit ea45db4

Browse files
committed
Use RDKit to detect chiral centres.
1 parent aee5694 commit ea45db4

1 file changed

Lines changed: 25 additions & 21 deletions

File tree

src/ghostly/_ghostly.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2179,35 +2179,39 @@ def _linearise_ring_break(
21792179
theta = Symbol("theta")
21802180
r = Symbol("r")
21812181

2182-
# Find ghost atoms with exactly 2 connections, both physical.
2183-
# If G has additional ghost substituents it may be a chiral centre at the
2184-
# physical end state; linearising at 180° would destroy that geometry, so
2185-
# we skip it and warn.
2182+
# Build an RDKit molecule for the physical end state so we can query
2183+
# chirality directly rather than inferring it from substituent counts.
2184+
from sire.convert import to_rdkit as _to_rdkit
2185+
from rdkit.Chem import ChiralType as _ChiralType
2186+
2187+
phys_mol = (
2188+
_morph.link_to_reference(mol) if is_lambda1 else _morph.link_to_perturbed(mol)
2189+
)
2190+
rdmol = _to_rdkit(phys_mol)
2191+
21862192
linearised = set()
21872193
for ghost in ghosts:
21882194
all_neighbors = list(connectivity.connections_to(ghost))
21892195
physical_neighbors = [n for n in all_neighbors if n not in ghost_set]
2190-
ghost_neighbors = [n for n in all_neighbors if n in ghost_set]
21912196

2197+
# Find ghost atoms with exactly 2 connections, both physical.
21922198
if len(physical_neighbors) == 2:
2193-
# Hydrogen ghost substituents cannot create chirality so are safe
2194-
# to ignore. Heavy ghost substituents may indicate a chiral centre
2195-
# at the physical end state, so we skip linearisation and warn.
2196-
elem_prop = "element0" if is_lambda1 else "element1"
2197-
heavy_ghost_neighbors = [
2198-
n
2199-
for n in ghost_neighbors
2200-
if mol.atom(n).property(elem_prop).symbol() not in ("H", "Xx", "")
2201-
]
2202-
if not heavy_ghost_neighbors:
2203-
linearised.add(ghost)
2204-
else:
2199+
# Check whether this atom is a chiral centre in the physical end
2200+
# state using RDKit. If so, linearising to 180° would destroy the
2201+
# geometry, so skip it and warn.
2202+
rdatom = rdmol.GetAtomWithIdx(ghost.value())
2203+
chiral = rdatom.GetChiralTag()
2204+
if chiral in (
2205+
_ChiralType.CHI_TETRAHEDRAL_CW,
2206+
_ChiralType.CHI_TETRAHEDRAL_CCW,
2207+
):
22052208
_logger.warning(
2206-
f" Ring-break ghost atom {ghost.value()} has "
2207-
f"{len(heavy_ghost_neighbors)} heavy ghost substituent(s) "
2208-
f"in addition to 2 physical neighbours. Linearisation "
2209-
f"skipped to preserve potential chirality."
2209+
f" Ring-break ghost atom {ghost.value()} is a chiral "
2210+
f"centre in the physical end state. Linearisation skipped "
2211+
f"to preserve chirality."
22102212
)
2213+
else:
2214+
linearised.add(ghost)
22112215

22122216
if not linearised:
22132217
return mol, linearised

0 commit comments

Comments
 (0)