atommoyer / stapler

A Motif Hash Based Method for Matching Crosslinkers into Peptides and Proteins
15 stars 3 forks source link

Fails on virtual residues in a symmetric pose #1

Open rdkibler opened 3 years ago

rdkibler commented 3 years ago

I am attempting to staple a symmetric interface using a bit of code thuddy sent me, but I'm getting an error related to virtual residues not having atoms. Here's the code:

import glob
import os
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("input_dir")
parser.add_argument("output_dir")
args = parser.parse_args()

import pyrosetta
pyrosetta.init()

from pyrosetta.rosetta.core.select.residue_selector import TrueResidueSelector
from pyrosetta.rosetta.core.select.residue_selector import AndResidueSelector
from pyrosetta.rosetta.core.select.residue_selector import ChainSelector
from pyrosetta.rosetta.core.select.residue_selector import SecondaryStructureSelector

from pyrosetta.rosetta.protocols.symmetry import DetectSymmetry
from pyrosetta.rosetta.protocols.symmetry import SetupForSymmetryMover

from stapler import *

# Preset ResidueSelectors
default_residue_selectors = [TrueResidueSelector(), TrueResidueSelector()]
interface_residue_selectors = [ChainSelector('A'), ChainSelector('B')]
interface_or_internal_residue_selectors = [ChainSelector('A'), ChainSelector('A,B')]
only_binder_residue_selectors = [ChainSelector('B'), ChainSelector('B')]
not_on_loops = [SecondaryStructureSelector('HE'), SecondaryStructureSelector('HE')]
not_on_loops_across_interface = [AndResidueSelector(SecondaryStructureSelector('HE'),ChainSelector('A')),
                                 AndResidueSelector(SecondaryStructureSelector('HE'),ChainSelector('B'))]

# Initialize the native disulfide stapler with defaults.
native_disulfide_stapler = NativeDisulfideStapler(
    residue_selectors=interface_residue_selectors,
    minimum_sequence_distance=4
)

for pdb in glob.glob(os.path.join(args.input_dir,'*.pdb*')):
    pdb_filename = os.path.basename(pdb).split(".pdb")[0]
    pose = pyrosetta.pose_from_file(pdb)

    #Preset Movers for Symmetry
    DetectSymmetry().apply(pose)
    #SetupForSymmetryMover('C2.sym').apply(pose)

    for i, crosslinked_pose in enumerate(native_disulfide_stapler.apply(pose)):
        crosslinked_pose.dump_pdb(os.path.join(args.output_dir,f"{pdb_filename}_staple_{i}.pdb"))

And here is the error.log. The important bit is:

ERROR:: Exit from: /home/benchmark/rosetta/source/build/PyRosetta/linux/clang-3.4.2/python-3.7/release.serialization.thread/source/src/core/chemical/ResidueType.hh line: 426
PyRosetta-4 2020 [Rosetta PyRosetta4.conda.linux.cxx11thread.serialization.CentOS.python37.Release 2020.23+release.0d6f90a8cb9fa0567ca76bb71ee93bfe73340c70 2020-06-04T19:12:24] retrieved from: http://www.pyrosetta.org
(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.
/home/rdkibler/.conda/envs/pyro/lib/python3.7/site-packages/stapler/hash_tables/default_native_disulfide.bin
Traceback (most recent call last):
  File "./stapler/staple.py", line 49, in <module>
    for i, crosslinked_pose in enumerate(native_disulfide_stapler.apply(pose)):
  File "/home/rdkibler/.conda/envs/pyro/lib/python3.7/site-packages/stapler/stapler.py", line 43, in apply
    xyzs_a = np.array([[residue.atom(atom).xyz() for atom in self.atom_selectors[0]] for residue in pose.residues])
  File "/home/rdkibler/.conda/envs/pyro/lib/python3.7/site-packages/stapler/stapler.py", line 43, in <listcomp>
    xyzs_a = np.array([[residue.atom(atom).xyz() for atom in self.atom_selectors[0]] for residue in pose.residues])
  File "/home/rdkibler/.conda/envs/pyro/lib/python3.7/site-packages/stapler/stapler.py", line 43, in <listcomp>
    xyzs_a = np.array([[residue.atom(atom).xyz() for atom in self.atom_selectors[0]] for residue in pose.residues])
RuntimeError:

File: /home/benchmark/rosetta/source/build/PyRosetta/linux/clang-3.4.2/python-3.7/release.serialization.thread/source/src/core/chemical/ResidueType.hh:426
[ ERROR ] UtilityExitException
ERROR: ResidueType VRT does not have an atom N
atom-moyer commented 3 years ago

Is there a residue named vrt in your pdb? Basically you can’t have your residue selectors select residues without backbone atoms.

rdkibler commented 3 years ago

There are not ATOM lines in the pdb file with residues named vrt, but the pose in pyrosetta does have virtual residues after symmetrization

atom-moyer commented 3 years ago

Ok. Somehow you will have to make the residue selectors such that they avoid those residues. Something like a residue index selector is a work around.

rdkibler commented 3 years ago

adding if not residue.is_virtual_residue() to the first two list comprehensions in the apply() func in stapler.py fixes this

    def apply(self, pose):
        xyzs_a = np.array([[residue.atom(atom).xyz() for atom in self.atom_selectors[0]] for residue in pose.residues if not residue.is_virtual_residue()])
        xyzs_b = np.array([[residue.atom(atom).xyz() for atom in self.atom_selectors[0]] for residue in pose.residues if not residue.is_virtual_residue()])