Exemplo n.º 1
0
 def set_up_pack_mover(self, pose, scorefxn, res_list=None):
     task_pack = pyrosetta.standard_packer_task(pose)
     task_pack.restrict_to_repacking()
     task_pack.temporarily_fix_everything()
     if res_list is None:
         for i in range(1, 1+len(pose.sequence())):
             task_pack.temporarily_set_pack_residue(i, True)
     else:
         for i in res_list:
             task_pack.temporarily_set_pack_residue(i, True)
     self.packmover = pyrosetta.rosetta.protocols.minimization_packing.PackRotamersMover(scorefxn, task_pack)
     return None
Exemplo n.º 2
0
def mutate_residue(pack_or_pose,
                   mutant_position,
                   mutant_aa,
                   pack_radius=0.,
                   pack_scorefxn=None):
    """Replace the residue at a single position in a Pose with a new amino acid
        and repack any residues within user-defined radius of selected residue's
        center using.

    Args:
        pack_or_pose (pyrosetta.rosetta.core.pose.Pose OR pyrosetta.distributed.packed_pose.PackedPose):
                    the `Pose` instance to use.
        mutant_position (int): Pose-numbered position of the residue to mutate.
        mutant_aa (str): The single letter name for the desired amino acid.
        pack_radius (float): Radius used to define neighboring residues.
        pack_scorefxn (pyrosetta.ScoreFunction): `ScoreFunction` to use when repacking the `Pose`.
            Defaults to the standard `ScoreFunction`.
    """
    import pyrosetta
    import pyrosetta.distributed.packed_pose as packed_pose

    wpose = packed_pose.to_pose(pack_or_pose)

    if not wpose.is_fullatom():
        raise IOError("mutate_residue only works with fullatom poses")

    # create a standard scorefxn by default
    if not pack_scorefxn:
        pack_scorefxn = pyrosetta.get_score_function()

    # the numbers 1-20 correspond individually to the 20 proteogenic amino acids
    from pyrosetta.rosetta.core.chemical import aa_from_oneletter_code

    mutant_aa = int(aa_from_oneletter_code(mutant_aa))
    aa_bool = pyrosetta.Vector1([aa == mutant_aa for aa in range(1, 21)])

    # mutation is performed by using a PackerTask with only the mutant
    # amino acid available during design
    task = pyrosetta.standard_packer_task(wpose)
    task.nonconst_residue_task(mutant_position).restrict_absent_canonical_aas(
        aa_bool)

    # prevent residues from packing by setting the per-residue "options" of the PackerTask
    task = restrict_non_nbrs_from_repacking(wpose, mutant_position, task,
                                            pack_radius)

    # apply the mutation and pack nearby residues
    from pyrosetta.rosetta.protocols.minimization_packing import PackRotamersMover

    packer = PackRotamersMover(pack_scorefxn, task)
    packer.apply(wpose)
Exemplo n.º 3
0
def sample_refinement(pdb_filename,
                      kT=1.0,
                      smallmoves=3,
                      shearmoves=5,
                      backbone_angle_max=7,
                      cycles=9,
                      jobs=1,
                      job_output='refine_output'):
    """
    Performs fullatom structural refinement on the input  <pdb_filename>  by
        perturbing backbone torsion angles with a maximum perturbation of
        <backbone_angle_max>  for  <cycles>  trials of
        <smallmoves>  perturbations of a random residue's phi or psi and
        <shearmoves>  perturbations of a random residue's phi and the preceding
        residue's psi followed by gradient based backbone torsion angle
        minimization and sidechain packing with an acceptance criteria scaled
        by  <kT>.  <jobs>  trajectories are performed, continually exporting
        structures to a PyMOL instance.
        Output structures are named  <job_output>_(job#).pdb.
    """
    # 1. create a pose from the desired PDB file
    pose = Pose()
    pose_from_file(pose, pdb_filename)

    # 2. create a reference copy of the pose in fullatom
    starting_pose = Pose()
    starting_pose.assign(pose)

    # 3. create a standard ScoreFunction
    #### implement the desired ScoreFunction here
    scorefxn = get_fa_scorefxn()  #  create_score_function('standard')

    #### If you wish to use the ClassRelax protocol, uncomment the following
    ####    line and comment-out the protocol setup below
    #refinement = protocols.relax.ClassicRelax( scorefxn )

    #### Setup custom high-resolution refinement protocol
    #### backbone refinement protocol

    # 4. create a MoveMap, all backbone torsions free
    movemap = MoveMap()
    movemap.set_bb(True)

    # 5. create a SmallMover
    # a SmallMover perturbs a random (free in the MoveMap) residue's phi or psi
    #    torsion angle for an input number of times and accepts of rejects this
    #    change based on the Metropolis Criteria using the "rama" ScoreType and
    #    the parameter kT
    # set the maximum angle to backbone_angle_max, apply it smallmoves times
    smallmover = protocols.simple_moves.SmallMover(movemap, kT, smallmoves)
    # angle_max is secondary structure dependent, however secondary structure
    #    has not been evaulated in this protocol, thus they are all set
    #    to the same value0
    smallmover.angle_max(backbone_angle_max)  # sets all at once
    #### use the overloaded version of the SmallMover.angle_max method if you
    ####    want to use secondary structure biased moves
    #smallmover.angle_max('H', backbone_angle_max)
    #smallmover.angle_max('E', backbone_angle_max)
    #smallmover.angle_max('L', backbone_angle_max)

    # 6. create a ShearMover
    # a ShearMover is identical to a SmallMover except that the angles perturbed
    #    are instead a random (free in the MoveMap) residue's phi and the
    #    preceding residue's psi, this reduces the downstream structural change
    # set the maximum angle to backbone_angle_max, apply it shearmoves times
    shearmover = protocols.simple_moves.ShearMover(movemap, kT, shearmoves)
    # same angle_max restictions as SmallMover
    shearmover.angle_max(backbone_angle_max)
    #### use the overloaded version of the SmallMover.angle_max method if you
    ####    want to use secondary structure biased moves
    #shearmover.angle_max('H', backbone_angle_max)
    #shearmover.angle_max('E', backbone_angle_max)
    #shearmover.angle_max('L', backbone_angle_max)

    # 7. create a MinMover, for backbone torsion minimization
    minmover = protocols.minimization_packing.MinMover()
    minmover.movemap(movemap)
    minmover.score_function(scorefxn)

    #### sidechain refinement protocol, simple packing

    # 8. setup a PackRotamersMover
    to_pack = standard_packer_task(starting_pose)
    to_pack.restrict_to_repacking()  # prevents design, packing only
    to_pack.or_include_current(True)  # considers the original sidechains
    packmover = protocols.minimization_packing.PackRotamersMover(
        scorefxn, to_pack)

    #### assess the new structure
    # 9. create a PyMOLMover
    pymover = PyMOLMover()
    # uncomment the line below to load structures into successive states
    #pymover.keep_history(True)
    #### the PyMOLMover slows down the protocol SIGNIFICANTLY but provides
    ####    very informative displays
    #### the keep_history flag (when True) tells the PyMOLMover to store new
    ####    structures into successive states, for a single trajectory, this
    ####    allows you to see intermediate changes (depending on where the
    ####    PyMOLMover is applied), when using a JobDistributor or otherwise
    ####    displaying multiple trajectories with a single protocol, the output
    ####    can get confusing to interpret, by changing the pose's PDBInfo.name
    ####    the structure will load into a new PyMOL state
    #### try uncommenting the lines below to see different output
    #pymover.update_energy(True)    # see the total score in color

    # 10. export the original structure, and scores, to PyMOL
    pymover.apply(pose)
    scorefxn(pose)
    pymover.send_energy(pose)

    # 11. setup a RepeatMover on a TrialMover of a SequenceMover (wow!)
    # -setup a TrialMover
    #    a. create a SequenceMover of the previous moves
    #### add any other moves you desire
    combined_mover = SequenceMover()
    combined_mover.add_mover(smallmover)
    combined_mover.add_mover(shearmover)
    combined_mover.add_mover(minmover)
    combined_mover.add_mover(packmover)
    #### explore the protocol using the PyMOLMover, try viewing structures
    ####    before they are accepted or rejected
    combined_mover.add_mover(pymover)
    #    b. create a MonteCarlo object to define success/failure
    mc = MonteCarlo(pose, scorefxn, kT)  # must reset for each trajectory!
    # c. create the TrialMover
    trial = TrialMover(combined_mover, mc)

    #### explore the protocol using the PyMOLMover, try viewing structures
    ####    after acceptance/rejection, comment-out the lines below
    #original_trial = TrialMover(combined_mover, mc)
    #trial = SequenceMover()
    #trial.add_mover(original_trial)
    #trial.add_mover(pymover)

    #### for each trajectory, try cycles number of applications

    # -create the RepeatMover
    refinement = RepeatMover(trial, cycles)
    ####

    # 12. create a (Py)JobDistributor
    jd = PyJobDistributor(job_output, jobs, scorefxn)
    jd.native_pose = starting_pose

    # 13. store the score evaluations for output
    # printing the scores as they are produced would be difficult to read,
    #    Rosetta produces a lot of verbose output when running
    scores = [0] * (jobs + 1)
    scores[0] = scorefxn(starting_pose)

    # 14. perform the refinement protocol
    counter = 0  # for exporting to PyMOL
    while not jd.job_complete:
        # a. set necessary variables for the new trajectory
        # -reload the starting pose
        pose.assign(starting_pose)
        # -change the pose's PDBInfo.name, for the PyMOLMover
        counter += 1
        pose.pdb_info().name(job_output + '_' + str(counter))
        # -reset the MonteCarlo object (sets lowest_score to that of p)
        mc.reset(pose)
        #### if you create a custom protocol, you may have additional
        ####    variables to reset, such as kT

        #### if you create a custom protocol, this section will most likely
        ####    change, many protocols exist as single Movers or can be
        ####    chained together in a sequence (see above) so you need
        ####    only apply the final Mover
        # b. apply the refinement protocol
        refinement.apply(pose)
        ####

        # c. output the lowest scoring decoy structure for this trajectory
        # -recover and output the decoy structure to a PDB file
        mc.recover_low(pose)
        jd.output_decoy(pose)
        # -export the final structure to PyMOL for each trajectory
        pose.pdb_info().name(job_output + '_' + str(counter) + '_final')
        pymover.apply(pose)
        pymover.send_energy(pose)  # see the total score in color

        # -store the final score for this trajectory
        scores[counter] = scorefxn(pose)

    # 15. output the score evaluations
    print('Original Score\t:\t', scores[0])
    for i in range(1, len(scores)):  # print out the job scores
        print(job_output + '_' + str(i) + '\t:\t', scores[i])

    return scores  # for other protocols
Exemplo n.º 4
0
pr.init('-extra_res_fa inputs/AZC.params -ex1 -ex2')
pose = pr.pose_from_pdb('TEV_solo.pdb')

print("emd182::Building score function")
sf = pr.rosetta.core.scoring.ScoreFunction()
sf.add_weights_from_file('ref2015')

print("emd182::Setting up and making a mutation")
res_mut = 30
mutater = pr.rosetta.protocols.simple_moves.MutateResidue()
mutater.set_target(res_mut)
mutater.set_res_name('AZC')
mutater.apply(pose)

print("emd182::Making Packertask and restricting to repacking")
packer_task = pr.standard_packer_task(pose)
packer_task.restrict_to_repacking()
packer_task.set_bump_check(False)
pack_mover = PackRotamersMover(sf, packer_task)

rsf = RotamerSetFactory()
rs = rsf.create_rotamer_set(pose)
rs.set_resid(res_mut)
sf(pose)
packer_graph = pr.rosetta.core.pack.create_packer_graph(pose, sf, packer_task)
rs.build_rotamers(pose, sf, packer_task, packer_graph)

print(rs.rotamer(1).name(), rs.num_rotamers())
short_pose = pr.rosetta.core.pose.Pose()
short_pose.detached_copy(pose)
for i in range(1, rs.num_rotamers() + 1):
Exemplo n.º 5
0
def mutate_residue(pose,
                   mutant_position,
                   mutant_aa,
                   pack_radius=0.0,
                   pack_scorefxn=''):
    """
    Replaces the residue at  <mutant_position>  in  <pose>  with  <mutant_aa>
        and repack any residues within  <pack_radius>  Angstroms of the mutating
        residue's center (nbr_atom) using  <pack_scorefxn>
    note: <mutant_aa>  is the single letter name for the desired ResidueType

    example:
        mutate_residue(pose, 30, A)
    See also:
        Pose
        PackRotamersMover
        MutateResidue
        pose_from_sequence
    """
    #### a MutateResidue Mover exists similar to this except it does not pack
    ####    the area around the mutant residue (no pack_radius feature)
    #mutator = MutateResidue(mutant_position, mutant_aa)
    #mutator.apply(test_pose)

    if pose.is_fullatom() == False:
        IOError('mutate_residue only works with fullatom poses')

    # create a standard scorefxn by default
    if not pack_scorefxn:
        pack_scorefxn = rosetta.core.scoring.get_score_function()

    task = pyrosetta.standard_packer_task(pose)

    # the Vector1 of booleans (a specific object) is needed for specifying the
    #    mutation, this demonstrates another more direct method of setting
    #    PackerTask options for design
    aa_bool = rosetta.utility.vector1_bool()
    # PyRosetta uses several ways of tracking amino acids (ResidueTypes)
    # the numbers 1-20 correspond individually to the 20 proteogenic amino acids
    # aa_from_oneletter returns the integer representation of an amino acid
    #    from its one letter code
    # convert mutant_aa to its integer representation
    mutant_aa = rosetta.core.chemical.aa_from_oneletter_code(mutant_aa)

    # mutation is performed by using a PackerTask with only the mutant
    #    amino acid available during design
    # to do this, construct a Vector1 of booleans indicating which amino acid
    #    (by its numerical designation, see above) to allow
    for i in range(1, 21):
        # in Python, logical expression are evaluated with priority, thus the
        #    line below appends to aa_bool the truth (True or False) of the
        #    statement i == mutant_aa
        aa_bool.append(i == int(mutant_aa))

    # modify the mutating residue's assignment in the PackerTask using the
    #    Vector1 of booleans across the proteogenic amino acids
    task.nonconst_residue_task(mutant_position).restrict_absent_canonical_aas(
        aa_bool)

    # prevent residues from packing by setting the per-residue "options" of
    #    the PackerTask
    restrict_non_nbrs_from_repacking(pose, mutant_position, task, pack_radius)

    # apply the mutation and pack nearby residues
    #print task
    packer = rosetta.protocols.simple_moves.PackRotamersMover(
        pack_scorefxn, task)
    packer.apply(pose)
Exemplo n.º 6
0
initial_pose = pose_from_pdb(clean_name)
print initial_pose
print toolbox.get_secstruct(initial_pose)
#Set up ScoreFunction
sf = get_fa_scorefxn()

#Set up MoveMap.
mm = MoveMap()
#change these for more or less flexability
mm.set_bb(True)
mm.set_chi(True)

#Pack and minimize initial pose to remove clashes.
pre_pre_packing_score = sf(initial_pose)
print "1"
task = standard_packer_task(initial_pose)
task.restrict_to_repacking()
task.or_include_current(True)
print "2"
pack_rotamers_mover = protocols.simple_moves.RotamerTrialsMover(sf, task)
pack_rotamers_mover.apply(initial_pose)
print "3"

min_mover = protocols.simple_moves.MinMover()
print "4"

min_mover.movemap(mm)
print "5"
min_mover.score_function(sf)
print "6"
min_mover.min_type('dfpmin_armijo_nonmonotone')
Exemplo n.º 7
0
def packer_task(pose, PDB_out=False):
    """
    Demonstrates the syntax necessary for basic usage of the PackerTask object
		performs demonstrative sidechain packing and selected design
		using  <pose>  and writes structures to PDB files if  <PDB_out>
		is True

    """
    # create a copy of the pose
    test_pose = Pose()
    test_pose.assign(pose)

    # this object is contained in PyRosetta v2.0 and above
    pymover = PyMOLMover()

    # create a standard ScoreFunction
    scorefxn = get_fa_scorefxn(
    )  #  create_score_function_ws_patch('standard', 'score12')

    ############
    # PackerTask
    # a PackerTask encodes preferences and options for sidechain packing, an
    #    effective Rosetta methodology for changing sidechain conformations, and
    #    design (mutation)
    # a PackerTask stores information on a per-residue basis
    # each residue may be packed or designed
    # PackerTasks are handled slightly differently in PyRosetta
    ####pose_packer = PackerTask()    # this line will not work properly
    pose_packer = standard_packer_task(test_pose)
    # the pose argument tells the PackerTask how large it should be

    # sidechain packing "optimizes" a pose's sidechain conformations by cycling
    #    through (Dunbrack) rotamers (sets of chi angles) at a specific residue
    #    and selecting the rotamer which achieves the lowest score,
    #    enumerating all possibilities for all sidechains simultaneously is
    #    impractically expensive so the residues to be packed are individually
    #    optimized in a "random" order
    # packing options include:
    #    -"freezing" the residue, preventing it from changing conformation
    #    -including the original sidechain conformation when determining the
    #        lowest scoring conformation
    pose_packer.restrict_to_repacking()  # turns off design
    pose_packer.or_include_current(True)  # considers original conformation
    print(pose_packer)

    # packing and design can be performed by a PackRotamersMover, it requires
    #    a ScoreFunction, for optimizing the sidechains and a PackerTask,
    #    setting the packing and design options
    packmover = protocols.minimization_packing.PackRotamersMover(
        scorefxn, pose_packer)

    scorefxn(pose)  # to prevent verbose output on the next line
    print('\nPre packing score:', scorefxn(test_pose))
    test_pose.pdb_info().name('original')  # for PyMOLMover
    pymover.apply(test_pose)

    packmover.apply(test_pose)
    print('Post packing score:', scorefxn(test_pose))
    test_pose.pdb_info().name('packed')  # for PyMOLMover
    pymover.apply(test_pose)
    if PDB_out:
        test_pose.dump_pdb('packed.pdb')

    # since the PackerTask specifies how the sidechains change, it has been
    #    extended to include sidechain constitutional changes allowing
    #    protein design, this method of design is very similar to sidechain
    #    packing; all rotamers of the possible mutants at a single residue
    #    are considered and the lowest scoring conformation is selected
    # design options include:
    #    -allow all amino acids
    #    -allow all amino acids except cysteine
    #    -allow specific amino acids
    #    -prevent specific amino acids
    #    -allow polar amino acids only
    #    -prevent polar amino acids
    #    -allow only the native amino acid
    # the myriad of packing and design options can be set manually or, more
    #    commonly, using a specific file format known as a resfile
    #    resfile syntax is explained at:
    #    http://www.rosettacommons.org/manuals/archive/rosetta3.1_user_guide/file_resfiles.html
    # manually setting deign options is tedious, the methods below are handy
    #    for creating resfiles
    # mutate the "middle" residues
    center = test_pose.total_residue() // 2
    specific_design = {}
    for i in range(center - 2, center + 3):
        specific_design[i] = 'ALLAA'
    # write a resfile to perform these mutations
    generate_resfile_from_pose(test_pose,
                               'sample_resfile',
                               False,
                               specific=specific_design)

    # setup the design PackerTask, use the generated resfile
    pose_design = standard_packer_task(test_pose)
    rosetta.core.pack.task.parse_resfile(test_pose, pose_design,
                                         'sample_resfile')
    print(pose_design)

    # prepare a new structure
    test_pose.assign(pose)

    # perform design
    designmover = protocols.minimization_packing.PackRotamersMover(
        scorefxn, pose_design)
    print(
        '\nDesign with all proteogenic amino acids at (pose numbered)\
        residues', center - 2, 'to', center + 2)
    print('Pre-design score:', scorefxn(test_pose))
    print( 'Pre-design sequence: ...' + \
        test_pose.sequence()[center - 5:center + 4] + '...' )

    designmover.apply(test_pose)  # perform design
    print('\nPost-design score:', scorefxn(test_pose))
    print( 'Post-design sequence: ...' + \
        test_pose.sequence()[center - 5:center + 4] + '...' )
    test_pose.pdb_info().name('designed')  # for PyMOLMover
    pymover.apply(test_pose)
    if PDB_out:
        test_pose.dump_pdb('designed.pdb')
Exemplo n.º 8
0
def mutate(pdb_name, n_muts=100):
    OUT = open(mydir + '/data/deltas.txt', 'w')
    #takes name of pdb file without the extention
    init(extra_options='-mute basic -mute core')
    # Constants
    PACK_RADIUS = 10.0
    #Amino acids, notice there is no C
    AAs = ("A", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P", "Q",
           "R", "S", "T", "V", "W", "Y")
    #Number of mutations to accept
    max_accept_mut = 600
    #Population size
    N = 100
    #Beta (temp term)
    beta = 1
    pdb = pdb_name + ".pdb"
    cleanATOM(pdb)
    pdb_clean_name = pdb_name + '.clean.pdb'
    initial_pose = pose_from_pdb(pdb_clean_name)

    #Set up ScoreFunction
    sf = get_fa_scorefxn()

    #Set up MoveMap.
    mm = MoveMap()
    #change these for more or less flexability
    mm.set_bb(True)
    mm.set_chi(True)

    #Pack and minimize initial pose to remove clashes.
    pre_pre_packing_score = sf(initial_pose)

    task = standard_packer_task(initial_pose)
    task.restrict_to_repacking()
    task.or_include_current(True)
    pack_rotamers_mover = RotamerTrialsMover(sf, task)
    pack_rotamers_mover.apply(initial_pose)

    min_mover = MinMover()
    min_mover.movemap(mm)
    min_mover.score_function(sf)
    min_mover.min_type('dfpmin_armijo_nonmonotone')
    min_mover.apply(initial_pose)

    post_pre_packing_score = sf(initial_pose)

    #Set threshold for selection
    threshold = pre_pre_packing_score / 2

    #number of residues to select from
    n_res = initial_pose.total_residue()

    max_accept_mut = 1500
    #start sim
    i = 0
    gen = 0
    columns = ['Number', 'Selection', 'P_fix', 'P_fix_MH']
    print >> OUT, '\t'.join(columns)
    while i < max_accept_mut:
        #update the number of generations that have pased
        gen += 1

        #pick a place to mutate
        mut_location = random.randint(1, n_res)

        #get the amino acid at that position
        res = initial_pose.residue(mut_location)
        #don't mess with C, just choose again
        if res.name1() == 'C':
            mut_location = random.randint(1, n_res)
            #get the amino acid at that position
            res = initial_pose.residue(mut_location)

        #choose the amino acid to mutate to
        new_mut_key = random.randint(0, len(AAs) - 1)

        proposed_res = AAs[new_mut_key]

        #don't bother mutating to the same amino acid it just takes more time
        if proposed_res == res.name1():
            new_mut_key = random.randint(0, len(AAs) - 1)
            proposed_res = AAs[new_mut_key]

        #make the mutation
        mutant_pose = mutate_residue(initial_pose, mut_location, proposed_res,
                                     PACK_RADIUS, sf)
        #score mutant
        variant_score = sf(mutant_pose)

        probability = calc_prob_fix(variant_score, post_pre_packing_score, N,
                                    beta, threshold)
        probability_mh = calc_prob_mh(variant_score, post_pre_packing_score, N,
                                      beta, threshold)
        f_i = calc_x_fix(post_pre_packing_score, beta, threshold)
        f_j = calc_x_fix(variant_score, beta, threshold)
        s = math.log(f_j) - math.log(f_i)
        #test to see if mutation is accepted
        if np.isnan(probability) == True:
            continue
        rndm = random.random()
        if (i < 100):
            if (rndm < probability):
                initial_pose = mutant_pose
                post_pre_packing_score = variant_score
            else:
                continue
        # Assuming 100 burn in phase, take this if out if you want to store everything
        else:
            data = [str(i), str(s), str(probability), str(probability_mh)]
            print >> OUT, '\t'.join(data)
            #save name and energy change
            #data.append(variant_name + "," + str(variant_score) + "," + str(variant_score - post_pre_packing_score) + "," + str(probability) + "," + str(gen) + "\n")
            #pdb_name=str(i)+".pdb"
            #mutant_pose.dump_pdb(pdb_name)

        print i, s, probability, rndm
        #update number of accepts
        i += 1

    OUT.close()
    def apply( self, pose ):
        '''
        This is an adjustable 3ay4-glycan modeling protocol (as of my PyRosetta-3's most recent abilities 9/26/16). Use all the adjustable arguments to figure out what the best protocol actually is
        :param pose: Pose
        '''
        #################
        #### IMPORTS ####
        #################
        from os import popen
        from random import choice
        from rosetta.protocols.simple_moves import MinMover
        from pyrosetta import MonteCarlo, standard_packer_task
        from rosetta.protocols.simple_moves import RotamerTrialsMover
        from rosetta.core.scoring import fa_atr, fa_rep
        #from antibody_functions import native_Fc_glycan_nums_except_core_GlcNAc  # shouldn't need this as a MoveMap is passed to create this class
        from native_3ay4_glycan_modeling_protocol_functions import native_3ay4_Fc_glycan_LCM_reset, \
            add_constraints_to_pose, get_ramp_score_weight, get_ramp_angle_max, \
            native_3ay4_Fc_glycan_random_reset, get_res_nums_within_radius_of_residue_list, \
            SugarSmallMover


        ########################################
        #### COPY POSES AND MAKE VISUALIZER ####
        ########################################
        # get the working and native pose (for this particular script, they are the same thing)
        native_pose = pose.clone()
        working_pose = pose.clone()
        self.decoy_name = working_pose.pdb_info().name()
        self.native_pose = native_pose.clone()


        ###############################
        #### GET MOVEABLE RESIDUES ####
        ###############################
        # get the moveable residues from passed MoveMap
        # moveable means the BackBone in the MoveMap was set to True and it is a carbohydrate
        moveable_residues = [ res_num for res_num in range( 1, working_pose.size() + 1 ) if self.mm.get_bb( res_num ) and working_pose.residue( res_num ).is_carbohydrate() ]


        ###################
        #### LCM RESET ####
        ###################
        # reset the glycan using the data from the default.table used for the LinkageConformerMover
        if self.LCM_reset:
            working_pose.assign( native_3ay4_Fc_glycan_LCM_reset( mm = self.mm, 
                                                                  input_pose = working_pose, 
                                                                  use_population_ideal_LCM_reset = self.use_population_ideal_LCM_reset ) )
            if self.verbose:
                print "score of LCM reset:", self.watch_sf( working_pose )


        ##########################
        #### OR, RANDOM RESET ####
        ##########################
        # reset the glycan to random values from -180 to 180
        if self.random_reset:
            working_pose.assign( native_3ay4_Fc_glycan_random_reset( mm = self.mm, 
                                                                     input_pose = working_pose ) )
            if self.verbose:
                print "score of random reset:", self.watch_sf( working_pose )


        ######################################################
        #### SPIN CARB OF PROTEIN-CARBOHYDRATE CONNECTION ####
        ######################################################
        # the intent of this spin is to set the carbohydrate involved in the protein-carbohydrate connection into
        # a reasonable starting position after the reset. This is because current LCM data found in the default.table
        # was collected for surface glycans. These data are not reflective of the glycans found in the Ig system
        # use the MoveMap to see which residues have a parent connection to a protein
        if self.spin_carb_connected_to_prot:
            from native_3ay4_glycan_modeling_protocol_functions import spin_carbs_connected_to_prot

            # the spin takes residue 216 and 440 of 3ay4 and assigns either 180, 60, or -60 to omega1 and omega2 individually
            # can sample within +/- 15 of those three values as well, if specified
            working_pose.assign( spin_carbs_connected_to_prot( self.mm, 
                                                               input_pose = working_pose, 
                                                               spin_using_ideal_omegas = self.spin_using_ideal_omegas) )
            if self.verbose:
                print "score of core GlcNAc spin:", self.watch_sf( working_pose )


        #########################################
        #### HARDCODED OMEGA RESET TO NATIVE ####
        #########################################
        # reset the native omega torsion, if desired
        # hardcoded for now as this is not something that would be done in a real protocol
        if self.set_native_omega:
            working_pose.set_omega( 221, native_pose.omega( 221 ) )
            working_pose.set_omega( 445, native_pose.omega( 445 ) )
            if self.verbose:
                print "score of omega branch reset:", self.watch_sf( working_pose )


        ########################################
        #### HARDCODED CORE RESET TO NATIVE ####
        ########################################
        # reset the native torsions for the core GlcNAcs, if desired
        # hardcoded for now as this is not something that would be done in a real protocol
        if self.set_native_core:
            from rosetta.core.id import omega2_dihedral
            from rosetta.core.pose.carbohydrates import get_glycosidic_torsion, set_glycosidic_torsion

            # reset the phi, psi, omega, and omega2 torsions of residues 216 and 440 (core GlcNAc to ASN-69)
            # 216
            working_pose.set_phi( 216, native_pose.phi( 216 ) )
            working_pose.set_psi( 216, native_pose.psi( 216 ) )
            working_pose.set_omega( 216, native_pose.omega( 216 ) )
            set_glycosidic_torsion( omega2_dihedral, working_pose, 216, 
                                    get_glycosidic_torsion( omega2_dihedral, native_pose, 216 ) )
            # 440
            working_pose.set_phi( 440, native_pose.phi( 440 ) )
            working_pose.set_psi( 440, native_pose.psi( 440 ) )
            working_pose.set_omega( 440, native_pose.omega( 440 ) )
            set_glycosidic_torsion( omega2_dihedral, working_pose, 440, 
                                    get_glycosidic_torsion( omega2_dihedral, native_pose, 440 ) )
            if self.verbose:
                print "score of core GlcNAc reset:", self.watch_sf( working_pose )


        ###################################################
        #### HARDCODED CORE RESET TO IgG FC STATISTICS ####
        ###################################################
        # reset the torsions for the core GlcNAcs to values seen in IgG Fcs, if desired
        # hardcoded for now as this is not something that would be done in a real protocol
        if self.set_native_core_omegas_to_stats:
            from rosetta.core.id import omega2_dihedral
            from rosetta.core.pose.carbohydrates import set_glycosidic_torsion
            from rosetta.numeric.random import gaussian
            from native_3ay4_glycan_modeling_protocol_functions import calc_mean_degrees, calc_stddev_degrees

            # compile the data I have found from native crystal structures
            # subtracting 360 from positive numbers because...I think that's how I should do this
            phi_data = []
            psi_data = []
            omega1_data = [ -154.566, -162.504,  # 3ay4 - IgG1 Fc G2 to FcgRIIIa
                             -163.850, 176.923,  # 3ave - IgG1 Fc no paper, but it comes out as G0F2
                             -164.387, -146.038, # 5d4q - IgG1 Fc G2F1 ( check )
                             -146.449, -146.340, # 5d6d - IgG1 Fc G2F2 to FcgRIIIa ( check )
                             -166.996, -171.113  # 1h3x - IgG1 Fc G0F2
                             ]
            omega1_data = [ deg - 360 if deg > 0 else deg for deg in omega1_data ]
            omega2_data = [ 59.198, 59.055,  # 3ay4
                            53.823, 47.082,  # 3ave
                            48.590, 63.976,  # 5d4q
                            64.005, 63.988,  # 5d6d
                            45.997, 59.196   # 1h3x
                            ]
            omega2_data = [ deg - 360 if deg > 0 else deg for deg in omega2_data ]

            # pick a number within a gaussian distribution (I think??) of the torsions
            # mean + ( stddev * gaussian() )
            # not doing it the SmallMover way because I would want to be able to sample out more than 1 standard deviation
            # SmallMover way would be periodic_range( mean_torsion - torsion_stddev * rg().uniform(), 360.0 )
            # mean
            base_omega1 = calc_mean_degrees( omega1_data )
            base_omega2 = calc_mean_degrees( omega2_data )
            # standard deviation
            omega1_stddev = calc_stddev_degrees( omega1_data )
            omega2_stddev = calc_stddev_degrees( omega2_data )
            # 216
            new_omega1_216 = base_omega1 + ( omega1_stddev * gaussian() )
            new_omega2_216 = base_omega2 + ( omega2_stddev * gaussian() )
            # 440
            new_omega1_440 = base_omega1 + ( omega1_stddev * gaussian() )
            new_omega2_440 = base_omega2 + ( omega2_stddev * gaussian() )

            # reset the omega1 and omega2 torsions of residues 216 and 440 (core GlcNAc to ASN-69)
            # 216
            working_pose.set_omega( 216, new_omega1_216 )
            set_glycosidic_torsion( int( omega2_dihedral ), working_pose, 216, new_omega2_216 )
            # 440
            working_pose.set_omega( 440, new_omega1_440 )
            set_glycosidic_torsion( int( omega2_dihedral ), working_pose, 440, new_omega2_440 )

            if self.verbose:
                print "score of core GlcNAc reset using IgG Fc statistics:", self.watch_sf( working_pose )


        ############################################
        #### VISUALIZE AND STORE THE RESET POSE ####
        ############################################
        # visualize the pose that has had all components of reset completed
        try:
            if self.pmm_name is not None:
                working_pose.pdb_info().name( self.pmm_name )
                self.pmm.apply( working_pose )
                working_pose.pdb_info().name( self.decoy_name )
            else:
                self.pmm.apply( working_pose )
        except:
            pass

        # store a copy of the reset pose object
        # storing it here so that all types of resets could have been done, including the reset back to natives
        self.reset_pose = working_pose.clone()

        # dump the reset pose, if desired
        if self.dump_reset_pose:
            reset_name = self.reset_pose.pdb_info().name().split( ".pdb" )[0] + "_reset.pdb"
            self.reset_pose.dump_file( reset_name )
            # zip the dump file, if desired
            if self.zip_dump_poses:
                os.popen( "gzip %s" %reset_name )


        #########################
        #### ADD CONSTRAINTS ####
        #########################
        if self.constraint_file is not None:
            from rosetta.core.scoring import atom_pair_constraint
            try:
                # set the constraints from the constraint_file
                working_pose.assign( add_constraints_to_pose( self.constraint_file, working_pose ) )
                # add atom_pair_constraint to the ScoreFunction, if needed
                self.sf.set_weight_if_zero( atom_pair_constraint, 1.0 )
            except:
                print "\nThere was something wrong with your constraint file. Are you sure it exists? Are you sure you used the correct names for the constraints?\n"
                sys.exit()


        ############################
        #### MIN MOVER CREATION ####
        ############################
        # make the MinMover from the passed MoveMap
        # if desired
        if self.minimize_each_round:
            # if needed
            if self.min_mover is None:
                self.min_mover = MinMover()
                self.min_mover.movemap( self.mm )
                self.min_mover.score_function( self.sf )
                self.min_mover.min_type( "dfpmin_strong_wolfe" )
                self.min_mover.tolerance( 0.01 )
                self.min_mover.nb_list( True )


        ######################################
        #### PACK ROTAMERS MOVER CREATION ####
        ######################################
        # make the PackerRotamersMover from the passed MoveMap
        # if desired
        if self.pack_after_x_rounds > 0:
            # if needed
            if self.pack_rotamers_mover is None:
                # make the packer task
                # default of standard_packer_task is to set packing for residues to True
                task = standard_packer_task( working_pose )
                task.or_include_current( True )
                task.restrict_to_repacking()

                # get all the protein residues within 8A of the moveable_residues
                # this uses the nbr_atom to determine if a residue is nearby or not, hence why I'm using a big distance like 8A
                # nbr_atom seems to be basically the same as C4 in sugars
                # this should include the Tyr if core GlcNAc is moveable in 3ay4
                nearby_protein_residues = get_res_nums_within_radius_of_residue_list( moveable_residues, working_pose, 
                                                                                      radius = 8, 
                                                                                      include_res_nums = False )

                # create a list of residue numbers that can be packed
                # meaning, the moveable carbohydrate residues and the residues around them
                packable_residues = moveable_residues
                packable_residues.extend( nearby_protein_residues )
                packable_residues = set( packable_residues )

                # turn off packing for all residues that are NOT_packable_residues
                # this is a new set with elements in pose.size() but not in packable_residues ( disjoint, s - t )
                # meaning, all residue numbers in pose.size() that are not packable need to be NOT packed
                NOT_packable_residues = list( set( range( 1, working_pose.size() + 1 ) ) - packable_residues )
                [ task.nonconst_residue_task( res_num ).prevent_repacking() for res_num in NOT_packable_residues ]

                # make the pack_rotamers_mover
                pack_rotamers_mover = RotamerTrialsMover( self.sf, task )

                # attach the task and the mover to the protocol object
                self.packer_task = task
                self.pack_rotamers_mover = pack_rotamers_mover


        ####################################
        #### MAKE THE MONTECARLO OBJECT ####
        ####################################
        # create the MonteCarlo object, if needed
        if self.mc is None:
            self.mc = MonteCarlo( working_pose, self.sf, self.kT )
        self.mc.reset_scorefxn( working_pose, self.sf )


        ########################################
        #### MAKE AND APPLY THE SUGAR MOVER ####
        ########################################
        # for as many trials as specified
        num_mc_accepts = 0
        num_mc_checks = 0
        mc_acceptance = -1
        for trial_num in range( 1, self.trials + 1 ):
            # print current score
            if self.verbose:
                print "\nstarting score:", self.watch_sf( working_pose )

            ####################################
            #### RAMP WITH ANGLE MAX UPDATE ####
            ####################################
            if self.ramp_angle_max:
                # skip ramping on the first trial because the passed angle_max should be the angle_max used
                if trial_num !=1:
                    # by the end of the protocol our angle_max should be angle_min
                    # angle_min is 6.0 by default which is the angle_max for loop residues in the BackboneMover
                    self.angle_max = get_ramp_angle_max( current_angle_max = self.angle_max, 
                                                         target_angle_max = self.angle_min, 
                                                         current_step = trial_num, 
                                                         total_steps = self.trials )


            #########################################
            #### RAMP WITH SCORE FUNCTION UPDATE ####
            #########################################
            if self.ramp_sf:
                # if this is the first move, adjust the fa_atr and fa_rep terms by the corresponding factors
                if trial_num == 1:
                    # store the original fa_atr and fa_rep
                    FA_ATR_ORIG = self.sf.get_weight( fa_atr )
                    FA_REP_ORIG = self.sf.get_weight( fa_rep )
                    # adjust the fa_atr weight by the passed fa_atr_ramp_factor
                    FA_ATR_NEW = FA_ATR_ORIG * self.fa_atr_ramp_factor
                    self.sf.set_weight( fa_atr, FA_ATR_NEW )
                    # adjust the fa_rep weight by the passed fa_rep_ramp_factor
                    FA_REP_NEW = FA_REP_ORIG * self.fa_rep_ramp_factor
                    self.sf.set_weight( fa_rep, FA_REP_NEW )

                # else, adjust the score weight
                else:
                    # ramp up or down the appropriate scoring terms
                    self.sf.set_weight( fa_atr, get_ramp_score_weight( current_weight = self.sf.get_weight( fa_atr ), 
                                                                       target_weight = FA_ATR_ORIG, 
                                                                       current_step = trial_num, 
                                                                       total_steps = self.trials ) )
                    self.sf.set_weight( fa_rep, get_ramp_score_weight( current_weight = self.sf.get_weight( fa_rep ), 
                                                                       target_weight = FA_REP_ORIG, 
                                                                       current_step = trial_num, 
                                                                       total_steps = self.trials ) )
                # DEBUG
                #print "\n".join( [ "%s %s" %( str( score_type ), str( self.sf.get_weight( score_type ) ) ) for score_type in self.sf.get_nonzero_weighted_scoretypes() ] )
                # give ramped sf back to MC and MinMover
                # this is because PyRosetta apparently doesn't do the whole pointer thing with the sf
                self.mc.score_function( self.sf )
                self.mc.reset_scorefxn( working_pose, self.sf )
                self.min_mover.score_function( self.sf )


            ##########################
            #### MAKE SUGAR MOVES ####
            ##########################
            # make as many moves per trial as desired
            # SugarSmallMover
            if self.make_small_moves:
                working_pose.assign( SugarSmallMover( self.mm, self.moves_per_trial, self.angle_max, working_pose, 
                                                      move_all_torsions = self.move_all_torsions ) )
            # SugarShearMover
            elif self.make_shear_moves:
                pass

            # relay score information
            if self.verbose:
                print "score after sugar moves:", self.watch_sf( working_pose )


            ##############
            #### PACK ####
            ##############
            # pack the sugars and surrounding residues, if desired
            if self.pack_after_x_rounds > 0:
                if trial_num % self.pack_after_x_rounds == 0:
                    self.pack_rotamers_mover.apply( working_pose )
                    if self.verbose:
                        print "score after local pack:", self.watch_sf( working_pose )


            ###################
            #### MINIMIZE #####
            ###################
            # minimize the backbone of the sugars, if desired
            if self.minimize_each_round:
                self.min_mover.apply( working_pose )
                if self.verbose:
                    print "score after min:", self.watch_sf( working_pose )


            ###############################
            #### ACCEPT OR REJECT MOVE ####
            ###############################
            # accept or reject the total move using the MonteCarlo object
            if self.mc.boltzmann( working_pose ):
                # up the counters and send to pymol
                num_mc_accepts += 1
                try:
                    # switching between a name for pymol and for the decoy
                    # just for clarity
                    if self.pmm_name is not None:
                        working_pose.pdb_info().name( self.pmm_name )
                        self.pmm.apply( working_pose )
                        working_pose.pdb_info().name( self.decoy_name )
                    else:
                        self.pmm.apply( working_pose )
                # if pymol doesn't work for whatever reason, pass
                except:
                    pass
            num_mc_checks += 1

            # print out the MC acceptance rate every 3 trials and on the last trial
            mc_acceptance = round( ( float( num_mc_accepts ) / float( num_mc_checks ) * 100 ), 2 )
            if self.verbose:
                if trial_num % 3 == 0 or trial_num == self.trials:
                    print "Moves made so far:", num_mc_checks,
                    print "  Moves accepted:", num_mc_accepts,
                    print "  Acceptance rate:", mc_acceptance

        # add any relevant data to the class object
        self.mc_acceptance = mc_acceptance

        return working_pose
Exemplo n.º 10
0
from pyrosetta import init, get_fa_scorefxn, standard_packer_task, standard_task_factory
from pyrosetta.rosetta import core, protocols

init(
    extra_options="-constant_seed"
)  # WARNING: option '-constant_seed' is for testing only! MAKE SURE TO REMOVE IT IN PRODUCTION RUNS!!!!!
import os
os.chdir('.test.output')

print('Packing and Design ----------------------------------------------')

print('mover: PackRotamersMover')
pose = core.import_pose.pose_from_file("../test/data/test_in.pdb")
scorefxn = get_fa_scorefxn()  #  create_score_function('standard')
#task_pack = core.pack.task.TaskFactory.create_packer_task(pose)
task_pack = standard_packer_task(pose)
task_pack.restrict_to_repacking()
task_pack.nonconst_residue_task(5).prevent_repacking()
print(task_pack)
pack = protocols.minimization_packing.PackRotamersMover(scorefxn, task_pack)
pack.apply(pose)

rotamer_trials = protocols.minimization_packing.RotamerTrialsMover(
    scorefxn, task_pack)
rotamer_trials.apply(pose)

#TODO add task interface commands like:
#prevent_repacking(1,total_residue) or (res) or (True [=all])
#allow_repacking() # same argument options/overload
# ... needs discussion with Mini community...task is 'commutative'