Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SymMinimizerMap.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 // This file is part of the Rosetta software suite and is made available under license.
5 // The Rosetta software is developed by the contributing members of the Rosetta Commons consortium.
6 // (C) 199x-2009 Rosetta Commons participating institutions and developers.
7 // For more information, see http://www.rosettacommons.org/.
8 
9 /// @file core/optimization/SymMinimizerMap.cc
10 /// @brief MinimizerMap for symmetric minimization implementation
11 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
12 
13 
14 // Unit headers
16 
17 // Package headers
20 
21 // Project headers
24 // AUTO-REMOVED #include <core/pose/symmetry/util.hh>
26 // AUTO-REMOVED #include <core/id/AtomID_Mask.hh>
29 #include <core/pose/util.hh>
30 #include <core/pose/Pose.hh>
31 #include <core/scoring/Energies.hh>
33 
34 
35 /// Numeric headers
36 #include <numeric/conversions.hh>
37 
39 #include <utility/vector1.hh>
40 #include <utility/options/BooleanVectorOption.hh>
41 
42 //Auto Headers
43 #include <core/pose/util.tmpl.hh>
44 
45 namespace core {
46 namespace optimization {
47 namespace symmetry {
48 
49 /////////////////////////////////////////////////////////////////////////////
50 /// Stolen from MinimizerMap.cc
51 bool
53 {
54  return *a < *b;
55 }
56 
57 /////////////////////////////////////////////////////////////////////////////
58 
60  pose::Pose const & pose,
61  kinematics::MoveMap const & asymm_movemap,
62  SymmetryInfoCOP symm_info
63 ) :
64  pose_( pose ),
65  symm_info_( symm_info ),
66  res_interacts_with_asymmetric_unit_( pose.total_residue(), false ),
67  n_dof_nodes_( 0 ),
68  n_independent_dof_nodes_( 0 ),
69  atom_derivatives_( pose.total_residue() )
70 {
71 
72  //std::cout << "SymMinimizerMap ctor: " << std::endl;
73  //std::cout << pose.conformation().fold_tree() << std::endl;
74 
75  DOF_NodeOP tmp(0);
77 
78  for ( Size ii = 1; ii <= pose.total_residue(); ++ii ) {
79  atom_derivatives_[ ii ].resize( pose.residue( ii ).natoms() );
80  if ( symm_info_->bb_follows( ii ) == 0 ) {
81  res_interacts_with_asymmetric_unit_[ ii ] = true; // residues in the asymmetric unit are always included
82  continue;
83  }
84  /// ASSUMPTION the energy graph only includes edges where at least one node belongs to the asymmetric unit
86  iter = pose.energies().energy_graph().get_node( ii )->const_edge_list_begin(),
87  iter_end = pose.energies().energy_graph().get_node( ii )->const_edge_list_end();
88  iter != iter_end; ++iter ) {
89  Size jj = (*iter)->get_other_ind( ii );
90  if ( symm_info_->bb_follows( jj ) == 0 ) {
92  break;
93  }
94  }
95  }
96 
97  /// tell the atom tree about every DOF that will be changing, even if some of the DOFs are clones
98  id::DOF_ID_Mask dof_mask( false );
99  pose::setup_dof_mask_from_move_map( asymm_movemap, pose, dof_mask );
100 
101  // this fills the torsion and atom lists
102  DOF_ID temp( id::BOGUS_DOF_ID );
103  pose.atom_tree().root()->setup_min_map( temp, dof_mask, *this );
104 
105  /// sort dof nodes by tree depth.
106  dof_nodes_.sort( DOF_Node_sorter );
107 
108 
109  // identify phi/psi/omega...
110  //
111  this->assign_rosetta_torsions( pose );
112 
113 
114  /// STOLEN directly from MinimizerMap.cc
115  // setup the domain_map which indicates what rsd pairs are fixed/moving
116  id::AtomID_Mask moving_dof, moving_xyz;
117  core::pose::initialize_atomid_map( moving_xyz, pose, false );
118  core::pose::initialize_atomid_map( moving_dof, pose, false );
119  for ( const_iterator it = dof_nodes_.begin(), it_end = dof_nodes_.end();
120  it != it_end; ++it ) {
121  moving_dof[ (**it).atom_id() ] = true;
122  }
123 
124  domain_map_.dimension( pose.total_residue() );
126  ( domain_map_, moving_dof, moving_xyz );
127 
128 }
129 
131 
132 void
134  DOF_ID const & new_torsion,
135  DOF_ID const & parent
136 )
137 {
138  //std::cout << "add torsion: " << new_torsion.atomno() << " " << new_torsion.rsd() << " " << new_torsion.type();// << std::endl;
139  //std::cout << "add torsion parent: " << parent.atomno() << " " << parent.rsd() << " " << parent.type() << std::endl;
140  if ( symm_info_->dof_is_independent( new_torsion, pose_.conformation() ) ) {
141  //std::cout << " ind" << std::endl;
142  add_new_dof_node( new_torsion, parent, false );
143  //last_cloned_jump_ = DOF_ID( id::BOGUS_DOF_ID ); // set invalid
144  } else {
145 
146  if ( new_torsion.type() >= id::RB1 ) { // We have a jump
148  dynamic_cast< conformation::symmetry::SymmetricConformation const & > ( pose_.conformation()) );
149  assert( conformation::symmetry::is_symmetric( symm_conf ) );
150  if ( symm_info_->get_dof_derivative_weight( new_torsion, symm_conf ) != 0.0 ) {
151  DOF_ID parent_dof( id::BOGUS_DOF_ID );
152  add_new_dof_node( new_torsion, parent_dof, true );
153  }
154  }
155 
156  }
157 }
158 
159 void
161  AtomID const & atom_id,
162  DOF_ID const & dof_id
163 )
164 {
165  if ( ! dof_id.valid() ) return;
166 
167  //std::cout << "add atom? atom " << atom_id << " dof " << dof_id.rsd() << " " << dof_id.atomno() << " " << dof_id.type() << std::endl;
168  //std::cout << " last_cloned_jump_?: "<< last_cloned_jump_.rsd() << " " << last_cloned_jump_.atomno() << " " << last_cloned_jump_.type() << std::endl;
169 
170  assert( dof_node_pointer_[ dof_id ] );
171  dof_node_pointer_[ dof_id ]->add_atom( atom_id );
172 
173  /*if ( symm_info_->dof_is_independent( dof_id, pose_.conformation() ) ) {
174  dof_node_pointer_[ dof_id ]->add_atom( atom_id );
175  std::cout << " added to independ dof" << std::endl;
176  } else if ( dof_node_pointer_[ dof_id ] ) {
177  //assert( dof_id == last_cloned_jump_ );
178  assert( ! symm_info_->dof_is_independent( dof_id, pose_.conformation() ) );
179  //assert( dof_node_pointer_[ last_cloned_jump_ ] );
180  dof_node_pointer_[ dof_id ] ->add_atom( atom_id );
181  std::cout << " added to last_cloned_jump_: "<< last_cloned_jump_.rsd() << " " << last_cloned_jump_.atomno() << " " << last_cloned_jump_.type() << std::endl;
182  } */
183 }
184 
185 kinematics::DomainMap const &
187 {
188  return domain_map_;
189 }
190 
191 void
193  pose::Pose const & pose,
194  Multivec & dofs
195 ) const
196 {
197  int imap = 1;
198  for ( const_iterator it=dof_nodes_.begin(), it_end = dof_nodes_.end();
199  it != it_end; ++it, ++imap ) {
200  DOF_Node const & dof_node( **it );
201  dofs[ imap ] = torsion_scale_factor( dof_node ) *
202  pose.dof( dof_node.dof_id() );
203  }
204 }
205 
206 void
208  pose::Pose & pose,
209  Multivec const & dofs
210 ) const
211 {
212  int imap = 1;
213  for ( const_iterator it=dof_nodes_.begin(), it_end = dof_nodes_.end();
214  it != it_end; ++it, ++imap ) {
215  DOF_Node const & dof_node( **it );
216  pose.set_dof( dof_node.dof_id(),
217  dofs[ imap ] / torsion_scale_factor( dof_node ));
218  }
219 }
220 
223 {
224  DOF_NodeOP node = 0;
225  if ( id.valid() ) {
226  node = dof_node_pointer_[ id ];
227  if ( node == 0 ) {
228  std::cerr << "DOF_ID does not exist in map! torsion= " << id << std::endl;
229  utility_exit();
230  }
231  }
232  return node;
233 }
234 
235 
236 
238 {
239  for ( const_iterator iter = dof_nodes_.begin(),
240  iter_end = dof_nodes_.end(); iter != iter_end; ++iter ) {
241  (*iter)->F1() = 0;
242  (*iter)->F2() = 0;
243  }
244  for ( Size ii = 1, iiend = atom_derivatives_.size(); ii <= iiend; ++ii ) {
245  for ( Size jj = 1, jjend = atom_derivatives_[ ii ].size(); jj <= jjend; ++jj ) {
246  atom_derivatives_[ ii ][ jj ].f1() = 0.0;
247  atom_derivatives_[ ii ][ jj ].f2() = 0.0;
248  }
249  }
250 }
251 
252 void
254 {
255  int last_depth = -1;
256  for ( const_iterator it=dof_nodes_.begin(),
257  it_end=dof_nodes_.end(); it != it_end; ++it ) {
258  DOF_Node & dof_node( **it );
259  assert( last_depth == -1 || dof_node.depth() <= last_depth );
260  last_depth = dof_node.depth();
261  dof_node.link_vectors();
262  }
263 }
264 
265 /////////////////////////////////////////////////////////////////////////////
266 Real
268  DOF_Node const & dof_node
269 ) const
270 {
271  static Real const rad2deg( numeric::conversions::degrees(1.0) );
272  DOF_Type const type( dof_node.type() );
273  Real factor( 1.0 );
274  if ( type == id::PHI ) {
275  // bond torsion
276  factor = rad2deg;
277  } else if ( type == id::THETA ) {
278  // bond angle
279  factor = rad2deg * 10.0;
280  } else if ( type == id::D ) {
281  // bond length
282  factor = 100.0;
283  } else if ( type == id::RB4 ||
284  type == id::RB5 ||
285  type == id::RB6 ) {
286  // the jump_rb_delta's are stored in degrees!!!
287  factor = 1.0;
288  } else if ( type == id::RB1 ||
289  type == id::RB2 ||
290  type == id::RB3 ) {
291  // rigid body translation
292  factor = 10.0;
293  }
294  return factor;
295 }
296 
297 /////////////////////////////////////////////////////////////////////////////
298 void
300  pose::Pose & pose,
301  Multivec & dofs
302 ) const
303 {
304  int imap = 1;
305  for ( const_iterator it=dof_nodes_.begin(), it_end = dof_nodes_.end();
306  it != it_end; ++it, ++imap ) {
307  DOF_Node const & dof_node( **it );
308  if ( DOF_type_is_rb( dof_node.type() ) ) {
309  // will do this multiple times for each jump, but should be OK
310  AtomID const & id( dof_node.atom_id() );
311  kinematics::Jump jump( pose.jump( id ) );
312  jump.fold_in_rb_deltas();
313  pose.set_jump( id, jump );
314  dofs[ imap ] = 0.0;
315  }
316  }
317 }
318 
319 
320 
321 void
323  DOF_ID const & new_torsion,
324  DOF_ID const & parent,
325  bool dependent
326 )
327 {
328  //std::cout << "add new dof node: " << new_torsion.atomno() << " " << new_torsion.rsd() << " " << new_torsion.type() << std::endl;
329  //std::cout << "add new dof node parent: " << parent.atomno() << " " << parent.rsd() << " " << parent.type() << std::endl;
330 
331  assert( ! parent.valid() || symm_info_->bb_follows( parent.rsd() ) == 0 );
332  assert( symm_info_->bb_follows( new_torsion.rsd() ) == 0 );
333  DOF_NodeOP dof_node = new DOF_Node( new_torsion, DOF_NodeOP( 0 ) );
334 
335  if ( parent.valid() ) {
336  DOF_NodeOP parent_ptr = dof_node_pointer_[ parent ];
337  if ( parent_ptr ) {
338  dof_node->set_parent( parent_ptr );
339  }
340  }
341 
342  dof_node_pointer_[ new_torsion ] = dof_node;
343  if ( dependent ) {
344  dependent_dof_nodes_.push_back( dof_node ); ++n_dof_nodes_;
345  } else {
346  dof_nodes_.push_back( dof_node ); ++n_dof_nodes_; ++n_independent_dof_nodes_;
347  }
348 }
349 
350 /// @details use the bb_follows mapping to find the residue in the asymmetric unit that
351 /// this cloned atom corresponds to
353 SymMinimizerMap::asymmetric_dof( DOF_ID const & cloned_dof ) const
354 {
355  if ( cloned_dof.type() >= id::RB1 ) {
356  /// we have a jump
357  Size cloned_jumpno = pose_.conformation().fold_tree().get_jump_that_builds_residue( cloned_dof.rsd() );
358  assert( symm_info_->jump_follows( cloned_jumpno ) != 0 );
359  Size asymm_jumpno = symm_info_->jump_follows( cloned_jumpno );
360  Size asymm_resno = pose_.conformation().fold_tree().jump_edge( asymm_jumpno ).stop();
361  id::AtomID asymmatom( cloned_dof.atomno(), asymm_resno );
362  return DOF_ID( asymmatom, cloned_dof.type() );
363  } else {
364  assert( symm_info_->bb_follows( cloned_dof.rsd() ) != 0 );
365  id::AtomID asymmatom( cloned_dof.atomno(), symm_info_->bb_follows( cloned_dof.rsd() ) );
366 
367  return DOF_ID( asymmatom, cloned_dof.type() );
368  }
369 }
370 
371 void
373 {
374  // mapping from AtomTree DOF ID's to bb/chi torsion angle ids
377 
378  pose::setup_dof_to_torsion_map( pose, dof_map );
379 
380  for ( const_iterator it = dof_nodes_.begin(), it_end = dof_nodes_.end();
381  it != it_end; ++it ) {
382  DOF_Node & dof_node( **it );
383 
384  if ( dof_node.type() == id::PHI ) {
385  id::TorsionID const & id( dof_map[ dof_node.dof_id() ] );
386  if ( id.valid() ) {
387  dof_node.torsion_id( id );
388  }
389  }
390  }
391 }
392 
393 } // symmetry
394 } // namespace optimization
395 } // namespace core