Source code for schrodinger.comparison.chirality
from schrodinger.infra import mm
[docs]def get_chirality(st, ignore_annotations=True):
"""
Make list of the chiralities and stereo chemistry.
:type st: Structure instance
:param st: Use the atoms in this structure
:type ignore_annotations: boolean
:param ignore_annotations: If True then structure level properties
defining the stereochemistry will be ignored and
stereochemistry is computed only from geometries
and current Lewis structure
:return: list of chirality/stereo chemistry
"""
ignore_stereo, _, _ = mm.mmstereo_get_option(mm.MMSTEREO_IGNORE_STEREO_PROP)
try:
if ignore_annotations and st.has3dCoords():
mm.mmstereo_set_option(mm.MMSTEREO_IGNORE_STEREO_PROP, 1, 0.0, '')
else:
mm.mmstereo_set_option(mm.MMSTEREO_IGNORE_STEREO_PROP, 0, 0.0, '')
handle = mm.mmstereo_new(st)
at_chirality = []
for at in st.atom:
chirality = mm.mmstereo_atom_stereo(handle, at.index)
ez = mm.mmstereo_double_bond_stereo(handle, at.index)
char = _assign_chirality(chirality)
if char is None:
char = _assign_EZ(ez)
at_chirality.append(char)
mm.mmstereo_delete(handle)
finally:
mm.mmstereo_set_option(mm.MMSTEREO_IGNORE_STEREO_PROP, ignore_stereo,
0.0, '')
return at_chirality
[docs]def get_atom_numbering_chirality(st):
"""
Make list of the chiralities and stereo chemistry due to atom number
for the atoms in st.
:type st: Structure instance
:param st: Use the atoms in this structure
:return: list of chirality/stereo chemistry
"""
handle = mm.mmstereo_new_anc(st)
at_chirality = []
for at in st.atom:
chirality = mm.mmstereo_atom_stereo(handle, at.index)
ez = mm.mmstereo_double_bond_stereo(handle, at.index)
char = _assign_chirality(chirality)
if char is None or char == 'undef':
char = _assign_EZ(ez)
at_chirality.append(char)
mm.mmstereo_delete(handle)
return at_chirality
[docs]def get_chiral_centers(st):
"""
Return indices of CIP chiral centers in structure.
:type st: Structure instance
:param st: Use the atoms in this structure
"""
ch = get_chirality(st)
return [idx for idx, label in enumerate(ch, 1) if label in {'R', 'S'}]
[docs]def valid_chiral_comp(ch1, ch2):
"""
Maestro's chirality checker returns both E/Z double bond isomer labels
and R/S chirality labels. If a reaction (e.g. and addition or elimination reaction)
changes a molecule from a double bond to a single bond, merely checking if
the chirality labels match will always lead to an apparent mismatch, even though
there is no actual problem. This function returns True if the chirality types
can be correctly compared and False if not.
:type ch1: string
:param ch1: chirality label of atom 1
:type ch2: string
:param ch2: chirality label of atom 2
:return: True if chiralities are comparable else False
"""
comparable_stereo = [{"R", "S"}, {"E", "Z"}, {"P", "M"}, {"ANS", "ANR"}]
if ch1 is None or ch2 is None:
return True
elif any({ch1, ch2}.issubset(comp_set) for comp_set in comparable_stereo):
return True
else:
return False
def _assign_EZ(ez):
key = {
mm.MMSTEREO_no_EZPM: None,
mm.MMSTEREO_P: 'P',
mm.MMSTEREO_M: 'M',
mm.MMSTEREO_E: 'E',
mm.MMSTEREO_Z: 'Z',
mm.MMSTEREO_ANP: 'ANP',
mm.MMSTEREO_ANM: 'ANM',
mm.MMSTEREO_ANZ: 'ANZ',
mm.MMSTEREO_ANE: 'ANE'
}
return key.get(ez, 'undef')
def _assign_chirality(chirality):
key = {
mm.MMSTEREO_NO_CHIRALITY: None,
mm.MMSTEREO_CHIRALITY_R: 'R',
mm.MMSTEREO_CHIRALITY_S: 'S',
mm.MMSTEREO_CHIRALITY_ANR: 'ANR',
mm.MMSTEREO_CHIRALITY_ANS: 'ANS'
}
return key.get(chirality, 'undef')