Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LK_BallInfo.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 // This file is made available under the Rosetta Commons license.
5 // See http://www.rosettacommons.org/license
6 // (C) 199x-2007 University of Washington
7 // (C) 199x-2007 University of California Santa Cruz
8 // (C) 199x-2007 University of California San Francisco
9 // (C) 199x-2007 Johns Hopkins University
10 // (C) 199x-2007 University of North Carolina, Chapel Hill
11 // (C) 199x-2007 Vanderbilt University
12 
13 /// @file core/scoring/methods/LK_BallEnergy.hh
14 /// @brief LK Solvation using hemisphere culling class declaration
15 /// @author David Baker
16 /// @author Andrew Leaver-Fay
17 
18 
19 // Unit headers
21 
22 // // Package headers
23 // #include <core/scoring/methods/LK_BallEnergy.hh>
24 // #include <core/scoring/ScoringManager.hh>
25 // #include <core/scoring/NeighborList.hh>
26 // #include <core/scoring/EnergyGraph.hh>
27 // #include <core/scoring/etable/Etable.hh>
28 // #include <core/scoring/etable/count_pair/CountPairFunction.hh>
29 // #include <core/scoring/etable/count_pair/CountPairFactory.hh>
30 // #include <core/scoring/etable/count_pair/types.hh>
31 
32 // // Project headers
33 #include <core/pose/Pose.hh>
34 // #include <core/scoring/ScoreFunction.hh>
37 //#include <core/pack/rotamer_set/WaterPackingInfo.hh>
38 
39 
40 #include <core/io/pdb/pose_io.hh> // HACK
41 #include <fstream> // HACK
42 #include <ObjexxFCL/format.hh>
43 #include <ObjexxFCL/string.functions.hh>
44 
45 // #include <core/scoring/constraints/AngleConstraint.hh>
46 
47 #include <core/chemical/types.hh>
49 
50 #include <core/kinematics/Stub.hh>
51 #include <basic/Tracer.hh>
52 
53 #include <numeric/conversions.hh>
54 #include <numeric/xyz.functions.hh>
55 
56 // #include <utility/vector1.functions.hh> // HACK
57 
58 //#ifdef WIN32
59 //#include <core/pack/rotamer_set/WaterAnchorInfo.hh>
60 //#endif
61 
62 namespace core {
63 namespace scoring {
64 namespace methods {
65 
66 /// @details Auto-generated virtual destructor
68 
69 
70 static basic::Tracer TR("core.scoring.methods.LK_BallInfo" );
71 
72 
73 /// LAZY
74 using namespace chemical;
75 using namespace pose;
76 using namespace conformation;
77 
78  static Real const optimal_water_distance( 2.65 ); /// note that this number is re-defined in hbonds.cc !!
79 
80 /// Not doing backbone waters on protein or DNA
81 inline
82 bool
83 residue_type_has_waters( ResidueType const & rsd_type ) {
84  return ( rsd_type.is_polar() || rsd_type.is_charged() ||
85  ( rsd_type.is_aromatic() && ( rsd_type.aa() == aa_trp || rsd_type.aa() == aa_tyr ) ) );
86 }
87 
89 /////////////////////////////////////////////////////////////////////////////
90 
92  Vector const & water,
93  conformation::Residue const & rsd,
94  Size const atom1,
95  Size const atom2,
96  Size const atom3
97  ):
98  atom1_( atom1 ),
99  atom2_( atom2 ),
100  atom3_( atom3 ),
101  xyz_local_( kinematics::Stub( rsd.xyz( atom1 ), rsd.xyz( atom2 ), rsd.xyz( atom3 ) ).global2local( water ) )
102 {}
103 
104 Vector
106 {
107  return kinematics::Stub( rsd.xyz( atom1_ ), rsd.xyz( atom2_ ), rsd.xyz( atom3_ ) ).local2global( xyz_local_ );
108 }
109 
110 /// The next two functions were taken from protocols/water/rotamer_building_functions.cc with slight modifications
111 ///
112 Vector
114  Vector const & hxyz,
115  Vector const & dxyz
116 )
117 {
118  return ( dxyz + optimal_water_distance * ( hxyz - dxyz ).normalized() );
119 }
120 
121 
124  Size const acc_atm,
125  conformation::Residue const & acc_rsd,
126  Vector const & a_xyz,
127  Vector b1_xyz, // local copy
128  Vector b2_xyz,// local copy
129  chemical::Hybridization const & hybrid
130 )
131 {
132  using numeric::conversions::radians;
133  using namespace chemical;
134 
135  Real const distance( optimal_water_distance ); // acceptor--O distance
136 
137  Real theta(0);
138  utility::vector1< Real > phi_list;
139 
140  // detect special case of DNA phosphate hydration:
141  std::string const & acc_atm_name( acc_rsd.atom_name( acc_atm ) );
142 
143  if ( acc_rsd.is_DNA() && acc_rsd.atom_is_backbone( acc_atm ) &&
144  ( acc_atm_name == " O1P" || acc_atm_name == " O2P" ) ) {
145  // special case: hydration of the DNA phosphate group
146  b1_xyz = acc_rsd.xyz( "P" );
147  b2_xyz = ( ( acc_atm_name == " O1P" ) ? acc_rsd.xyz( "O2P" ) : acc_rsd.xyz( "O1P" ) );
148  // these numbers are taken from "Hydration of the Phosphate Group in Double-Helical DNA",
149  // Schneider, Patel, and Berman, Biophysical Journal Vol. 75 2422-2434
150  theta = 180.0 - 125.0;
151  phi_list.push_back( 45.0 );
152  phi_list.push_back( 160.0 );
153  phi_list.push_back( 280.0 );
154  } else {
155 
156  switch( hybrid ) {
157  case SP2_HYBRID:
158  theta = 180.0 - 120.0;
159  phi_list.push_back( 0.0 );
160  phi_list.push_back( 180.0 );
161  break;
162  case SP3_HYBRID:
163  theta = 180.0 - 109.0;
164  phi_list.push_back( 120.0 );
165  phi_list.push_back( 240.0 );
166  break;
167  case RING_HYBRID:
168  b1_xyz = 0.5 * ( b1_xyz + b2_xyz );
169  theta = 0.0;
170  phi_list.push_back( 0.0 ); // doesnt matter
171  break;
172  default:
173  TR.Error << "Bad hybridization type for acceptor " << hybrid << std::endl;
174  utility_exit();
175  }
176  }
177 
179  kinematics::Stub stub( a_xyz, b1_xyz, b2_xyz );
180  for ( Size i=1; i<= phi_list.size(); ++i ) {
181  waters.push_back( stub.spherical( radians( phi_list[i] ), radians( theta ), distance ) );
182  }
183  return waters;
184 }
185 void
187  ResidueType const & rsd_type,
188  bool const sidechain_only,
189  utility::vector1< WaterBuilders > & rsd_water_builders
190  )
191 {
192  using namespace conformation;
193  using namespace chemical;
194 
195  //bool const no_lk_ball_for_SP2( options::option[ options::OptionKeys::dna::specificity::no_lk_ball_for_SP2 ] );
196 
197  bool const dump_waters_pdb( false ); // for debugging purposes
198 
199  ResidueOP rsd( ResidueFactory::create_residue( rsd_type ) );
200 
201  rsd_water_builders.clear();
202  rsd_water_builders.resize( rsd_type.natoms() ); // initialize to empty vector1s
203 
204  utility::vector1< Vector > all_waters; // for debugging
205 
206  // donors
207  for ( chemical::AtomIndices::const_iterator
208  hnum = rsd->Hpos_polar().begin(),
209  hnume = rsd->Hpos_polar().end(); hnum != hnume; ++hnum ) {
210  Size const hatm( *hnum );
211  if ( sidechain_only && rsd_type.atom_is_backbone( hatm ) ) continue;
212 
213  Size const datm( rsd->atom_base( hatm ) );
214  Size const datm_base( rsd->atom_base( datm ) );
215 
216  Vector const water( build_optimal_water_O_on_donor( rsd->xyz( hatm ), rsd->xyz( datm ) ) );
217  rsd_water_builders[ datm ].push_back( WaterBuilder( water, *rsd, hatm, datm, datm_base ) );
218  TR.Trace << "adding ideal water to rsd_type= " << rsd_type.name() << " anchored to atom " <<
219  rsd_type.atom_name( datm ) << " datm_base= " << rsd_type.atom_name( datm_base ) << std::endl;
220  all_waters.push_back( water );
221  }
222 
223  // acceptors
224  for ( chemical::AtomIndices::const_iterator
225  anum = rsd->accpt_pos().begin(),
226  anume = rsd->accpt_pos().end(); anum != anume; ++anum ) {
227  Size const aatm( *anum );
228  if ( sidechain_only && rsd_type.atom_is_backbone( aatm ) ) continue;
229  if ( rsd_type.atom_type( aatm ).hybridization() == chemical::SP2_HYBRID ) {
230  /// sidechain SP2
231 // if ( rsd_type.is_protein() && no_lk_ball_for_SP2 ) {
232 // TR.Trace << "NOT adding any waters to rsd_type: "<< rsd_type.name() << " anchored to atom " <<
233 // rsd_type.atom_name( aatm ) << std::endl;
234 // continue;
235 // }
236  }
237  Size const abase1( rsd->atom_base( aatm ) ), abase2( rsd->abase2( aatm ) );
238  utility::vector1< Vector > const waters
240  rsd->xyz( aatm ), rsd->xyz( abase1 ), rsd->xyz( abase2 ),
241  rsd->atom_type( aatm ).hybridization() ) );
242  for ( Size i=1; i<= waters.size(); ++i ) {
243  rsd_water_builders[ aatm ].push_back( WaterBuilder( waters[i], *rsd, aatm, abase1, abase2 ) );
244  TR.Trace << "adding ideal water to rsd_type= " << rsd_type.name() << " anchored to atom " <<
245  rsd_type.atom_name( aatm ) << " abase1= " << rsd_type.atom_name( abase1 ) <<
246  " abase2= " << rsd_type.atom_name( abase2 ) << std::endl;
247  all_waters.push_back( waters[i] );
248  }
249  }
250 
251  if ( dump_waters_pdb && !all_waters.empty() ) { // HACKING -- dump a pdb containing just this residue:
252  std::ofstream out( std::string( rsd->name() + "_waters.pdb" ).c_str() );
253  Size atom_number( 0 );
254  rsd->chain( 1 );
255  rsd->seqpos( 1 );
256  io::pdb::dump_pdb_residue( *rsd, atom_number, out );
257 
258  /// now add all the waters
259  char const chain = 'A';
260  for ( Size i=1; i<= all_waters.size(); ++i ) {
261  using namespace ObjexxFCL::fmt;
262  ++atom_number;
263  std::string const atom_name( "W" + ObjexxFCL::lead_zero_string_of( i, 3 ) );
264  out << "ATOM " << I(5,atom_number) << ' ' << atom_name << ' ' <<
265  rsd->name3() << ' ' << chain << I(4,rsd->seqpos() ) << " " <<
266  F(8,3,all_waters[i](1)) <<
267  F(8,3,all_waters[i](2)) <<
268  F(8,3,all_waters[i](3)) <<
269  F(6,2,1.0) << F(6,2,0.0) << '\n';
270  }
271  out.close();
272  }
273 }
274 
276  pose::Pose const &,
277  conformation::Residue const & rsd
278 )
279 {
280  build_waters( rsd );
281 }
282 
283 
284 
285 /// called the first time we encounter a given ResidueType
286 void
288 {
289  using namespace conformation;
290  using namespace chemical;
291 
292  assert( residue_type_has_waters( rsd_type ) );
293 
294  TR.Trace << "initialize_residue_type: " << rsd_type.name() << std::endl;
295 
296  bool const sidechain_only( true );
297 
298  ResidueTypeCOP const address( &rsd_type );
299  assert( ! water_builder_map_.count( address ) );
300 
301  water_builder_map_[ address ]; // create entry in map
302  utility::vector1< WaterBuilders > & rsd_water_builders( water_builder_map_.find( address )->second );
303 
304  setup_water_builders_for_residue_type( rsd_type, sidechain_only, rsd_water_builders );
305 }
306 
307 
308 void
310 {
311  waters_.clear(); waters_.resize( rsd.nheavyatoms() );
312  has_waters_ = false;
313 
314  if ( !residue_type_has_waters( rsd.type() ) ) return;
315 
316  ResidueTypeCOP const address( &( rsd.type() ) );
317 
318  WaterBuilderMap::const_iterator it( water_builder_map_.find( address ) );
319  if ( it == water_builder_map_.end() ) {
320  initialize_residue_type( rsd.type() );
321  it = water_builder_map_.find( address );
322  }
323 
324  for ( Size i=1; i<= rsd.nheavyatoms(); ++i ) {
325  WaterBuilders const & water_builders( it->second[ i ] );
326  for ( WaterBuilders::const_iterator water= water_builders.begin(), water_e = water_builders.end();
327  water != water_e; ++water ) {
328  waters_[i].push_back( water->build( rsd ) );
329  has_waters_ = true;
330  }
331  }
332 }
333 
335  ReferenceCount(),
336  waters_( src.waters_ ),
337  has_waters_( src.has_waters_ )
338 {}
339 
342 {
343  return new LKB_ResidueInfo( *this );
344 }
345 
346 
348  CacheableData()
349 {
350  residues_info_.clear();
351  for ( Size i=1; i<= src.size(); ++i ) {
352  residues_info_.push_back( src[i].clone() );
353  }
354 }
355 
356 basic::datacache::CacheableDataOP
358 {
359  return new LKB_ResiduesInfo( *this );
360 }
361 
362 
363 
364 }
365 }
366 }