import os
from schrodinger.infra import canvas
from schrodinger.utils import fileutils
from . import common
RESIDUE_ATOM_TYPES = {}
# standard amino-acids
RESIDUE_ATOM_TYPES['ALA '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3'
}
RESIDUE_ATOM_TYPES['ARG '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.3',
' CD ': 'C.3',
' NE ': 'N.pl3',
' CZ ': 'C.cat',
' NH1': 'N.pl3',
' NH2': 'N.pl3'
}
RESIDUE_ATOM_TYPES['ASP '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.2',
' OD1': 'O.co2',
' OD2': 'O.co2'
}
RESIDUE_ATOM_TYPES['ASH '] = RESIDUE_ATOM_TYPES['ASP ']
RESIDUE_ATOM_TYPES['ASX '] = RESIDUE_ATOM_TYPES['ASP ']
RESIDUE_ATOM_TYPES['ASN '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.2',
' OD1': 'O.2',
' ND2': 'N.am'
}
RESIDUE_ATOM_TYPES['CYS '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' SG ': 'S.3'
}
RESIDUE_ATOM_TYPES['GLU '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.3',
' CD ': 'C.2',
' OE1': 'O.co2',
' OE2': 'O.co2'
}
RESIDUE_ATOM_TYPES['GLH '] = RESIDUE_ATOM_TYPES['GLU ']
RESIDUE_ATOM_TYPES['GLX '] = RESIDUE_ATOM_TYPES['GLU ']
RESIDUE_ATOM_TYPES['GLN '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.3',
' CD ': 'C.2',
' OE1': 'O.2',
' NE2': 'N.am'
}
RESIDUE_ATOM_TYPES['GLY '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2'
}
RESIDUE_ATOM_TYPES['HIS '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.ar',
' ND1': 'N.his',
' CD2': 'C.ar',
' CE1': 'C.ar',
' NE2': 'N.his'
}
RESIDUE_ATOM_TYPES['HID '] = RESIDUE_ATOM_TYPES['HIS ']
RESIDUE_ATOM_TYPES['HIE '] = RESIDUE_ATOM_TYPES['HIS ']
RESIDUE_ATOM_TYPES['HIP '] = RESIDUE_ATOM_TYPES['HIS ']
RESIDUE_ATOM_TYPES['HIX '] = RESIDUE_ATOM_TYPES['HIS ']
RESIDUE_ATOM_TYPES['ILE '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG1': 'C.3',
' CG2': 'C.3',
' CD1': 'C.3'
}
RESIDUE_ATOM_TYPES['LEU '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.3',
' CD1': 'C.3',
' CD2': 'C.3'
}
RESIDUE_ATOM_TYPES['LYS '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.3',
' CD ': 'C.3',
' CE ': 'C.3',
' NZ ': 'N.4'
}
RESIDUE_ATOM_TYPES['LYN '] = RESIDUE_ATOM_TYPES['LYS ']
RESIDUE_ATOM_TYPES['LYX '] = RESIDUE_ATOM_TYPES['LYS ']
RESIDUE_ATOM_TYPES['MET '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.3',
' SD ': 'S.3',
' CE ': 'C.3'
}
RESIDUE_ATOM_TYPES['PHE '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.ar',
' CD1': 'C.ar',
' CD2': 'C.ar',
' CE1': 'C.ar',
' CE2': 'C.ar',
' CZ ': 'C.ar'
}
RESIDUE_ATOM_TYPES['PRO '] = {
' CD ': 'C.3',
' N ': 'N.3',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.3'
}
RESIDUE_ATOM_TYPES['SER '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' OG ': 'O.3'
}
RESIDUE_ATOM_TYPES['THR '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' OG1': 'O.3',
' CG2': 'C.3'
}
RESIDUE_ATOM_TYPES['TRP '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.ar',
' CD1': 'C.ar',
' CD2': 'C.ar',
' NE1': 'N.am',
' CE2': 'C.ar',
' CE3': 'C.ar',
' CZ2': 'C.ar',
' CZ3': 'C.ar',
' CH2': 'C.ar'
}
RESIDUE_ATOM_TYPES['TYR '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG ': 'C.ar',
' CD1': 'C.ar',
' CD2': 'C.ar',
' CE1': 'C.ar',
' CE2': 'C.ar',
' CZ ': 'C.ar',
' OH ': 'O.3'
}
RESIDUE_ATOM_TYPES['VAL '] = {
' N ': 'N.am',
' CA ': 'C.3',
' C ': 'C.2',
' O ': 'O.2',
' CB ': 'C.3',
' CG1': 'C.3',
' CG2': 'C.3'
}
# capping groups
RESIDUE_ATOM_TYPES['ACE '] = {
' C ': 'C.2',
' CH3': 'C.3',
' O ': 'O.2'
} # yapf: disable
RESIDUE_ATOM_TYPES['NMA '] = {
' N ': 'N.am',
' CA ': 'C.3'
} # yapf: disable
for residue in RESIDUE_ATOM_TYPES.values():
residue[' OXT'] = 'O.co2'
# DNA
RESIDUE_ATOM_TYPES[' DA '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' C1\'': 'C.3',
' N9 ': 'N.ar',
' C8 ': 'C.ar',
' N7 ': 'N.ar',
' C5 ': 'C.ar',
' C6 ': 'C.ar',
' N6 ': 'N.3',
' N1 ': 'N.ar',
' C2 ': 'C.ar',
' N3 ': 'N.ar',
' C4 ': 'C.ar'
} # yapf: disable
RESIDUE_ATOM_TYPES[' DG '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' C1\'': 'C.3',
' N9 ': 'N.ar',
' C8 ': 'C.ar',
' N7 ': 'N.ar',
' C5 ': 'C.ar',
' C6 ': 'C.ar',
' O6 ': 'O.2',
' N1 ': 'N.am',
' C2 ': 'C.ar',
' N2 ': 'N.3',
' N3 ': 'N.ar',
' C4 ': 'C.ar'
} # yapf: disable
RESIDUE_ATOM_TYPES[' DT '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' C1\'': 'C.3',
' N1 ': 'N.ar',
' C2 ': 'C.ar',
' O2 ': 'O.2',
' N3 ': 'N.am',
' C4 ': 'C.ar',
' O4 ': 'O.2',
' C5 ': 'C.ar',
' C7 ': 'C.3',
' C6 ': 'C.ar'
} # yapf: disable
RESIDUE_ATOM_TYPES[' DC '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' C1\'': 'C.3',
' N1 ': 'N.ar',
' C2 ': 'C.ar',
' O2 ': 'O.2',
' N3 ': 'N.ar',
' C4 ': 'C.ar',
' N4 ': 'N.3',
' C5 ': 'C.ar',
' C6 ': 'C.ar'
} # yapf: disable
# RNA
RESIDUE_ATOM_TYPES[' A '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' O2\'': 'O.3',
' C1\'': 'C.3',
' N9 ': 'N.ar',
' C8 ': 'C.ar',
' N7 ': 'N.ar',
' C5 ': 'C.ar',
' C6 ': 'C.ar',
' N6 ': 'N.3',
' N1 ': 'N.ar',
' C2 ': 'C.ar',
' N3 ': 'N.ar',
' C4 ': 'C.ar'
} # yapf: disable
RESIDUE_ATOM_TYPES[' U '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' O2\'': 'O.3',
' C1\'': 'C.3',
' N1 ': 'N.ar',
' C2 ': 'C.ar',
' O2 ': 'O.2',
' N3 ': 'N.am',
' C4 ': 'C.ar',
' O4 ': 'O.2',
' C5 ': 'C.ar',
' C6 ': 'C.ar'
} # yapf: disable
RESIDUE_ATOM_TYPES[' G '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' O2\'': 'O.3',
' C1\'': 'C.3',
' N9 ': 'N.ar',
' C8 ': 'C.ar',
' N7 ': 'N.ar',
' C5 ': 'C.ar',
' C6 ': 'C.ar',
' O6 ': 'O.2',
' N1 ': 'N.am',
' C2 ': 'C.ar',
' N2 ': 'N.3',
' N3 ': 'N.ar',
' C4 ': 'C.ar'
} # yapf: disable
RESIDUE_ATOM_TYPES[' C '] = {
' P ': 'P.3',
' OP1': 'O.co2',
' OP2': 'O.co2',
' O5\'': 'O.3',
' C5\'': 'C.3',
' C4\'': 'C.3',
' O4\'': 'O.3',
' C3\'': 'C.3',
' O3\'': 'O.3',
' C2\'': 'C.3',
' O2\'': 'O.3',
' C1\'': 'C.3',
' N1 ': 'N.ar',
' C2 ': 'C.ar',
' O2 ': 'O.2',
' N3 ': 'N.ar',
' C4 ': 'C.ar',
' N4 ': 'N.3',
' C5 ': 'C.ar',
' C6 ': 'C.ar'
} # yapf: disable
RESIDUE_ATOM_TYPES['HEM '] = {
'FE ': 'm.2', # m = metal, 2 means +2 charge
' CHA': 'C.ar',
' CHB': 'C.ar',
' CHC': 'C.ar',
' CHD': 'C.ar',
' NA ': 'N.ar',
' C1A': 'C.ar',
' C2A': 'C.ar',
' C3A': 'C.ar',
' C4A': 'C.ar',
' CMA': 'C.3',
' CAA': 'C.3',
' CBA': 'C.3',
' CGA': 'C.2',
' O1A': 'O.2',
' O2A': 'O.co2',
' NB ': 'N.ar',
' C1B': 'C.ar',
' C2B': 'C.ar',
' C3B': 'C.ar',
' C4B': 'C.ar',
' CMB': 'C.3',
' CAB': 'C.2',
' CBB': 'C.2',
' NC ': 'N.ar',
' C1C': 'C.ar',
' C2C': 'C.ar',
' C3C': 'C.ar',
' C4C': 'C.ar',
' CMC': 'C.3',
' CAC': 'C.2',
' CBC': 'C.2',
' ND ': 'N.ar',
' C1D': 'C.ar',
' C2D': 'C.ar',
' C3D': 'C.ar',
' C4D': 'C.ar',
' CMD': 'C.3',
' CAD': 'C.3',
' CBD': 'C.3',
' CGD': 'C.2',
' O1D': 'O.2',
' O2D': 'O.co2'
} # yapf: disable
#------------------------------------------------------------------------------#
CANVAS_MOL2_TYPE_NAME = {
1: 'C.3',
2: 'C.2',
3: 'C.ar',
4: 'C.1',
33: 'C.cat',
5: 'N.3',
6: 'N.2',
7: 'N.1',
11: 'N.ar',
28: 'N.am',
19: 'N.pl3',
31: 'N.4',
8: 'O.3',
9: 'O.2',
32: 'O.co2',
10: 'S.3',
18: 'S.2',
29: 'S.o',
30: 'S.o2',
12: 'P.3'
} # yapf: disable
#------------------------------------------------------------------------------#
[docs]class AtomTyper(object):
'''
Maps PDB residue/atom names onto SYBYL atom types.
Uses ChmAtomTyperMol2 as fallback.
'''
[docs] def __init__(self):
self.adaptor = canvas.ChmMmctAdaptor()
self.mol2_typer = canvas.ChmAtomTyper(
os.path.join(fileutils.get_mmshare_data_dir(), 'canvas',
'Mol2.typ'))
def __call__(self, st, atom_indices=None, logger=None):
'''
Assigns SYBYL atom types.
:param st: Structure.
:type st: `schrodinger.structure.Structure`
:param atom_indices: Indices of the atoms to be considered.
:type atom_indices: iterable over int
:return: List of atom index-type pairs.
:rtype: list(tuple(int, str or None))
'''
logger = common.ensure_logger(logger)
if atom_indices is None:
atom_indices = range(1, st.atom_total + 1)
types = []
all_found = True
for i in atom_indices:
atom = st.atom[i]
try:
t = RESIDUE_ATOM_TYPES[atom.pdbres][atom.pdbname]
except KeyError:
t = None
all_found = False
logger.debug('using fallback typer for atom %d (%s/%s)', i,
atom.pdbname, atom.pdbres)
types.append((i, t))
if all_found:
return types
assignments = self.mol2_typer.type(self.adaptor.create(st))
for j in range(len(types)):
i, t = types[j]
if t is None:
tc = assignments[i - 1]
types[j] = (i, CANVAS_MOL2_TYPE_NAME.get(tc, None))
return types
#------------------------------------------------------------------------------#