Source code for rif.rcl.pyrosetta_util



"""
nRosetta Compatibility Layer

if pyrosetta is available, provides pyrosetta. check value of HAVE_PYROSETTA.
"""

import os

try:
    import pyrosetta
    from pyrosetta import _rosetta_database_from_env
    try:
        from pyrosetta import rosetta
        from pyrosetta.rosetta import utility, numeric, basic, core
        from pyrosetta.rosetta.core.conformation import Residue
        from pyrosetta.rosetta.core.pose import make_pose_from_sequence, Pose
        from pyrosetta.rosetta.core.kinematics import FoldTree, MoveMap, Stub
        from pyrosetta.rosetta.core.import_pose import pose_from_file
        from pyrosetta.rosetta.core.io.pdb import dump_pdb
        from pyrosetta.rosetta.core.id import AtomID
        from pyrosetta.rosetta.core.scoring import ScoreFunction, get_score_function
        from pyrosetta.rosetta.numeric import xyzVector_double_t as xyzVector
        from pyrosetta.rosetta.numeric import xyzVector_double_t as xyzMatrix
        import pyrosetta.rosetta.basic
        import pyrosetta.rosetta.core
        import pyrosetta.rosetta.core.pack.rotamer_set
        from pyrosetta.rosetta.protocols.protein_interface_design.movers import TryRotamers
    except ImportError:
        import rosetta
        from rosetta import utility, numeric, basic, core
        from rosetta.core.conformation import Residue
        from rosetta.core.pose import make_pose_from_sequence, Pose
        from rosetta.core.kinematics import FoldTree, MoveMap, Stub
        from rosetta.core.import_pose import pose_from_file
        from rosetta.core.io.pdb import dump_pdb
        from rosetta.core.id import AtomID
        from rosetta.core.scoring import ScoreFunction, get_score_function
        from rosetta.numeric import xyzVector_double_t as xyzVector
        from rosetta.numeric import xyzVector_double_t as xyzMatrix
        import rosetta.basic
        import rosetta.core
        import rosetta.core.pack.rotamer_set
        from rosetta.protocols.protein_interface_design.movers import TryRotamers

    create_score_function = rosetta.core.scoring.ScoreFunctionFactory.create_score_function
    # for x in dir(pyrosetta):
    # print('pyrosetta:', x)/
    ROSETTA_DB = _rosetta_database_from_env()
    HAVE_PYROSETTA = True
except ImportError as e:
    # import mock
    HAVE_PYROSETTA = False
    # pyrosetta = mock.MagicMock()
    # rosetta = mock.MagicMock()

from .conversions import to_rosetta_stub, bbstubs
import numpy as np


[docs]class Error(Exception): """Rosetta Compatibility Exception"""
[docs]class ReInitError(Error): """Tried to reinitialize rosetta with different options"""
[docs]class AlreadyInitError(Error): """Rosetta already initialized but should not be"""
[docs]class RosettaDBError(Error): """Rosetta Database Error"""
pyrosetta_init_options = None def is_initialized(): return pyrosetta_init_options is not None def init_check(options=None, strict=True): if options is None: strict = False options = '-corrections:beta_nov16 -mute all' global pyrosetta_init_options if pyrosetta_init_options is None: pyrosetta.init(options=options) pyrosetta_init_options = options elif options != pyrosetta_init_options: if strict: raise ReInitError( 'attempt to init rosetta with different options: previous: {}, thiscall: {}' .format(pyrosetta_init_options, options)) def ats(kind='fa_standard'): init_check() return core.chemical.ChemicalManager.get_instance().atom_type_set(kind) def rts(kind='fa_standard'): init_check() return core.chemical.ChemicalManager.get_instance().residue_type_set(kind) def get_rtype(res_type_name): return rts().name_map(res_type_name) def make_res(res_type_name): return core.conformation.ResidueFactory.create_residue( get_rtype(res_type_name))
[docs]def add_files_to_rosettaDB(fname, contents): """returns true if update was done""" mypath = ROSETTA_DB + '/' + fname if not os.path.exists(os.path.dirname(mypath)): os.mkdir(os.path.dirname(mypath)) update_needed = False if os.path.exists(mypath): with open(mypath, 'r') as f: if f.read() != contents: update_needed = True # raise RosettaDBError("patched rosetta database " \ # "file exists and dosen't match: " + mypath) print('updating rosettaDB:', fname) if update_needed: with open(mypath, 'w') as f: f.write(contents) print('added to rosettaDB:', mypath) return update_needed
[docs]def add_residue_types_to_rosettaDB(newfiles, comment="## RIF added restypes", typeset='fa_standard'): """return true if update was done""" assert newfiles mypath = (ROSETTA_DB + '/chem/residue_type_sets/' + typeset + '/residue_types.txt') update_needed = list() with open(mypath, 'r') as f: existing_files = set(x.strip() for x in f) for newfile in newfiles: if newfile not in existing_files: update_needed.append(newfile) if update_needed: with open(mypath, 'a') as f: f.write(os.linesep * 2 + comment + os.linesep) for newline in update_needed: f.write(newline + os.linesep) print('modified rosettaDB:', mypath) else: print('nochange rosettaDB:', mypath) return bool(update_needed)
def update_roesettaDB_file(fname, newtext): if not os.path.exists(fname): raise RosettaDBError('rosettaDB file doesnt exist: ' + fname) with open(fname, 'r') as f: update_needed = newtext not in f.read() if update_needed: with open(fname, 'a') as f: f.write(newtext) print('modified rosettaDB:', fname) else: print('nochange rosettaDB:', fname) return update_needed def add_atom_types_to_rosettaDB(newprops, extradict, typeset='fa_standard'): any_updates = False atomprops = (ROSETTA_DB + '/chem/atom_type_sets/' + typeset + '/atom_properties.txt') updated = update_roesettaDB_file(atomprops, newprops) any_updates = any_updates or updated for extraname, extraval in list(extradict.items()): mypath = (ROSETTA_DB + '/chem/atom_type_sets/' + typeset + '/extras/' + extraname + '.txt') updated = update_roesettaDB_file(mypath, extraval) any_updates = any_updates or updated return any_updates def generate_canonical_residue(residue_name3): work_pose = Pose() make_pose_from_sequence( work_pose, "X[%s]" % residue_name3, "fa_standard", auto_termini=False) work_residue = rosetta.core.conformation.Residue(work_pose.residue(1)) ca_loc = work_residue.xyz("CA") for a in range(work_residue.natoms()): work_residue.set_xyz(a + 1, work_residue.xyz(a + 1) - ca_loc) return work_residue def generate_canonical_rotamer_residues_phipsi(residue_name3, target_phi_psi): raise NotImlementedError canonical_residue = generate_canonical_residue(residue_name3) test_sequence = "AAX[%s]AA" % residue_name3 target_phi, target_psi = target_phi_psi sf = get_score_function() tryrot = TryRotamers( resnum=3, scorefxn=sf, explosion=0, jump_num=0, clash_check=True, solo_res=False, include_current=False) test_pose = Pose() make_pose_from_sequence(test_pose, test_sequence, "fa_standard") for i in range(1, test_pose.size() + 1): test_pose.set_psi(i, target_psi) test_pose.set_phi(i, target_phi) test_pose.set_omega(i, 180) tryrot.setup_rotamer_set(test_pose) rotamer_set = tryrot.rotamer_set() # print('rotamer_set.num_rotamers()', # residue_name3, target_phi_psi, rotamer_set.num_rotamers()) rotamers = [rotamer_set.rotamer(i).clone() for i in range(1, rotamer_set.num_rotamers() + 1)] for r in rotamers: r.orient_onto_residue(canonical_residue) r.seqpos(1) return rotamers def generate_canonical_rotamer_residues(residue_name3): canonical_phi_psi = { "helical": (-66.0, -42.0), "sheet": (-126.0, 124.0), } result = list() for phipsi in canonical_phi_psi.values(): result.extend( generate_canonical_rotamer_residues_phipsi(residue_name3, phipsi)) # print(phipsi, len(result)) return result def worst_CN_connect(p): for ir in range(1, len(p)): worst = 0 if (p.residue(ir).is_protein() and p.residue(ir + 1).is_protein() and not ( rosetta.core.pose.is_upper_terminus(p, ir) or rosetta.core.pose.is_lower_terminus(p, ir + 1))): dist = p.residue(ir).xyz('C').distance(p.residue(ir + 1).xyz('N')) worst = max(abs(dist - 1.32), worst) return worst def pose_bounds(pose, lb, ub): if ub < 0: ub = len(pose) + 1 + ub if lb < 1 or ub > len(pose): raise ValueError('lb/ub ' + str(lb) + '/' + str(ub) + ' out of bounds for pose with len ' + str(len(pose))) return lb, ub def xform_pose(xform, pose, lb=1, ub=-1): lb, ub = pose_bounds(pose, lb, ub) if xform.shape != (4, 4): raise ValueError( 'invalid xform, must be 4x4 homogeneous matrix, shape is: ' + str(xform.shape)) xform = to_rosetta_stub(xform) rosetta.protocols.sic_dock.xform_pose(pose, xform, lb, ub) def subpose(pose, lb, ub=-1): lb, ub = pose_bounds(pose, lb, ub) p = rosetta.core.pose.Pose() rosetta.core.pose.append_subpose_to_pose(p, pose, lb, ub) return p
[docs]def concatenate_pose(p, to_append, lb=1, ub=-1, out=None): "put poses together aligning on end of p" lb, ub = pose_bounds(to_append, lb, ub) if not p.residue(len(p)).is_protein(): raise ValueError('last res of p is not protein') if not to_append.residue(lb).is_protein(): raise ValueError('lb res of to_append is not protein') if out is not p: out = p.clone() stub1 = bbstubs(p, [len(p)])['raw'][0] stub2 = bbstubs(to_append, [lb])['raw'][0] xalign = stub1 @ np.linalg.inv(stub2) rosetta.core.pose.remove_upper_terminus_type_from_pose_residue( out, len(out)) outlen = len(out) rosetta.core.pose.append_subpose_to_pose( out, to_append, lb + 1, ub, new_chain=0) xform_pose(xalign, out, outlen + 1) # todo: fix NH/CO return out