Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MinimizeBackbone.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/pack/task/ResfileReader.cc
11 /// @brief implementation of resfile reader and its command classes
12 /// @author Gordon Lemmon (glemmon@gmail.com), adapted from the ResfileReader code
13 /// by Steven Lewis (smlewi@unc.edu) and Andrew Leaver-Fay
14 
15 // Unit Headers
20 #include <protocols/loops/Loop.hh>
21 
23 
24 //Project Headers
27 #include <core/pose/Pose.hh>
28 
29 
33 #include <core/kinematics/Edge.hh>
34 
35 // Utility Headers
36 #include <numeric/random/random.hh>
37 #include <utility/exit.hh>
38 #include <basic/Tracer.hh>
39 #include <core/types.hh>
40 #include <utility/tag/Tag.hh>
42 
43 using basic::T;
44 using basic::Error;
45 using basic::Warning;
46 
47 //STL headers
48 #include <algorithm> // for std::min, find_if
49 
50 #include <core/pose/util.hh>
52 #include <utility/vector0.hh>
53 #include <utility/vector1.hh>
54 
55 //Auto Headers
57 
58 // Boost Headers
59 #include <utility/excn/Exceptions.hh>
60 #include <boost/foreach.hpp>
61 #define foreach BOOST_FOREACH
62 
63 
64 namespace protocols {
65 namespace ligand_docking {
66 
67 static basic::Tracer minimize_backbone_tracer("protocols.ligand_docking.ligand_options.MinimizeBackbone", basic::t_debug);
68 
71 {
73 }
74 
77  return new MinimizeBackbone;
78 }
79 
82 {
83  return "MinimizeBackbone";
84 }
85 
87  protocols::moves::Mover(),
88  interface_builder_()
89 {}
90 
92  protocols::moves::Mover(),
93  interface_builder_(interface_builder)
94 {}
95 
97  //utility::pointer::ReferenceCount(),
98  protocols::moves::Mover( that ),
99  interface_builder_(that.interface_builder_)
100 {}
101 
103 
105  return new MinimizeBackbone( *this );
106 }
107 
109  return new MinimizeBackbone;
110 }
111 
113  return "MinimizeBackbone";
114 }
115 
116 //@brief parse XML (specifically in the context of the parser/scripting scheme)
117 void
119  utility::tag::TagPtr const tag,
120  protocols::moves::DataMap & datamap,
121  protocols::filters::Filters_map const & /*filters*/,
122  protocols::moves::Movers_map const & /*movers*/,
123  core::pose::Pose const & /*pose*/
124 )
125 {
126  if ( tag->getName() != "MinimizeBackbone" ) throw utility::excn::EXCN_RosettaScriptsOption("This should be impossible");
127 
128  if ( ! tag->hasOption("interface") ) throw utility::excn::EXCN_RosettaScriptsOption("'HighResDocker' requires 'interface' tag (comma separated chains to dock)");
129 
130  std::string interface_name= tag->getOption<std::string>("interface");
131  interface_builder_= datamap.get< protocols::ligand_docking::InterfaceBuilder * >( "interface_builders", interface_name);
132 }
133 
134 /// setting up backbone_minimization foldtree
135 void
137  assert(pose.fold_tree().check_edges_for_atom_info());
138  assert(interface_builder_);// make sure the pointer points
139  ligand_options::Interface interface= interface_builder_->build(pose);
140  restrict_to_protein_residues(interface, pose);
141  minimize_backbone_tracer.Debug << "interface for fold_tree: "<< interface << std::endl;
142  assert(pose.fold_tree().check_edges_for_atom_info());
144  restrain_protein_Calphas(interface, pose);
145  assert(pose.fold_tree().check_edges_for_atom_info());
146 }
147 
149  ligand_options::Interface const & interface,
150  core::pose::Pose & pose
151 ) {
152  assert(pose.fold_tree().check_edges_for_atom_info());
153  core::kinematics::FoldTree const & fold_tree_copy = pose.fold_tree();
154  assert(fold_tree_copy.check_edges_for_atom_info());
155  minimize_backbone_tracer.Debug << "Initial foldtree " << fold_tree_copy << std::endl;
156  core::kinematics::FoldTreeOP better_ligand_jumps = create_fold_tree_with_ligand_jumps_from_attach_pts(&fold_tree_copy, interface, pose);
157  assert(better_ligand_jumps->check_edges_for_atom_info());
158  minimize_backbone_tracer.Debug << "foldtree with ligand jumps from attach pts" << *better_ligand_jumps << std::endl;
159  core::kinematics::FoldTreeOP with_cutpoints = create_fold_tree_with_cutpoints(better_ligand_jumps, interface, pose);
160  minimize_backbone_tracer.Debug << "foldtree with cutpoints" << *with_cutpoints << std::endl;
161  assert(with_cutpoints->check_edges_for_atom_info());
162  with_cutpoints->delete_extra_vertices();
163  assert(with_cutpoints->check_edges_for_atom_info());
164  minimize_backbone_tracer.Debug << "foldtree with less vertices" << *with_cutpoints << std::endl;
165  assert(with_cutpoints->check_edges_for_atom_info());
166  reorder_with_first_non_mobile_as_root(with_cutpoints, interface, pose);
167  minimize_backbone_tracer.Debug << "Final loops foldtree " << *with_cutpoints << std::endl;
168  if (!with_cutpoints->check_fold_tree()) {
169  utility_exit_with_message("Invalid fold tree after trying to set up for minimization!");
170  }
171  assert(with_cutpoints->check_edges_for_atom_info());
172  pose.fold_tree(*with_cutpoints);
173  assert(pose.fold_tree().check_edges_for_atom_info());
174 }
175 
178  ligand_options::Interface const & interface,
179  core::pose::Pose & pose
180 ) {
181  for (core::Size i = 1; i <= pose.n_residue(); ++i) {
182  if (pose.residue(i).is_polymer() && interface[i].type == ligand_options::InterfaceInfo::non_interface) {
183  f->reorder(i);
184  return;
185  }
186  }
187  utility_exit_with_message("Every residue is mobile! We need a non-mobile residue");
188 }
189 
192  ligand_options::Interface const & interface,
193  core::pose::Pose & pose
194 ) {
195  core::kinematics::FoldTreeOP f_new= new core::kinematics::FoldTree();// Deleting edges is bad so add them to a new foldtree
196 
197  int new_jump = f->num_jump();
198 
199  for (
200  core::kinematics::FoldTree::const_iterator edge_itr = f->begin();
201  edge_itr != f->end();
202  ++edge_itr
203  ) {
204 
205  if (!edge_itr->is_polymer()) {
206  f_new->add_edge(*edge_itr);
207  continue; // only subdivide "peptide" edges of the fold tree
208  }
209 
210  utility::vector1< protocols::loops::Loop> loops = add_cut_points( *edge_itr, interface, pose);
211 
212  const int e_start = edge_itr->start();
213  const int e_stop = edge_itr->stop();
214 
215  int last_rigid = e_start;
216  for (Size i = 1; i <= loops.size(); ++i) {
217  protocols::loops::Loop const & l = loops[i];
218  int first = std::max(int(e_start), int(l.start() - 1));
219  int last = std::min(int(e_stop), int(l.stop() + 1));
220  if (first != last_rigid) {
221  f_new->add_edge(last_rigid, first, core::kinematics::Edge::PEPTIDE);
222  }
223  f_new->add_edge(first, l.cut(), core::kinematics::Edge::PEPTIDE);
224  f_new->add_edge(core::kinematics::Edge(first, last, ++new_jump, "CA", "CA", false ));
225  f_new->add_edge(last, l.cut() + 1, core::kinematics::Edge::PEPTIDE);
226 
227  last_rigid = last;
228  }
229 
230  if (last_rigid != int(e_stop)) {
231  f_new->add_edge(last_rigid, e_stop, core::kinematics::Edge::PEPTIDE);
232  }
233  }
234  return f_new;
235 }
236 
238  core::kinematics::Edge const & edge,
239  ligand_options::Interface const & interface,
240  core::pose::Pose & pose
241 ) {
242  static numeric::random::RandomGenerator my_RG(4376910); // 4376910 is just a random seed
243  if (edge.start() > edge.stop())
244  utility_exit_with_message("Not prepared to deal with backwards fold tree edges!");
246 
247  core::Size start= interface.find_first_interface_residue(edge.start(), edge.stop());
248  core::Size stop= 0;
249 
250  while(start){
251  stop= interface.find_stop_of_this_interface_region(start, edge.stop());
252 
253  minimize_backbone_tracer.Debug << "start,stop:"<< start << ','<< stop << std::endl;
254  minimize_backbone_tracer.Debug << "edge.start,edge.stop:"<< edge.start() << ','<< edge.stop() << std::endl;
255  runtime_assert( stop >= start );
256  if ((stop - start + 1) < 4) {
257  minimize_backbone_tracer.Debug
258  << "WARNING: for backbone minimization to work properly, a stretch of at least 4 residues needs to be allowed to move. Stretch between "
259  << start << " and " << stop << " is too short. This should never happen after extending the interface"
260  << std::endl;
261  continue;
262  }
263 
264  // Cutpoint should fall between start and stop, but not if the rsd on either side is a terminus.
265  // Because this happens within one peptide edge, no "internal" residue should ever be a terminus.
266  core::Size const cut_start = (pose.residue(start).is_terminus() ? start + 1 : start);
267  core::Size const cut_end = ( pose.residue(stop).is_terminus() ? stop - 2 : stop - 1);
268 
269  runtime_assert( cut_start <= cut_end );
270 
271  core::Size cutpt = Size(my_RG.random_range(cut_start, cut_end)); // cut is made between cutpt and cutpt+1
272 
273  loops.push_back(protocols::loops::Loop(start, stop, cutpt));
274  // also need to set up residue variants so chainbreak score works correctly!
277 
278  if( static_cast<int>(stop) == edge.stop()) break; // cast the stop as an int
279  start= interface.find_start_of_next_interface_region(stop+1, edge.stop());
280  }
281  return loops;
282 }
283 
287  ligand_options::Interface const & interface,
288  core::pose::Pose & pose
289 
290 ) const {
291  std::map<core::Size, core::Size> jump_to_attach = find_attach_pts(interface, pose);
292 
293  core::kinematics::FoldTreeOP new_fold_tree =
295 
296  for (
297  core::kinematics::FoldTree::const_iterator e = f_const->begin(),
298  edge_end = f_const->end();
299  e != edge_end;
300  ++e
301  ) {
302  std::map<core::Size, core::Size>::const_iterator const jump_attach = jump_to_attach.find(e->label());
303  if (jump_attach != jump_to_attach.end()) {
304  core::Size const jump_id = jump_attach->first;
305  core::Size const attach_pt = jump_attach->second;
306  core::Size const ligand_residue_id = pose.fold_tree().downstream_jump_residue(jump_id);
307  new_fold_tree->add_edge(attach_pt, ligand_residue_id, jump_id);
308  } else {
309  core::Size const attach_pt= find_peptide_attach_pt(e->start(), e->stop(), jump_to_attach);
310 
311  if (e->label() == core::kinematics::Edge::PEPTIDE && attach_pt != 0) {
312  new_fold_tree->add_edge(e->start(), attach_pt, core::kinematics::Edge::PEPTIDE);
313  new_fold_tree->add_edge(attach_pt, e->stop(), core::kinematics::Edge::PEPTIDE);
314  } else if (e->label() == core::kinematics::Edge::CHEMICAL){
315  new_fold_tree->add_edge(e->start(), e->stop(), e->start_atom(), e->stop_atom());
316  } else {// add a jump edge
317  new_fold_tree->add_edge(e->start(), e->stop(), e->label());
318  }
319  }
320  }
321 
322  if (!new_fold_tree->check_fold_tree())
323  utility_exit_with_message("Fold tree did not pass check!");
324  if (!new_fold_tree->check_edges_for_atom_info())
325  utility_exit_with_message("Fold tree has chemical edge problems!");
326  if (f_const->nres() != new_fold_tree->nres())
327  utility_exit_with_message("Number of residues changed?!");
328  if (f_const->num_jump() != new_fold_tree->num_jump())
329  utility_exit_with_message("Number of jumps changed?!");
330  if (!new_fold_tree->connected())
331  utility_exit_with_message("Fold tree not connected?!");
332  return new_fold_tree;
333 }
334 
335 ///@detail: residues that are near the interface residues will be allowed to move with restraint
337  ligand_options::Interface const & interface,
338  core::pose::Pose & pose
339 ) {
340  core::id::AtomID fixed_pt(pose.atom_tree().root()->atom_id());
341  minimize_backbone_tracer.Debug << interface << std::endl;
342  for (core::Size residue_id = 1; residue_id <= interface.size(); ++residue_id) { // didn't use an iterator because pose needs a #
343  if (interface[residue_id].type != ligand_options::InterfaceInfo::non_interface) {
344  restrain_protein_Calpha(interface, pose, residue_id, fixed_pt);
345  }
346  }
347 }
348 
350  ligand_options::Interface const & interface,
351  core::pose::Pose & pose,
352  core::Size residue_id,
353  core::id::AtomID const & fixed_pt
354 ) {
355  core::conformation::Residue const & residue = pose.residue(residue_id);
356  char const & ligand_chain= interface[residue_id].chain;
357  std::map<char, LigandAreaOP> const & ligand_areas= interface_builder_->get_ligand_areas();
358  std::map<char, LigandAreaOP>::const_iterator found= ligand_areas.find(ligand_chain);
359  assert( found != ligand_areas.end() );// this shouldn't be possible
360  LigandAreaOP const ligand_area= found->second;
361  core::id::AtomID const atom_ID(residue.atom_index("CA"), residue_id);
362  core::scoring::constraints::FuncOP const harmonic_function=
363  new core::scoring::constraints::HarmonicFunc(0, ligand_area->Calpha_restraints_);
366  atom_ID,
367  fixed_pt,
368  residue.xyz("CA"),
369  harmonic_function
370  )
371  ;
372  minimize_backbone_tracer.Debug << "Restraining C-alpha of residue " << residue_id << " with "<< ligand_area->Calpha_restraints_<< std::endl;
373  pose.add_constraint(constraint);
374 }
375 
376 std::map<core::Size, core::Size> MinimizeBackbone::find_attach_pts(
377  ligand_options::Interface const interface,
378  core::pose::Pose const & pose
379 ) const {
380  std::map<core::Size, core::Size> jumpToAttach;
381  std::map<char, LigandAreaOP> const ligand_areas= interface_builder_->get_ligand_areas();
382  //std::map<char, LigandAreaOP>::const_iterator index = ligand_areas.begin();
383  foreach(LigandAreas::value_type ligand_area_pair, ligand_areas){
384  //for (; index != ligand_areas.end(); ++index) { // these are just the ligand chains to dock
385  utility::vector1<core::Size> jump_ids = core::pose::get_jump_ids_from_chain(ligand_area_pair.first, pose);
386  foreach(core::Size jump_id, jump_ids){
387  jumpToAttach[jump_id] = find_attach_pt(jump_id, interface, pose);
388  }
389  }
390  return jumpToAttach;
391 }
392 
393 //std::map<char, LigandArea>
394 //MinimizeBackbone::get_ligand_areas(){
395 // return interface_builder_->get_ligand_areas();
396 //}
397 
399  int const & start,
400  int const & stop,
401  std::map<core::Size, core::Size> const jump_to_attach
402 ){
403  std::map<core::Size, core::Size>::const_iterator index =
404  jump_to_attach.begin();
405  std::map<core::Size, core::Size>::const_iterator const end =
406  jump_to_attach.end();
407  for (; index != end; ++index) {
408  int const attach_pt = (int) index->second;
409 
410  if (start < attach_pt && attach_pt < stop){
411  return index->second;
412  }
413  if (stop < attach_pt && attach_pt < start){
414  return index->second;
415  }
416  }
417  return 0;
418 }
419 
420 
422  core::Size const jump_id,
423  ligand_options::Interface const interface,
424  core::pose::Pose const & pose
425 ){
426  core::Size attach_pt = 1; // for now, attach ligand to residue 1
427  core::Real shortest_dist2 = 1e99;
428  //core::Vector center= protocols::geometry::downstream_centroid_by_jump(pose, jump_id);
429  const core::Size residue_id = pose.fold_tree().downstream_jump_residue(jump_id);
430  const core::conformation::Residue & residue = pose.residue(residue_id);
431  const core::Vector lig_nbr_vector = residue.nbr_atom_xyz();
432  //for(core::Size i = 1; i <= pose.n_residue(); ++i) { // only look at upstream residues, else multi-residue ligand will attach to itself
433  for (core::Size i = 1; i < residue_id; ++i) {
434  if (!pose.residue(i).is_protein() && interface[i].type != ligand_options::InterfaceInfo::non_interface) {
435  core::Real const new_dist2 = lig_nbr_vector.distance_squared(
436  pose.residue(i).xyz("CA"));
437  if (new_dist2 < shortest_dist2) {
438  shortest_dist2 = new_dist2;
439  attach_pt = i;
440  }
441  }
442  }
443 
444  return attach_pt;
445 }
446 
448  ligand_options::Interface & interface,
449  core::pose::Pose const & pose
450 ){
451  for(core::Size i=1; i <= interface.size(); ++i){
452  if(interface[i].type == ligand_options::InterfaceInfo::is_interface
453  && pose.residue(i).is_ligand()
454  ){
456  }
457  }
458 }
459 
460 } //namespace ligand_docking
461 } //namespace protocols