Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ExplicitWaterUnsatisfiedPolarsCalculator.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 //////////////////////////////////////////////////////////////////////
10 /// @begin ExplicitWaterUnsatisfiedPolarsCalculator
11 ///
12 /// @brief This Calculator tries to solvate all polar groups by
13 /// docking explicit TP5 water molecules, then counts
14 /// unsatisfied hydrogen bonds using the same criteria in
15 /// BuriedUnsatisfiedHydrogenBondCalculator
16 ///
17 ///
18 ///
19 ///
20 ///
21 ///
22 ///
23 ///
24 ///
25 ///
26 ///
27 ///
28 ///
29 ///
30 /// @author Chris King - dr.chris.king@gmail.com
31 ///
32 ///
33 /// @last_modified 4.8.2011
34 /////////////////////////////////////////////////////////////////////////
36 
37 #include <numeric/random/random.hh>
38 
43 #include <core/kinematics/Jump.hh>
44 
45 #include <core/pose/Pose.hh>
49 
50 //protocol headers
54 
55 // Utility headers
56 #include <basic/Tracer.hh>
57 #include <utility/exit.hh>
58 #include <utility/stream_util.hh>
59 #include <utility/string_util.hh>
60 #include <basic/MetricValue.hh>
61 
62 namespace protocols{
63 namespace toolbox {
64 namespace pose_metric_calculators {
65 
66  ////////////////////////////////////////////////
67  // danger USING ////////////////////////////////
68  using namespace core;
69  using namespace basic;
70  using namespace id;
71  using namespace pose;
72  using namespace conformation;
73  using namespace chemical;
74  using namespace kinematics;
75  using namespace scoring;
76  using namespace options;
77  using namespace basic::options::OptionKeys;
78  using namespace optimization;
79  using utility::vector1;
80 
81  static basic::Tracer TR("protocols.toolbox.PoseMetricCalculators.ExplicitWaterUnsatisfiedPolarsCalculator");
82  static numeric::random::RandomGenerator RG(2718);
83 
84  ///@brief default constructor sets shell_cutoff to 4.0.
86  scorefxn_( scorefxn ),
87  shell_cutoff_( 4.0 ),
88  all_unsat_polars_( 0 )
89  {
90 
91  }
92 
93 
94  ///@brief constructor user defined water shell max distance
95  ExplicitWaterUnsatisfiedPolarsCalculator::ExplicitWaterUnsatisfiedPolarsCalculator( ScoreFunctionOP scorefxn, Real shell_cutoff ):
96  scorefxn_( scorefxn ),
97  shell_cutoff_( shell_cutoff ),
98  all_unsat_polars_( 0 )
99  {
100 
101  }
102 
103 
104 
105 
106 
107 void ExplicitWaterUnsatisfiedPolarsCalculator::lookup( std::string const & key, basic::MetricValueBase * valptr ) const{
108  if ( key == "all_unsat_polars" ) {
109  basic::check_cast( valptr, &all_unsat_polars_, "all_unsat_polars expects to return a Size" );
110  (static_cast<basic::MetricValue<Size> *>(valptr))->set( all_unsat_polars_ );
111  }else {
112  basic::Error() << "ExplicitWaterUnsatisfiedPolarsCalculator cannot compute the requested metric " << key << std::endl;
113  utility_exit();
114  }
115 }
116 
117 
118 std::string ExplicitWaterUnsatisfiedPolarsCalculator::print( std::string const & key ) const{
119  if ( key == "all_unsat_polars" ) {
120  return utility::to_string( all_unsat_polars_ );
121  }
122  basic::Error() << "ExplicitWaterUnsatisfiedPolarsCalculator cannot compute metric " << key << std::endl;
123  utility_exit();
124  return "";
125 
126 }
127 
128 void
130  pose::Pose & pose,
131  Size seqpos,
132  Size atomno,
133  conformation::Residue new_rsd,
134  Size new_atomno,
135  Real dist_min,
136  Real dist_max
137 )
138 {
140 
141  Residue rsd( pose.residue( seqpos ) );
142  //append by jump from seqpos atomno to new_rsd atom 1, maybe make random downstream atom?
143  pose.append_residue_by_jump( new_rsd, seqpos, rsd.atom_name( atomno ), new_rsd.atom_name( new_atomno ), true );
144  Size new_seqpos( pose.total_residue() );
145  Size jump_number( pose.fold_tree().num_jump() );
146  Jump jump( pose.jump( jump_number ) );
147 
148  //set jump distance as random val from dist_min to dist_max
149  Real jump_dist( dist_min + RG.uniform() * ( dist_max - dist_min ) );
150  jump.random_trans( jump_dist );
151  //set jump rotation as random matrix
152  jump.set_rotation( protocols::geometry::random_reorientation_matrix( 360, 360 ) );
153 
154  //and set jump in pose at our new jump
155  pose.set_jump( jump_number, jump );
156 
157 }
158 
159 void
161  pose::Pose & pose,
162  ScoreFunctionOP scorefxn,
163  Size seqpos,
164  Size atomno,
165  conformation::Residue wat_rsd,
166  Size new_atomno,
167  Real dist_min,
168  Real dist_max
169 )
170 {
172 
173  //attempt appending in 20 random orientations
174  Size const max_attempt_per_atom( 20 );
175  Size const max_wat_per_atom( 5 );
176  Size n_wat( 0 );
177  pose::Pose start_pose( pose );
178  protocols::moves::MonteCarloOP mc_create( new protocols::moves::MonteCarlo( pose, *scorefxn, 0.8 ) );
179  for( Size i = 1; i <= max_attempt_per_atom; ++i ){
180  if( n_wat >= max_wat_per_atom ) break;
181 
182  pose = start_pose;
183  append_rsd_by_jump_near_atom( pose, seqpos, atomno, wat_rsd, new_atomno, dist_min, dist_max );
184 
185  Size jump_number( pose.fold_tree().num_jump() );
186  //gaussian perturbations to RB dofs
187  protocols::moves::MonteCarloOP mc_dock( new protocols::moves::MonteCarlo( pose, *scorefxn, 0.8 ) );
188  for( Size i = 1; i <= 10; ++i ){
189  Jump jump( pose.jump( jump_number ) );
190  jump.gaussian_move( 1, 0.05, 90.0 );
191  pose.set_jump( jump_number, jump );
192  mc_dock->boltzmann( pose );
193  }
194  mc_dock->recover_low( pose );
195  //if accept, minimize
196  if( mc_create->boltzmann( pose ) ){
197  MoveMapOP mm = new MoveMap;
198  mm->set_jump( pose.fold_tree().num_jump(), true );
199  protocols::simple_moves::MinMoverOP min_mover = new protocols::simple_moves::MinMover( mm, scorefxn, "dfpmin", 0.001, false );
200  min_mover->apply( pose );
201  ++n_wat;
202  }
203  }
204  mc_create->recover_low( pose );
205 }
206 
207 //count residue unsat polar atoms, pass back bool vector of unsat atoms
208 void
210  Pose const pose,
211  Size const seqpos,
212  vector1< bool > & atm_is_unsat
213  )
214 {
215  using namespace core::scoring::hbonds;
216  HBondSet hbset;
217  hbset.setup_for_residue_pair_energies( pose, false, false );
218  conformation::Residue rsd( pose.residue( seqpos ) );
219  //count n hbonds for donors and acceptors
220  vector1< Size > n_atom_hbonds( rsd.natoms(), 0 );
221  for( Size i = 1; i <= hbset.nhbonds(); ++i ){
222  HBond hb( hbset.hbond( i ) );
223  if( hb.don_res() == seqpos ){
224  Size don_atm( rsd.atom_base( hb.don_hatm() ) );
225  n_atom_hbonds[ don_atm ] += 1;
226  }
227  else if( hb.acc_res() == seqpos ){
228  n_atom_hbonds[ hb.acc_atm() ] += 1;
229  }
230  }
231  //calc unsat hbonds a la BuriedUnsatisfied calculator
232  for( Size atm = 1; atm <= rsd.nheavyatoms(); ++atm ){
233  if( !( rsd.atom_type( atm ).is_acceptor() || rsd.atom_type( atm ).is_donor() ) ) continue;
234  //we need at least one hbond
235  if( n_atom_hbonds[ atm ] == 0 ){
236  atm_is_unsat[ atm ] = true; continue;
237  }
238  //may need > 1 hbond, see BuriedUnsatCalc
239  //behavior copied from Florian!
240  std::string atom_type( rsd.type().atom_type( atm ).name() );
241  Size satisfac_cut = 3;
242  if( atom_type == "OH" || atom_type == "OCbb" || atom_type == "S" ){
243  satisfac_cut = 2;
244  }
245  Size bonded_heavyatoms = rsd.n_bonded_neighbor_all_res( atm )
246  - rsd.type().number_bonded_hydrogens( atm );
247  if( bonded_heavyatoms + n_atom_hbonds[ atm ] < satisfac_cut ){
248  atm_is_unsat[ atm ] = true;
249  }
250  }
251 }
252 
253 ///@brief this should just be called "compute"
254 void ExplicitWaterUnsatisfiedPolarsCalculator::recompute( core::pose::Pose const & pose_in ){
255  ScoreFunctionOP scorefxn( scorefxn_ );
256  all_unsat_polars_ = 0;
257  ResidueTypeSet const & rsd_set( pose_in.residue( 1 ).residue_type_set() );
258 
259  //for each residue
260  for( core::Size seqpos = 1; seqpos <= pose_in.total_residue(); ++seqpos ){
261  //check each residue seperately
262  Pose pose( pose_in );
263  Residue rsd( pose.residue( seqpos ) );
264 
265  //first check for unsat polars in residue
266  //we only need to try solvating unsat atoms
267  vector1< bool > atm_is_unsat( rsd.natoms(), false );
268  find_res_unsat_polars( pose, seqpos, atm_is_unsat );
269 
270  Real min_dist( 1.5 );
271  ResidueTypeSet const & rsd_set( rsd.residue_type_set() );
272  ResidueOP wat_rsd( ResidueFactory::create_residue( rsd_set.name_map( "TP5" ) ) );
273  //turn off solvation score
274  Real fa_sol_wt( scorefxn->get_weight( fa_sol ) );
275  scorefxn->set_weight( fa_sol, 0.0 );
276 
277  //do polar hydrogens
278  for ( chemical::AtomIndices::const_iterator hnum = rsd.Hpos_polar().begin(),
279  hnume = rsd.Hpos_polar().end(); hnum != hnume; ++hnum ) {
280  Size const iatom( *hnum );
281  if( !atm_is_unsat[ iatom ] ) continue;
282  //append water molecule from iatom to water oxygen (atom 1)
283  dock_waters_to_atom( pose, scorefxn, seqpos, iatom, *wat_rsd, 1, min_dist, shell_cutoff_ );
284  }
285  //then do acceptors
286  for ( chemical::AtomIndices::const_iterator anum = rsd.accpt_pos().begin(),
287  anume = rsd.accpt_pos().end(); anum != anume; ++anum ){
288  Size const iatom( *anum );
289  if( !atm_is_unsat[ iatom ] ) continue;
290  //append water molecule from iatom to water
291  dock_waters_to_atom( pose, scorefxn, seqpos, iatom, *wat_rsd, 1, min_dist, shell_cutoff_ );
292  }
293 
294  //now check again for unsat hbonds in residue
295  find_res_unsat_polars( pose, seqpos, atm_is_unsat );
296  for( Size iatom = 1; iatom <= atm_is_unsat.size(); ++iatom ){
297  if( atm_is_unsat[ iatom ] ) ++all_unsat_polars_;
298  }
299  }
300 
301 
302 }
303 
304 
305 }
306 }
307 }