Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SymmetricRotamerSet_.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/pack/rotamer_set/symmetry/SymmetricRotamerSet_.cc
10 /// @brief amino acid rotamer set class implementation for symmetric packing
11 /// @author Ingemar Andre
12 
13 // Unit Headers
15 
16 // Package Headers
22 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
23 
24 
25 // Project Headers
30 #include <basic/Tracer.hh>
31 
32 #include <core/graph/Graph.hh>
33 
34 #include <core/pose/Pose.hh>
35 #include <core/scoring/Energies.hh>
37 
38 // AUTO-REMOVED #include <core/scoring/EnergyGraph.hh>
41 
42 // ObjexxFCL Headers
43 #include <ObjexxFCL/FArray2.hh>
44 
45 // C++ headers
46 #include <string>
47 #include <iostream>
48 
50 #include <utility/vector1.hh>
51 
52 //Auto Headers
53 #include <ObjexxFCL/FArray2D.hh>
54 
55 namespace core {
56 namespace pack {
57 namespace rotamer_set {
58 namespace symmetry {
59 
60 static basic::Tracer tt("core.pack.rotamer_set.symmetry.SymmetricRotamerSet_",basic::t_info );
61 
63 : RotamerSet_()
64 {}
65 
67 
68 // @ details The packer's 1-body is a combination of the rotamer internal energies (the
69 // context dependent and independent one body energies), the intra-residue
70 // energies defined by the two body energies, and the sum of the
71 // two body energies with the background residues in this repacking. The
72 // PackerTask tells the RotamerSet_ what residues are part of the
73 // background and which are being repacked.
74 // This is the symmetrical version of the class. It adds the score for the clone residues into
75 // the energy for the master residue
76 void
78  pose::Pose const & pose,
79  scoring::ScoreFunction const & sf,
80  task::PackerTask const & task,
81  graph::GraphCOP packer_neighbor_graph,
83 ) const
84 {
85  using namespace conformation;
86  using namespace scoring;
87 
88  //fpd make sure the pose is symmetric
89  if ( !core::pose::symmetry::is_symmetric( pose ) ) {
90  RotamerSet_::compute_one_body_energies( pose, sf, task, packer_neighbor_graph, energies );
91  return;
92  }
93 
94  // find SymmInfo
95  SymmetricConformation const & SymmConf (
96  dynamic_cast<SymmetricConformation const &> ( pose.conformation() ) );
97  SymmetryInfoCOP symm_info( SymmConf.Symmetry_Info() );
98 
99  std::fill( energies.begin(), energies.end(), core::PackerEnergy( 0.0 ) );
100  utility::vector1< core::PackerEnergy > temp_energies = energies;
101 
102  int const nrotamers = num_rotamers(); // does not change in this function
103  Size const theresid = resid();
104 
105  for ( int ii = 1; ii <= nrotamers; ++ii ) {
106  EnergyMap emap;
107  sf.eval_ci_1b( *rotamer( ii ), pose, emap );
108  sf.eval_cd_1b( *rotamer( ii ), pose, emap );
109  energies[ ii ] += static_cast< core::PackerEnergy > (sf.weights().dot( emap ))*symm_info->score_multiply_factor(); // precision loss here. Multiply with the number of total subunits to get the total energy
110  }
111 
112 
113  sf.evaluate_rotamer_intrares_energies( *this, pose, temp_energies );
114  // multiply the rotamer_intrares energy with the number of subunits in the system
115  PackerEnergyMultiply( temp_energies, symm_info->score_multiply_factor() );
116  PackerEnergyAdd( energies, temp_energies );
117 
118  // define a factory
119  RotamerSetFactory rsf;
120 
122  ir = packer_neighbor_graph->get_node( theresid )->const_edge_list_begin(),
123  ire = packer_neighbor_graph->get_node( theresid )->const_edge_list_end();
124  ir != ire; ++ir ) {
125  int const neighbor_id( (*ir)->get_other_ind( theresid ) );
126  if ( task.pack_residue( neighbor_id ) ) continue;
127  Residue const & neighbor( pose.residue( neighbor_id ) );
128  uint const symm_clone ( symm_info->chi_follows( neighbor_id ) );
129  if ( symm_clone != 0 && task.pack_residue( symm_clone )
130  && symm_clone != theresid ) continue;
131  // Residue is not interating with itself
132  if ( symm_clone != theresid ) {
133  // evaluate the energy for one rotamer pair interaction and
134  // multiply it with the number of subunits in the system
135  std::fill( temp_energies.begin(), temp_energies.end(), core::PackerEnergy( 0.0 ) );
136  sf.evaluate_rotamer_background_energies( *this, neighbor, pose, temp_energies );
137  PackerEnergyMultiply( temp_energies, symm_info->score_multiply_factor() );
138  PackerEnergyAdd( energies, temp_energies );
139 // PackerEnergyAdd( energies, temp_energies );
140  } else {
141  // We have a self interaction. We have to calculate the rotamer-rotamer pair interaction
142  // where both rotamers change at the same time to the same state. We go through all rotamers
143  // and calculated interaction energies with translated copies of itself
144  for ( int jj = 1; jj <= nrotamers; ++jj ) {
145  // make a new rotamer set that is going to be translated to the neighbor interation residue
146  conformation::ResidueOP sym_rsd( *this->rotamer( jj )->clone() );
147  RotamerSetOP one_rotamer_set = rsf.create_rotamer_set( *sym_rsd );
148  one_rotamer_set->set_resid( theresid );
149  one_rotamer_set->add_rotamer( *sym_rsd );
150  // place rotamer set at neighbor position
151  RotamerSetOP sym_rotset(
152  orient_rotamer_set_to_symmetric_partner( pose, sym_rsd, neighbor_id, one_rotamer_set ) );
153  sf.prepare_rotamers_for_packing( pose, *one_rotamer_set );
154  sf.prepare_rotamers_for_packing( pose, *sym_rotset );
155  // make a temporary core::PackerEnergy object with on rotamer in it
156  ObjexxFCL::FArray2D< core::PackerEnergy > temp_energies( 1, 1, 0.0 );
157  // evaluate the energy for this rotamer-rotamer interaction
159  *one_rotamer_set, *sym_rotset, pose, temp_energies );
160  // add the energy of this interaction. Mulitply with the number of subunits in
161  // the system
162  energies[ jj ] += temp_energies[ 0 ]*symm_info->score_multiply( theresid, neighbor_id );
163  }
164  }
165  }
166 
167  // long-range energy interactions with background
168  // Iterate across the long range energy functions and use the iterators generated
169  // by the LRnergy container object
171  lr_iter = sf.long_range_energies_begin(),
172  lr_end = sf.long_range_energies_end();
173  lr_iter != lr_end; ++lr_iter ) {
174  LREnergyContainerCOP lrec = pose.energies().long_range_container( (*lr_iter)->long_range_type() );
175  if ( !lrec || lrec->empty() ) continue; // only score non-emtpy energies.
176 
177  // Potentially O(N) operation leading to O(N^2) behavior
179  rni = lrec->const_neighbor_iterator_begin( theresid ),
180  rniend = lrec->const_neighbor_iterator_end( theresid );
181  (*rni) != (*rniend); ++(*rni) ) {
182  Size const neighbor_id = rni->neighbor_id();
183  assert( neighbor_id != theresid );
184  if ( task.pack_residue( neighbor_id ) ) continue;
185 
186  // Residue is not interating with itself
187  if ( symm_info->chi_follows( theresid ) != neighbor_id ) {
188  // evaluate the energy for one rotamer pair interaction and
189  // multiply it with the number of subunits in the system
190  std::fill( temp_energies.begin(), temp_energies.end(), core::PackerEnergy( 0.0 ) );
191  (*lr_iter)->evaluate_rotamer_background_energies(
192  *this, pose.residue( neighbor_id ), pose, sf,
193  sf.weights(), temp_energies );
194  PackerEnergyMultiply( temp_energies, symm_info->score_multiply_factor() );
195  PackerEnergyAdd( energies, temp_energies );
196  } else {
197  // We have a self interaction. We have to calculate the rotamer-rotamer pair interaction
198  // where both rotamers change at the same time to the same state. We go through all rotamers
199  // and calculated interaction energies with translated copies of itself
200  //Residue const & neighbor( pose.residue( neighbor_id ) );
201  for ( int jj = 1; jj <= nrotamers; ++jj ) {
202  // make a new rotamer set that is going to be translated to the neighbor interation residue
203  conformation::ResidueOP sym_rsd( *this->rotamer( jj )->clone() );
204  RotamerSetOP one_rotamer_set = rsf.create_rotamer_set( *sym_rsd );
205  one_rotamer_set->set_resid( theresid );
206  one_rotamer_set->add_rotamer( *sym_rsd );
207  // place rotamer set at neighbor position
208  RotamerSetOP sym_rotset(
209  orient_rotamer_set_to_symmetric_partner( pose, sym_rsd, neighbor_id, one_rotamer_set ) );
210  sf.prepare_rotamers_for_packing( pose, *one_rotamer_set );
211  sf.prepare_rotamers_for_packing( pose, *sym_rotset );
212  ObjexxFCL::FArray2D< core::PackerEnergy > temp_energies( 1, 1, 0.0 );
213  // evaluate the energy for this rotamer-rotamer interaction
214  (*lr_iter)->evaluate_rotamer_pair_energies(
215  *one_rotamer_set, *sym_rotset, pose, sf, sf.weights(), temp_energies );
216  // add the energy of this interaction. Mulitply with the number of subunits in
217  // the system
218  energies[ jj ] += temp_energies[ 0 ]*symm_info->score_multiply( theresid, neighbor_id );
219  }
220  }
221  } // (potentially) long-range neighbors of theresid [our resid()]
222  } // long-range energy functions
223 }
224 // @details function for mulitplying core::PackerEnergy objects. Should make a * operator in core::PackerEnergy
225 // instead
226 void
228  Size factor ) const
229 {
230  int const nrotamers = num_rotamers();
231  for ( int ii = 1; ii <= nrotamers; ++ii ){
232  energies[ii] = energies[ii]*factor;
233  }
234 }
235 
236 // @details function for adding core::PackerEnergy objects. Should make a + operator in core::PackerEnergy
237 // instead. The objects must have the same size
238 void
240  utility::vector1< core::PackerEnergy > const & add ) const
241 {
242  assert( energies.size() == add.size() );
243  int const nrotamers = num_rotamers();
244  for ( int ii = 1; ii <= nrotamers; ++ii ){
245  energies[ii] = energies[ii] + add[ii];
246  }
247 }
248 
249 // @details function for subtract core::PackerEnergy objects. Should make a - operator in core::PackerEnergy
250 // instead. The objects must have the same size
251 void
253  utility::vector1< core::PackerEnergy > const & subtract ) const
254 {
255  assert( energies.size() == subtract.size() );
256  int const nrotamers = num_rotamers();
257  for ( int ii = 1; ii <= nrotamers; ++ii ){
258  energies[ii] = energies[ii] - subtract[ii];
259  }
260 }
261 
262 // @details translate a rotamer_set to a different sequence position
265  pose::Pose const & pose,
266  conformation::ResidueOP residue_in,
267  int const & sympos,
268  RotamerSetOP rotset_in
269 ) const
270 {
271 
272  RotamerSetFactory rsf;
273  RotamerSetOP sym_rotamer_set = rsf.create_rotamer_set( *residue_in );
274  for (Rotamers::const_iterator
275  rot = rotset_in->begin(),
276  rot_end = rotset_in->end();
277  rot != rot_end; ++rot) {
278  conformation::Residue target_rsd( *residue_in );
279  target_rsd.orient_onto_residue( pose.residue( sympos ) );
280  target_rsd.copy_residue_connections_from( pose.residue( sympos ) );
281  sym_rotamer_set->set_resid( sympos );
282  sym_rotamer_set->add_rotamer( target_rsd );
283  }
284  return sym_rotamer_set;
285 }
286 
287 } // symmetry
288 } // rotamer_set
289 } // pack
290 } // core