Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RingConformationMover.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 RingConformationMover.cc
11 /// @brief Method definitions for RingConformationMover.
12 /// @author labonte
13 
14 // Unit headers
16 #include <protocols/moves/Mover.hh>
17 
18 // Project headers
19 #include <core/types.hh>
20 #include <core/pose/Pose.hh>
23 
24 // Utility headers
25 #include <utility/excn/Exceptions.hh>
26 
27 // Basic headers
28 #include <basic/Tracer.hh>
29 #include <basic/options/option.hh>
30 #include <basic/options/keys/carbohydrates.OptionKeys.gen.hh>
31 
32 // Numeric headers
33 #include <numeric/random/random.hh>
34 
35 // C++ headers
36 #include <string>
37 #include <iostream>
38 
39 
40 // Construct tracers.
41 static basic::Tracer TR("protocols.simple_moves.carbohydrates.RingConformationMover");
42 
43 using basic::Warning;
44 
45 // Construct random-number generator.
46 static numeric::random::RandomGenerator RG(17); // Does this # mattter?
47 
48 
49 namespace protocols {
50 namespace simple_moves {
51 namespace carbohydrates {
52 
53 using namespace core;
54 
55 // Public methods //////////////////////////////////////////////////////////////
56 // Standard methods ////////////////////////////////////////////////////////////
57 // Default constructor
58 /// @details By default, all carbohydrate rings within a given pose will be moved.
60 {
61  using namespace kinematics;
62 
63  // Set default MoveMap.
64  MoveMapOP default_movemap = new MoveMap();
65  default_movemap->set_bb(true);
66 
67  init(default_movemap);
68 }
69 
70 // Copy constructor
72 {
73  copy_data(*this, object_to_copy);
74 }
75 
76 // Constructor with MoveMap input option
77 /// @param <input_movemap>: a MoveMap with desired backbone torsions set to true
78 /// @remarks Movable carbohydrate residues will generally be a subset of residues in the MoveMap whose backbone
79 /// torsions are set to true.
81 {
82  init(input_movemap);
83 }
84 
85 // Assignment operator
88 {
89  // Abort self-assignment.
90  if (this == &object_to_copy) {
91  return *this;
92  }
93 
94  Mover::operator=(object_to_copy);
95  copy_data(*this, object_to_copy);
96  return *this;
97 }
98 
99 // Destructor
101 
102 
103 // Standard Rosetta methods ////////////////////////////////////////////////////
104 // General methods
105 void
107 {
108  // No options to register yet
109 }
110 
111 void
112 RingConformationMover::show(std::ostream & output) const
113 {
114  using namespace std;
115 
116  moves::operator<<(output, *this); // name, type, tag
117 
118  output << "Current MoveMap:" << endl << *movemap_ << endl;
119 }
120 
121 
122 // Mover methods
125 {
126  return type();
127 }
128 
131 {
132  return new RingConformationMover(*this);
133 }
134 
137 {
138  return new RingConformationMover();
139 }
140 
141 
142 /// @details The mover will create a list of movable residues based on the given MoveMap and select a residue from
143 /// the list at random. The torsion angles of a randomly selected ring conformer will be applied to the selected
144 /// residue.
145 /// @param <input_pose>: the structure to be moved
146 /// @remarks A work in progress...
147 /// Currently, this algorithm depends on CHI angles being set in the params file to fill in for nu angles, as
148 /// Rosetta has no mechanism for dealing with ring torsions. This may cause issues with other protocols using
149 /// MoveMap, since MoveMap considers part of the ring as BB and part of the ring as CHI, with some overlap.
150 void
152 {
153  using namespace std;
154  using namespace basic::options;
155  using namespace utility;
156  using namespace conformation;
157  using namespace id;
158 
159  if (option[OptionKeys::carbohydrates::lock_rings]) {
160  Warning() << "Rings have been locked; no ring conformation moves are being applied to this pose." << endl;
161  return;
162  }
163 
164  show(TR);
165 
166  TR << "Getting movable residues...." << endl;
167 
168  setup_residue_list(input_pose);
169 
170  if (residue_list_.empty()) {
171  Warning() << "There are no movable carbohydrate residues available in the given pose." << endl;
172  return;
173  }
174 
175  TR << "Applying " << get_name() << " to pose...." << endl;
176 
177  Size i = RG.uniform() * residue_list_.size() + 1;
178  Size res_num = residue_list_[i];
179  Residue res = input_pose.residue(res_num);
180 
181  TR << "Selected residue " << res_num << ": " << res.name() << endl;
182 
183  Size ring_size = res.carbohydrate_info()->ring_size();
184  ring_conf_def conformer;
185  Size j;
186 
187  switch (ring_size) {
188  case 5:
189  //j = RG.uniform() * five_membered_ring_conformers_.size() + 1;
190  //conformer = five_membered_ring_conformers_[j];
191  Warning() << "Ring flips for 5-membered rings not yet coded!" << endl;
192  return;
193  case 6:
194  j = RG.uniform() * six_membered_ring_conformers_.size() + 1;
195  conformer = six_membered_ring_conformers_[j];
196  break;
197  }
198 
199  TR << "Selected the " << conformer.first << " conformation to apply." << endl;
200 
201  TR << "Making move...." << endl;
202 
203  pair<TorsionType, Size> nu_id;
204  for (Size k = 1; k <= ring_size - 2; ++k) {
205  nu_id = res.carbohydrate_info()->nu_id(k);
206  input_pose.set_torsion(TorsionID(res_num, nu_id.first, nu_id.second), conformer.second[k]);
207  }
208 
209  TR << "Move complete." << endl;
210 }
211 
212 
213 // Accessors/Mutators
216 {
217  return movemap_;
218 }
219 
220 void
222 {
223  movemap_ = new_movemap;
224 }
225 
226 
227 // Private methods /////////////////////////////////////////////////////////////
228 // Initialize data members from arguments.
229 void
231 {
232  using namespace std;
233  using namespace utility;
234  using namespace id;
235 
236  type("RingConformationMover");
237 
238  movemap_ = movemap;
239 
240  // TODO: Create ring_conformer_io.cc file that will include function to read the below data from rosetta_database.
241 
242  // TODO: Define furanose ring conformers.
243 
244  // TODO: Properly name other conformers.
245 
246  // Define pyranose ring conformers.
247 
248  // (C-style arrays should normally be avoided, but it makes initializing the vector1 so much easier.)
249  // We only need 4 torsion angles to define a 6-membered conformer.
250  Real angles[4];
251 
252  // Two chair conformers
253  // It's lazy, but for now, I am adding multiple copies of each to compete with entropy of multiple twist-boat states.
254  // This will result in a 2:1 chair to twist-boat ratio, which at least matches the CAPRI 27 starting structure.
255  for (Size i = 1; i <= 6; ++i) {
256  angles[0] = -60.0; angles[1] = 60.0; angles[2] = -60.0; angles[3] = 60.0;
257  six_membered_ring_conformers_.push_back(make_pair("1C4", vector1<Real>(angles, angles + 4)));
258  angles[0] = 60.0; angles[1] = -60.0; angles[2] = 60.0; angles[3] = -60.0;
259  six_membered_ring_conformers_.push_back(make_pair("4C1", vector1<Real>(angles, angles + 4)));
260  }
261 
262  // Six boat conformers
263  // We'll assume these are always energy maxima and comment them out for now. Maybe add option for them later?
264  /*angles[0] = 0.0; angles[1] = -60.0; angles[2] = 60.0; angles[3] = 0.0;
265  six_membered_ring_conformers_.push_back(make_pair("boat", vector1<Real>(angles, angles + 4)));
266  angles[0] = 60.0; angles[1] = 0.0; angles[2] = -60.0; angles[3] = 60.0;
267  six_membered_ring_conformers_.push_back(make_pair("B1,4", vector1<Real>(angles, angles + 4)));
268  angles[0] = -60.0; angles[1] = 60.0; angles[2] = 0.0; angles[3] = -60.0;
269  six_membered_ring_conformers_.push_back(make_pair("boat", vector1<Real>(angles, angles + 4)));
270 
271  angles[0] = 0.0; angles[1] = 60.0; angles[2] = -60.0; angles[3] = 0.0;
272  six_membered_ring_conformers_.push_back(make_pair("boat", vector1<Real>(angles, angles + 4)));
273  angles[0] = -60.0; angles[1] = 0.0; angles[2] = 60.0; angles[3] = -60.0;
274  six_membered_ring_conformers_.push_back(make_pair("1,4B", vector1<Real>(angles, angles + 4)));
275  angles[0] = 60.0; angles[1] = -60.0; angles[2] = 0.0; angles[3] = 60.0;
276  six_membered_ring_conformers_.push_back(make_pair("boat", vector1<Real>(angles, angles + 4)));*/
277 
278  // Six twist-boat conformers
279  angles[0] = -30.0; angles[1] = -30.0; angles[2] = 60.0; angles[3] = -30.0;
280  six_membered_ring_conformers_.push_back(make_pair("4S1", vector1<Real>(angles, angles + 4)));
281  angles[0] = -30.0; angles[1] = 60.0; angles[2] = -30.0; angles[3] = -30.0;
282  six_membered_ring_conformers_.push_back(make_pair("twist-boat", vector1<Real>(angles, angles + 4)));
283  angles[0] = 60.0; angles[1] = -30.0; angles[2] = -30.0; angles[3] = 60.0;
284  six_membered_ring_conformers_.push_back(make_pair("twist-boat", vector1<Real>(angles, angles + 4)));
285 
286  angles[0] = 30.0; angles[1] = 30.0; angles[2] = -60.0; angles[3] = 30.0;
287  six_membered_ring_conformers_.push_back(make_pair("1S4", vector1<Real>(angles, angles + 4)));
288  angles[0] = 30.0; angles[1] = -60.0; angles[2] = 30.0; angles[3] = 30.0;
289  six_membered_ring_conformers_.push_back(make_pair("twist-boat", vector1<Real>(angles, angles + 4)));
290  angles[0] = -60.0; angles[1] = 30.0; angles[2] = 30.0; angles[3] = -60.0;
291  six_membered_ring_conformers_.push_back(make_pair("twist-boat", vector1<Real>(angles, angles + 4)));
292 }
293 
294 // Copy all data members from <object_to_copy_from> to <object_to_copy_to>.
295 void
297  RingConformationMover object_to_copy_to,
298  RingConformationMover object_to_copy_from)
299 {
300  object_to_copy_to.movemap_ = object_to_copy_from.movemap_;
301  object_to_copy_to.residue_list_ = object_to_copy_from.residue_list_;
302 
303  object_to_copy_to.five_membered_ring_conformers_ =
304  object_to_copy_from.five_membered_ring_conformers_;
305  object_to_copy_to.six_membered_ring_conformers_ =
306  object_to_copy_from.six_membered_ring_conformers_;
307 }
308 
309 // Setup list of movable carbohydrate residues from MoveMap.
310 void
312 {
313  using namespace conformation;
314 
315  residue_list_.clear();
316 
317  for (Size res_num = 1, last_res_num = pose.total_residue(); res_num <= last_res_num; ++res_num) {
318  Residue const & residue = pose.residue(res_num);
319  if (residue.is_carbohydrate()) {
320  if (residue.carbohydrate_info()->is_cyclic() && movemap_->get_bb(res_num) == true) {
321  residue_list_.push_back(res_num);
322  }
323  }
324  }
325 }
326 
327 
328 // Friend methods //////////////////////////////////////////////////////////////
329 // Insertion operator (overloaded so that RingConformationMover can be "printed" in PyRosetta).
330 std::ostream &
331 operator<<(std::ostream & output, RingConformationMover const & object_to_output)
332 {
333  object_to_output.show(output);
334  return output;
335 }
336 
337 } // namespace carbohydrates
338 } // namespace simple_moves
339 } // namespace protocols