def pose_scoring(pose, display_residues = []): """ Extracts and displays various score evaluations on the input <pose> and its <display_residues> including: total score score term evaluations per-residue score radius of gyration (approximate) """ # this object is contained in PyRosetta v2.0 and above # create a PyMOLMover for exporting structures directly to PyMOL pymover = PyMOLMover() # 1. score the pose using the default full-atom (fa) ScoreFunction # a ScoreFunction is essentially a list of weights indicating which # ScoreTypes are "on" and how they are scaled when summed together # ScoreTypes define what scoring methods are performed on the pose # some ScoreTypes are centroid or fullatom specific, others are not # there are (at least) 5 ways to obtain the general fullatom ScoreFunction # the 1st (a) and 2nd (b) methods are only present since PyRosetta v2.0 # # a. this method returns the hard-coded set of weights for the standard # fullatom ScoreFunction, which is currently called "ref2015" fa_scorefxn = get_fa_scorefxn() # b. this method returns a ScoreFunction with its weights set based on # files stored in the database/scoring/weights (.wts files) full_scorefxn = create_score_function('ref2015') # c. this method sets the weights based on 'ref2015.wts' and then # corrects them based on 'docking.wts_patch' ws_patch_scorefxn = create_score_function('ref2015', 'docking') # create_score_function_ws_patch('ref2015', 'docking') # d. this method returns a ScoreFunction with its weights set by loading # weights from 'ref2015' followed by an adjustment by setting # weights from 'docking.wts_patch' patch_scorefxn = create_score_function('ref2015') patch_scorefxn.apply_patch_from_file('docking') # e. here an empty ScoreFunction is created and the weights are set manually scorefxn = ScoreFunction() scorefxn.set_weight(core.scoring.fa_atr, 0.800) # full-atom attractive score scorefxn.set_weight(core.scoring.fa_rep, 0.440) # full-atom repulsive score scorefxn.set_weight(core.scoring.fa_sol, 0.750) # full-atom solvation score scorefxn.set_weight(core.scoring.fa_intra_rep, 0.004) # f.a. intraresidue rep. score scorefxn.set_weight(core.scoring.fa_elec, 0.700) # full-atom electronic score scorefxn.set_weight(core.scoring.pro_close, 1.000) # proline closure scorefxn.set_weight(core.scoring.hbond_sr_bb, 1.170) # short-range hbonding scorefxn.set_weight(core.scoring.hbond_lr_bb, 1.170) # long-range hbonding scorefxn.set_weight(core.scoring.hbond_bb_sc, 1.170) # backbone-sidechain hbonding scorefxn.set_weight(core.scoring.hbond_sc, 1.100) # sidechain-sidechain hbonding scorefxn.set_weight(core.scoring.dslf_fa13, 1.000) # disulfide full-atom score scorefxn.set_weight(core.scoring.rama, 0.200) # ramachandran score scorefxn.set_weight(core.scoring.omega, 0.500) # omega torsion score scorefxn.set_weight(core.scoring.fa_dun, 0.560) # fullatom Dunbrack rotamer score scorefxn.set_weight(core.scoring.p_aa_pp, 0.320) scorefxn.set_weight(core.scoring.ref, 1.000) # reference identity score # ScoreFunction a, b, and e above have the same weights and thus return # the same score for an input pose. Likewise, c and d should return the # same scores. # 2. output the ScoreFunction evaluations #ws_patch_scorefxn(pose) # to prevent verbose output on the next line print( '='*80 ) print( 'ScoreFunction a:', fa_scorefxn(pose) ) print( 'ScoreFunction b:', full_scorefxn(pose) ) print( 'ScoreFunction c:', ws_patch_scorefxn(pose) ) print( 'ScoreFunction d:', patch_scorefxn(pose) ) print( 'ScoreFunction e:', scorefxn(pose) ) pose_score = scorefxn(pose) # 3. obtain the pose Energies object and all the residue total scores energies = pose.energies() residue_energies = [energies.residue_total_energy(i) for i in range(1, pose.total_residue() + 1)] # 4. obtain the non-zero weights of the ScoreFunction, active ScoreTypes weights = [core.scoring.ScoreType(s) for s in range(1, int(core.scoring.end_of_score_type_enumeration) + 1) if scorefxn.weights()[core.scoring.ScoreType(s)]] # 5. obtain all the pose energies using the weights list # Energies.residue_total_energies returns an EMapVector of the unweighted # score values, here they are multiplied by their weights # remember when performing individual investigation, these are the raw # unweighted score! residue_weighted_energies_matrix = [ [energies.residue_total_energies(i)[w] * scorefxn.weights()[w] for i in range(1, pose.total_residue() + 1)] for w in weights] # Unfortunately, hydrogen bonding scores are NOT stored in the structure # returned by Energies.residue_total_energies # 6. hydrogen bonding information must be extracted separately pose_hbonds = core.scoring.hbonds.HBondSet() core.scoring.hbonds.fill_hbond_set( pose , False , pose_hbonds ) # 7. create a dictionary with the pose residue numbers as keys and the # residue hydrogen bonding information as values # hydrogen bonding information is stored as test in the form: # (donor residue) (donor atom) => (acceptor residue) (accecptor atom) |score hbond_dictionary = {} for residue in range(1, pose.total_residue() + 1): hbond_text = '' for hbond in range(1, pose_hbonds.nhbonds() + 1): hbond = pose_hbonds.hbond(hbond) acceptor_residue = hbond.acc_res() donor_residue = hbond.don_res() if residue == acceptor_residue or residue == donor_residue: hbond_text += str(donor_residue).ljust(4) + ' ' + \ str(pose.residue(donor_residue).atom_name(\ hbond.don_hatm() )).strip().ljust(4) + \ ' => ' + str(acceptor_residue).ljust(4) + ' ' + \ str(pose.residue(acceptor_residue).atom_name(\ hbond.acc_atm() )).strip().ljust(4) + \ ' |score: ' + str(hbond.energy()) + '\n' hbond_dictionary[residue] = hbond_text # 8. approximate the radius of gyration # there is an rg ScoreType in PyRosetta for performing this computation so # a ScoreFunction can be made as an Rg calculator, likewise you can # bias a structure towards more or less compact structures using this # NOTE: this is NOT the true radius of gyration for a protein, it uses # the Residue.nbr_atom coordinates to save time, this nbr_atom is the # Residue atom closest to the Residue's center of geometry RadG = ScoreFunction() RadG.set_weight(core.scoring.rg , 1) pose_radg = RadG(pose) # 9. output the pose information # the information is not expressed sequentially as it is produced because # several PyRosetta objects and methods output intermediate information # to screen, this would produce and unattractive output print( '='*80 ) print( 'Loaded from' , pose.pdb_info().name() ) print( pose.total_residue() , 'residues' ) print( 'Radius of Gyration ~' , pose_radg ) print( 'Total Rosetta Score:' , pose_score ) scorefxn.show(pose) # this object is contained in PyRosetta v2.0 and above pymover.apply(pose) pymover.send_energy(pose) # 10. output information on the requested residues for i in display_residues: print( '='*80 ) print( 'Pose numbered Residue' , i ) print( 'Total Residue Score:' , residue_energies[i-1] ) print( 'Score Breakdown:\n' + '-'*45 ) # loop over the weights, extract the scores from the matrix for w in range(len(weights)): print( '\t' + core.scoring.name_from_score_type(weights[w]).ljust(20) + ':\t' ,\ residue_weighted_energies_matrix[w][i-1] ) print( '-'*45 ) # print the hydrogen bond information print( 'Hydrogen bonds involving Residue ' + str(i) + ':' ) print( hbond_dictionary[i][:-1] ) print( '='*80 )
from pyrosetta.teaching import fa_atr, fa_rep, fa_sol, hbonds, EMapVector 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') # Scoring Poses ras = pose_from_file("../test/data/workshops/6Q21.clean.pdb") scorefxn = create_score_function("ref2015") print(scorefxn) scorefxn2 = ScoreFunction() scorefxn2.set_weight(fa_atr, 1.0) scorefxn2.set_weight(fa_rep, 1.0) print(scorefxn(ras)) scorefxn.show(ras) print(ras.energies().show(24)) r1 = ras.residue(24) r2 = ras.residue(20) a1 = r1.atom_index("N") a2 = r2.atom_index("O") etable_atom_pair_energies(r1, a1, r2, a2, scorefxn)