# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED. OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.
"""Module to identify Lipinski donor."""
import rich
from openeye import oechem
def has_hydrogen(atom: oechem.OEAtomBase) -> bool:
"""Return true if the atom has implicit or explicit hydrogens."""
if atom.GetImplicitHCount() > 0:
return True
return any(neigh.IsHydrogen() for neigh in atom.GetAtoms())
[docs]
class IsLipinskiDonor(oechem.OEUnaryAtomPred):
"""
Predicate class to identify Lipinski donor atoms.
See Also
--------
* num_lipinsky_donors_
* :ref:`section_cheminfo_acceptor_donor` section
"""
[docs]
def __call__(self, atom: oechem.OEAtomBase) -> bool:
"""Evaluate the atom."""
if atom.GetAtomicNum() not in [oechem.OEElemNo_O, oechem.OEElemNo_N]:
return False
return has_hydrogen(atom)
[docs]
def num_lipinsky_donors(mol: oechem.OEAtomBase) -> int:
"""
Return the number of Lipinski acceptors in the molecule.
Parameters
----------
mol: oechem.OEMolBase
Input molecule
Returns
-------
int:
Number of Lipinsky donor atoms defined by IsLipinskiDonor predicate.
Examples
--------
>>> lipitor = "CC(C)c1c(c(c(n1CC[C@H](C[C@H](CC(=O)[O-])O)O)c2ccc(cc2)F)c3ccccc3)C(=O)Nc4ccccc4"
>>> mol = oechem.OEGraphMol()
>>> if oechem.OESmilesToMol(mol, lipitor):
... print(f"Number of donors: {oecookbook.num_lipinsky_donors(mol)}")
Number of donors: 3
"""
return oechem.OECount(mol, IsLipinskiDonor())
class IsHBondDonor(oechem.OEUnaryAtomPred):
"""Predicate class to identify atoms in [!H0;#7,#8,#9]."""
def __call__(self, atom: oechem.OEAtomBase) -> bool:
"""Evaluate the atom."""
if atom.GetAtomicNum() not in [
oechem.OEElemNo_O,
oechem.OEElemNo_N,
oechem.OEElemNo_F,
]:
return False
return has_hydrogen(atom)
def print_lipinsky_donors(mol: oechem.OEMolBase) -> None:
"""Print Lipinsky donor atoms to console."""
oechem.OETriposAtomNames(mol)
console = rich.console.Console()
console.print(f"Acceptor atoms in molecule '{oechem.OEMolToSmiles(mol)}'")
for atom in mol.GetAtoms(IsLipinskiDonor()):
console.print(atom.GetName())
def print_custom_donors(mol: oechem.OEMolBase) -> None:
"""Print donor atoms to console."""
oechem.OETriposAtomNames(mol)
console = rich.console.Console()
donor_pred = oechem.OEMatchAtom("[!H0;#7,#8,#9]")
console.print(f"Donor atoms in molecule '{oechem.OEMolToSmiles(mol)}'")
for atom in mol.GetAtoms(donor_pred):
console.print(atom.GetName())
class IsHBondDonorInclusive(oechem.OEUnaryAtomPred):
"""Predicate class to identify atoms in [!$([#6,H0,-,-2,-3])]."""
def __call__(self, atom: oechem.OEAtomBase) -> bool:
"""Evaluate the atom."""
if atom.GetAtomicNum() in [oechem.OEElemNo_C, oechem.OEElemNo_H]:
return False
if atom.GetFormalCharge() != 0:
return False
return has_hydrogen(atom)