Source code for schrodinger.structutils.interactions.protein_protein_interactions
from schrodinger import structure
from schrodinger.structutils import analyze
[docs]def get_interface_atoms(structs, dist=4.5):
"""
Returns a list of protein interface atoms found in specified structures
Protein interface atoms are atoms close to an atom in a different chain,
whether the same protein or not. All atoms in a residues are included if
any atom in it meets this criterion.
:param structs: list of structures to examine
:type structs: list[schrodinger.structure.Structure]
:param cutoff: The minimum number of atoms in the chain to be considered
:param cutoff: int
:param dist: The distance used in the definition of "close"
:type dist: float
:rtype: list[schrodinger.structure._StructureAtom]
:return: a list of interface atoms that belong to chains with more than
cutoff residues
"""
structs = list(structs)
# Create a structure that contains all the structures, keeping a mapping so
# we can return atoms in the original structures
index_map = {}
merged = structure.create_new_structure()
for st in structs:
index_map.update(
(at, i)
for (i, at) in enumerate(st.atom, start=merged.atom_total + 1))
merged.extend(st)
back_map = {i: at for at, i in index_map.items()}
# Now find the interface atoms for each chain in the merged structure and
# map them to the original structures
protein_atom_indices = set(analyze.evaluate_asl(merged, "protein"))
interface_atoms = set()
for st in structs:
for chain in st.chain:
chain_atoms = (index_map[a] for a in chain.atom)
chain_atoms = [i for i in chain_atoms if i in protein_atom_indices]
if not chain_atoms:
continue
chain_asl = analyze.generate_asl(merged, chain_atoms)
close_asl = (f"(protein) and (fillres (within {dist} ({chain_asl}))"
f"and not ({chain_asl}))")
close_atom_indices = analyze.evaluate_asl(merged, close_asl)
interface_atoms.update(back_map[i] for i in close_atom_indices)
return interface_atoms