Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AtomPairConstraint.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/constraints/AtomPairConstraint.cc
11 ///
12 /// @brief
13 /// @author Oliver Lange
14 
15 // Unit Headers
17 
18 // Package Headers
21 
22 // Project Headers
25 #include <core/id/NamedAtomID.hh>
26 #include <core/id/AtomID.hh>
27 #include <core/pose/Pose.hh>
28 #include <core/pose/util.hh>
30 // Utility Headers
31 #include <basic/Tracer.hh>
32 
33 // Numeric Headers
34 #include <numeric/deriv/distance_deriv.hh>
35 
36 //Auto Headers
41 #include <utility/vector1.hh>
42 
43 
44 static basic::Tracer tr("core.io.constraints");
45 
46 
47 namespace core {
48 namespace scoring {
49 namespace constraints {
50 
53 
54 ///
55 void
56 AtomPairConstraint::score( XYZ_Func const & xyz, EnergyMap const &, EnergyMap & emap ) const
57 {
58  Real const score_val = score( xyz( atom1_ ), xyz( atom2_ ) );
59  emap[ this->score_type() ] += score_val;
60 }
61 
62 ///
63 Real
65  Vector const & xyz1,
66  Vector const & xyz2
67  ) const
68 {
69  // std::cout << "score " << atom1_ << ' ' << atom2_ << ' ' << xyz1.distance( xyz2 ) << " --> " << func( xyz1.distance( xyz2 ) ) << std::endl;;
70  return func( xyz1.distance( xyz2 ) );
71 }
72 
73 /// @brief Copies the data from this Constraint into a new object and returns an OP
74 /// atoms are mapped to atoms with the same name in dest pose ( e.g. for switch from centroid to fullatom )
75 /// if a sequence_mapping is present it is used to map residue numbers .. NULL = identity mapping
76 /// to the new object. Intended to be implemented by derived classes.
78  id::NamedAtomID atom1( atom_id_to_named_atom_id( atom(1), src ) );
79  id::NamedAtomID atom2( atom_id_to_named_atom_id( atom(2), src ) );
80 
81  if ( smap ) {
82  atom1.rsd() = (*smap)[ atom1_.rsd() ];
83  atom2.rsd() = (*smap)[ atom2_.rsd() ];
84  }
85 
86  if ( atom1.rsd() == 0 || atom2.rsd() == 0 ) return NULL;
87 
88  //get AtomIDs for target pose
89  id::AtomID id1( named_atom_id_to_atom_id( atom1, dest ) );
90  id::AtomID id2( named_atom_id_to_atom_id( atom2, dest ) );
91  if ( id1.valid() && id2.valid() ) {
92  return new AtomPairConstraint( id1, id2, func_, score_type() );
93  } else {
94  return NULL;
95  }
96 }
97 
98 bool
99 AtomPairConstraint::operator == ( Constraint const & other_cst ) const
100 {
101  if( !dynamic_cast< AtomPairConstraint const * > ( &other_cst ) ) return false;
102 
103  AtomPairConstraint const & other( static_cast< AtomPairConstraint const & > (other_cst) );
104 
105  if( atom1_ != other.atom1_ ) return false;
106  if( atom2_ != other.atom2_ ) return false;
107  if( func_ != other.func_ ) return false;
108  if( this->score_type() != other.score_type() ) return false;
109 
110  return true;
111 }
112 
113 void AtomPairConstraint::show( std::ostream& out ) const {
114  out << "AtomPairConstraint ("
115  << atom1_.atomno() << "," << atom1_.rsd() << "-"
116  << atom2_.atomno() << "," << atom2_.rsd() << ")" << std::endl;
117  func_->show( out );
118 }
119 
120 void AtomPairConstraint::show_def( std::ostream& out, pose::Pose const& pose ) const {
121  out << type() << " " << atom_id_to_named_atom_id( atom1_, pose ) << " " << atom_id_to_named_atom_id( atom2_, pose ) << " ";
122  func_->show_definition( out );
123 }
124 
125 Real
126 AtomPairConstraint::dist( pose::Pose const & pose ) const {
127  return dist( pose.conformation() );
128 }
129 
131  conformation::Residue const& res1( conformation.residue( atom1_.rsd() ) );
132  conformation::Residue const& res2( conformation.residue( atom2_.rsd() ) );
133  bool fail( false );
134  if ( atom1_.atomno() == 0 || atom1_.atomno() > res1.natoms() ) {
135  std::cerr << "AtomPairConstraint: atom1 out of bounds" << atom1_ << std::endl;
136  fail = true;
137  }
138  if ( atom2_.atomno() == 0 || atom2_.atomno() > res2.natoms() ) {
139  std::cerr << "AtomPairConstraint: atom2 out of bounds" << atom2_ << std::endl;
140  fail = true;
141  }
142  assert( conformation.atom_tree().has( atom1_ ) );
143  assert( conformation.atom_tree().has( atom2_ ) );
144 
145  if ( !conformation.atom_tree().has( atom1_ ) ) {
146  std::cerr << "AtomPairConstraint: cannot find atom " << atom1_ << std::endl;
147  }
148  if ( !conformation.atom_tree().has( atom2_ ) ) {
149  std::cerr << "AtomPairConstraint: cannot find atom " << atom2_ << std::endl;
150  }
151  assert( !fail );
152  Vector const & xyz1( conformation.xyz( atom1_ ) ), xyz2( conformation.xyz( atom2_ ) );
153  Vector const f2( xyz1 - xyz2 );
154  Real const dist( f2.length() );
155  return dist;
156 }
157 
159  assert( atom1_.atomno() );
160  assert( atom2_.atomno() );
161  return xyz( atom1_ ).distance( xyz( atom2_ ) );
162 }
163 
165  std::ostream& out,
166  pose::Pose const& pose,
167  Size verbose_level,
168  Real threshold
169 ) const {
170 
171  if ( verbose_level > 80 ) {
172  out << "AtomPairConstraint ("
173  << pose.residue_type(atom1_.rsd() ).atom_name( atom1_.atomno() ) << ":"
174  << atom1_.atomno() << "," << atom1_.rsd() << "-"
175  << pose.residue_type(atom2_.rsd() ).atom_name( atom2_.atomno() ) << ":"
176  << atom2_.atomno() << "," << atom2_.rsd() << ") ";
177  }
178  if ( verbose_level > 120 ) { //don't ask but I had a really weird bug to track down!
179  conformation::Conformation const & conformation( pose.conformation() );
180  Vector const & xyz1( conformation.xyz( atom1_ ) ), xyz2( conformation.xyz( atom2_ ) );
181  out << "\ncoords1: " << xyz1[ 1 ] << " " << xyz1[ 2 ] << " " << xyz1[ 3 ] << " --- ";
182  out << "coords1: " << xyz2[ 1 ] << " " << xyz2[ 2 ] << " " << xyz2[ 3 ] << "\n";
183  }
184 
185  return func_->show_violations( out, dist( pose ), verbose_level, threshold );
186 }
187 
188 // atom deriv
189 void
191  AtomID const & atom,
192  XYZ_Func const & xyz,
193  Vector & F1,
194  Vector & F2,
195  EnergyMap const & weights
196 ) const
197 {
198  AtomID other_atom;
199  if ( atom == atom1_ ) other_atom = atom2_;
200  else if ( atom == atom2_ ) other_atom = atom1_;
201  else {
202  // std::cout << "Error in AtomPairConstraint::fill_f1_f2()" << std::endl;
203  // std::cout << "Bad AtomID: (" << atom.rsd() << ", " << atom.atomno() << ") -- options: (";
204  // std::cout << atom1_.rsd() << ", " << atom1_.atomno() << ") and (";
205  // std::cout << atom2_.rsd() << ", " << atom2_.atomno() << ");" << std::endl;
206  return;
207  }
208 
209  //Vector const & xyz1( conformation.xyz( atom ) ), xyz2( conformation.xyz( other_atom ) );
210 
211  /*
212  Vector const f2( xyz1 - xyz2 );
213  Real const dist( f2.length() ), deriv( dfunc( dist ) );
214  if ( deriv != 0.0 && dist != 0.0 ) {
215  Vector const f1( xyz1.cross( xyz2 ) );
216  F1 += ( ( deriv / dist ) * f1 ) * weights[ this->score_type() ];
217  F2 += ( ( deriv / dist ) * f2 ) * weights[ this->score_type() ];
218  }*/
219 
220  Real dist(0.0);
221  Vector f1(0.0), f2(0.0);
222  numeric::deriv::distance_f1_f2_deriv( xyz( atom ), xyz( other_atom ), dist, f1, f2 );
223  Real wderiv( weights[ this->score_type() ] * dfunc( dist ));
224  F1 += wderiv * f1;
225  F2 += wderiv * f2;
226 
227 }
228 
231 {
232  if ( seqmap[atom1_.rsd()] != 0 && seqmap[atom2_.rsd()] != 0 ) {
233  AtomID remap_a1( atom1_.atomno(), seqmap[atom1_.rsd()] ),
234  remap_a2( atom2_.atomno(), seqmap[atom2_.rsd()] );
235  return ConstraintOP( new AtomPairConstraint( remap_a1, remap_a2, this->func_ ) );
236  } else {
237  return NULL;
238  }
239 }
240 
241 ///@details one line definition "AtomPairs atom1 res1 atom2 res2 function_type function_definition"
242 void
244  std::istream & data,
245  core::pose::Pose const & pose,
246  FuncFactory const & func_factory
247 ) {
248  Size res1, res2;
249  std::string tempres1, tempres2;
250  std::string name1, name2;
251  std::string func_type;
253 
254  data
255  >> name1 >> tempres1
256  >> name2 >> tempres2
257  >> func_type;
258 
259  ConstraintIO::parse_residue( pose, tempres1, res1 );
260  ConstraintIO::parse_residue( pose, tempres2, res2 );
261 
262  tr.Debug << "read: " << name1 << " " << name2 << " " << res1 << " " << res2 << " func: " << func_type << std::endl;
263  if ( res1 > pose.total_residue() || res2 > pose.total_residue() ) {
264  tr.Warning << "ignored constraint (requested residue numbers exceed numbers of residues in pose): " << "Total in Pose: " << pose.total_residue() << " "
265  << name1 << " " << name2 << " " << res1 << " " << res2 << std::endl;
266  data.setstate( std::ios_base::failbit );
267  return;
268  }
269 
270  if ( name1 == "H" && res1 == 1 && pose.is_fullatom() ) name1 = "1H";
271  if ( name2 == "H" && res2 == 1 && pose.is_fullatom() ) name2 = "1H";
272 
273  atom1_ = named_atom_id_to_atom_id( id::NamedAtomID( name1, res1 ), pose );
274  atom2_ = named_atom_id_to_atom_id( id::NamedAtomID( name2, res2 ), pose );
275 
276  if ( atom1_.atomno() == 0 || atom2_.atomno() == 0 ) {
277  tr.Warning << "Error reading atoms: read in atom names("
278  << name1 << "," << name2 << "), "
279  << "and found AtomIDs (" << atom1_ << "," << atom2_ << ")" << std::endl;
280  data.setstate( std::ios_base::failbit );
281  runtime_assert( false );
282  return;
283  }
284 
285  func_ = func_factory.new_func( func_type );
286  func_->read_data( data );
287 
288  if ( data.good() ) {
289  //chu skip the rest of line since this is a single line defintion.
290  while( data.good() && (data.get() != '\n') ) {}
291  if ( !data.good() ) data.setstate( std::ios_base::eofbit );
292  }
293 
294  if ( tr.Debug.visible() ) {
295  func_->show_definition( tr.Debug );
296  tr.Debug << std::endl;
297  }
298  runtime_assert( atom1_.valid() && atom2_.valid() );
299 } // read_def
300 
303  return sp.dist( atom1_.rsd(), atom2_.rsd() );
304 }
305 
306 } // constraints
307 } // scoring
308 } // core