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
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)
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
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):
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)
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')
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')
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
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'