def refine_saccharide(pose, args): """Perform packing, small, and shear moves.""" print ' Initial Score:', sf(pose) # Set up BB Movers. mm = MoveMap() mm.set_bb(True) mm.set_chi(False) mm.set_nu(False) small_mover = SmallMover(mm, args.kt, args.n_small_moves) small_mover.angle_max(args.max_angle) shear_mover = ShearMover(mm, args.kt, args.n_shear_moves) shear_mover.angle_max(args.max_angle / 2) min_mover = MinMover(mm, sf, args.min_type, 0.001, True) # Set up ring Mover. if not args.lock_rings: mm_rings = MoveMap() mm_rings.set_bb(False) mm_rings.set_chi(False) mm_rings.set_nu(True) ring_flipper = RingConformationMover() ring_flipper.movemap(mm_rings) ring_min_mover = MinMover(mm_rings, sf, args.min_type, 0.001, True) # Set up Monte Carlo object. mc = MonteCarlo(pose, sf, args.kt) for cycle in range(1, args.n_cycles + 1): small_mover.apply(pose) shear_mover.apply(pose) visualize(pose) if not args.lock_rings: ring_flipper.apply(pose) ring_min_mover.apply(pose) visualize(pose) packer.apply(pose) min_mover.apply(pose) visualize(pose) mc.boltzmann(pose) if not args.mute and cycle % 5 == 0: print ' Cycle', cycle, ' Current Score:', sf(pose) visualize(pose) print ' Final Score:', sf(pose) sf.show(pose) # TEMP
apply_sf_sugar_constraints = False, pack_branch_points = True ) pack_rotamers_mover.apply( working_pose ) # minimize mm = MoveMap() mm.set_bb( True ) mm.set_chi( True ) mm.set_branches( True ) min_mover = MinMover( movemap_in = mm, scorefxn_in = sf, min_type_in = "dfpmin_strong_wolfe", tolerance_in = 0.01, use_nb_list_in = True ) min_mover.apply( working_pose ) pmm.apply( working_pose ) # inform user of decoy number print "\tFinished with decoy %s" %str( decoy_num ) decoy_num += 1 # collect additional metric data try: metrics = get_pose_metrics_on_native( working_pose, working_pose_info, native_pose, native_pose_info, sf, 2, # Fc-FcR interface JUMP_NUM
for jj in range( input_args.num_moves_per_trial ): # pick a random Fc glycan residue except the core GlcNAc res_num = random.choice( testing_pose_info.native_Fc_glycan_nums_except_core_GlcNAc ) # apply the SugarSmallMover testing_pose.assign( SugarSmallMover( res_num, testing_pose, angle_max ) ) if input_args.verbose: print "score after SugarSmallMover:", main_sf( testing_pose ) # pack the Fc sugars except core GlcNac using the previously-made pack_rotamers_mover #pack_rotamers_mover.apply( testing_pose ) #if input_args.verbose: # print "score after pack:", main_sf( testing_pose ) # minimize the backbone of the Fc sugars Fc_glycan_min_mover.apply( testing_pose ) if input_args.verbose: print "score after min:", main_sf( testing_pose ) # accept or reject the total move using the MonteCarlo object if mc.boltzmann( testing_pose ): # reset the counter num_mc_rejects_in_a_row = 0 # up the counters and send to pymol num_ssh_accept += 1 pmm.apply( testing_pose ) # print out a non-ramped sf to watch for convergence, if desired if input_args.watch_for_convergence: print "***Am I converging?:", convergence_sf( testing_pose )
def main(): parser = argparse.ArgumentParser() parser.add_argument('pdb_filename', action="store", type=str) parser.add_argument('replicate_number', action="store", type=int) inputs = parser.parse_args() #takes name of pdb file without the extention pdb_file = inputs.pdb_filename prot_name = pdb_file.split('/')[-1].split('.')[0] #set up timer to figure out how long the code took to run t0 = time() fasta_file = pdb_file.replace('/structures/', '/fastas/').replace('.pdb', '.fasta') records = list(SeqIO.parse(fasta_file, 'fasta')) assert len(records) == 1 wt_seq = str(records[0].seq) # Initialize Rosetta. #init(extra_options='-mute basic -mute core') init(extra_options= '-mute basic -mute core -rebuild_disulf false -detect_disulf false') ######################## # Constants ######################## PACK_RADIUS = 12.0 #Amino acids AAs = ("A", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "V", "W", "Y") AAs_choice_dict = {} for aa in AAs: AAs_choice_dict[aa] = [other_aa for other_aa in AAs if other_aa != aa] #Number of mutations to accept max_accept_mut = 10 * len(wt_seq) #max_accept_mut = 2048 #Population size N = 1000 #Beta (temp term) beta = 1 #Fraction of the WT stability value to shoot for threshold_fraction = 0.5 ######################## ######################## #Prepare data headers data = ['Variant,Rosetta Score,"delta-delta-G",Probability,Generation\n'] #Load a clean pdb file initial_pose = pose_from_pdb(pdb_file) if '.clean' in pdb_file: pdb_file = ''.join(pdb_file.split('.clean')) #Set up ScoreFunction sf = get_fa_scorefxn() #Set up MoveMap. mm = MoveMap() 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) #Threshold for selection threshold = post_pre_packing_score * threshold_fraction print 'threshold:', threshold data.append('WT,' + str(post_pre_packing_score) + ',0.0,0.0,0\n') #number of residues to select from n_res = initial_pose.total_residue() #start evolution i = 0 gen = 0 while i < max_accept_mut: #update the number of generations that have pased gen += 1 #print 'accepts:', i #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) #choose the amino acid to mutate to #new_mut_key = random.randint(0,len(AAs)-1) #proposed_res = AAs[new_mut_key] proposed_res = random.choice(AAs_choice_dict[res.name1()]) #make the mutation mutant_pose = mutate_residue(initial_pose, mut_location, proposed_res, PACK_RADIUS, sf) #score mutant variant_score = sf(mutant_pose) #get the probability that the mutation will be accepted probability = calc_prob_mh(variant_score, post_pre_packing_score, N, beta, threshold) #test to see if mutation is accepted if random.random() < probability: #create a name for the mutant if its going to be kept variant_name = res.name1() + str(initial_pose.pdb_info().number( mut_location)) + str(proposed_res) #save name and energy change data.append(variant_name + "," + str(variant_score) + "," + str(variant_score - post_pre_packing_score) + "," + str(probability) + "," + str(gen) + "\n") # if i == (max_accept_mut - 1): # final_pdb_name=pdb_file.replace('.pdb', '_thresh={}_Neff={}_beta={}_i={}_nmut={}.pdb'.format(threshold_fraction, N, beta, inputs.replicate_number, i)) # mutant_pose.dump_pdb(final_pdb_name) #update the wildtype initial_pose = mutant_pose post_pre_packing_score = variant_score #update number of accepts i += 1 print '\nMutations and scoring complete.' t1 = time() # Output results. output_filename = '../Results/{}/{}_thresh={}_Neff={}_beta={}_i={}.csv'.format( prot_name, prot_name, threshold_fraction, N, beta, inputs.replicate_number) with open(output_filename, "w") as outfile: outfile.writelines(data) print 'Data written to:', output_filename print 'program takes %f' % (t1 - t0)
apply_sf_sugar_constraints = False, pack_branch_points = True, residue_range = Fc_sugar_nums, use_pack_radius = True, pack_radius = 20 ) # do 2 pack/mins to try to get to a low-energy structure # those that don't get to a negative score will probably just be outliers? for ii in range( 2 ): # pack pack_rotamers_mover.apply( testing_pose ) if input_args.verbose: print "score of pack", main_sf( testing_pose ) # minimize min_mover.apply( testing_pose ) if input_args.verbose: print "score of min", main_sf( testing_pose ) pmm.apply( testing_pose ) # collect additional metric data try: metrics = get_pose_metrics( testing_pose, native_pose, main_sf, 2, # interface JUMP_NUM Fc_glycan_chains, Fc_sugar_nums, FcR_sugar_nums,
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 import MoveMap, MinMover, MonteCarlo, PyMOL_Mover from rosetta.core.scoring import fa_atr, fa_rep 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, SugarSmallMover, \ make_RotamerTrialsMover, get_res_nums_within_radius # pandas isn't on Jazz, so use the csv module if you can't use pandas if self.watch_accepted_move_sizes or self.watch_E_vs_trial: try: import pandas as pd self.pandas = True self.E_vs_trial_df = pd.DataFrame() self.move_size_df = pd.DataFrame() except: import csv self.pandas = False pass # for watching the range of accepted move size if self.watch_accepted_move_sizes: move_size_trial_nums = [] moved_torsions = [] move_sizes = [] res_nums = [] move_accepted = [] # for watching the energy per trial if self.watch_E_vs_trial: E_vs_trial_nums = [] energies = [] lowest_seen_energies = [] ########################## #### COPY INPUT POSES #### ########################## # get the working and native pose (for this particular script, they are the same thing) self.native_pose = pose.clone() working_pose = pose.clone() self.decoy_name = working_pose.pdb_info().name() ####################################### #### PREPARE FOR MOVIE, IF DESIRED #### ####################################### # create a movie_poses_dir, if desired if self.make_movie: # each apply should have an empty self.movie_poses list self.movie_poses = [] # make the directory, if needed self.movie_poses_dir = self.dump_dir + "movie_poses_dir/" if not os.path.isdir( self.movie_poses_dir ): try: os.mkdir( self.movie_poses_dir ) except: pass ############################### #### 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 self.moveable_residues = [ res_num for res_num in range( 1, working_pose.n_residue() + 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.clone() ) ########################## #### 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.clone() ) ###################################################### #### 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.clone() ) ######################################### #### 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, self.native_pose.omega( 221 ) ) working_pose.set_omega( 445, self.native_pose.omega( 445 ) ) if self.verbose: print "score of omega branch reset:", self.watch_sf( working_pose.clone() ) ######################################## #### 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, self.native_pose.phi( 216 ) ) working_pose.set_psi( 216, self.native_pose.psi( 216 ) ) working_pose.set_omega( 216, self.native_pose.omega( 216 ) ) set_glycosidic_torsion( omega2_dihedral, working_pose, 216, get_glycosidic_torsion( omega2_dihedral, self.native_pose, 216 ) ) # 440 working_pose.set_phi( 440, self.native_pose.phi( 440 ) ) working_pose.set_psi( 440, self.native_pose.psi( 440 ) ) working_pose.set_omega( 440, self.native_pose.omega( 440 ) ) set_glycosidic_torsion( omega2_dihedral, working_pose, 440, get_glycosidic_torsion( omega2_dihedral, self.native_pose, 440 ) ) if self.verbose: print "score of core GlcNAc reset:", self.watch_sf( working_pose.clone() ) # no longer needed because I changed the default.table to store these data # thus, I am letting the LCM choose from IgG1 Fc stats to reset GlcNAc core omega1 and omega2 # commented, not deleted, so that I may reference it and how it was structured to work ''' #################################################### #### HARDCODED CORE RESET TO IgG1 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 omega_dihedral, 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 set_glycosidic_torsion( omega_dihedral, working_pose, 216, new_omega1_216 ) set_glycosidic_torsion( omega2_dihedral, working_pose, 216, new_omega2_216 ) # 440 set_glycosidic_torsion( omega_dihedral, working_pose, 440, new_omega1_440 ) set_glycosidic_torsion( 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.clone() ) ''' ############################################ #### 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 the reset pose to the list of poses for the movie, if desired if self.make_movie: # change the name to just "protocol_X_decoy_Y_0.pdb" without path location # X is protocol number, Y is decoy number, 0 for the movie number # state 0 is the reset_pose for when making a movie orig_name = self.reset_pose.pdb_info().name() reset_name = self.reset_pose.pdb_info().name().split( '/' )[-1].split( ".pdb" )[0] + "_0.pdb" self.reset_pose.pdb_info().name( reset_name ) self.movie_poses.append( self.reset_pose.clone() ) self.reset_pose.pdb_info().name( orig_name ) # append all the information to the lists if self.watch_E_vs_trial: # 0th trial is the reset pose E_vs_trial_nums.append( 0 ) energies.append( self.watch_sf( working_pose.clone() ) ) # the lowest seen pose and energy will be that of the reset pose to start lowest_seen_energies.append( self.watch_sf( working_pose.clone() ) ) self.lowest_score_seen = self.watch_sf( working_pose.clone() ) self.lowest_score_pose_seen = working_pose.clone() ######################### #### 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? Check on %s\n" %self.constraint_file sys.exit() #################################### #### MAKE THE MONTECARLO OBJECT #### #################################### # create the MonteCarlo object if self.mc is None: self.mc = MonteCarlo( working_pose, self.sf, self.kT ) self.mc.set_temperature( self.kT ) # reset everything just to be safe since MonteCarlo is a mess # clear and reset the counters self.mc.reset_counters() # last_accepted_pose and lowest_score_pose is an empty pose # lowest_score is still the lowest E seen self.mc.clear_poses() # sets the passed sf as the mc.sf and the last_accepted_pose as the passed pose # the lowest_score_pose is the passed pose and the lowest_score is the # score of the passed pose using the passed sf self.mc.reset_scorefxn( working_pose, self.sf ) ############################# #### PREPARE FOR RAMPING #### ############################# # store the original fa_atr and fa_rep # this will be accessed as the outer_trials pass and the sf gets re-ramped FA_ATR_ORIG = self.sf.get_weight( fa_atr ) FA_REP_ORIG = self.sf.get_weight( fa_rep ) # set the local angle_max to the passed angle_max value # this will be adjusted if ramp_angle_max is True angle_max = self.angle_max ######################################## #### MAKE AND APPLY THE SUGAR MOVER #### ######################################## # for as many trials as specified num_mc_accepts = 0 num_mc_checks = 0 mc_acceptance = -1 # -1 so that it will play nice in the metrics file if the number doesn't get updated somehow movie_num = 1 # for each set of outer trials for outer_trial in range( 1, self.outer_trials + 1 ): # inner_trial must be 1 to N because decoy 0 will be the reset_pose when creating a movie for inner_trial in range( 1, self.inner_trials + 1 ): # print current score if self.verbose: print "\nstarting score:", self.watch_sf( working_pose.clone() ) #################################### #### RAMP WITH ANGLE MAX UPDATE #### #################################### if self.ramp_angle_max: # the last ~10% of moves in the inner_trials will be the angle_min # the first move should use the passed angle_max if inner_trial == 1: angle_max = self.angle_max # otherwise, adjust the angle_max according to which inner_trial number we are on else: # 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 angle_max = get_ramp_angle_max( current_angle_max = angle_max, target_angle_max = self.angle_min, current_step = inner_trial, total_steps = self.inner_trials ) # DEBUG #print "angle_max: %s" %angle_max ######################################### #### 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 # after the first move, we will ramp the score up or down accordingly back to the original value # the last ~10% of moves in the inner_trials will be the original values if inner_trial == 1: # 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 ) # reset the MonteCarlo object with the working_pose and ramped sf # inner_trial == 1 means we should forget everything that happened in a previous round of outer_trials self.mc.reset_counters() self.mc.clear_poses() # the sf was just re-ramped, so ensure the MonteCarlo object is aware of this change and thinks # the working_pose using this ramped sf is the lowest_score_pose it has seen self.mc.reset_scorefxn( working_pose, self.sf ) # else, adjust the score weight based on the current inner_trial step 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 = inner_trial, total_steps = self.inner_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 = inner_trial, total_steps = self.inner_trials ) ) # give ramped sf back to MonteCarlo object # this is because MonteCarlo stores a clone so it does not update the sf itself self.mc.score_function( self.sf ) # the sf was just re-ramped, so ensure the MonteCarlo object is aware of this change and thinks # the current working_pose using this ramped sf is the lowest_score_pose it has seen self.mc.reset_scorefxn( working_pose, self.sf ) # 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() ] ) #print "\n".join( [ "%s %s" %( str( score_type ), str( self.mc.score_function().get_weight( score_type ) ) ) for score_type in self.mc.score_function().get_nonzero_weighted_scoretypes() ] ) ########################## #### MAKE SUGAR MOVES #### ########################## # make as many moves per trial as desired # SugarSmallMover if self.make_small_moves: SSmM = SugarSmallMover( self.mm, self.moves_per_trial, angle_max, working_pose, move_all_torsions = self.move_all_torsions ) working_pose.assign( SSmM.apply( working_pose ) ) # SugarShearMover elif self.make_shear_moves: pass # relay score information if self.verbose: print "score after sugar moves:", self.watch_sf( working_pose.clone() ) ################################## #### PREPARE FOR PACK AND MIN #### ################################## # if you aren't going to pack this round, then the pack_and_min_residues will mirror the glycan residues # if you are packing this round, then you need residues surrounding as well pack_and_min_residues = [ res_num for res_num in self.moveable_residues ] # if you aren't going to pack this round, then the minimizer's MoveMap should only include the self.moveable_residues (bb and chi) # if you are packing this round, then the MoveMap has bb and chi for self.moveable_residues and chi for surrounding_residues # default MoveMap creation has everything set to False, so set the appropriate residues to True min_mm = MoveMap() for res_num in pack_and_min_residues: min_mm.set_bb( res_num, True ) # minimizing the chi of carbohydrates is really weird as it moves the whole residue #min_mm.set_chi( res_num, True ) # check if we are packing, adjust the pack_and_min_residues and min_mm accordingly if self.pack_after_x_rounds > 0: if inner_trial % self.pack_after_x_rounds == 0: # this function I wrote uses the nbr_atom to calculate distances, which is about the C4 atom # 10A should be enough to include Tyr296 if the fucose is in the pose surrounding_residues = get_res_nums_within_radius( pack_and_min_residues, working_pose, radius = 10, include_passed_res_nums = False ) # add the surrounding_residues to the list of residues that will be packed and minimized pack_and_min_residues.extend( surrounding_residues ) # set chi to True in the min_mm if the residue is not a branch point # skipping surrounding carbohydrate residues (FcR glycan) because PyR3 treats the bb # as chi for some reason (setting chi min to True for glycan moves more than the side # chains. This is a bug. Just ignoring the bug for now) # ignoring the chi of branch points and sugar residues because it does weird stuff for surrounding_res in surrounding_residues: if not working_pose.residue( surrounding_res ).is_branch_point(): if not working_pose.residue( surrounding_res ).is_carbohydrate(): min_mm.set_chi( surrounding_res, True ) ############## #### PACK #### ############## # pack the sugars and surrounding residues, if desired if self.pack_after_x_rounds > 0: if inner_trial % self.pack_after_x_rounds == 0: # have to make the packer task each time because the residues surrounding the sugars # will likely change after each move, thus need to make a new RotamerTrialsMover # pack_radius of None means that only the residues specified will be packed rotamer_trials_mover = make_RotamerTrialsMover( pack_and_min_residues, self.sf, working_pose, pack_radius = None ) rotamer_trials_mover.apply( working_pose ) if self.verbose: print "score after local pack:", self.watch_sf( working_pose.clone() ) ################### #### MINIMIZE ##### ################### # make the MinMover from the pack_and_min_residues, if desired # if a pack was not just done, this will only include the self.moveable_residues (bb and chi) # if a pack was just done, this will include self.moveable_residues (bb and chi) and the surrounding_residues (chi) if self.minimize_each_round: # make and apply the min_mover min_mover = MinMover( movemap_in = min_mm, scorefxn_in = self.sf, #min_type_in = "dfpmin_strong_wolfe", min_type_in = "lbfgs_armijo_nonmonotone", # will move to this because this is Rosetta standard tolerance_in = 0.01, use_nb_list_in = True ) min_mover.apply( working_pose ) if self.verbose: print "score after min:", self.watch_sf( working_pose.clone() ) ############################### #### ACCEPT OR REJECT MOVE #### ############################### # accept or reject the total move using the MonteCarlo object accepted = False if self.mc.boltzmann( working_pose ): accepted = True # add the accepted-move pose to the list of poses for the movie, if desired if self.make_movie: # change the name to just "protocol_X_decoy_Y_Z.pdb" without path location # X is protocol number, Y is decoy number, Z is movie number # ex name) protocol_10_decoy_5_23.pdb working_pose.pdb_info().name( self.decoy_name.split( '/' )[-1].split( ".pdb" )[0] + "_%s.pdb" %movie_num ) self.movie_poses.append( working_pose.clone() ) working_pose.pdb_info().name( self.decoy_name ) movie_num += 1 # up the counters and send to pymol num_mc_accepts += 1 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 num_mc_checks += 1 # for watching range of accepted move size if self.watch_accepted_move_sizes: # each residue has each torsion in it perturbed by a different amount for ii in range( SSmM.n_moves ): for jj in range( len( SSmM.moved_residues_torsions[ ii ] ) ): move_size_trial_nums.append( inner_trial + self.inner_trials * ( outer_trial - 1 ) ) moved_torsions.append( SSmM.moved_residues_torsions[ ii ][ jj ] ) move_sizes.append( SSmM.moved_residues_torsions_perturbations[ ii ][ jj ] ) res_nums.append( SSmM.moved_residues[ ii ] ) move_accepted.append( accepted ) # for watching energy during a protocol if self.watch_E_vs_trial: # collect the lowest-scoring decoy seen using the watch_sf # can't use the mc.lowest_score() because that uses the ramped sf, so the score is variable # update the lowest_score_seen if the current working_pose has a lower score if self.watch_sf( working_pose.clone() ) < self.lowest_score_seen: self.lowest_score_seen = self.watch_sf( working_pose.clone() ) self.lowest_score_pose_seen = working_pose.clone() # append all the information to the lists E_vs_trial_nums.append( inner_trial + self.inner_trials * ( outer_trial - 1 ) ) energies.append( self.watch_sf( working_pose.clone() ) ) lowest_seen_energies.append( self.lowest_score_seen ) # 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 inner_trial % 3 == 0 or inner_trial == self.inner_trials: print "Moves made so far:", num_mc_checks, print " Moves accepted:", num_mc_accepts, print " Acceptance rate:", mc_acceptance # finished outer_trials and inner_trials # add any relevant data to the class object self.mc_acceptance = mc_acceptance # for watching energy during a protocol if self.watch_E_vs_trial: # make the dump dir for the .csv files if needed E_vs_trial_dir = self.dump_dir + "E_vs_trial_dir/" if not os.path.isdir( E_vs_trial_dir ): try: os.mkdir( E_vs_trial_dir ) except: pass # make the filename using the E_vs_trial_dir E_vs_trial_filename = E_vs_trial_dir + self.decoy_name.split( '/' )[-1].split( ".pdb" )[0] + "_E_vs_trial.csv" # use a pandas DataFrame, if possible if self.pandas: self.E_vs_trial_df[ "trial_nums" ] = E_vs_trial_nums self.E_vs_trial_df[ "total_score" ] = energies self.E_vs_trial_df[ "lowest_score" ] = lowest_seen_energies self.E_vs_trial_df.to_csv( E_vs_trial_filename ) # otherwise I'm on jazz and can't use a DataFrame, so use a csv file instead else: data_rows = zip( E_vs_trial_nums, energies, lowest_seen_energies ) with open( E_vs_trial_filename, "wb" ) as fh: csvwriter = csv.writer( fh ) csvwriter.writerow( [ "trial_num", "score", "lowest_score" ] ) [ csvwriter.writerow( row ) for row in data_rows ] if self.watch_accepted_move_sizes: if self.pandas: self.move_size_df[ "trial_nums" ] = move_size_trial_nums self.move_size_df[ "torsion" ] = moved_torsions self.move_size_df[ "res_num" ] = res_nums self.move_size_df[ "move_size" ] = move_sizes self.move_size_df[ "mc_accept" ] = move_accepted else: pass return working_pose
def main(): #read in the file made by the forward sim args = sys.argv inputfile = args[1] data = open(inputfile) first_line = data.readlines()[1] var_line=first_line.split(',') start_stab=var_line[1] #the first entry in the file is the wild type structure, calc the threshold using this threshold=float(start_stab)+10 print(threshold) # Initialize Rosetta. init(extra_options='-mute basic -mute core') # Constants PACK_RADIUS = 0 #Population size N = 100 #Beta (temp term) beta = .6 #Set up ScoreFunction sf = get_fa_scorefxn() #Set up MoveMap. mm = MoveMap() mm.set_bb(True) mm.set_chi(True) min_mover = MinMover() min_mover.movemap(mm) min_mover.score_function(sf) min_mover.min_type('dfpmin_armijo_nonmonotone') #Prepare data headers data = ['pdbfile_target,pdbfile_used,step,RevertTo,Change,Pos,From,OrgScore,RevScore,Change,Prob\n'] # Get the reversions file, the output file the score_mutant_pdb has made variant_scores=open(inputfile) #get just the mutation we want to revert to lines= variant_scores.readlines() var_line=lines[500] #gets the Nth line how ever long you want the burn to be print "staring here", var_line var_line=var_line.split(',')[0] var_loc=int(filter(str.isdigit, var_line)) var_rev=var_line[:1] gen=1 #get all the pdb files sort_list=sorted(glob.glob('*[0-9].pdb'), key=numericalSort) sort_list=sort_list[-1016:] #include the last 1000 and some pdbs, the 16 is because we want the ones that happened before the 500th mutation too. for i in range(1,len(sort_list)-30): step=-15 #calc reversion for next 15 moves for infile in sort_list[i:i+31]: #for each mutation var_line=lines[gen+500] #gets the Nth line how ever long you want the burn to be var_line=var_line.split(',')[0] print(var_line) var_loc=int(filter(str.isdigit, var_line)) var_rev="" old="" if(step<0): var_rev=var_line[len(var_line)-1:len(var_line)] old=var_line[:1] else: var_rev=var_line[:1] old=var_line[len(var_line)-1:len(var_line)] print "Current File Being Processed is: " + infile print "revering to:", var_rev print "at:", var_loc #get the pdb you want to revert and make the reversion initial_pose = pose_from_pdb(infile) mutant_pose = mutate_residue(initial_pose, var_loc , var_rev, PACK_RADIUS, sf) #repack mut task1 = standard_packer_task(mutant_pose) task1.restrict_to_repacking() task1.or_include_current(True) packer_rotamers_mover1 = RotamerTrialsMover(sf,task1) packer_rotamers_mover1.apply(mutant_pose) #repack init task2 = standard_packer_task(initial_pose) task2.restrict_to_repacking() task2.or_include_current(True) pack_rotamers_mover2 = RotamerTrialsMover(sf, task2) pack_rotamers_mover2.apply(initial_pose) #apply min mover min_mover.apply(mutant_pose) min_mover.apply(initial_pose) #get scores variant_score = sf(mutant_pose) initial_score = sf(initial_pose) #get prob probability = calc_prob_mh(variant_score, initial_score, N, beta, threshold) print(str(gen+499)+".pdb"+","+str(infile)+","+str(step)+","+ str(var_line) + ","+str(var_rev)+","+str(var_loc)+","+str(old)+"," +str(initial_score) + "," + str(variant _score) + "," + str(variant_score - initial_score)+ ","+ str(probability)+ "\n") data.append(str(gen+499)+".pdb"+","+str(infile)+","+str(step)+","+ str(var_line) + ","+str(var_rev)+","+str(var_loc)+","+str(old)+"," +str(initial_score) + "," + str(v ariant_score) + "," + str(variant_score - initial_score)+ ","+ str(probability)+ "\n") step=step+1 gen+=1 print '\nDONE' data_filename = 'premutate_rep1_bb_T_ch_T.csv' with open(data_filename, "w") as f: f.writelines(data)
def main(): #takes name of pdb file without the extention args = sys.argv pdb_file = args[1] #set up timer to figure out how long the code took to run t0 = time() # Initialize Rosetta. 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 = 1500 #Population size N = 100 #Beta (temp term) beta = 1 #Prepare data headers data = ['Variant,Rosetta Score,"delta-delta-G",Probability,Generation\n'] #Load and clean up pdb file name = pdb_file + ".pdb" cleanATOM(name) clean_name = pdb_file + ".clean.pdb" initial_pose = pose_from_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 data.append('WT,' + str(post_pre_packing_score) + ',0.0 ,0.0,0\n') #number of residues to select from n_res = initial_pose.total_residue() #start sim i = 0 gen = 0 while i < max_accept_mut: #update the number of generations that have pased gen += 1 print 'accepts:', i #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 while (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 while (proposed_res == res.name1()): new_mut_key = random.randint(0, len(AAs) - 1) proposed_res = AAs[new_mut_key] #make the mutation #this is actually a really bad model, and probably shouldnt be used. In new version is repack the whole thing, then reminimize, I should also backrub it. mutant_pose = mutate_residue(initial_pose, mut_location, proposed_res, PACK_RADIUS, sf) #score mutant variant_score = sf(mutant_pose) #get the probability that the mutation will be accepted probability = calc_prob_mh(variant_score, post_pre_packing_score, N, beta, threshold) #test to see if mutation is accepted if random.random() < probability: #create a name for the mutant if its going to be kept variant_name = res.name1() + str(initial_pose.pdb_info().number( mut_location)) + str(proposed_res) # Assuming 1000 burn in phase, take this if out if you want to store everything if i > 1000: #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) #update the wildtype initial_pose = mutant_pose post_pre_packing_score = variant_score #update number of accepts i += 1 print '\nMutations and scoring complete.' t1 = time() # Output results. data_filename = pdb_file[:-5] + 'mh_1500_rep3.csv' with open(data_filename, "w") as f: f.writelines(data) print 'Data written to:', data_filename print 'program takes %f' % (t1 - t0)
ramp_score_weight(sf, fa_rep, target_rep, fraction) mc.reset(pose) # Save information needed for distance criterion distance = pose.jump(JUMP_NUM).get_translation().length last_pose.assign(pose) while True: # Apply moves. perturber.apply(pose) #slider.apply(pose) visualize(pose) #print 'SCORE BEFORE MIN:', sf(pose), 'DISTANCE:', pose.jump(JUMP_NUM).get_translation().length # DEBUG try: with TimeLimit(3): jump_minimizer.apply( pose) # Often doesn't finish; why? break except TimeOutError as e: print ' ' + str(e) pose.dump_pdb('time-out_decoy.pdb') # DEBUG pose.assign(last_pose) except PyRosettaException as e: print ' NaN error during minimization; reattempting...' pose.dump_pdb('NaN_decoy.pdb') # DEBUG pose.assign(last_pose) #print 'SCORE AFTER MIN: ', sf(pose), 'DISTANCE:', pose.jump(JUMP_NUM).get_translation().length # DEBUG visualize(pose) # Move-Acceptance Criteria if mc.boltzmann(pose): mc.distance_criterion(pose, distance, last_pose)
# 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('linmin') if args.minimize: min_mover.apply(initial_pose) post_pre_packing_score = sf(initial_pose) print print 'Reference Protein:', args.pdb_filename print ' Score:' print ' Before pre-packing:', pre_pre_packing_score print ' After pre-packing:', post_pre_packing_score print data.append('WT,' + str(post_pre_packing_score) + ',0.0\n') # Loop over all residues in the protein. print 'Making mutations', if args.minimize:
def main(): #takes name of pdb file without the extention args = sys.argv pdb_file = args[1] #set up timer to figure out how long the code took to run t0 = time() # Initialize Rosetta. 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 = 5000 #Population size N = 100 #Beta (temp term) beta = 1 #Prepare data headers data = ['Variant,Rosetta Score,"delta-delta-G",Probability,Generation\n'] #Load and clean up pdb file name = pdb_file + ".pdb" cleanATOM(name) clean_name = pdb_file + ".clean.pdb" initial_pose = pose_from_pdb(clean_name) #Set up ScoreFunction sf = get_fa_scorefxn() #Set up MoveMap. mm = MoveMap() 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) pdb_name = str(pdb_file) + "_min.pdb" initial_pose.dump_pdb(pdb_name) #Set threshold for selection #threshold = post_pre_packing_score/2 #threshold = post_pre_packing_score data.append(str(pdb_file) + str(post_pre_packing_score) + ',0.0,0.0,0\n') data_filename = pdb_file + '.score' with open(data_filename, "w") as f: f.writelines(data) print 'Data written to:', data_filename '''
apply_sf_sugar_constraints = False, pack_branch_points = True, residue_range = res_nums_around_mutation_site ) pack_rotamers_mover.apply( mutant ) # minimize around mutation min_mm = MoveMap() for res_num in res_nums_around_mutation_site: min_mm.set_bb( res_num, True ) min_mm.set_chi( res_num, True ) min_mover = MinMover( movemap_in = min_mm, scorefxn_in = sf, min_type_in = "dfpmin_strong_wolfe", tolerance_in = 0.01, use_nb_list_in = True ) min_mover.apply(mutant) # visualize mutation #pmm.apply(mutant) # score and add to list for dataframe # total score new_E = sf( mutant ) mut_E.append( new_E ) native_E.append( nat_E ) ddG.append( new_E - nat_E ) # total score of residue new_E_res = mutant.energies().residue_total_energy( seq_pos ) nat_E_res = native_pose.energies().residue_total_energy( seq_pos )
mm.set_chi( res_num, True ) # gradient min of mutant_pose for jj in range( 3 ): if jj == 0: sf.set_weight( fa_rep, orig_fa_rep * 0.1 ) elif jj == 1: sf.set_weight( fa_rep, orig_fa_rep * 0.33 ) elif jj == 2: sf.set_weight( fa_rep, orig_fa_rep ) min_mover = MinMover( movemap_in = mm, scorefxn_in = sf, min_type_in = "lbfgs_armijo_nonmonotone", tolerance_in = 0.001, use_nb_list_in = True ) min_mover.max_iter( 2500 ) min_mover.apply( mutant_pose ) print "mutant_pose", sf( mutant_pose ), jj # collect additional metric data try: # all this is here until I update get_pose_metrics(_on_native) from antibody_functions import hold_chain_and_res_designations_3ay4 from get_pose_metrics_on_native import main as get_pose_metrics_on_native low_E_native_pose_info = hold_chain_and_res_designations_3ay4() low_E_native_pose_info.native() mutant_pose_info = hold_chain_and_res_designations_3ay4() mutant_pose_info.native() # metric calculations metrics = get_pose_metrics_on_native( mutant_pose, mutant_pose_info, low_E_native_pose,