Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SuckerEnergy.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 /// @file core/scoring/methods/SuckerEnergy.cc
11 /// @brief Statistically derived rotamer pair potential class implementation
12 /// @author Phil Bradley
13 /// @author Andrew Leaver-Fay
14 
15 
16 
18 #include <basic/database/open.hh>
19 #include <basic/options/option.hh>
20 #include <basic/options/keys/in.OptionKeys.gen.hh>
21 #include <core/pose/Pose.hh>
24 // AUTO-REMOVED #include <core/scoring/NeighborList.hh>
25 //#include <core/scoring/ScoringManager.hh>
27 #include <numeric/interpolation/spline/SplineGenerator.hh>
28 #include <utility/io/izstream.hh>
29 #include <sstream>
30 
31 #include <core/id/AtomID.hh>
32 #include <utility/vector1.hh>
33 
34 
35 
36 #define DIST_TH 6.0
37 //#define TETHER_WT 10.0
38 
39 namespace core {
40 namespace scoring {
41 namespace methods {
42 
44 
45 
46 /// @details This must return a fresh instance of the SuckerEnergy class,
47 /// never an instance already in use
51 ) const {
52  return new SuckerEnergy;
53 }
54 
57  ScoreTypes sts;
58  sts.push_back( suck );
59  return sts;
60 }
61 
62 
65 {
66  utility::io::izstream izin;
67  basic::database::open( izin, basic::options::option[ basic::options::OptionKeys::in::file::sucker_params ]() );
68 
70 
71  char s[999];
72  izin.getline(s,999); // read in and ignore header line
73  while( true ) {
74  izin.getline(s,999);
75  // std::cerr << "string: '" << s << "'" << std::endl;
76  std::istringstream iss(s);
77  core::Real tmp;
79  if( !(iss >> tmp ) ) break; // if no line, done
80  point.push_back(tmp);
81  iss >> tmp;
82  point.push_back(tmp);
83  if( iss >> tmp ) point.push_back(tmp);
84  points.push_back(point);
85  }
86 
87  assert( points.size() >= 2 );
88 
89  // std::cerr << "printing points" << std::endl;
90  // for( Size i = 1; i <= points.size(); ++i ) {
91  // std::cerr << "point: ";
92  // for( Size j = 1; j <= points[i].size(); ++j ) {
93  // std::cerr << points[i][j] << ",";
94  // }
95  // std::cerr << std::endl;
96  // }
97 
98  using namespace numeric::interpolation::spline;
99  SplineGenerator sg( points[ 1 ][1], points[ 1 ][2], points[ 1 ][3],
100  points[points.size()][1], points[points.size()][2], points[points.size()][3] );
101 
102  for( Size i = 2; i < points.size(); ++i ) {
103  if( points[i].size() == 2 ) sg.add_known_value( points[i][1], points[i][2] );
104  if( points[i].size() == 3 ) sg.add_known_value( points[i][1], points[i][2], points[i][3] );
105  }
106 
107  interp_ = sg.get_interpolator();
108 
109  // core::Real x,y,dy;
110  // for( x = 0; x <= 6.0; x += 0.01 ) {
111  // interp_->interpolate(x,y,dy);
112  // std::cerr << "SUCKERE " << x << " " << y << " " << dy << std::endl;
113  // }
114 
115 }
116 
117 
118 /// clone
121 {
122  return new SuckerEnergy();
123 }
124 
125 
126 inline bool count_atom( int const & atype ) {
127  // return true;
128  return ( ( 1 <= atype && atype <= 6 ) // just carbons for now...
129  || ( 18 <= atype && atype <= 19 )
130  );
131 }
132 /////////////////////////////////////////////////////////////////////////////
133 // scoring
134 /////////////////////////////////////////////////////////////////////////////
135 
136 ///
137 void
139  conformation::Residue const & rsd1,
140  conformation::Residue const & rsd2,
141  pose::Pose const & /*pose*/,
142  ScoreFunction const &,
143  EnergyMap & emap
144 ) const
145 {
146  using namespace core;
147  using namespace conformation;
148 
149  if ( rsd1.seqpos() == rsd2.seqpos() ) return;
150 
151  std::string name1 = rsd1.name();
152  std::string name2 = rsd2.name();
153 
154  if( "SUCK" == name1 && "SUCK" == name2 ) return;
155  if( "SUCK" != name1 && "SUCK" != name2 ) return;
156 
157  Residue const & rsd( ( "SUCK" != name1 ) ? rsd1 : rsd2 );
158  Residue const & sck( ( "SUCK" == name1 ) ? rsd1 : rsd2 );
159 
160  numeric::xyzVector<Real> suck_xyz( sck.xyz(1) );
161  for( int i = 1; i <= (int)rsd.nheavyatoms(); ++i ) {
162  conformation::Atom const & atom( rsd.atom(i) );
163  if( !count_atom( atom.type() ) ) continue;
164  numeric::xyzVector<Real> atom_xyz( rsd.xyz(i) );
165  Real const d = atom_xyz.distance( suck_xyz );
166  if( d <= DIST_TH ) {
167  Real f, df;
168  interp_->interpolate( d, f, df );
169  // std::cerr << rsd.seqpos() << " " << i << " " << d << " " << f << " " << df << " SUCKER" << std::endl;
170  // std::cerr << "SCOREATOMS " << rsd.seqpos() << " " << i << " " << sck.seqpos() << " " << 1 << " " << d << std::endl;
171  emap[ suck ] += f;
172  }
173  }
174 
175 }
176 
177 /////////////////////////////////////////////////////////////////////////////
178 /// probably move this logic to PairEPotential ??
179 void
181  id::AtomID const & id,
182  pose::Pose const & pose,
183  kinematics::DomainMap const &, // domain_map,
184  ScoreFunction const &,
185  EnergyMap const & weights,
186  Vector & F1,
187  Vector & F2
188 ) const
189 {
190  using namespace numeric;
191 
192  // id is a SUCK atom
193  if( "SUCK" == pose.residue(id.rsd()).name() ) { // loop over atom neighbors and suck
194  // conformation::Residue const & sck( pose.residue(id.rsd()) );
195  assert( 1 <= id.atomno() && id.atomno() <= 3 );
196  if( id.atomno() > 1 ) return;
197  numeric::xyzVector<Real> suck_xyz( pose.xyz(id) );
198 
199  for( int ir = 1; ir <= (int)pose.total_residue(); ++ir ) {
200  conformation::Residue const & res( pose.residue(ir) );
201  if( "SUCK" == res.name() ) continue;
202 
203  for( int ia = 1; ia <= (int)res.nheavyatoms(); ++ia ) {
204  conformation::Atom const & atom( res.atom( ia ) );
205  if( !count_atom( atom.type() ) ) continue;
206 
207  xyzVector<Real> const & atom_xyz( atom.xyz() );
208 
209  Real const d = suck_xyz.distance(atom_xyz);
210  if( d > DIST_TH ) continue;
211 
212  // std::cerr << "DERIVATOMS " << res.seqpos() << " " << ia << " " << sck.seqpos() << " " << 1 << " " << d << " LPA " << id.rsd() << " " << id.atomno() << std::endl;
213 
214  // compute suck F1, F2
215  numeric::xyzVector<Real> const f1( suck_xyz.cross( atom_xyz ));
216  numeric::xyzVector<Real> const f2( suck_xyz - atom_xyz );
217  Real const dist( f2.length() );
218  Real deriv, dummy;
219  interp_->interpolate( dist, dummy, deriv );
220  // std::cerr << "sck_atm " << deriv << std::endl;
221  F1 += ( deriv / dist ) * weights[ suck ] * f1;
222  F2 += ( deriv / dist ) * weights[ suck ] * f2;
223 
224  }
225  }
226 
227  // // teathers, orig pos from pose data cache
228  // using namespace basic;
229  // CacheableData const & cd = pose.data().get(SUCKER_ORIG_POSITIONS);
230  // CacheableIntXyzVectorMap const & cxmap = dynamic_cast<CacheableIntXyzVectorMap const &>( cd );
231  // numeric::xyzVector<Real> const & orig_xyz = cxmap.map().find( id.rsd() )->second;
232  //
233  // numeric::xyzVector<Real> const f1( suck_xyz.cross( orig_xyz ));
234  // numeric::xyzVector<Real> const f2( suck_xyz - orig_xyz );
235  // std::cerr << "intrares dE " << distance(suck_xyz,orig_xyz) << " " << 2*TETHER_WT*distance(suck_xyz,orig_xyz) << std::endl;
236  // std::cerr << " SUCKER ORIG POS " << id.rsd() << " " << orig_xyz.x() << "," << orig_xyz.y() << "," << orig_xyz.z() << std::endl;
237  // std::cerr << " SUCKER POS " << id.rsd() << " " << suck_xyz.x() << "," << suck_xyz.y() << "," << suck_xyz.z() << std::endl;
238  // Real dist = distance( suck_xyz, orig_xyz );
239  // Real deriv = -dist * 2;
240  // F1 += ( deriv / dist ) * TETHER_WT * weights[ suck ] * f1;
241  // F2 += ( deriv / dist ) * TETHER_WT * weights[ suck ] * f2;
242 
243 
244  } else { // loop over suck residues and suck
245 
246  // heavy atoms only
247  if( id.atomno() > pose.residue(id.rsd()).nheavyatoms() ) return;
248  conformation::Atom const & atom( pose.residue(id.rsd()).atom(id.atomno()) );
249  if( !count_atom( atom.type() ) ) return;
250 
251  numeric::xyzVector<Real> atom_xyz( atom.xyz() );
252  // while( "SUCK" == pose.residue(i).name() ) {
253  for( Size i = 1; i <= pose.total_residue(); ++i ) {
254  if( "SUCK" != pose.residue(i).name() ) continue;
255 
256  conformation::Residue const & sck( pose.residue(i) );
257  numeric::xyzVector<Real> suck_xyz( sck.xyz(1) );
258  Real const d = suck_xyz.distance(atom_xyz);
259  if( d <= DIST_TH ) {
260 
261  // std::cerr << "DERIVATOMS " << id.rsd() << " " << id.atomno() << " " << sck.seqpos() << " " << 1 << " " << d << " LPB " << id.rsd() << " " << id.atomno() << std::endl;
262 
263  // compute suck F1, F2
264  numeric::xyzVector<Real> const f1( atom_xyz.cross( suck_xyz ));
265  numeric::xyzVector<Real> const f2( atom_xyz - suck_xyz );
266  Real const dist( f2.length() );
267  Real deriv, dummy;
268  interp_->interpolate( dist, dummy, deriv );
269  // std::cerr << "reg_atm " << deriv << std::endl;
270  F1 += ( deriv / dist ) * weights[ suck ] * f1;
271  F2 += ( deriv / dist ) * weights[ suck ] * f2;
272 
273  }
274  // --i;
275 
276  }
277 
278  }
279 
280 }
281 
282 void
284  conformation::Residue const & /*rsd*/,
285  pose::Pose const & /*pose*/,
286  ScoreFunction const & /*sfxn*/,
287  EnergyMap & /*emap*/
288 ) const {
289  // using namespace basic;
290  // if( "SUCK" == rsd.name() ) {
291  // CacheableData const & cd = pose.data().get(SUCKER_ORIG_POSITIONS);
292  // CacheableIntXyzVectorMap const & cxmap = dynamic_cast<CacheableIntXyzVectorMap const &>( cd );
293  // numeric::xyzVector<Real> const & orig_xyz = cxmap.map().find( rsd.seqpos() )->second;
294  // numeric::xyzVector<Real> const & curr_xyz( rsd.xyz(1) );
295  // Real const d2( distance_squared(orig_xyz,curr_xyz) );
296  // std::cerr << "intrareas E " << distance(curr_xyz,orig_xyz) << " " << TETHER_WT*d2 << std::endl;
297  // std::cerr << " SUCKER ORIG POS " << rsd.seqpos() << " " << orig_xyz.x() << "," << orig_xyz.y() << "," << orig_xyz.z() << std::endl;
298  // std::cerr << " SUCKER POS " << rsd.seqpos() << " " << curr_xyz.x() << "," << curr_xyz.y() << "," << curr_xyz.z() << std::endl;
299  // emap[ suck ] += TETHER_WT*d2;
300  // }
301 }
302 
303 
304 /// @brief SuckerEnergy distance cutoff set to the same cutoff used by EtableEnergy, for now
305 Distance
307 {
308  return interaction_cutoff();
309 }
310 
311 /// @details non-virtual accessor for speed; assumption: SuckerEnergy is not inherrited from.
312 Distance
314 {
315  return DIST_TH;
316 }
317 
318 /// @brief SuckerEnergy requires that Energies class maintains a TenANeighborGraph
319 void
321 {
322 }
325 {
326  return 1; // Initial versioning
327 }
328 
329 
330 }
331 }
332 }