├── .gitignore ├── LICENSE ├── README.rst ├── analyze_flex_ddG.py ├── ddG-backrub.xml ├── ddG-no_backrub_control.xml ├── extract_structures.py ├── fig-overview.png ├── inputs └── 1JTG │ ├── 1JTG_AB.pdb │ ├── chains_to_move.txt │ ├── mutations.mutfile │ ├── mutations.resfile │ ├── nataa_mutations.resfile │ ├── pdb2rosetta.resmap.json │ └── rosetta2pdb.resmap.json ├── run_example_1.py ├── run_example_2_saturation.py └── split_protocol ├── flex_ddG-backrub_step.xml ├── flex_ddG-mutation_step.xml └── split_commands.txt /.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | output_saturation 3 | analysis_output 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kyle Barlow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Flex ddG Tutorial 3 | ====================== 4 | 5 | The most up-to-date version of this tutorial `is available on GitHub `_. 6 | 7 | Introduction 8 | ------------ 9 | 10 | In this activity, you will utilize the Flex ddG [KB2018]_ protocol within Rosetta to computationally model and predict changes in binding free energies upon mutation (interface ΔΔG). 11 | 12 | This protocol uses the "backrub" protocol [CS2018]_ implemented in `Rosetta `_ to sample conformational diversity. 13 | 14 | It is recommeded that you use weekly release "Rosetta 2017.52", which was released on Wednesday, January 3, 2018. More recent versions of Rosetta may not be able to run this tutorial. 15 | 16 | The flex ddG protocol is outlined below (Fig 1. from [KB2018]_): 17 | 18 | .. image:: fig-overview.png 19 | :align: center 20 | :width: 70 % 21 | 22 | Example runs 23 | ------------ 24 | 25 | Example 1: Run Flex ddG on a specific set of mutations 26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 27 | 28 | 1. From within your downloaded copy of this tutorial, open ``run_example_1.py`` in your `editor of choice `_. 29 | #. Find the ``rosetta_scripts_path`` at the top of ``run_example_1.py`` and check that it is set to the appropriate location of your compiled Rosetta rosetta_scripts binary. 30 | #. Run ``python run_example_1.py``. The full command line call to each instance of Rosetta will be displayed, and will look something like this: 31 | 32 | ``/home/user/rosetta/source/bin/rosetta_scripts -s /home/user/flex_ddG_tutorial/inputs/1JTG/1JTG_AB.pdb -parser:protocol /home/user/flex_ddG_tutorial/ddG-backrub.xml -parser:script_vars chainstomove=B mutate_resfile_relpath=/home/user/flex_ddG_tutorial/inputs/1JTG/nataa_mutations.resfile number_backrub_trials=10 max_minimization_iter=5 abs_score_convergence_thresh=200.0 backrub_trajectory_stride=5 -restore_talaris_behavior -in:file:fullatom -ignore_unrecognized_res -ignore_zero_occupancy false -ex1 -ex2`` 33 | 34 | Important flags explained: 35 | 36 | * ``-ex1 -ex2`` tell Rosetta's side chain packing algorithm to sample extra subrotamers for chi1 and chi2 angles (`Packer documentation `_) 37 | * ``mutate_resfile_relpath=`` is an input file that tells Rosetta which protein positions to mutate in the ΔΔG calculation. The resfile must start with ``NATAA``. See the `Rosetta documentation `_ for more information on resfiles. 38 | * ``number_backrub_trials=`` is the number of backrub sampling steps. 35,000 steps gives good performance for a variety of inputs, although it is likely similar performance could be achieved for certain cases with less sampling. 39 | * ``max_minimization_iter=`` is the maximum number of minimization gradient descent steps to take. 5000 is the normal, benchmarked value. 40 | * ``abs_score_convergence_thresh=`` is the maximum allowed change in total model score after minimization (comparing initial score to score after minimization). If this change exceeds this threshold, then another minimization cycle will be started. 41 | * ``backrub_trajectory_stride=`` after every N backrub steps, finish the flex ddG calculations. This allows protocol performance to be judged at intermediate number of backrub sampling steps without running a separate trajectory. In general, this can be set to the same number as ``number_backrub_trials``, but it may be useful for benchmarking purposes to set this at an intermediate value. 42 | * ``chainstomove=`` This arguments is passed as a Rosetta Script variable to the InterfaceDdGMover as the "chain_name" argument. It defines one side of the interface by specifying all of the chains that make up that side. Can be a single chain as in "B" or multiple chains, as in "L,H". 43 | 44 | #. Output will be saved in a new directory named ``output`` 45 | 46 | Example 2: Run Flex ddG for single site saturation mutagenesis 47 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 48 | 49 | This example covers the commonly desired use case is to evaluate the energies of all possible mutations at a single residue site in the interface. 50 | To do this in Rosetta, it is necessary to create a resfile for each possible amino acid mutation, and run the flex ddG protocol with each of these resfile as inputs. 51 | In this example, ``run_example_2.py`` is a modified version of the first example script that has been modified to automatically create resfiles for all 20 possible canonical amino acid mutations, and then run flex ddG on those resfiles. 52 | You can also create the resfiles yourself manually before running the protocol. 53 | 54 | 1. From within your downloaded copy of this tutorial, open ``run_example_2.py`` in your editor of choice. 55 | #. Find the ``rosetta_scripts_path`` at the top of ``run_example_2.py`` and check that it is set to the appropriate location of your compiled Rosetta rosetta_scripts binary. 56 | #. Run ``python run_example_2.py``. The full command line call to each instance of Rosetta will be displayed. 57 | #. Output will be saved in a new directory named ``output_saturation`` 58 | 59 | Analysis 60 | -------- 61 | 62 | In normal usage, you would run the flex ddG protocol 35+ times (at 35,000 backrub steps each run), and average the resulting ΔΔG predictions for best performance. For the purposes of making this tutorial run quickly on an average laptop, we will generate fewer output models for many fewer backrub and minimization steps. 63 | 64 | Python analysis 65 | ^^^^^^^^^^^^^^^ 66 | 67 | These Python packages are required in order to run the analysis, and can be installed via pip: ``pip install numpy pandas``. 68 | 69 | Run the analysis script for example 1 as follows: 70 | 71 | :: 72 | 73 | python analyze_flex_ddG.py output 74 | 75 | Or for example 2: 76 | 77 | :: 78 | 79 | python analyze_flex_ddG.py output_saturation 80 | 81 | The script will print to the terminal (in separate table blocks) the wild type interface binding ΔG score (wt_dG), the mutant interface ΔG (mut_dG), and the ΔΔG of binding post-mutation. These scores are also written to a .csv file in analysis_output. Scores for both of the checkpoint steps (5 backrub steps and 10 backrub steps) are calculated. For the mutant ΔΔG, the ΔΔG score is also calculated and reweighted with the fitted GAM model [KB2018]_. 82 | 83 | Extract structures 84 | ^^^^^^^^^^^^^^^^^^ 85 | 86 | If you are interested in viewing or using the generated backrub, wildtype minimized, or mutant minimized structures, you can extract them from the struct.db3 file in the output. A convenience wrapper script is provided to do this, and can be run as follows: 87 | 88 | :: 89 | 90 | python3 extract_structures.py output 91 | 92 | The script will recursively find all output struct.db3 files, run Rosetta to output PDBs, and rename the PDBs to more informative names. 93 | 94 | Additional reading 95 | ------------------ 96 | 97 | The `Rosetta documentation wiki `_ can provide additional context for how to adapt this Rosetta Scripts protocol to your specific use case. 98 | In particular, the page on `RosettaScripts `_ and the section of that page that explains `XML variable substitution `_ might prove helpful. 99 | 100 | References 101 | ---------- 102 | 103 | .. [KB2018] 104 | Kyle A. Barlow, Shane Ó Conchúir, Samuel Thompson, Pooja Suresh, James E. Lucas, Markus Heinonen, and Tanja Kortemme. 105 | Flex ddG: Rosetta Ensemble-Based Estimation of Changes in Protein–Protein Binding Affinity upon Mutation. 106 | *J. Phys. Chem. B*, 107 | February 2018. doi: 10.1021/acs.jpcb.7b11367. 108 | URL: https://pubs.acs.org/doi/pdf/10.1021/acs.jpcb.7b11367 109 | 110 | .. [KB2017] 111 | Kyle A. Barlow, Shane Ó Conchúir, Samuel Thompson, Pooja Suresh, James E. Lucas, Markus Heinonen, and Tanja Kortemme. 112 | Flex ddG: Rosetta Ensemble-Based Estimation of Changes in Protein–Protein Binding Affinity upon Mutation. 113 | *bioRxiv Preprint*, 114 | November 2017. 115 | URL: https://www.biorxiv.org/content/early/2017/11/17/221689 116 | 117 | .. [CS2008] 118 | Smith, C. A.; Kortemme, T. 119 | Backrub-Like Backbone Simulation Recapitulates Natural Protein Conformational Variability and Improves Mutant Side-Chain Prediction. 120 | *Journal of Molecular Biology* 121 | 2008. DOI:10.1016/j.jmb.2008.05.023. 122 | -------------------------------------------------------------------------------- /analyze_flex_ddG.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | import os 5 | import sqlite3 6 | import shutil 7 | import tempfile 8 | from pprint import pprint 9 | import pandas as pd 10 | import numpy as np 11 | import re 12 | import datetime 13 | import sys 14 | import collections 15 | import threading 16 | 17 | rosetta_output_file_name = 'rosetta.out' 18 | output_database_name = 'ddG.db3' 19 | trajectory_stride = 5 20 | script_output_folder = 'analysis_output' 21 | 22 | zemu_gam_params = { 23 | 'fa_sol' : (6.940, -6.722), 24 | 'hbond_sc' : (1.902, -1.999), 25 | 'hbond_bb_sc' : (0.063, 0.452), 26 | 'fa_rep' : (1.659, -0.836), 27 | 'fa_elec' : (0.697, -0.122), 28 | 'hbond_lr_bb' : (2.738, -1.179), 29 | 'fa_atr' : (2.313, -1.649), 30 | } 31 | 32 | def gam_function(x, score_term = None ): 33 | return -1.0 * np.exp( zemu_gam_params[score_term][0] ) + 2.0 * np.exp( zemu_gam_params[score_term][0] ) / ( 1.0 + np.exp( -1.0 * x * np.exp( zemu_gam_params[score_term][1] ) ) ) 34 | 35 | def apply_zemu_gam(scores): 36 | new_columns = list(scores.columns) 37 | new_columns.remove('total_score') 38 | scores = scores.copy()[ new_columns ] 39 | for score_term in zemu_gam_params: 40 | assert( score_term in scores.columns ) 41 | scores[score_term] = scores[score_term].apply( gam_function, score_term = score_term ) 42 | scores[ 'total_score' ] = scores[ list(zemu_gam_params.keys()) ].sum( axis = 1 ) 43 | scores[ 'score_function_name' ] = scores[ 'score_function_name' ] + '-gam' 44 | return scores 45 | 46 | def rosetta_output_succeeded( potential_struct_dir ): 47 | path_to_rosetta_output = os.path.join( potential_struct_dir, rosetta_output_file_name ) 48 | if not os.path.isfile(path_to_rosetta_output): 49 | return False 50 | 51 | db3_file = os.path.join( potential_struct_dir, output_database_name ) 52 | if not os.path.isfile( db3_file ): 53 | return False 54 | 55 | success_line_found = False 56 | no_more_batches_line_found = False 57 | with open( path_to_rosetta_output, 'r' ) as f: 58 | for line in f: 59 | if line.startswith( 'protocols.jd2.JobDistributor' ) and 'reported success in' in line: 60 | success_line_found = True 61 | if line.startswith( 'protocols.jd2.JobDistributor' ) and 'no more batches to process' in line: 62 | no_more_batches_line_found = True 63 | 64 | return no_more_batches_line_found and success_line_found 65 | 66 | def find_finished_jobs( output_folder ): 67 | return_dict = {} 68 | job_dirs = [ os.path.abspath(os.path.join(output_folder, d)) for d in os.listdir(output_folder) if os.path.isdir( os.path.join(output_folder, d) )] 69 | for job_dir in job_dirs: 70 | completed_struct_dirs = [] 71 | for potential_struct_dir in sorted([ os.path.abspath(os.path.join(job_dir, d)) for d in os.listdir(job_dir) if os.path.isdir( os.path.join(job_dir, d) )]): 72 | if rosetta_output_succeeded( potential_struct_dir ): 73 | completed_struct_dirs.append( potential_struct_dir ) 74 | return_dict[job_dir] = completed_struct_dirs 75 | 76 | return return_dict 77 | 78 | def get_scores_from_db3_file(db3_file, struct_number, case_name): 79 | conn = sqlite3.connect(db3_file) 80 | conn.row_factory = sqlite3.Row 81 | c = conn.cursor() 82 | 83 | num_batches = c.execute('SELECT max(batch_id) from batches').fetchone()[0] 84 | 85 | scores = pd.read_sql_query(''' 86 | SELECT batches.name, structure_scores.struct_id, score_types.score_type_name, structure_scores.score_value, score_function_method_options.score_function_name from structure_scores 87 | INNER JOIN batches ON batches.batch_id=structure_scores.batch_id 88 | INNER JOIN score_function_method_options ON score_function_method_options.batch_id=batches.batch_id 89 | INNER JOIN score_types ON score_types.batch_id=structure_scores.batch_id AND score_types.score_type_id=structure_scores.score_type_id 90 | ''', conn) 91 | 92 | def renumber_struct_id( struct_id ): 93 | return trajectory_stride * ( 1 + (int(struct_id-1) // num_batches) ) 94 | 95 | scores['struct_id'] = scores['struct_id'].apply( renumber_struct_id ) 96 | scores['name'] = scores['name'].apply( lambda x: x[:-9] if x.endswith('_dbreport') else x ) 97 | scores = scores.pivot_table( index = ['name', 'struct_id', 'score_function_name'], columns = 'score_type_name', values = 'score_value' ).reset_index() 98 | scores.rename( columns = { 99 | 'name' : 'state', 100 | 'struct_id' : 'backrub_steps', 101 | }, inplace=True) 102 | scores['struct_num'] = struct_number 103 | scores['case_name'] = case_name 104 | 105 | conn.close() 106 | 107 | return scores 108 | 109 | def process_finished_struct( output_path, case_name ): 110 | db3_file = os.path.join( output_path, output_database_name ) 111 | assert( os.path.isfile( db3_file ) ) 112 | struct_number = int( os.path.basename(output_path) ) 113 | scores_df = get_scores_from_db3_file( db3_file, struct_number, case_name ) 114 | 115 | return scores_df 116 | 117 | def calc_ddg( scores ): 118 | total_structs = np.max( scores['struct_num'] ) 119 | 120 | nstructs_to_analyze = set([total_structs]) 121 | for x in range(10, total_structs): 122 | if x % 10 == 0: 123 | nstructs_to_analyze.add(x) 124 | nstructs_to_analyze = sorted(nstructs_to_analyze) 125 | 126 | all_ddg_scores = [] 127 | for nstructs in nstructs_to_analyze: 128 | ddg_scores = scores.loc[ ((scores['state'] == 'unbound_mut') | (scores['state'] == 'bound_wt')) & (scores['struct_num'] <= nstructs) ].copy() 129 | for column in ddg_scores.columns: 130 | if column not in ['state', 'case_name', 'backrub_steps', 'struct_num', 'score_function_name']: 131 | ddg_scores.loc[:,column] *= -1.0 132 | ddg_scores = ddg_scores.append( scores.loc[ ((scores['state'] == 'unbound_wt') | (scores['state'] == 'bound_mut')) & (scores['struct_num'] <= nstructs) ].copy() ) 133 | ddg_scores = ddg_scores.groupby( ['case_name', 'backrub_steps', 'struct_num', 'score_function_name'] ).sum().reset_index() 134 | 135 | if nstructs == total_structs: 136 | struct_scores = ddg_scores.copy() 137 | 138 | ddg_scores = ddg_scores.groupby( ['case_name', 'backrub_steps', 'score_function_name'] ).mean().round(decimals=5).reset_index() 139 | new_columns = list(ddg_scores.columns.values) 140 | new_columns.remove( 'struct_num' ) 141 | ddg_scores = ddg_scores[new_columns] 142 | ddg_scores[ 'scored_state' ] = 'ddG' 143 | ddg_scores[ 'nstruct' ] = nstructs 144 | all_ddg_scores.append(ddg_scores) 145 | 146 | return (pd.concat(all_ddg_scores), struct_scores) 147 | 148 | def calc_dgs( scores ): 149 | l = [] 150 | 151 | total_structs = np.max( scores['struct_num'] ) 152 | 153 | nstructs_to_analyze = set([total_structs]) 154 | for x in range(10, total_structs): 155 | if x % 10 == 0: 156 | nstructs_to_analyze.add(x) 157 | nstructs_to_analyze = sorted(nstructs_to_analyze) 158 | 159 | for state in ['mut', 'wt']: 160 | for nstructs in nstructs_to_analyze: 161 | dg_scores = scores.loc[ (scores['state'].str.endswith(state)) & (scores['state'].str.startswith('unbound')) & (scores['struct_num'] <= nstructs) ].copy() 162 | for column in dg_scores.columns: 163 | if column not in ['state', 'case_name', 'backrub_steps', 'struct_num', 'score_function_name']: 164 | dg_scores.loc[:,column] *= -1.0 165 | dg_scores = dg_scores.append( scores.loc[ (scores['state'].str.endswith(state)) & (scores['state'].str.startswith('bound')) & (scores['struct_num'] <= nstructs) ].copy() ) 166 | dg_scores = dg_scores.groupby( ['case_name', 'backrub_steps', 'struct_num', 'score_function_name'] ).sum().reset_index() 167 | dg_scores = dg_scores.groupby( ['case_name', 'backrub_steps', 'score_function_name'] ).mean().round(decimals=5).reset_index() 168 | new_columns = list(dg_scores.columns.values) 169 | new_columns.remove( 'struct_num' ) 170 | dg_scores = dg_scores[new_columns] 171 | dg_scores[ 'scored_state' ] = state + '_dG' 172 | dg_scores[ 'nstruct' ] = nstructs 173 | l.append( dg_scores ) 174 | return l 175 | 176 | def analyze_output_folder( output_folder ): 177 | # Pass in an outer output folder. Subdirectories are considered different mutation cases, with subdirectories of different structures. 178 | finished_jobs = find_finished_jobs( output_folder ) 179 | if len(finished_jobs) == 0: 180 | print( 'No finished jobs found' ) 181 | return 182 | 183 | ddg_scores_dfs = [] 184 | struct_scores_dfs = [] 185 | for finished_job, finished_structs in finished_jobs.items(): 186 | inner_scores_list = [] 187 | for finished_struct in finished_structs: 188 | inner_scores = process_finished_struct( finished_struct, os.path.basename(finished_job) ) 189 | inner_scores_list.append( inner_scores ) 190 | scores = pd.concat( inner_scores_list ) 191 | ddg_scores, struct_scores = calc_ddg( scores ) 192 | struct_scores_dfs.append( struct_scores ) 193 | ddg_scores_dfs.append( ddg_scores ) 194 | ddg_scores_dfs.append( apply_zemu_gam(ddg_scores) ) 195 | ddg_scores_dfs.extend( calc_dgs( scores ) ) 196 | 197 | if not os.path.isdir(script_output_folder): 198 | os.makedirs(script_output_folder) 199 | basename = os.path.basename(output_folder) 200 | 201 | pd.concat( struct_scores_dfs ).to_csv( os.path.join(script_output_folder, basename + '-struct_scores_results.csv' ) ) 202 | 203 | df = pd.concat( ddg_scores_dfs ) 204 | df.to_csv( os.path.join(script_output_folder, basename + '-results.csv') ) 205 | 206 | display_columns = ['backrub_steps', 'case_name', 'nstruct', 'score_function_name', 'scored_state', 'total_score'] 207 | for score_type in ['mut_dG', 'wt_dG', 'ddG']: 208 | print( score_type ) 209 | print( df.loc[ df['scored_state'] == score_type ][display_columns].head( n = 20 ) ) 210 | print( '' ) 211 | 212 | if __name__ == '__main__': 213 | for folder_to_analyze in sys.argv[1:]: 214 | if os.path.isdir( folder_to_analyze ): 215 | analyze_output_folder( folder_to_analyze ) 216 | -------------------------------------------------------------------------------- /ddG-backrub.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /ddG-no_backrub_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /extract_structures.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | import re 7 | import shutil 8 | import datetime 9 | import math 10 | import collections 11 | import threading 12 | 13 | use_multiprocessing = False 14 | if use_multiprocessing: 15 | import multiprocessing 16 | 17 | # The Reporter class is useful for printing output for tasks which will take a long time 18 | # Really, you should just use tqdm now, but I used this before I knew about tqdm and it removes a dependency 19 | 20 | # Time in seconds function 21 | # Converts datetime timedelta object to number of seconds 22 | def ts(td): 23 | return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 1e6) / 1e6 24 | 25 | def mean(l): 26 | # Not using numpy mean to avoid dependency 27 | return float( sum(l) ) / float( len(l) ) 28 | 29 | class Reporter: 30 | def __init__( self, task, entries = 'files', print_output = True, eol_char = '\r' ): 31 | self._lock = threading.Lock() 32 | self.print_output = print_output 33 | self.start = datetime.datetime.now() 34 | self.entries = entries 35 | self.lastreport = self.start 36 | self.task = task 37 | self.report_interval = datetime.timedelta( seconds = 1 ) # Interval to print progress 38 | self.n = 0 39 | self.completion_time = None 40 | if self.print_output: 41 | print('\nStarting ' + task) 42 | self.total_count = None # Total tasks to be processed 43 | self.maximum_output_string_length = 0 44 | self.rolling_est_total_time = collections.deque( maxlen = 50 ) 45 | self.kv_callback_results = {} 46 | self.list_results = [] 47 | self.eol_char = eol_char 48 | 49 | def set_total_count(self, x): 50 | self.total_count = x 51 | self.rolling_est_total_time = collections.deque( maxlen = max(1, int( .05 * x )) ) 52 | 53 | def decrement_total_count(self): 54 | if self.total_count: 55 | self.total_count -= 1 56 | 57 | def report(self, n): 58 | with self._lock: 59 | self.n = n 60 | time_now = datetime.datetime.now() 61 | if self.print_output and self.lastreport < (time_now - self.report_interval): 62 | self.lastreport = time_now 63 | if self.total_count: 64 | percent_done = float(self.n) / float(self.total_count) 65 | est_total_time_seconds = ts(time_now - self.start) * (1.0 / percent_done) 66 | self.rolling_est_total_time.append( est_total_time_seconds ) 67 | est_total_time = datetime.timedelta( seconds = mean(self.rolling_est_total_time) ) 68 | time_remaining = est_total_time - (time_now - self.start) 69 | eta = time_now + time_remaining 70 | time_remaining_str = 'ETA: %s Est. time remaining: ' % eta.strftime("%Y-%m-%d %H:%M:%S") 71 | 72 | time_remaining_str += str( datetime.timedelta( seconds = int(ts(time_remaining)) ) ) 73 | 74 | output_string = " Processed: %d %s (%.1f%%) %s" % (n, self.entries, percent_done*100.0, time_remaining_str) 75 | else: 76 | output_string = " Processed: %d %s" % (n, self.entries) 77 | 78 | output_string += self.eol_char 79 | 80 | if len(output_string) > self.maximum_output_string_length: 81 | self.maximum_output_string_length = len(output_string) 82 | elif len(output_string) < self.maximum_output_string_length: 83 | output_string = output_string.ljust(self.maximum_output_string_length) 84 | sys.stdout.write( output_string ) 85 | sys.stdout.flush() 86 | 87 | def increment_report(self): 88 | self.report(self.n + 1) 89 | 90 | def increment_report_callback(self, cb_value): 91 | self.increment_report() 92 | 93 | def increment_report_keyval_callback(self, kv_pair): 94 | key, value = kv_pair 95 | self.kv_callback_results[key] = value 96 | self.increment_report() 97 | 98 | def increment_report_list_callback(self, new_list_items): 99 | self.list_results.extend(new_list_items) 100 | self.increment_report() 101 | 102 | def decrement_report(self): 103 | self.report(self.n - 1) 104 | 105 | def add_to_report(self, x): 106 | self.report(self.n + x) 107 | 108 | def done(self): 109 | self.completion_time = datetime.datetime.now() 110 | if self.print_output: 111 | print('Done %s, processed %d %s, took %s\n' % (self.task, self.n, self.entries, self.completion_time-self.start)) 112 | 113 | def elapsed_time(self): 114 | if self.completion_time: 115 | return self.completion_time - self.start 116 | else: 117 | return time.time() - self.start 118 | 119 | 120 | struct_db3_file = 'struct.db3' 121 | 122 | # Important - to correctly name extracted structures by the stride, this trajectory_stride must be used 123 | trajectory_stride = 5 124 | 125 | def recursive_find_struct_dbs( input_dir ): 126 | return_list = [] 127 | 128 | for path in [os.path.join(input_dir, x) for x in os.listdir( input_dir )]: 129 | if os.path.isdir( path ): 130 | return_list.extend( recursive_find_struct_dbs( path ) ) 131 | elif os.path.isfile( path ) and os.path.basename( path ) == struct_db3_file: 132 | return_list.append( path ) 133 | 134 | return return_list 135 | 136 | def extract_structures( struct_db, rename_function = None ): 137 | args = [ 138 | os.path.expanduser( '~/rosetta/source/bin/score_jd2' ), 139 | '-inout:dbms:database_name', struct_db3_file, 140 | '-in:use_database', 141 | '-out:pdb', 142 | ] 143 | 144 | working_directory = os.path.dirname( struct_db ) 145 | rosetta_outfile_path = os.path.join(working_directory, 'structure_output.txt' ) 146 | if not use_multiprocessing: 147 | print(rosetta_outfile_path) 148 | rosetta_outfile = open( rosetta_outfile_path, 'w') 149 | if not use_multiprocessing: 150 | print( ' '.join( args ) ) 151 | rosetta_process = subprocess.Popen( 152 | ' '.join(args), 153 | stdout=rosetta_outfile, stderr=subprocess.STDOUT, close_fds = True, cwd = working_directory, shell = True, 154 | ) 155 | return_code = rosetta_process.wait() 156 | rosetta_outfile.close() 157 | 158 | if return_code == 0: 159 | os.remove( rosetta_outfile_path ) 160 | 161 | if rename_function != None: 162 | output_pdbs = [] 163 | for path in [ os.path.join( working_directory, x ) for x in os.listdir( working_directory ) ]: 164 | m = re.match( '(\d+)_0001.pdb', os.path.basename(path) ) 165 | if m: 166 | dest_path = os.path.join( working_directory, rename_function( int(m.group(1)) ) ) 167 | shutil.move( path, dest_path ) 168 | 169 | return return_code 170 | 171 | def flex_ddG_rename(struct_id): 172 | steps = [ 173 | 'backrub', 174 | 'wt', 175 | 'mut', 176 | ] 177 | 178 | return '%s_%05d.pdb' % ( steps[ (struct_id-1) % len(steps) ], (((struct_id-1) // len(steps)) + 1) * trajectory_stride ) 179 | 180 | def main( input_dir ): 181 | struct_dbs = recursive_find_struct_dbs( input_dir ) 182 | print( 'Found {:d} structure database files to extract'.format( len(struct_dbs) ) ) 183 | 184 | if use_multiprocessing: 185 | pool = multiprocessing.Pool() 186 | r = Reporter('extracting structure database files', entries = '.db3 files') 187 | r.set_total_count( len(struct_dbs) ) 188 | 189 | for struct_db in struct_dbs: 190 | if use_multiprocessing: 191 | pool.apply_async( 192 | extract_structures, 193 | args = (struct_db,), 194 | kwds = {'rename_function' : flex_ddG_rename}, 195 | callback = r.increment_report_callback 196 | ) 197 | else: 198 | r.increment_report_callback( 199 | extract_structures( struct_db, rename_function = flex_ddG_rename ) 200 | ) 201 | 202 | if use_multiprocessing: 203 | pool.close() 204 | pool.join() 205 | r.done() 206 | 207 | if __name__ == '__main__': 208 | for x in sys.argv[1:]: 209 | if os.path.isdir(x): 210 | main( x ) 211 | else: 212 | print( 'ERROR: %s is not a valid directory' % x ) 213 | -------------------------------------------------------------------------------- /fig-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kortemme-Lab/flex_ddG_tutorial/722668db49dd7d1622a4d77d69848f5522c8d201/fig-overview.png -------------------------------------------------------------------------------- /inputs/1JTG/chains_to_move.txt: -------------------------------------------------------------------------------- 1 | B 2 | -------------------------------------------------------------------------------- /inputs/1JTG/mutations.mutfile: -------------------------------------------------------------------------------- 1 | total 4 2 | 4 3 | N 351 K 4 | D 397 K 5 | D 425 K 6 | V 427 K -------------------------------------------------------------------------------- /inputs/1JTG/mutations.resfile: -------------------------------------------------------------------------------- 1 | NATRO 2 | start 3 | 135 B PIKAA K 4 | 163 B PIKAA K 5 | 165 B PIKAA K 6 | 89 B PIKAA K -------------------------------------------------------------------------------- /inputs/1JTG/nataa_mutations.resfile: -------------------------------------------------------------------------------- 1 | NATAA 2 | start 3 | 135 B PIKAA K 4 | 163 B PIKAA K 5 | 165 B PIKAA K 6 | 89 B PIKAA K -------------------------------------------------------------------------------- /inputs/1JTG/pdb2rosetta.resmap.json: -------------------------------------------------------------------------------- 1 | { 2 | "A 26 ": 1, 3 | "A 27 ": 2, 4 | "A 28 ": 3, 5 | "A 29 ": 4, 6 | "A 30 ": 5, 7 | "A 31 ": 6, 8 | "A 32 ": 7, 9 | "A 33 ": 8, 10 | "A 34 ": 9, 11 | "A 35 ": 10, 12 | "A 36 ": 11, 13 | "A 37 ": 12, 14 | "A 38 ": 13, 15 | "A 39 ": 14, 16 | "A 40 ": 15, 17 | "A 41 ": 16, 18 | "A 42 ": 17, 19 | "A 43 ": 18, 20 | "A 44 ": 19, 21 | "A 45 ": 20, 22 | "A 46 ": 21, 23 | "A 47 ": 22, 24 | "A 48 ": 23, 25 | "A 49 ": 24, 26 | "A 50 ": 25, 27 | "A 51 ": 26, 28 | "A 52 ": 27, 29 | "A 53 ": 28, 30 | "A 54 ": 29, 31 | "A 55 ": 30, 32 | "A 56 ": 31, 33 | "A 57 ": 32, 34 | "A 58 ": 33, 35 | "A 59 ": 34, 36 | "A 60 ": 35, 37 | "A 61 ": 36, 38 | "A 62 ": 37, 39 | "A 63 ": 38, 40 | "A 64 ": 39, 41 | "A 65 ": 40, 42 | "A 66 ": 41, 43 | "A 67 ": 42, 44 | "A 68 ": 43, 45 | "A 69 ": 44, 46 | "A 70 ": 45, 47 | "A 71 ": 46, 48 | "A 72 ": 47, 49 | "A 73 ": 48, 50 | "A 74 ": 49, 51 | "A 75 ": 50, 52 | "A 76 ": 51, 53 | "A 77 ": 52, 54 | "A 78 ": 53, 55 | "A 79 ": 54, 56 | "A 80 ": 55, 57 | "A 81 ": 56, 58 | "A 82 ": 57, 59 | "A 83 ": 58, 60 | "A 84 ": 59, 61 | "A 85 ": 60, 62 | "A 86 ": 61, 63 | "A 87 ": 62, 64 | "A 88 ": 63, 65 | "A 89 ": 64, 66 | "A 90 ": 65, 67 | "A 91 ": 66, 68 | "A 92 ": 67, 69 | "A 93 ": 68, 70 | "A 94 ": 69, 71 | "A 95 ": 70, 72 | "A 96 ": 71, 73 | "A 97 ": 72, 74 | "A 98 ": 73, 75 | "A 99 ": 74, 76 | "A 100 ": 75, 77 | "A 101 ": 76, 78 | "A 102 ": 77, 79 | "A 103 ": 78, 80 | "A 104 ": 79, 81 | "A 105 ": 80, 82 | "A 106 ": 81, 83 | "A 107 ": 82, 84 | "A 108 ": 83, 85 | "A 109 ": 84, 86 | "A 110 ": 85, 87 | "A 111 ": 86, 88 | "A 112 ": 87, 89 | "A 113 ": 88, 90 | "A 114 ": 89, 91 | "A 115 ": 90, 92 | "A 116 ": 91, 93 | "A 117 ": 92, 94 | "A 118 ": 93, 95 | "A 119 ": 94, 96 | "A 120 ": 95, 97 | "A 121 ": 96, 98 | "A 122 ": 97, 99 | "A 123 ": 98, 100 | "A 124 ": 99, 101 | "A 125 ": 100, 102 | "A 126 ": 101, 103 | "A 127 ": 102, 104 | "A 128 ": 103, 105 | "A 129 ": 104, 106 | "A 130 ": 105, 107 | "A 131 ": 106, 108 | "A 132 ": 107, 109 | "A 133 ": 108, 110 | "A 134 ": 109, 111 | "A 135 ": 110, 112 | "A 136 ": 111, 113 | "A 137 ": 112, 114 | "A 138 ": 113, 115 | "A 139 ": 114, 116 | "A 140 ": 115, 117 | "A 141 ": 116, 118 | "A 142 ": 117, 119 | "A 143 ": 118, 120 | "A 144 ": 119, 121 | "A 145 ": 120, 122 | "A 146 ": 121, 123 | "A 147 ": 122, 124 | "A 148 ": 123, 125 | "A 149 ": 124, 126 | "A 150 ": 125, 127 | "A 151 ": 126, 128 | "A 152 ": 127, 129 | "A 153 ": 128, 130 | "A 154 ": 129, 131 | "A 155 ": 130, 132 | "A 156 ": 131, 133 | "A 157 ": 132, 134 | "A 158 ": 133, 135 | "A 159 ": 134, 136 | "A 160 ": 135, 137 | "A 161 ": 136, 138 | "A 162 ": 137, 139 | "A 163 ": 138, 140 | "A 164 ": 139, 141 | "A 165 ": 140, 142 | "A 166 ": 141, 143 | "A 167 ": 142, 144 | "A 168 ": 143, 145 | "A 169 ": 144, 146 | "A 170 ": 145, 147 | "A 171 ": 146, 148 | "A 172 ": 147, 149 | "A 173 ": 148, 150 | "A 174 ": 149, 151 | "A 175 ": 150, 152 | "A 176 ": 151, 153 | "A 177 ": 152, 154 | "A 178 ": 153, 155 | "A 179 ": 154, 156 | "A 180 ": 155, 157 | "A 181 ": 156, 158 | "A 182 ": 157, 159 | "A 183 ": 158, 160 | "A 184 ": 159, 161 | "A 185 ": 160, 162 | "A 186 ": 161, 163 | "A 187 ": 162, 164 | "A 188 ": 163, 165 | "A 189 ": 164, 166 | "A 190 ": 165, 167 | "A 191 ": 166, 168 | "A 192 ": 167, 169 | "A 193 ": 168, 170 | "A 194 ": 169, 171 | "A 195 ": 170, 172 | "A 196 ": 171, 173 | "A 197 ": 172, 174 | "A 198 ": 173, 175 | "A 199 ": 174, 176 | "A 200 ": 175, 177 | "A 201 ": 176, 178 | "A 202 ": 177, 179 | "A 203 ": 178, 180 | "A 204 ": 179, 181 | "A 205 ": 180, 182 | "A 206 ": 181, 183 | "A 207 ": 182, 184 | "A 208 ": 183, 185 | "A 209 ": 184, 186 | "A 210 ": 185, 187 | "A 211 ": 186, 188 | "A 212 ": 187, 189 | "A 213 ": 188, 190 | "A 215 ": 189, 191 | "A 216 ": 190, 192 | "A 217 ": 191, 193 | "A 218 ": 192, 194 | "A 219 ": 193, 195 | "A 220 ": 194, 196 | "A 221 ": 195, 197 | "A 222 ": 196, 198 | "A 223 ": 197, 199 | "A 224 ": 198, 200 | "A 225 ": 199, 201 | "A 226 ": 200, 202 | "A 227 ": 201, 203 | "A 228 ": 202, 204 | "A 229 ": 203, 205 | "A 230 ": 204, 206 | "A 231 ": 205, 207 | "A 232 ": 206, 208 | "A 233 ": 207, 209 | "A 234 ": 208, 210 | "A 235 ": 209, 211 | "A 236 ": 210, 212 | "A 237 ": 211, 213 | "A 238 ": 212, 214 | "A 239 ": 213, 215 | "A 240 ": 214, 216 | "A 241 ": 215, 217 | "A 242 ": 216, 218 | "A 243 ": 217, 219 | "A 244 ": 218, 220 | "A 245 ": 219, 221 | "A 246 ": 220, 222 | "A 247 ": 221, 223 | "A 248 ": 222, 224 | "A 249 ": 223, 225 | "A 250 ": 224, 226 | "A 251 ": 225, 227 | "A 252 ": 226, 228 | "A 253 ": 227, 229 | "A 254 ": 228, 230 | "A 255 ": 229, 231 | "A 256 ": 230, 232 | "A 257 ": 231, 233 | "A 258 ": 232, 234 | "A 259 ": 233, 235 | "A 260 ": 234, 236 | "A 261 ": 235, 237 | "A 262 ": 236, 238 | "A 263 ": 237, 239 | "A 264 ": 238, 240 | "A 265 ": 239, 241 | "A 266 ": 240, 242 | "A 267 ": 241, 243 | "A 268 ": 242, 244 | "A 269 ": 243, 245 | "A 270 ": 244, 246 | "A 271 ": 245, 247 | "A 272 ": 246, 248 | "A 273 ": 247, 249 | "A 274 ": 248, 250 | "A 275 ": 249, 251 | "A 276 ": 250, 252 | "A 277 ": 251, 253 | "A 278 ": 252, 254 | "A 279 ": 253, 255 | "A 280 ": 254, 256 | "A 281 ": 255, 257 | "A 282 ": 256, 258 | "A 283 ": 257, 259 | "A 284 ": 258, 260 | "A 285 ": 259, 261 | "A 286 ": 260, 262 | "A 287 ": 261, 263 | "A 288 ": 262, 264 | "B 1 ": 263, 265 | "B 2 ": 264, 266 | "B 3 ": 265, 267 | "B 4 ": 266, 268 | "B 5 ": 267, 269 | "B 6 ": 268, 270 | "B 7 ": 269, 271 | "B 8 ": 270, 272 | "B 9 ": 271, 273 | "B 10 ": 272, 274 | "B 11 ": 273, 275 | "B 12 ": 274, 276 | "B 13 ": 275, 277 | "B 14 ": 276, 278 | "B 15 ": 277, 279 | "B 16 ": 278, 280 | "B 17 ": 279, 281 | "B 18 ": 280, 282 | "B 19 ": 281, 283 | "B 20 ": 282, 284 | "B 21 ": 283, 285 | "B 22 ": 284, 286 | "B 23 ": 285, 287 | "B 24 ": 286, 288 | "B 25 ": 287, 289 | "B 26 ": 288, 290 | "B 27 ": 289, 291 | "B 28 ": 290, 292 | "B 29 ": 291, 293 | "B 30 ": 292, 294 | "B 31 ": 293, 295 | "B 32 ": 294, 296 | "B 33 ": 295, 297 | "B 34 ": 296, 298 | "B 35 ": 297, 299 | "B 36 ": 298, 300 | "B 37 ": 299, 301 | "B 38 ": 300, 302 | "B 39 ": 301, 303 | "B 40 ": 302, 304 | "B 41 ": 303, 305 | "B 42 ": 304, 306 | "B 43 ": 305, 307 | "B 44 ": 306, 308 | "B 45 ": 307, 309 | "B 46 ": 308, 310 | "B 47 ": 309, 311 | "B 48 ": 310, 312 | "B 49 ": 311, 313 | "B 50 ": 312, 314 | "B 51 ": 313, 315 | "B 52 ": 314, 316 | "B 53 ": 315, 317 | "B 54 ": 316, 318 | "B 55 ": 317, 319 | "B 56 ": 318, 320 | "B 57 ": 319, 321 | "B 58 ": 320, 322 | "B 59 ": 321, 323 | "B 60 ": 322, 324 | "B 61 ": 323, 325 | "B 62 ": 324, 326 | "B 63 ": 325, 327 | "B 64 ": 326, 328 | "B 65 ": 327, 329 | "B 66 ": 328, 330 | "B 67 ": 329, 331 | "B 68 ": 330, 332 | "B 69 ": 331, 333 | "B 70 ": 332, 334 | "B 71 ": 333, 335 | "B 72 ": 334, 336 | "B 73 ": 335, 337 | "B 74 ": 336, 338 | "B 75 ": 337, 339 | "B 76 ": 338, 340 | "B 77 ": 339, 341 | "B 78 ": 340, 342 | "B 79 ": 341, 343 | "B 80 ": 342, 344 | "B 81 ": 343, 345 | "B 82 ": 344, 346 | "B 83 ": 345, 347 | "B 84 ": 346, 348 | "B 85 ": 347, 349 | "B 86 ": 348, 350 | "B 87 ": 349, 351 | "B 88 ": 350, 352 | "B 89 ": 351, 353 | "B 90 ": 352, 354 | "B 91 ": 353, 355 | "B 92 ": 354, 356 | "B 93 ": 355, 357 | "B 94 ": 356, 358 | "B 95 ": 357, 359 | "B 96 ": 358, 360 | "B 97 ": 359, 361 | "B 98 ": 360, 362 | "B 99 ": 361, 363 | "B 100 ": 362, 364 | "B 101 ": 363, 365 | "B 102 ": 364, 366 | "B 103 ": 365, 367 | "B 104 ": 366, 368 | "B 105 ": 367, 369 | "B 106 ": 368, 370 | "B 107 ": 369, 371 | "B 108 ": 370, 372 | "B 109 ": 371, 373 | "B 110 ": 372, 374 | "B 111 ": 373, 375 | "B 112 ": 374, 376 | "B 113 ": 375, 377 | "B 114 ": 376, 378 | "B 115 ": 377, 379 | "B 116 ": 378, 380 | "B 117 ": 379, 381 | "B 118 ": 380, 382 | "B 119 ": 381, 383 | "B 120 ": 382, 384 | "B 121 ": 383, 385 | "B 122 ": 384, 386 | "B 123 ": 385, 387 | "B 124 ": 386, 388 | "B 125 ": 387, 389 | "B 126 ": 388, 390 | "B 127 ": 389, 391 | "B 128 ": 390, 392 | "B 129 ": 391, 393 | "B 130 ": 392, 394 | "B 131 ": 393, 395 | "B 132 ": 394, 396 | "B 133 ": 395, 397 | "B 134 ": 396, 398 | "B 135 ": 397, 399 | "B 136 ": 398, 400 | "B 137 ": 399, 401 | "B 138 ": 400, 402 | "B 139 ": 401, 403 | "B 140 ": 402, 404 | "B 141 ": 403, 405 | "B 142 ": 404, 406 | "B 143 ": 405, 407 | "B 144 ": 406, 408 | "B 145 ": 407, 409 | "B 146 ": 408, 410 | "B 147 ": 409, 411 | "B 148 ": 410, 412 | "B 149 ": 411, 413 | "B 150 ": 412, 414 | "B 151 ": 413, 415 | "B 152 ": 414, 416 | "B 153 ": 415, 417 | "B 154 ": 416, 418 | "B 155 ": 417, 419 | "B 156 ": 418, 420 | "B 157 ": 419, 421 | "B 158 ": 420, 422 | "B 159 ": 421, 423 | "B 160 ": 422, 424 | "B 161 ": 423, 425 | "B 162 ": 424, 426 | "B 163 ": 425, 427 | "B 164 ": 426, 428 | "B 165 ": 427 429 | } -------------------------------------------------------------------------------- /inputs/1JTG/rosetta2pdb.resmap.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": "A 26 ", 3 | "2": "A 27 ", 4 | "3": "A 28 ", 5 | "4": "A 29 ", 6 | "5": "A 30 ", 7 | "6": "A 31 ", 8 | "7": "A 32 ", 9 | "8": "A 33 ", 10 | "9": "A 34 ", 11 | "10": "A 35 ", 12 | "11": "A 36 ", 13 | "12": "A 37 ", 14 | "13": "A 38 ", 15 | "14": "A 39 ", 16 | "15": "A 40 ", 17 | "16": "A 41 ", 18 | "17": "A 42 ", 19 | "18": "A 43 ", 20 | "19": "A 44 ", 21 | "20": "A 45 ", 22 | "21": "A 46 ", 23 | "22": "A 47 ", 24 | "23": "A 48 ", 25 | "24": "A 49 ", 26 | "25": "A 50 ", 27 | "26": "A 51 ", 28 | "27": "A 52 ", 29 | "28": "A 53 ", 30 | "29": "A 54 ", 31 | "30": "A 55 ", 32 | "31": "A 56 ", 33 | "32": "A 57 ", 34 | "33": "A 58 ", 35 | "34": "A 59 ", 36 | "35": "A 60 ", 37 | "36": "A 61 ", 38 | "37": "A 62 ", 39 | "38": "A 63 ", 40 | "39": "A 64 ", 41 | "40": "A 65 ", 42 | "41": "A 66 ", 43 | "42": "A 67 ", 44 | "43": "A 68 ", 45 | "44": "A 69 ", 46 | "45": "A 70 ", 47 | "46": "A 71 ", 48 | "47": "A 72 ", 49 | "48": "A 73 ", 50 | "49": "A 74 ", 51 | "50": "A 75 ", 52 | "51": "A 76 ", 53 | "52": "A 77 ", 54 | "53": "A 78 ", 55 | "54": "A 79 ", 56 | "55": "A 80 ", 57 | "56": "A 81 ", 58 | "57": "A 82 ", 59 | "58": "A 83 ", 60 | "59": "A 84 ", 61 | "60": "A 85 ", 62 | "61": "A 86 ", 63 | "62": "A 87 ", 64 | "63": "A 88 ", 65 | "64": "A 89 ", 66 | "65": "A 90 ", 67 | "66": "A 91 ", 68 | "67": "A 92 ", 69 | "68": "A 93 ", 70 | "69": "A 94 ", 71 | "70": "A 95 ", 72 | "71": "A 96 ", 73 | "72": "A 97 ", 74 | "73": "A 98 ", 75 | "74": "A 99 ", 76 | "75": "A 100 ", 77 | "76": "A 101 ", 78 | "77": "A 102 ", 79 | "78": "A 103 ", 80 | "79": "A 104 ", 81 | "80": "A 105 ", 82 | "81": "A 106 ", 83 | "82": "A 107 ", 84 | "83": "A 108 ", 85 | "84": "A 109 ", 86 | "85": "A 110 ", 87 | "86": "A 111 ", 88 | "87": "A 112 ", 89 | "88": "A 113 ", 90 | "89": "A 114 ", 91 | "90": "A 115 ", 92 | "91": "A 116 ", 93 | "92": "A 117 ", 94 | "93": "A 118 ", 95 | "94": "A 119 ", 96 | "95": "A 120 ", 97 | "96": "A 121 ", 98 | "97": "A 122 ", 99 | "98": "A 123 ", 100 | "99": "A 124 ", 101 | "100": "A 125 ", 102 | "101": "A 126 ", 103 | "102": "A 127 ", 104 | "103": "A 128 ", 105 | "104": "A 129 ", 106 | "105": "A 130 ", 107 | "106": "A 131 ", 108 | "107": "A 132 ", 109 | "108": "A 133 ", 110 | "109": "A 134 ", 111 | "110": "A 135 ", 112 | "111": "A 136 ", 113 | "112": "A 137 ", 114 | "113": "A 138 ", 115 | "114": "A 139 ", 116 | "115": "A 140 ", 117 | "116": "A 141 ", 118 | "117": "A 142 ", 119 | "118": "A 143 ", 120 | "119": "A 144 ", 121 | "120": "A 145 ", 122 | "121": "A 146 ", 123 | "122": "A 147 ", 124 | "123": "A 148 ", 125 | "124": "A 149 ", 126 | "125": "A 150 ", 127 | "126": "A 151 ", 128 | "127": "A 152 ", 129 | "128": "A 153 ", 130 | "129": "A 154 ", 131 | "130": "A 155 ", 132 | "131": "A 156 ", 133 | "132": "A 157 ", 134 | "133": "A 158 ", 135 | "134": "A 159 ", 136 | "135": "A 160 ", 137 | "136": "A 161 ", 138 | "137": "A 162 ", 139 | "138": "A 163 ", 140 | "139": "A 164 ", 141 | "140": "A 165 ", 142 | "141": "A 166 ", 143 | "142": "A 167 ", 144 | "143": "A 168 ", 145 | "144": "A 169 ", 146 | "145": "A 170 ", 147 | "146": "A 171 ", 148 | "147": "A 172 ", 149 | "148": "A 173 ", 150 | "149": "A 174 ", 151 | "150": "A 175 ", 152 | "151": "A 176 ", 153 | "152": "A 177 ", 154 | "153": "A 178 ", 155 | "154": "A 179 ", 156 | "155": "A 180 ", 157 | "156": "A 181 ", 158 | "157": "A 182 ", 159 | "158": "A 183 ", 160 | "159": "A 184 ", 161 | "160": "A 185 ", 162 | "161": "A 186 ", 163 | "162": "A 187 ", 164 | "163": "A 188 ", 165 | "164": "A 189 ", 166 | "165": "A 190 ", 167 | "166": "A 191 ", 168 | "167": "A 192 ", 169 | "168": "A 193 ", 170 | "169": "A 194 ", 171 | "170": "A 195 ", 172 | "171": "A 196 ", 173 | "172": "A 197 ", 174 | "173": "A 198 ", 175 | "174": "A 199 ", 176 | "175": "A 200 ", 177 | "176": "A 201 ", 178 | "177": "A 202 ", 179 | "178": "A 203 ", 180 | "179": "A 204 ", 181 | "180": "A 205 ", 182 | "181": "A 206 ", 183 | "182": "A 207 ", 184 | "183": "A 208 ", 185 | "184": "A 209 ", 186 | "185": "A 210 ", 187 | "186": "A 211 ", 188 | "187": "A 212 ", 189 | "188": "A 213 ", 190 | "189": "A 215 ", 191 | "190": "A 216 ", 192 | "191": "A 217 ", 193 | "192": "A 218 ", 194 | "193": "A 219 ", 195 | "194": "A 220 ", 196 | "195": "A 221 ", 197 | "196": "A 222 ", 198 | "197": "A 223 ", 199 | "198": "A 224 ", 200 | "199": "A 225 ", 201 | "200": "A 226 ", 202 | "201": "A 227 ", 203 | "202": "A 228 ", 204 | "203": "A 229 ", 205 | "204": "A 230 ", 206 | "205": "A 231 ", 207 | "206": "A 232 ", 208 | "207": "A 233 ", 209 | "208": "A 234 ", 210 | "209": "A 235 ", 211 | "210": "A 236 ", 212 | "211": "A 237 ", 213 | "212": "A 238 ", 214 | "213": "A 239 ", 215 | "214": "A 240 ", 216 | "215": "A 241 ", 217 | "216": "A 242 ", 218 | "217": "A 243 ", 219 | "218": "A 244 ", 220 | "219": "A 245 ", 221 | "220": "A 246 ", 222 | "221": "A 247 ", 223 | "222": "A 248 ", 224 | "223": "A 249 ", 225 | "224": "A 250 ", 226 | "225": "A 251 ", 227 | "226": "A 252 ", 228 | "227": "A 253 ", 229 | "228": "A 254 ", 230 | "229": "A 255 ", 231 | "230": "A 256 ", 232 | "231": "A 257 ", 233 | "232": "A 258 ", 234 | "233": "A 259 ", 235 | "234": "A 260 ", 236 | "235": "A 261 ", 237 | "236": "A 262 ", 238 | "237": "A 263 ", 239 | "238": "A 264 ", 240 | "239": "A 265 ", 241 | "240": "A 266 ", 242 | "241": "A 267 ", 243 | "242": "A 268 ", 244 | "243": "A 269 ", 245 | "244": "A 270 ", 246 | "245": "A 271 ", 247 | "246": "A 272 ", 248 | "247": "A 273 ", 249 | "248": "A 274 ", 250 | "249": "A 275 ", 251 | "250": "A 276 ", 252 | "251": "A 277 ", 253 | "252": "A 278 ", 254 | "253": "A 279 ", 255 | "254": "A 280 ", 256 | "255": "A 281 ", 257 | "256": "A 282 ", 258 | "257": "A 283 ", 259 | "258": "A 284 ", 260 | "259": "A 285 ", 261 | "260": "A 286 ", 262 | "261": "A 287 ", 263 | "262": "A 288 ", 264 | "263": "B 1 ", 265 | "264": "B 2 ", 266 | "265": "B 3 ", 267 | "266": "B 4 ", 268 | "267": "B 5 ", 269 | "268": "B 6 ", 270 | "269": "B 7 ", 271 | "270": "B 8 ", 272 | "271": "B 9 ", 273 | "272": "B 10 ", 274 | "273": "B 11 ", 275 | "274": "B 12 ", 276 | "275": "B 13 ", 277 | "276": "B 14 ", 278 | "277": "B 15 ", 279 | "278": "B 16 ", 280 | "279": "B 17 ", 281 | "280": "B 18 ", 282 | "281": "B 19 ", 283 | "282": "B 20 ", 284 | "283": "B 21 ", 285 | "284": "B 22 ", 286 | "285": "B 23 ", 287 | "286": "B 24 ", 288 | "287": "B 25 ", 289 | "288": "B 26 ", 290 | "289": "B 27 ", 291 | "290": "B 28 ", 292 | "291": "B 29 ", 293 | "292": "B 30 ", 294 | "293": "B 31 ", 295 | "294": "B 32 ", 296 | "295": "B 33 ", 297 | "296": "B 34 ", 298 | "297": "B 35 ", 299 | "298": "B 36 ", 300 | "299": "B 37 ", 301 | "300": "B 38 ", 302 | "301": "B 39 ", 303 | "302": "B 40 ", 304 | "303": "B 41 ", 305 | "304": "B 42 ", 306 | "305": "B 43 ", 307 | "306": "B 44 ", 308 | "307": "B 45 ", 309 | "308": "B 46 ", 310 | "309": "B 47 ", 311 | "310": "B 48 ", 312 | "311": "B 49 ", 313 | "312": "B 50 ", 314 | "313": "B 51 ", 315 | "314": "B 52 ", 316 | "315": "B 53 ", 317 | "316": "B 54 ", 318 | "317": "B 55 ", 319 | "318": "B 56 ", 320 | "319": "B 57 ", 321 | "320": "B 58 ", 322 | "321": "B 59 ", 323 | "322": "B 60 ", 324 | "323": "B 61 ", 325 | "324": "B 62 ", 326 | "325": "B 63 ", 327 | "326": "B 64 ", 328 | "327": "B 65 ", 329 | "328": "B 66 ", 330 | "329": "B 67 ", 331 | "330": "B 68 ", 332 | "331": "B 69 ", 333 | "332": "B 70 ", 334 | "333": "B 71 ", 335 | "334": "B 72 ", 336 | "335": "B 73 ", 337 | "336": "B 74 ", 338 | "337": "B 75 ", 339 | "338": "B 76 ", 340 | "339": "B 77 ", 341 | "340": "B 78 ", 342 | "341": "B 79 ", 343 | "342": "B 80 ", 344 | "343": "B 81 ", 345 | "344": "B 82 ", 346 | "345": "B 83 ", 347 | "346": "B 84 ", 348 | "347": "B 85 ", 349 | "348": "B 86 ", 350 | "349": "B 87 ", 351 | "350": "B 88 ", 352 | "351": "B 89 ", 353 | "352": "B 90 ", 354 | "353": "B 91 ", 355 | "354": "B 92 ", 356 | "355": "B 93 ", 357 | "356": "B 94 ", 358 | "357": "B 95 ", 359 | "358": "B 96 ", 360 | "359": "B 97 ", 361 | "360": "B 98 ", 362 | "361": "B 99 ", 363 | "362": "B 100 ", 364 | "363": "B 101 ", 365 | "364": "B 102 ", 366 | "365": "B 103 ", 367 | "366": "B 104 ", 368 | "367": "B 105 ", 369 | "368": "B 106 ", 370 | "369": "B 107 ", 371 | "370": "B 108 ", 372 | "371": "B 109 ", 373 | "372": "B 110 ", 374 | "373": "B 111 ", 375 | "374": "B 112 ", 376 | "375": "B 113 ", 377 | "376": "B 114 ", 378 | "377": "B 115 ", 379 | "378": "B 116 ", 380 | "379": "B 117 ", 381 | "380": "B 118 ", 382 | "381": "B 119 ", 383 | "382": "B 120 ", 384 | "383": "B 121 ", 385 | "384": "B 122 ", 386 | "385": "B 123 ", 387 | "386": "B 124 ", 388 | "387": "B 125 ", 389 | "388": "B 126 ", 390 | "389": "B 127 ", 391 | "390": "B 128 ", 392 | "391": "B 129 ", 393 | "392": "B 130 ", 394 | "393": "B 131 ", 395 | "394": "B 132 ", 396 | "395": "B 133 ", 397 | "396": "B 134 ", 398 | "397": "B 135 ", 399 | "398": "B 136 ", 400 | "399": "B 137 ", 401 | "400": "B 138 ", 402 | "401": "B 139 ", 403 | "402": "B 140 ", 404 | "403": "B 141 ", 405 | "404": "B 142 ", 406 | "405": "B 143 ", 407 | "406": "B 144 ", 408 | "407": "B 145 ", 409 | "408": "B 146 ", 410 | "409": "B 147 ", 411 | "410": "B 148 ", 412 | "411": "B 149 ", 413 | "412": "B 150 ", 414 | "413": "B 151 ", 415 | "414": "B 152 ", 416 | "415": "B 153 ", 417 | "416": "B 154 ", 418 | "417": "B 155 ", 419 | "418": "B 156 ", 420 | "419": "B 157 ", 421 | "420": "B 158 ", 422 | "421": "B 159 ", 423 | "422": "B 160 ", 424 | "423": "B 161 ", 425 | "424": "B 162 ", 426 | "425": "B 163 ", 427 | "426": "B 164 ", 428 | "427": "B 165 " 429 | } -------------------------------------------------------------------------------- /run_example_1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from __future__ import print_function 4 | 5 | import socket 6 | import sys 7 | import os 8 | import subprocess 9 | 10 | use_multiprocessing = True 11 | if use_multiprocessing: 12 | import multiprocessing 13 | max_cpus = 2 # We might want to not run on the full number of cores, as Rosetta take about 2 Gb of memory per instance 14 | 15 | ################################################################################################################################################################### 16 | # Important: The variables below are set to values that will make the run complete faster (as a tutorial example), but will not give scientifically valid results. 17 | # Please change them to the "normal" default values before a real run. 18 | ################################################################################################################################################################### 19 | 20 | rosetta_scripts_path = os.path.expanduser("~/rosetta/source/bin/rosetta_scripts") 21 | nstruct = 3 # Normally 35 22 | max_minimization_iter = 5 # Normally 5000 23 | abs_score_convergence_thresh = 200.0 # Normally 1.0 24 | number_backrub_trials = 10 # Normally 35000 25 | backrub_trajectory_stride = 5 # Can be whatever you want, if you would like to see results from earlier time points in the backrub trajectory. 7000 is a reasonable number, to give you three checkpoints for a 35000 step run, but you could also set it to 35000 for quickest run time (as the final minimization and packing steps will only need to be run one time). 26 | path_to_script = 'ddG-backrub.xml' 27 | 28 | if not os.path.isfile(rosetta_scripts_path): 29 | print('ERROR: "rosetta_scripts_path" variable must be set to the location of the "rosetta_scripts" binary executable') 30 | print('This file might look something like: "rosetta_scripts.linuxgccrelease"') 31 | raise Exception('Rosetta scripts missing') 32 | 33 | def run_flex_ddg( name, input_path, input_pdb_path, chains_to_move, nstruct_i ): 34 | output_directory = os.path.join( 'output', os.path.join( name, '%02d' % nstruct_i ) ) 35 | if not os.path.isdir(output_directory): 36 | os.makedirs(output_directory) 37 | 38 | flex_ddg_args = [ 39 | os.path.abspath(rosetta_scripts_path), 40 | "-s %s" % os.path.abspath(input_pdb_path), 41 | '-parser:protocol', os.path.abspath(path_to_script), 42 | '-parser:script_vars', 43 | 'chainstomove=' + chains_to_move, 44 | 'mutate_resfile_relpath=' + os.path.abspath( os.path.join( input_path, 'nataa_mutations.resfile' ) ), 45 | 'number_backrub_trials=%d' % number_backrub_trials, 46 | 'max_minimization_iter=%d' % max_minimization_iter, 47 | 'abs_score_convergence_thresh=%.1f' % abs_score_convergence_thresh, 48 | 'backrub_trajectory_stride=%d' % backrub_trajectory_stride , 49 | '-restore_talaris_behavior', 50 | '-in:file:fullatom', 51 | '-ignore_unrecognized_res', 52 | '-ignore_zero_occupancy false', 53 | '-ex1', 54 | '-ex2', 55 | ] 56 | 57 | log_path = os.path.join(output_directory, 'rosetta.out') 58 | 59 | print( 'Running Rosetta with args:' ) 60 | print( ' '.join(flex_ddg_args) ) 61 | print( 'Output logged to:', os.path.abspath(log_path) ) 62 | print() 63 | 64 | outfile = open(log_path, 'w') 65 | process = subprocess.Popen(flex_ddg_args, stdout=outfile, stderr=subprocess.STDOUT, close_fds = True, cwd = output_directory) 66 | returncode = process.wait() 67 | outfile.close() 68 | 69 | if __name__ == '__main__': 70 | cases = [] 71 | for nstruct_i in range(1, nstruct + 1 ): 72 | for case_name in os.listdir('inputs'): 73 | case_path = os.path.join( 'inputs', case_name ) 74 | for f in os.listdir(case_path): 75 | if f.endswith('.pdb'): 76 | input_pdb_path = os.path.join( case_path, f ) 77 | break 78 | 79 | with open( os.path.join( case_path, 'chains_to_move.txt' ), 'r' ) as f: 80 | chains_to_move = f.readlines()[0].strip() 81 | 82 | cases.append( (case_name, case_path, input_pdb_path, chains_to_move, nstruct_i) ) 83 | 84 | if use_multiprocessing: 85 | pool = multiprocessing.Pool( processes = min(max_cpus, multiprocessing.cpu_count()) ) 86 | 87 | for args in cases: 88 | if use_multiprocessing: 89 | pool.apply_async( run_flex_ddg, args = args ) 90 | else: 91 | run_flex_ddg( *args ) 92 | 93 | if use_multiprocessing: 94 | pool.close() 95 | pool.join() 96 | -------------------------------------------------------------------------------- /run_example_2_saturation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from __future__ import print_function 4 | 5 | import socket 6 | import sys 7 | import os 8 | import subprocess 9 | 10 | use_multiprocessing = True 11 | if use_multiprocessing: 12 | import multiprocessing 13 | max_cpus = 2 # We might want to not run on the full number of cores, as Rosetta take about 2 Gb of memory per instance 14 | 15 | ################################################################################################################################################################### 16 | # Important: The variables below are set to values that will make the run complete faster (as a tutorial example), but will not give scientifically valid results. 17 | # Please change them to the "normal" default values before a real run. 18 | ################################################################################################################################################################### 19 | 20 | rosetta_scripts_path = os.path.expanduser("~/rosetta/source/bin/rosetta_scripts") 21 | nstruct = 3 # Normally 35 22 | max_minimization_iter = 5 # Normally 5000 23 | abs_score_convergence_thresh = 200.0 # Normally 1.0 24 | number_backrub_trials = 10 # Normally 35000 25 | backrub_trajectory_stride = 5 # Can be whatever you want, if you would like to see results from earlier time points in the backrub trajectory. 7000 is a reasonable number, to give you three checkpoints for a 35000 step run, but you could also set it to 35000 for quickest run time (as the final minimization and packing steps will only need to be run one time). 26 | path_to_script = 'ddG-backrub.xml' 27 | residue_to_mutate = ('B', 49, '') # Residue position to perfrom saturation mutatagenesis. Format: (Chain, PDB residue number, insertion code). 28 | 29 | if not os.path.isfile(rosetta_scripts_path): 30 | print('ERROR: "rosetta_scripts_path" variable must be set to the location of the "rosetta_scripts" binary executable') 31 | print('This file might look something like: "rosetta_scripts.linuxgccrelease"') 32 | raise Exception('Rosetta scripts missing') 33 | 34 | def run_flex_ddg_saturation( name, input_path, input_pdb_path, chains_to_move, mut_aa, nstruct_i ): 35 | output_directory = os.path.join( 'output_saturation', os.path.join( '%s_%s' % (name, mut_aa), '%02d' % nstruct_i ) ) 36 | if not os.path.isdir(output_directory): 37 | os.makedirs(output_directory) 38 | 39 | mutation_chain, mutation_resi, mutation_icode = residue_to_mutate 40 | resfile_path = os.path.join( output_directory, 'mutate_%s%d%s_to_%s.resfile' % (mutation_chain, mutation_resi, mutation_icode, mut_aa) ) 41 | with open( resfile_path, 'w') as f: 42 | f.write( 'NATRO\nstart\n%d%s %s PIKAA %s\n' % (mutation_resi, mutation_icode, mutation_chain, mut_aa) ) 43 | 44 | flex_ddg_args = [ 45 | os.path.abspath(rosetta_scripts_path), 46 | "-s %s" % os.path.abspath(input_pdb_path), 47 | '-parser:protocol', os.path.abspath(path_to_script), 48 | '-parser:script_vars', 49 | 'chainstomove=' + chains_to_move, 50 | 'mutate_resfile_relpath=' + os.path.abspath( resfile_path ), 51 | 'number_backrub_trials=%d' % number_backrub_trials, 52 | 'max_minimization_iter=%d' % max_minimization_iter, 53 | 'abs_score_convergence_thresh=%.1f' % abs_score_convergence_thresh, 54 | 'backrub_trajectory_stride=%d' % backrub_trajectory_stride , 55 | '-restore_talaris_behavior', 56 | '-in:file:fullatom', 57 | '-ignore_unrecognized_res', 58 | '-ignore_zero_occupancy false', 59 | '-ex1', 60 | '-ex2', 61 | ] 62 | 63 | log_path = os.path.join(output_directory, 'rosetta.out') 64 | 65 | print( 'Running Rosetta with args:' ) 66 | print( ' '.join(flex_ddg_args) ) 67 | print( 'Output logged to:', os.path.abspath(log_path) ) 68 | print() 69 | 70 | outfile = open(log_path, 'w') 71 | process = subprocess.Popen(flex_ddg_args, stdout=outfile, stderr=subprocess.STDOUT, close_fds = True, cwd = output_directory) 72 | returncode = process.wait() 73 | outfile.close() 74 | 75 | if __name__ == '__main__': 76 | mutation_chain, mutation_resi, mutation_icode = residue_to_mutate 77 | cases = [] 78 | for nstruct_i in range(1, nstruct + 1 ): 79 | for case_name in os.listdir('inputs'): 80 | case_path = os.path.join( 'inputs', case_name ) 81 | for f in os.listdir(case_path): 82 | if f.endswith('.pdb'): 83 | input_pdb_path = os.path.join( case_path, f ) 84 | break 85 | 86 | with open( os.path.join( case_path, 'chains_to_move.txt' ), 'r' ) as f: 87 | chains_to_move = f.readlines()[0].strip() 88 | 89 | for mut_aa in 'ACDEFGHIKLMNPQRSTVWY': 90 | cases.append( ('%s_%s%d%s' % (case_name, mutation_chain, mutation_resi, mutation_icode), case_path, input_pdb_path, chains_to_move, mut_aa, nstruct_i) ) 91 | 92 | if use_multiprocessing: 93 | pool = multiprocessing.Pool( processes = min(max_cpus, multiprocessing.cpu_count()) ) 94 | 95 | for args in cases: 96 | if use_multiprocessing: 97 | pool.apply_async( run_flex_ddg_saturation, args = args ) 98 | else: 99 | run_flex_ddg_saturation( *args ) 100 | 101 | if use_multiprocessing: 102 | pool.close() 103 | pool.join() 104 | -------------------------------------------------------------------------------- /split_protocol/flex_ddG-backrub_step.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /split_protocol/flex_ddG-mutation_step.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /split_protocol/split_commands.txt: -------------------------------------------------------------------------------- 1 | Backrub step command line example: 2 | 3 | rosetta_scripts.linuxgccrelease 4 | -parser:protocol flex_ddG-backrub_step.xml 5 | -s wt_pdb_path # Starting WT crystal structure 6 | -in:file:fullatom 7 | -parser:script_vars 8 | mutate_resfile_relpath=%s # Path to a resfile specifying mutant positions. Can be any set of mutations (only the positions matter), as mutations are made in the next step. Positions need to be known now to pick backrub region. 9 | backrub_kt=1.2 10 | backrub_trials=36000 11 | backrub_stride=12000 12 | neighbor_distance=12.0 13 | sc_sample_rotwells_unif=0 14 | min_tolerance=0.000001 15 | min_max_iter=5000 16 | min_abs_score_convergence_threshold=1.0 17 | 18 | Mutation step command line example: 19 | 20 | rosetta_scripts.linuxgccrelease 21 | -parser:protocol flex_ddG-mutation_step.xml 22 | -s wt_minimized_pdb_path # Path to the WT minimized PDB structure from the first script, needed to score ddG calculation 23 | -native # Path to the starting WT crystal structure, needed so that same neighbor residue bubble is selected 24 | -in:file:fullatom 25 | -parser:script_vars 26 | chainstomove=%s 27 | mutate_resfile_relpath=%s # Path to resfile specifying mutations 28 | min_tolerance=0.000001 29 | min_max_iter=5000 30 | neighbor_distance=12.0 31 | min_abs_score_convergence_threshold=1.0 32 | backrub_pdb_path=%s # Path to backrub PDB output from earlier step, mutations will be applied to this model --------------------------------------------------------------------------------