Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DecomposeAndReweightEnergiesCalculator.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 protocols/toolbox/PoseMetricCalculators/DecomposeAndReweightEnergiesCalculator.cc
11 /// @brief DecomposeAndReweightEnergiesCalculator class
12 /// @author Colin A. Smith
13 
14 // Unit headers
16 
17 // project headers
18 #include <core/pose/Pose.hh>
20 #include <core/scoring/Energies.hh>
23 // AUTO-REMOVED #include <core/scoring/ScoreTypeManager.hh>
24 #include <core/scoring/methods/Methods.hh> //for long range energies
25 #include <core/scoring/LREnergyContainer.hh> //long range energies
26 #include <basic/MetricValue.hh>
27 #include <basic/Tracer.hh>
28 
29 // Utility headers
30 #include <utility/exit.hh>
31 #include <utility/string_util.hh>
32 
33 // ObjexxFCL headers
34 #include <ObjexxFCL/format.hh>
35 
36 // C++ headers
37 #include <cassert>
38 
39 #include <utility/vector1.hh>
40 #include <set>
41 
42 
43 using namespace core;
44 using namespace core::pose;
45 using namespace core::pose::metrics;
46 using namespace utility;
47 using namespace ObjexxFCL::fmt;
48 
49 namespace protocols{
50 namespace toolbox {
51 namespace pose_metric_calculators {
52 
53 
54 // preferred constructor - use an existing InterfaceNeighborDefinitionCalculator
55 DecomposeAndReweightEnergiesCalculator::DecomposeAndReweightEnergiesCalculator( std::string const & NameOfResidueDecompositionCalculator ) :
57  name_of_ResidueDecompositionCalculator_(NameOfResidueDecompositionCalculator)
58 {
60  basic::Error() << "Tried to tie DecomposeAndReweightEnergiesCalculator to ResidueDecompositionCalculator " <<
61  name_of_ResidueDecompositionCalculator_ << " but this calculator does not exist." << std::endl;
62  utility_exit();
63  }
64 }
65 
68 ) :
70  name_of_ResidueDecompositionCalculator_(calculator.residue_decomposition_calculator()),
71  original_weights_(calculator.original_weights()),
72  other_energies_(calculator.other_energies()),
73  onebody_energies_(calculator.onebody_energies()),
74  twobody_energies_(calculator.twobody_energies()),
75  set_names_(calculator.set_names()),
76  weighted_total_(calculator.weighted_total())
77 {}
78 
79 void DecomposeAndReweightEnergiesCalculator::lookup( std::string const & key, basic::MetricValueBase * valptr ) const {
80 
81  if ( key == "weighted_total" ) {
82  basic::check_cast( valptr, &weighted_total_, "weighted_total expects to return a Real" );
83  (static_cast<basic::MetricValue<Real> *>(valptr))->set( weighted_total_ );
84 
85  } else if ( key == "master_weight_vector" ) {
86  utility::vector1<core::Real> const master_weight_vector_copy(master_weight_vector());
87  basic::check_cast( valptr, &master_weight_vector_copy, "master_weight_vector expects to return a utility::vector1< core::Real >" );
88  (static_cast<basic::MetricValue<utility::vector1<core::Real> > *>(valptr))->set( master_weight_vector_copy );
89 
90  } else if ( key == "weighted_total_vector" ) {
91  utility::vector1<core::Real> const weighted_total_vector_copy(weighted_total_vector());
92  basic::check_cast( valptr, &weighted_total_vector_copy, "weighted_total_vector expects to return a utility::vector1< core::Real >" );
93  (static_cast<basic::MetricValue<utility::vector1<core::Real> > *>(valptr))->set( weighted_total_vector_copy );
94 
95  } else if ( key == "weighted_total_no_master_vector" ) {
96  utility::vector1<core::Real> const weighted_total_no_master_vector_copy(weighted_total_no_master_vector());
97  basic::check_cast( valptr, &weighted_total_no_master_vector_copy, "weighted_total_no_master_vector expects to return a utility::vector1< core::Real >" );
98  (static_cast<basic::MetricValue<utility::vector1<core::Real> > *>(valptr))->set( weighted_total_no_master_vector_copy );
99 
100  } else if ( key == "summary" ) {
101  std::ostringstream sstream;
102  show(sstream);
103  std::string const & summary(sstream.str());
104  basic::check_cast( valptr, &summary, "summary expects to return a std::string" );
105  (static_cast<basic::MetricValue<std::string> *>(valptr))->set( summary );
106 
107  } else {
108  basic::Error() << "DecomposeAndReweightEnergiesCalculator cannot compute the requested metric " << key << std::endl;
109  utility_exit();
110  }
111 }
112 
113 
115 
116  if ( key == "weighted_total" ) {
117  return utility::to_string( weighted_total_ );
118  } else if ( key == "master_weight_vector" ) {
119  utility::vector1<core::Real> const master_weight_vector_copy(master_weight_vector());
120  std::ostringstream sstream;
121  sstream << "[";
122  for (core::Size i = 1; i <= master_weight_vector_copy.size(); ++i) {
123  if (i > 1) sstream << ", ";
124  sstream << master_weight_vector_copy[i];
125  }
126  sstream << "]";
127  return sstream.str();
128  } else if ( key == "weighted_total_vector" ) {
129  utility::vector1<core::Real> const weighted_total_vector_copy(weighted_total_vector());
130  std::ostringstream sstream;
131  sstream << "[";
132  for (core::Size i = 1; i <= weighted_total_vector_copy.size(); ++i) {
133  if (i > 1) sstream << ", ";
134  sstream << weighted_total_vector_copy[i];
135  }
136  sstream << "]";
137  return sstream.str();
138  } else if ( key == "weighted_total_no_master_vector" ) {
139  utility::vector1<core::Real> const weighted_total_no_master_vector_copy(weighted_total_no_master_vector());
140  std::ostringstream sstream;
141  sstream << "[";
142  for (core::Size i = 1; i <= weighted_total_no_master_vector_copy.size(); ++i) {
143  if (i > 1) sstream << ", ";
144  sstream << weighted_total_no_master_vector_copy[i];
145  }
146  sstream << "]";
147  return sstream.str();
148  } else if ( key == "summary" ) {
149  std::ostringstream sstream;
150  show(sstream);
151  return sstream.str();
152  }
153 
154  basic::Error() << "This Calculator cannot compute metric " << key << std::endl;
155  utility_exit();
156  return "";
157 
158 }
159 
160 void
162  Pose const & this_pose
163 )
164 {
165  runtime_assert(this_pose.energies().energies_updated());
166 
167  basic::MetricValue<utility::vector1<std::set<core::Size> > > residue_decomposition_value;
168  basic::MetricValue<utility::vector1<core::Size> > residue_set_numbers_value;
169  basic::MetricValue<utility::vector1<std::string > > set_names_value;
170  this_pose.metric(name_of_ResidueDecompositionCalculator_, "residue_decomposition", residue_decomposition_value);
171  this_pose.metric(name_of_ResidueDecompositionCalculator_, "residue_set_numbers", residue_set_numbers_value);
172  this_pose.metric(name_of_ResidueDecompositionCalculator_, "set_names", set_names_value);
173  utility::vector1<std::set<core::Size> > const & residue_decomposition(residue_decomposition_value.value());
174  utility::vector1<core::Size> const & residue_set_numbers(residue_set_numbers_value.value());
175  set_names_ = set_names_value.value();
176  runtime_assert(residue_set_numbers.size() == this_pose.total_residue());
177 
178  core::Size num_sets_from_decomposition = residue_decomposition.size();
179  // if num_sets is 0, set num_sets to be the size of the decomposition
180  if (num_sets() == 0) num_sets(num_sets_from_decomposition);
181  // make sure the weight vector and weight graph are the right size
182  runtime_assert(onebody_energies_.size() == num_sets_from_decomposition &&
183  twobody_energies_.num_vertices() == num_sets_from_decomposition);
184 
185  clear_energies();
186 
187  // add one body energies to the correct one body location
188  for (core::Size i = 1; i <= this_pose.total_residue(); ++i) {
189  core::Size const set_num(residue_set_numbers[i]);
190  if (set_num) onebody_energies_[set_num].energy_map() += this_pose.energies().onebody_energies(i);
191  }
192 
193  core::scoring::EnergyGraph const & energy_graph(this_pose.energies().energy_graph());
194 
195  // add two body energies to the correct one body or two body locations
196  for (core::graph::Graph::EdgeListConstIter iter = energy_graph.const_edge_list_begin();
197  iter != energy_graph.const_edge_list_end(); ++iter) {
198  core::scoring::EnergyEdge const * const energy_edge = static_cast<core::scoring::EnergyEdge const *>(*iter);
199  core::Size const first_set_num(residue_set_numbers[energy_edge->get_first_node_ind()]);
200  core::Size const second_set_num(residue_set_numbers[energy_edge->get_second_node_ind()]);
201  // only place the energies if both residues in a set
202  if (first_set_num && second_set_num) {
203  if (first_set_num == second_set_num) {
204  // add two body energies between residues in the same set to the one body energy for that set
205  energy_edge->add_to_energy_map( onebody_energies_[first_set_num].energy_map() );
206  } else {
207  // add two body energies between residues in different sets to the EnergyEdge between those sets
208  energy_edge->add_to_energy_map( twobody_energies_.get_edge(first_set_num, second_set_num)->data().energy_map() );
209  }
210  }
211  }
212 
213  // add long range two body energies to the correct onebody or twobody locations
214  for( Size lr = 1; lr <= scoring::methods::n_long_range_types; lr++){
216  scoring::LREnergyContainerCOP lrec = this_pose.energies().long_range_container( lr_type );
217  if( !lrec ) continue;
218  if( lrec->empty() ) continue;
219 
220  // iterate over all residues
221  for (core::Size i = 1; i <= this_pose.total_residue(); ++i) {
222  core::Size const first_set_num(residue_set_numbers[i]);
223  if (!first_set_num) continue;
224  // iterate over all neighbors of the residue
225  for (core::scoring::ResidueNeighborConstIteratorOP rni = lrec->const_upper_neighbor_iterator_begin(i);
226  *rni != *( lrec->const_upper_neighbor_iterator_end(i) ); ++(*rni) ) {
227  core::Size const second_set_num(residue_set_numbers[rni->upper_neighbor_id()]);
228  // only place the energies if both residues both part of a set
229  if (!second_set_num) continue;
230  if (first_set_num == second_set_num) {
231  // add two body energies between residues in the same set to the one body energy for that set
232  rni->accumulate_energy(onebody_energies_[first_set_num].energy_map());
233  } else {
234  // add two body energies between residues in different sets to the EnergyEdge between those sets
235  rni->accumulate_energy(twobody_energies_.get_edge(first_set_num, second_set_num)->data().energy_map());
236  }
237  }
238  }
239  }
240 
242 
243  // subtract out the one body and two body energies from other_energies_
244  core::Size nc = num_components();
245  for (core::Size i = 2; i <= nc; ++i) {
247  }
248 
249  original_weights_ = this_pose.energies().weights();
251 
253 }
254 
257 {
258  return onebody_energies_.size();
259 }
260 
261 void
263 
264  onebody_energies_.resize(num_sets);
265 
266  // avoid destruction of edges if the graphs are already the correct size
268 
269  for (core::Size i = 1; i < twobody_energies_.num_vertices(); ++i) {
270  for (core::Size j = i+1; j <= twobody_energies_.num_vertices(); ++j) {
271  if (!twobody_energies_.edge_exists(i, j)) {
273  }
274  }
275  }
276 }
277 
280 {
281  return 1+(num_sets()+1)*num_sets()/2;
282 }
283 
284 EnergiesData const &
286  core::Size index
287 ) const
288 {
289  runtime_assert(index >= 1 && index <= num_components());
290 
291  if (index == 1) return other_energies_;
292  --index;
293 
294  if (index <= onebody_energies_.size()) return onebody_energies_[index];
295  index -= onebody_energies_.size();
296 
297  core::Size set1;
298  for (set1 = 1; index > num_sets() - set1; ++set1) {
299  index -= num_sets() - set1;
300  }
301  core::Size set2 = set1+index;
302  return twobody_energies_.get_vertex(set1).get_edge(set2)->data();
303 }
304 
305 EnergiesData &
307  core::Size index
308 )
309 {
310  runtime_assert(index >= 1 && index <= num_components());
311 
312  if (index == 1) return other_energies_;
313  --index;
314 
315  if (index <= onebody_energies_.size()) return onebody_energies_[index];
316  index -= onebody_energies_.size();
317 
318  core::Size set1;
319  for (set1 = 1; index > num_sets() - set1; ++set1) {
320  index -= num_sets() - set1;
321  }
322  core::Size set2 = set1+index;
323  return twobody_energies_.get_vertex(set1).get_edge(set2)->data();
324 }
325 
328 {
330 
331  for (core::Size i = 1; i <= master_weight_vector.size(); ++i) {
332  master_weight_vector[i] = component(i).master_weight();
333  }
334 
335  return master_weight_vector;
336 }
337 
338 void
340  utility::vector1<core::Real> const & master_weight_vector
341 )
342 {
343  // determine the number sets that the vector corresponds to
344  core::Size num_sets_for_vector = static_cast<core::Size> (floor(sqrt(float((master_weight_vector.size()-1)*2))));
345  // apply the reverse mapping to make sure it is the correct length
346  runtime_assert(master_weight_vector.size() == 1+(num_sets_for_vector+1)*num_sets_for_vector/2);
347  // if num_sets is 0, set num_sets to be the size of the vector
348  if (num_sets() == 0) num_sets(num_sets_for_vector);
349  // make sure that the vector and num_sets are are compatible
350  runtime_assert(num_sets() == num_sets_for_vector);
351 
352  for (core::Size i = 1; i <= master_weight_vector.size(); ++i) {
353  component(i).master_weight(master_weight_vector[i]);
354  }
355 }
356 
359 {
361 
362  names_vec.push_back("Other");
363 
364  names_vec.insert(names_vec.end(), set_names_.begin(), set_names_.end());
365 
366  for (core::Size i = 1; i < set_names_.size(); ++i) {
367  for (core::Size j = i+1; j <= set_names_.size(); ++j) {
368  names_vec.push_back(set_names_[i]+"-"+set_names_[j]);
369  }
370  }
371 
372  return names_vec;
373 }
374 
377 {
378  utility::vector1<core::scoring::EnergyMap> weighted_energy_map_vector_result(num_components());
379 
380  for (core::Size i = 1; i <= weighted_energy_map_vector_result.size(); ++i) {
381  weighted_energy_map_vector_result[i] = component(i).weighted_energy_map();
382  }
383 
384  return weighted_energy_map_vector_result;
385 }
386 
389 {
390  utility::vector1<core::Real> weighted_total_vector_result(num_components());
391 
392  for (core::Size i = 1; i <= weighted_total_vector_result.size(); ++i) {
393  weighted_total_vector_result[i] = component(i).weighted_total_no_master();
394  }
395 
396  return weighted_total_vector_result;
397 }
398 
401 {
402  utility::vector1<core::Real> weighted_total_vector_result(num_components());
403 
404  for (core::Size i = 1; i <= weighted_total_vector_result.size(); ++i) {
405  weighted_total_vector_result[i] = component(i).weighted_total();
406  }
407 
408  return weighted_total_vector_result;
409 }
410 
413 {
415 
416  for (core::Size i = 1; i <= weight_map_vector.size(); ++i) {
417  weight_map_vector[i] = component(i).weight_map();
418  }
419 
421 
422  for (int i = 1; i < core::scoring::n_score_types; ++i) {
423  for (core::Size j = 1; j < weight_map_vector.size(); ++j) {
424  if (weight_map_vector[j][core::scoring::ScoreType(i)]) {
425  score_types.push_back(core::scoring::ScoreType(i));
426  break;
427  }
428  }
429  }
430 
431  return score_types;
432 }
433 
434 void
436  std::ostream & out
437 ) const
438 {
441  utility::vector1<core::Real> const weighted_total_vec(weighted_total_vector());
442  utility::vector1<std::string> const names_vec(names_vector());
443 
444  out << "------------------------";
445  for (core::Size i = 1; i <= names_vec.size(); ++i) out << "---------";
446  out << "---------" << std::endl;
447 
448  out << LJ(24,"Score Type");
449  for (core::Size i = 1; i <= names_vec.size(); ++i) out << RJ(9,names_vec[i]);
450  out << RJ(9,"Total") << std::endl;
451 
452  out << "------------------------";
453  for (core::Size i = 1; i <= names_vec.size(); ++i) out << "---------";
454  out << "---------" << std::endl;
455 
456  for (core::Size i = 1; i <= score_types.size(); ++i) {
457  core::Real total = 0;
458  out << LJ(24,score_types[i]);
459  for (core::Size j = 1; j <= weighted_energy_map_vec.size(); ++j) {
460  out << F(9,3, weighted_energy_map_vec[j][score_types[i]]);
461  total += weighted_energy_map_vec[j][score_types[i]];
462  }
463  out << F(9,3, total) << std::endl;
464  }
465 
466  out << "------------------------";
467  for (core::Size i = 1; i <= names_vec.size(); ++i) out << "---------";
468  out << "---------" << std::endl;
469 
470  out << LJ(24,"Total");
471  for (core::Size i = 1; i <= weighted_total_vec.size(); ++i) out << F(9,3, weighted_total_vec[i]);
472  out << F(9,3, weighted_total_) << std::endl;
473 }
474 
475 void
477 {
478  core::Size nc = num_components();
479  for (core::Size i = 1; i <= nc; ++i) {
480  component(i).energy_map().clear();
481  }
482 
483  weighted_total_ = 0;
484 }
485 
486 void
488 {
489  core::Size nc = num_components();
490  for (core::Size i = 1; i <= nc; ++i) {
491  EnergiesData & this_component(component(i));
492  if (this_component.use_original_weights()) this_component.weight_map(original_weights_);
493  }
494 }
495 
496 void
498 {
499  weighted_total_ = 0;
500 
501  core::Size nc = num_components();
502  for (core::Size i = 1; i <= nc; ++i) {
504  }
505 }
506 
507 
508 } // PoseMetricCalculators
509 } // toolbox
510 } // protocols