Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DihedralPairConstraint.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 src/core/scoring/DihedralPairConstraint.cc
11 /// @brief Restrain a pair of residues to take the same torsion angles
12 /// @author Frank DiMaio
13 
17 
18 #include <core/pose/Pose.hh>
19 #include <core/pose/util.hh>
21 #include <basic/Tracer.hh>
22 
23 #include <numeric/xyz.functions.hh>
24 #include <numeric/trig.functions.hh>
25 #include <numeric/deriv/dihedral_deriv.hh>
26 
27 #include <utility/exit.hh>
28 
29 #include <core/id/NamedAtomID.hh>
33 #include <utility/vector1.hh>
34 
35 namespace core {
36 namespace scoring {
37 namespace constraints {
38 
39 static basic::Tracer TR("core.io.constraints");
40 
41 
42 /////////////////////////////////////////////////////////////////////////////
43 
46  core::id::SequenceMapping const & seqmap
47 ) const {
48  if ( seqmap[atomA1_.rsd()] != 0 && seqmap[atomA2_.rsd()] != 0
49  && seqmap[atomA3_.rsd()] != 0 && seqmap[atomA4_.rsd()] != 0
50  && seqmap[atomB1_.rsd()] != 0 && seqmap[atomB2_.rsd()] != 0
51  && seqmap[atomB3_.rsd()] != 0 && seqmap[atomB4_.rsd()] != 0 ) {
52  AtomID remap_a1( atomA1_.atomno(), seqmap[atomA1_.rsd()] ),
53  remap_a2( atomA2_.atomno(), seqmap[atomA2_.rsd()] ),
54  remap_a3( atomA3_.atomno(), seqmap[atomA3_.rsd()] ),
55  remap_a4( atomA4_.atomno(), seqmap[atomA4_.rsd()] );
56  AtomID remap_b1( atomB1_.atomno(), seqmap[atomB1_.rsd()] ),
57  remap_b2( atomB2_.atomno(), seqmap[atomB2_.rsd()] ),
58  remap_b3( atomB3_.atomno(), seqmap[atomB3_.rsd()] ),
59  remap_b4( atomB4_.atomno(), seqmap[atomB4_.rsd()] );
60  return ConstraintOP(
62  remap_a1, remap_a2, remap_a3, remap_a4,
63  remap_b1, remap_b2, remap_b3, remap_b4,
64  this->func_ ) );
65  } else {
66  return NULL;
67  }
68 }
69 
70 
71 /// @brief Copies the data from this Constraint into a new object and returns an OP
72 /// atoms are mapped to atoms with the same name in dest pose ( e.g. for switch from centroid to fullatom )
73 /// if a sequence_mapping is present it is used to map residue numbers .. NULL = identity mapping
74 /// to the new object. Intended to be implemented by derived classes.
84  if ( smap ) {
85  atomA1.rsd() = (*smap)[ atomA1_.rsd() ];
86  atomA2.rsd() = (*smap)[ atomA2_.rsd() ];
87  atomA3.rsd() = (*smap)[ atomA3_.rsd() ];
88  atomA4.rsd() = (*smap)[ atomA4_.rsd() ];
89  atomB1.rsd() = (*smap)[ atomB1_.rsd() ];
90  atomB2.rsd() = (*smap)[ atomB2_.rsd() ];
91  atomB3.rsd() = (*smap)[ atomB3_.rsd() ];
92  atomB4.rsd() = (*smap)[ atomB4_.rsd() ];
93  }
94 
95  //get AtomIDs for target pose
104  if ( id1.valid() && id2.valid() && id3.valid() && id4.valid()
105  && id5.valid() && id6.valid() && id7.valid() && id8.valid() ) {
106  return new DihedralPairConstraint( id1, id2, id3, id4, id5, id6, id7, id8, func_, score_type() );
107  } else {
108  return NULL;
109  }
110 }
111 
112 
113 id::AtomID const &
115  switch( n ) {
116  case 1: return atomA1_;
117  case 2: return atomA2_;
118  case 3: return atomA3_;
119  case 4: return atomA4_;
120  case 5: return atomB1_;
121  case 6: return atomB2_;
122  case 7: return atomB3_;
123  case 8: return atomB4_;
124  default:
125  utility_exit_with_message( "DihedralPairConstraint::atom() bad argument" );
126  }
127  return atomA1_;
128 }
129 
130 
131 
132 ////////////////////////////////////////////////////////////////////////////////////////////////////
133 ///@details one line definition "Dihedral atom1 res1 atom2 res2 atom3 res3 atom4 res4 function_type function_definition"
134 void
136  std::istream & in,
137  pose::Pose const & pose,
138  FuncFactory const & func_factory
139 ) {
140  Size res1, res2, res3, res4, res5, res6, res7, res8;
141  std::string tempres1, tempres2, tempres3, tempres4, tempres5, tempres6, tempres7, tempres8;
142  std::string name1, name2, name3, name4, name5, name6, name7, name8;
143  std::string func_type;
145 
146  in
147  >> name1 >> tempres1
148  >> name2 >> tempres2
149  >> name3 >> tempres3
150  >> name4 >> tempres4
151  >> name5 >> tempres5
152  >> name6 >> tempres6
153  >> name7 >> tempres7
154  >> name8 >> tempres8
155  >> func_type;
156 
157  ConstraintIO::parse_residue( pose, tempres1, res1 );
158  ConstraintIO::parse_residue( pose, tempres2, res2 );
159  ConstraintIO::parse_residue( pose, tempres3, res3 );
160  ConstraintIO::parse_residue( pose, tempres4, res4 );
161  ConstraintIO::parse_residue( pose, tempres5, res5 );
162  ConstraintIO::parse_residue( pose, tempres6, res6 );
163  ConstraintIO::parse_residue( pose, tempres7, res7 );
164  ConstraintIO::parse_residue( pose, tempres8, res8 );
165 
166  TR.Debug << "read: " << name1 << " " << name2 << " " << name3 << " " << name4 << " "
167  << res1 << " " << res2 << " " << res3 << " " << res4 << " func: " << func_type
168  << std::endl;
169  if ( res1 > pose.total_residue() || res2 > pose.total_residue()
170  || res3 > pose.total_residue() || res4 > pose.total_residue()
171  || res5 > pose.total_residue() || res6 > pose.total_residue()
172  || res7 > pose.total_residue() || res8 > pose.total_residue() ) {
173  TR.Warning << "ignored constraint (no such atom in pose!)"
174  << name1 << " " << name2 << " " << name3 << " " << name4 << " "
175  << res1 << " " << res2 << " " << res3 << " " << res4 << " func: " << func_type
176  << std::endl;
177  in.setstate( std::ios_base::failbit );
178  return;
179  }
180 
189 
190  if ( atomA1_.atomno() == 0 || atomA2_.atomno() == 0 || atomA3_.atomno() == 0 || atomA4_.atomno() == 0
191  || atomB1_.atomno() == 0 || atomB2_.atomno() == 0 || atomB3_.atomno() == 0 || atomB4_.atomno() == 0 ) {
192  TR.Warning << "Error reading atoms: read in atom names("
193  << name1 << "," << name2 << "," << name3 << "," << name4 << ","
194  << name5 << "," << name6 << "," << name7 << "," << name8 << "), "
195  << "and found AtomIDs (" << atomA1_ << "," << atomA2_ << "," << atomA3_ << "," << atomA4_ << " -- "
196  << atomB1_ << "," << atomB2_ << "," << atomB3_ << "," << atomB4_ << ")" << std::endl;
197  in.setstate( std::ios_base::failbit );
198  return;
199  }
200 
201  func_ = func_factory.new_func( func_type );
202  func_->read_data( in );
203 
204  while( in.good() && (in.get() != '\n') ) {}
205 
206  if ( TR.Debug.visible() ) {
207  func_->show_definition( std::cout );
208  std::cout << std::endl;
209  }
210 }
211 
212 /////////////////////////////////////////////////////////////////////////////
213 
214 Real
216  conformation::Conformation const & conformation
217 ) const {
218  return score(
219  conformation.xyz( atomA1_ ), conformation.xyz( atomA2_ ),
220  conformation.xyz( atomA3_ ), conformation.xyz( atomA4_ ),
221  conformation.xyz( atomB1_ ), conformation.xyz( atomB2_ ),
222  conformation.xyz( atomB3_ ), conformation.xyz( atomB4_ ));
223 }
224 
225 void
227  XYZ_Func const & xyz,
228  EnergyMap const &,
229  EnergyMap & emap
230 ) const {
231  emap[ this->score_type() ] += score(
232  xyz( atomA1_ ), xyz( atomA2_ ), xyz( atomA3_ ), xyz( atomA4_ ),
233  xyz( atomB1_ ), xyz( atomB2_ ), xyz( atomB3_ ), xyz( atomB4_ )
234  );
235 }
236 
237 
238 Real
240  Vector const & p1, Vector const & p2, Vector const & p3, Vector const & p4,
241  Vector const & p5, Vector const & p6, Vector const & p7, Vector const & p8
242 ) const {
243  core::Real difference = dihedral_degrees( p1, p2, p3, p4 ) - dihedral_degrees( p5, p6, p7, p8 ) ;
244  if (difference > 180) difference -=360;
245  if (difference < -180) difference +=360;
246  TR.Debug << "difference of " << difference << " degrees" << std::endl;
247  return func(difference);
248 }
249 
250 
251 void
253  AtomID const & atom,
254  XYZ_Func const & xyz,
255  Vector & F1,
256  Vector & F2,
257  EnergyMap const & weights
258 ) const {
259  using namespace numeric::deriv;
260 
261  Vector f1(0.0) ,f2(0.0);
262 
263  Real theta(0.0), theta0;
264  if ( atom == atomA1_ ) {
265  dihedral_p1_cosine_deriv( xyz( atomA1_ ),xyz( atomA2_ ), xyz( atomA3_ ), xyz( atomA4_ ), theta, f1, f2 );
266  theta0 = dihedral_degrees( xyz( atomB1_ ),xyz( atomB2_ ), xyz( atomB3_ ), xyz( atomB4_ ) );
267  } else if ( atom == atomA2_ ) {
268  dihedral_p2_cosine_deriv( xyz( atomA1_ ),xyz( atomA2_ ), xyz( atomA3_ ), xyz( atomA4_ ), theta, f1, f2 );
269  theta0 = dihedral_degrees( xyz( atomB1_ ),xyz( atomB2_ ), xyz( atomB3_ ), xyz( atomB4_ ) );
270  } else if ( atom == atomA3_ ) {
271  dihedral_p2_cosine_deriv( xyz( atomA4_ ), xyz( atomA3_ ), xyz( atomA2_ ), xyz( atomA1_ ), theta, f1, f2 );
272  theta0 = dihedral_degrees( xyz( atomB4_ ), xyz( atomB3_ ), xyz( atomB2_ ), xyz( atomB1_ ) );
273  } else if ( atom == atomA4_ ) {
274  dihedral_p1_cosine_deriv( xyz( atomA4_ ), xyz( atomA3_ ), xyz( atomA2_ ), xyz( atomA1_ ), theta, f1, f2 );
275  theta0 = dihedral_degrees( xyz( atomB4_ ), xyz( atomB3_ ), xyz( atomB2_ ), xyz( atomB1_ ) );
276  } else if ( atom == atomB1_ ) {
277  dihedral_p1_cosine_deriv( xyz( atomB1_ ),xyz( atomB2_ ), xyz( atomB3_ ), xyz( atomB4_ ), theta, f1, f2 );
278  theta0 = dihedral_degrees( xyz( atomA1_ ),xyz( atomA2_ ), xyz( atomA3_ ), xyz( atomA4_ ) );
279  } else if ( atom == atomB2_ ) {
280  dihedral_p2_cosine_deriv( xyz( atomB1_ ),xyz( atomB2_ ), xyz( atomB3_ ), xyz( atomB4_ ), theta, f1, f2 );
281  theta0 = dihedral_degrees( xyz( atomA1_ ),xyz( atomA2_ ), xyz( atomA3_ ), xyz( atomA4_ ) );
282  } else if ( atom == atomB3_ ) {
283  dihedral_p2_cosine_deriv( xyz( atomB4_ ), xyz( atomB3_ ), xyz( atomB2_ ), xyz( atomB1_ ), theta, f1, f2 );
284  theta0 = dihedral_degrees( xyz( atomA4_ ), xyz( atomA3_ ), xyz( atomA2_ ), xyz( atomA1_ ) );
285  } else if ( atom == atomB4_ ) {
286  dihedral_p1_cosine_deriv( xyz( atomB4_ ), xyz( atomB3_ ), xyz( atomB2_ ), xyz( atomB1_ ), theta, f1, f2 );
287  theta0 = dihedral_degrees( xyz( atomA4_ ), xyz( atomA3_ ), xyz( atomA2_ ), xyz( atomA1_ ) );
288  } else {
289  return;
290  }
291 
292  core::Real difference = numeric::conversions::degrees( theta ) - theta0;
293  if (difference > 180) difference -=360;
294  if (difference < -180) difference +=360;
295  Real const dE_dtheta( numeric::conversions::degrees( dfunc( difference ) ) );
296 
297  F1 += dE_dtheta * weights[ this->score_type() ] * f1;
298  F2 += dE_dtheta * weights[ this->score_type() ] * f2;
299 }
300 
301 
302 bool
304  if( !dynamic_cast< DihedralPairConstraint const * > ( &other_cst ) ) return false;
305 
306  DihedralPairConstraint const & other( static_cast< DihedralPairConstraint const & > (other_cst) );
307 
308  if( atomA1_ != other.atomA1_ ) return false;
309  if( atomA2_ != other.atomA2_ ) return false;
310  if( atomA3_ != other.atomA3_ ) return false;
311  if( atomA4_ != other.atomA4_ ) return false;
312  if( atomB1_ != other.atomB1_ ) return false;
313  if( atomB2_ != other.atomB2_ ) return false;
314  if( atomB3_ != other.atomB3_ ) return false;
315  if( atomB4_ != other.atomB4_ ) return false;
316  if( func_ != other.func_ ) return false;
317  if( this->score_type() != other.score_type() ) return false;
318 
319  return true;
320 }
321 
322 
323 void DihedralPairConstraint::show( std::ostream & out ) const {
324  out << "DihedralPairConstraint";
325  for ( Size i = 1; i <= natoms(); ++i ) {
326  AtomID const & id = atom(i);
327  out << ' ' << id.rsd() << ' ' << id.atomno();
328  }
329  out << ' ';
330  func_->show_definition(out);
331 }
332 
333 
335  std::ostream& out,
336  pose::Pose const& pose,
337  Size verbose_level,
338  Real threshold
339 ) const {
340  if ( verbose_level > 80 ) {
341  out << "DihedralPair ("
342  << pose.residue_type(atomA2_.rsd() ).atom_name( atomA2_.atomno() ) << ":"
343  << atomA2_.atomno() << "," << atomA2_.rsd() << "-"
344  << pose.residue_type(atomA3_.rsd() ).atom_name( atomA3_.atomno() ) << ":"
345  << atomA3_.atomno() << "," << atomA3_.rsd() << " === "
346  << pose.residue_type(atomB2_.rsd() ).atom_name( atomB2_.atomno() ) << ":"
347  << atomB2_.atomno() << "," << atomB2_.rsd() << "-"
348  << pose.residue_type(atomB3_.rsd() ).atom_name( atomB3_.atomno() ) << ":"
349  << atomB3_.atomno() << "," << atomB3_.rsd() << "-";
350  }
351  return func_->show_violations( out, 0.0, verbose_level, threshold );
352 }
353 
354 
355 Real
356 DihedralPairConstraint::func( Real const theta ) const {
357  return func_->func( theta );
358 }
359 
360 Real
361 DihedralPairConstraint::dfunc( Real const theta ) const {
362  return func_->dfunc( theta );
363 }
364 
365 } // constraints
366 } // scoring
367 } // core