Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EnergyGraph.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/EnergyGraph.cc
11 /// @brief Energy graph class implementation
12 /// @author Andrew Leaver-Fay (leaverfa@email.unc.edu)
13 
14 // Unit Headers
16 
17 // Boost Headers
19 
20 #include <iostream>
21 
22 #include <utility/vector1.hh>
23 #include <boost/pool/pool.hpp>
24 
25 
26 namespace core {
27 namespace scoring {
28 
29 using namespace graph;
30 
31 ///////// Energy Node Class /////////////
32 
33 EnergyNode::EnergyNode( Graph * owner, Size index ) :
34  parent( owner, index )//, moved_( false )
35 {}
36 
38 
39 
40 void EnergyNode::print() const
41 {
42  std::cout << "EnergyNode::print() deferring to parent::print()" << std::endl;
43  parent::print();
44 }
45 
46 /// @brief copy mmember data from source node
47 ///
48 /// invoked by copy ctor and operator= methods from Graph base class
49 void EnergyNode::copy_from( parent const * source )
50 {
51  //EnergyNode const * en_source = utility::down_cast< EnergyNode const * > ( source ); //nothing to copy, still -- want to assert the dynamic cast
52  EnergyNode const * en_source = static_cast< EnergyNode const * > ( source );
53  moved_ = en_source->moved_;
54 }
55 
57 {
58  return sizeof ( EnergyNode );
59 }
60 
62 {
63  Size tot = 0;
64  tot += parent::count_dynamic_memory(); //recurse to parent
65  return tot;
66 }
67 
68 bool EnergyNode::moved() const { return moved_; }
69 void EnergyNode::moved( bool setting ) { moved_ = setting; }
70 
71 
72 ///////// Energy Edge Class /////////////
73 
74 /// @brief Energy edge ctor
75 ///
76 /// when first added to the graph, sets its enegies_not_yet_computed_ to true
77 /// the responsibility of marking the energies as having been computed falls on
78 /// class ScoringFunction
80  EnergyGraph * owner,
81  Size n1,
82  Size n2
83 ) :
84  parent( owner, n1, n2 ),
85  energies_not_yet_computed_( true ),
86  dsqr_( 0.0 ),
87  array_( get_energy_owner()->array_pool().new_array() )
88 {}
89 
91  EnergyGraph * owner,
92  EnergyEdge const & example_edge
93 )
94 :
95  parent( owner, example_edge.get_first_node_ind(), example_edge.get_second_node_ind() ),
96  energies_not_yet_computed_( example_edge.energies_not_yet_computed_ ),
97  //energy_map_( example_edge.energy_map_ )//,
98  dsqr_( example_edge.dsqr_ ),
99  array_( get_energy_owner()->array_pool().new_array() )
100 {
101  array_.copy_array_contents( example_edge.array_ );
102 }
103 
104 /// @brief virtual dstor; The EnergyEdge must free the array pool element it
105 /// holds before it disappears.
107 {
109 }
110 
111 /// @brief copies data from EnergyEdge const * source;
112 ///
113 /// called from the copy ctor and operator= methods defined in the Graph base class
114 void EnergyEdge::copy_from( parent const * source )
115 {
116  EnergyEdge const * ee = static_cast< EnergyEdge const * > ( source );
117  // down_cast is *supposed* to assert the dynamic cast in debug builds; doesn't work for some reason
118  //EnergyEdge const * ee = utility::down_cast< EnergyEdge const * > ( source );
120  dsqr_ = ee->dsqr_;
122  return;
123 }
124 
125 
126 /// @brief set energies_computed_ to true for an edge
128 
129 /// @brief set energies_computed_ to false for an edge
130 ///
131 /// this function would allow edges to be marked as dirty without deleting
132 /// it from the graph. Currently, edges are not marked as dirty; they are simply
133 /// deleted (and if still needed) returned to the graph. If edge addition and
134 /// deletion starts to show up as a hotspot, we will examine if simply marking
135 /// edges as dirty is faster. For now, this function is not used.
137 
138 /// @brief virtual call to determine the static size of an Edge object
139 /// dynamic memory use is counted through the recursive count_dynamic_memory()
140 /// calling path
142 {
143  return sizeof ( EnergyEdge );
144 }
145 
146 /// @brief virtual call to determine the amount of dynamic memory allocated by
147 /// an edge; this function must recurse to the parent class to determine how
148 /// much memory the parent class is responsible for. Do not account for
149 /// the size of the ArrayPool array here; instead, that is accounted for in
150 /// the EnergyGraph::count_dynamic_memory method.
152 {
153  Size tot = 0;
154  tot += parent::count_dynamic_memory(); //recurse to parent
155  return tot;
156 }
157 
158 
159 ///////// Energy Graph Class /////////////
160 
162 {
163  Edge * edge( find_edge( n1, n2 ) );
164  if ( edge ) {
165  return static_cast< EnergyEdge * > ( edge );
166  //return utility::down_cast< EnergyEdge * > ( edge );
167  } else {
168  return 0;
169  }
170 }
171 
173 {
174  Edge const * edge( find_edge( n1, n2 ) );
175  if ( edge ) {
176  return static_cast< EnergyEdge const * > ( edge );
177  //return utility::down_cast< EnergyEdge const * > ( edge );
178  } else {
179  return 0;
180  }
181 }
182 
183 
185 :
186  parent(),
187  energy_edge_pool_( new boost::unordered_object_pool< EnergyEdge > ( 256 ) ),
188  energy_array_pool_( 256 ),
189  score_type_2_active_( n_shortranged_2b_score_types, -1 )
190 {}
191 
192 /// @details This does not call the base class parent( Size ) constructor since
193 /// that produces calls to the polymorphic function create_new_node() and polymorphism
194 /// does not work during constructor intialization.
196 :
197  parent(),
198  energy_edge_pool_( new boost::unordered_object_pool< EnergyEdge > ( 256 ) ),
199  energy_array_pool_( 256 ),
200  score_type_2_active_( n_shortranged_2b_score_types, -1 )
201 {
202  set_num_nodes( num_nodes );
203 }
204 
205 /// @details Notice that this does not call the parent( src ) copy constructor.
206 /// This is because the copy constructor relies on polymorphic functions which
207 /// are unavailable during the Graph constructor. Instead, this function waits
208 /// until parent construction is complete, and relies on the assigmnent operator.
210 :
211  parent( ),
212  energy_edge_pool_( new boost::unordered_object_pool< EnergyEdge > ( 256 ) ),
213  energy_array_pool_( 256 ),
214  score_type_2_active_( n_shortranged_2b_score_types, -1 )
215 {
217  parent::operator = ( src );
218 }
219 
223 }
224 
225 void
227  Size index1,
228  Size index2,
229  DistanceSquared dsq
230 )
231 {
232  Edge* newedge = add_edge( index1, index2 );
233  (static_cast< EnergyEdge * > (newedge))->square_distance( dsq );
234 }
235 
236 //void
237 //EnergyGraph::add_energy_edge(
238 // Size index1,
239 // Size index2,
240 // EnergyMap const & emap
241 //)
242 //{
243 // Edge * newedge = add_edge( index1, index2 );
244 // (static_cast< EnergyEdge * > ( newedge ))->store_active_energies( emap );
245 //}
246 
247 
248 /// @brief assignment operator -- performs a deep copy
249 EnergyGraph const &
251 {
253  parent::operator = ( rhs );
254  return *this;
255 }
256 
257 /// @details The array pool only needs to be resized if the number
258 /// of active score types has changed; it doesn't have to be
259 /// resized if the actual active types have changed but the number
260 /// of active score types has remained constant. However, if either
261 /// the number or the identity of the active score types have changed,
262 /// then all old edges in the EnergyGraph should be dropped.
263 /// The input array "active" must be sorted.
264 bool
266 {
267  for ( Size ii = 1; ii < active.size(); ++ii ) {
268  assert( active[ ii ] < active[ ii + 1 ] );
269  }
270  bool clear_edges = false;
271  if ( active.size() != active_2b_score_types_.size() ) clear_edges = true;
272 
273  bool const resize_array_pool = clear_edges;
274 
275  //ScoreTypes sactive = active;
276  //std::sort( sactive.begin(), sactive.end() );
277  if ( ! clear_edges ) {
278  for ( Size ii = 1; ii <= active.size(); ++ii ) {
279  if ( active_2b_score_types_[ ii ] != active[ ii ] ) {
280  clear_edges = true;
281  break;
282  }
283  }
284  }
285 
286  if ( clear_edges ) {
287  drop_all_edges();
288  /// Update the mapping between active score types and their positions in the ArrayPoolElement arrays.
289  active_2b_score_types_ = active;
290  std::fill( score_type_2_active_.begin(), score_type_2_active_.end(), -1 );
291  int count_active( 0 );
292  for ( Size ii = 1; ii <= active_2b_score_types_.size(); ++ii ) {
293  score_type_2_active_[ active_2b_score_types_[ ii ] ] = count_active;
294  ++count_active;
295  }
296  }
297 
298  if ( resize_array_pool ) {
299  energy_array_pool_.set_array_size( active.size() );
300  }
301 
302  return ! clear_edges;
303 }
304 
306 {
307  assert( dynamic_cast< EnergyEdge* > (edge) );
308  energy_edge_pool_->destroy( static_cast< EnergyEdge* > (edge) );
309 }
310 
313 )
314 {
316 }
317 
319 {
320  return sizeof ( EnergyGraph );
321 }
322 
324 {
326  tot += parent::count_dynamic_memory(); //recurse to parent
327  return tot;
328 }
329 
330 /// @brief Factory method for node creation
331 Node*
333 {
334  return new EnergyNode( this, index );
335 }
336 
337 /// @brief Factory method for edge creation
338 Edge*
340 {
341  return energy_edge_pool_->construct( this, index1, index2 );
342 }
343 
344 /// @brief Factory copy-constructor method for edge creation
345 Edge*
346 EnergyGraph::create_new_edge( Edge const * example_edge )
347 {
348  return energy_edge_pool_->construct(
349  this,
350  static_cast< EnergyEdge const & > (*example_edge)
351  );
352 }
353 
354 
355 } //namespace scoring
356 } //namespace core