Examples » Predicate generators

In this example we will see how selections of atoms/residues/molecules can be created using predicates.

We start from importing required stuff from pyxmolpp2 and reading the frame

from pyxmolpp2 import PdbFile
import os

pdb_filename = os.path.join(os.environ["TEST_DATA_PATH"], "pdb/rcsb/1UBQ.pdb")
frame = PdbFile(pdb_filename).frames()[0]

Let's print structural info about our frame:

print('\n'.join([
    f"Molecule {mol.name:1s}: ({mol.residues.size} residues)\n    " +
    ", ".join([f"{r.name}-{r.id}" for r in mol.residues])
    for mol in frame.molecules
]))
Molecule A: (76 residues)
    MET-1, GLN-2, ILE-3, PHE-4, VAL-5, LYS-6, THR-7, LEU-8, THR-9, GLY-10, LYS-11, THR-12, ILE-13, THR-14, LEU-15, GLU-16, VAL-17, GLU-18, PRO-19, SER-20, ASP-21, THR-22, ILE-23, GLU-24, ASN-25, VAL-26, LYS-27, ALA-28, LYS-29, ILE-30, GLN-31, ASP-32, LYS-33, GLU-34, GLY-35, ILE-36, PRO-37, PRO-38, ASP-39, GLN-40, GLN-41, ARG-42, LEU-43, ILE-44, PHE-45, ALA-46, GLY-47, LYS-48, GLN-49, LEU-50, GLU-51, ASP-52, GLY-53, ARG-54, THR-55, LEU-56, SER-57, ASP-58, TYR-59, ASN-60, ILE-61, GLN-62, LYS-63, GLU-64, SER-65, THR-66, LEU-67, HIS-68, LEU-69, VAL-70, LEU-71, ARG-72, LEU-73, ARG-74, GLY-75, GLY-76
Molecule A: (58 residues)
    HOH-77, HOH-78, HOH-79, HOH-80, HOH-81, HOH-82, HOH-83, HOH-84, HOH-85, HOH-86, HOH-87, HOH-88, HOH-89, HOH-90, HOH-91, HOH-92, HOH-93, HOH-94, HOH-95, HOH-96, HOH-97, HOH-98, HOH-99, HOH-100, HOH-101, HOH-102, HOH-103, HOH-104, HOH-105, HOH-106, HOH-107, HOH-108, HOH-109, HOH-110, HOH-111, HOH-112, HOH-113, HOH-114, HOH-115, HOH-116, HOH-117, HOH-118, HOH-119, HOH-120, HOH-121, HOH-122, HOH-123, HOH-124, HOH-125, HOH-126, HOH-127, HOH-128, HOH-129, HOH-130, HOH-131, HOH-132, HOH-133, HOH-134

Let's filter frame residues with some arbitrary predicates:

def adhoc_predicate(r):
    return (r.id <= 10) and (r.id not in {2, 4, 9}) and (r.name not in {"GLY", "PRO"})

print(frame.residues.filter(lambda r: r.name == "GLY"))
print(frame.residues.filter(lambda r: r.id <= 10))
print(frame.residues.filter(adhoc_predicate))
ResidueSelection<size=6, residues=[A.GLY-10, A.GLY-35, ... , A.GLY-76]>
ResidueSelection<size=10, residues=[A.MET-1, A.GLN-2, ... , A.GLY-10]>
ResidueSelection<size=6, residues=[A.MET-1, A.ILE-3, ... , A.LEU-8]>

Using lambda or ad-hoc predicate functions adds a bit of boilerplate, which can be avoided by using predicate generators: aName, aId, rId, rName, mName. Predicate generators provide a convenient syntax to construct & combine predicates:

from pyxmolpp2 import aName, aId, rName, rId, mName

print(frame.residues.filter(rName == "GLY"))
print(frame.residues.filter(rId <= 10))
print(frame.residues.filter((rId <= 10) & ~rId.is_in(2,4,9) & ~rName.is_in("GLY", "PRO")))
ResidueSelection<size=6, residues=[A.GLY-10, A.GLY-35, ... , A.GLY-76]>
ResidueSelection<size=10, residues=[A.MET-1, A.GLN-2, ... , A.GLY-10]>
ResidueSelection<size=6, residues=[A.MET-1, A.ILE-3, ... , A.LEU-8]>

An extra bonus generated ResiduePredicate can be naturally applied to atoms as well:

print(frame.atoms.filter(rName == "GLY"))
print(frame.atoms.filter(rId <= 10))
print(frame.atoms.filter( (rId <= 10) & ~rId.is_in(2,4,9) & ~rName.is_in("GLY", "PRO")))
AtomSelection<size=25, atoms=[A.GLY-10.N, A.GLY-10.CA, ... , A.GLY-76.OXT]>
AtomSelection<size=78, atoms=[A.MET-1.N, A.MET-1.CA, ... , A.GLY-10.O]>
AtomSelection<size=47, atoms=[A.MET-1.N, A.MET-1.CA, ... , A.LEU-8.CD2]>