Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ThreadingMover.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 protocols/comparative_modeling/ThreadingMover.cc
11 /// @brief method declarations for ThreadingMover.
12 /// @author James Thompson
13 
16 #include <protocols/loops/Loops.hh>
19 
20 #include <core/types.hh>
21 
24 
25 #include <core/pose/util.hh>
26 #include <core/pose/Pose.hh>
27 #include <core/pose/PDBInfo.hh>
28 
31 
33 
34 #include <core/id/AtomID.hh>
35 #include <core/id/AtomID_Map.hh>
37 #include <core/id/NamedAtomID.hh>
38 
45 #include <core/sequence/util.hh>
46 
47 #include <core/pack/optimizeH.hh>
49 
54 
57 #include <basic/Tracer.hh>
58 
59 #include <utility/vector1.hh>
60 #include <utility/string_util.hh>
61 
62 // C++ headers
63 #include <string>
64 
65 // option key includes
66 #include <basic/options/option.hh>
67 #include <basic/options/keys/cm.OptionKeys.gen.hh>
68 
70 
71 //Auto Headers
72 #include <core/pose/util.tmpl.hh>
73 
74 namespace protocols {
75 namespace comparative_modeling {
76 
77 static basic::Tracer tr("protocols.comparative_modeling.threading");
78 
81  core::pose::Pose const & template_pose
82 ) :
83  protocols::moves::Mover( "ThreadingMover" ),
84  query_index_( 1 ),
85  template_index_( 2 ),
86  template_pose_( template_pose ),
87  align_( align ),
88  build_query_loops_( true ),
89  repack_query_( true ),
90  randomize_loop_coords_( false ),
91  min_loop_size_( 3 )
92 {}
93 
94 /// @brief Returns the index of the query sequence in SequenceAlignment
95 /// object.
97  return query_index_;
98 }
99 
100 /// @brief Returns the index of the template sequence in SequenceAlignment
101 /// object.
103  return template_index_;
104 }
105 
106 /// @brief Returns the SequenceAlignment object used in threading.
108  return align_;
109 }
110 
111 /// @brief Sets the index of the query sequence in SequenceAlignment object.
113  query_index_ = new_index;
114 }
115 
116 /// @brief Sets the index of the template sequence in SequenceAlignment
117 /// object.
119  template_index_ = new_index;
120 }
121 
122 /// @brief Sets the SequenceAlignment associated with this object.
124  align_ = new_align;
125 }
126 
129 }
130 
131 //boolean setters
132 void ThreadingMover::build_loops( bool setting ) {
133  build_query_loops_ = setting;
134 }
135 
137  randomize_loop_coords_ = setting;
138 }
139 
140 void ThreadingMover::repack_query( bool setting ) {
141  repack_query_ = setting;
142 }
143 
144 //boolean getters
146  return build_query_loops_;
147 }
148 
150  return repack_query_;
151 }
152 
154  return randomize_loop_coords_;
155 }
156 
158  min_loop_size_ = new_size;
159 }
160 
162  return min_loop_size_;
163 }
164 
166  return frag_libs_;
167 }
168 
171 ) {
172  frag_libs_ = new_libs;
173 }
174 
176  core::pose::Pose const & query_pose
177 ) const {
178  // put checks here to make sure that the template pose and the template
179  // pose in the alignment file match up!
180  using namespace core::id;
181  using namespace core::sequence;
182 
183  SequenceOP query_sequence(
184  new Sequence(
185  align_.sequence( 1 )->ungapped_sequence(),
186  align_.sequence( 1 )->id(),
187  align_.sequence( 1 )->start()
188  )
189  );
190 
191  SequenceOP aligned_template(
193  );
194 
195  SequenceOP t_align_seq(
196  new Sequence(
197  aligned_template->ungapped_sequence(),
198  aligned_template->id() + "_align_seq",
199  aligned_template->start()
200  )
201  );
202 
203  SequenceOP t_pdb_seq(
204  new Sequence (
206  aligned_template->id() + "_pdb_seq",
207  1
208  )
209  );
210 
211  // construct an intermediate alignment of the sequence from the alignment
212  // to the sequence in the PDB file.
213  SWAligner sw_align;
214  ScoringSchemeOP ss( new SimpleScoringScheme( 120, 0, -100, 0 ) );
215 
216  tr.Debug << "query sequence : " << query_pose.sequence() << std::endl;
217  tr.Debug << "query sequence : " << (*query_sequence) << std::endl;
218  tr.Debug << "aligned_template : " << (*aligned_template) << std::endl;
219  tr.Debug << "template_sequence (aln): " << (*t_align_seq) << std::endl;
220  tr.Debug << "template_sequence (pdb): " << (*t_pdb_seq) << std::endl;
221 
222  SequenceAlignment intermediate = sw_align.align( t_align_seq, t_pdb_seq, ss );
223 
224  if ( intermediate.identities() != intermediate.length() ) {
225  tr.Warning << "Error: potential mismatch between sequence from alignment ";
226  tr.Warning << " and sequence from PDB!" << std::endl;
227  tr.Warning << "alignment: " << std::endl << intermediate
228  << std::endl;
229  }
230 
231  SequenceMapping query_to_fullseq = align_.sequence_mapping(
233  );
234  tr.Debug << "Query: " << *align_.sequence( query_index_ ) << std::endl;
235  tr.Debug << "Template: " << *align_.sequence( template_index_ ) << std::endl;
236  tr.Debug << "Original Mapping:" << query_index_ << "-->" << template_index_
237  << std::endl;
238  query_to_fullseq.show( tr.Debug );
239 
240  SequenceMapping intermed_map = intermediate.sequence_mapping( 1, 2 );
241 
242  // final mapping is the mapping from query to the template PDB sequence,
243  // rather then the direct template sequence.
245  query_to_fullseq, intermed_map
246  );
247  tr.Debug << "Transitive Map" << std::endl;
248  query_to_pdbseq.show( tr.Debug );
249 
250  return query_to_pdbseq;
251 }
252 
254  core::pose::Pose & query_pose
255 ) {
256  using core::Real;
257  using core::Size;
258  using std::string;
259  using utility::vector1;
260  using namespace basic::options;
261  using namespace basic::options::OptionKeys;
262 
263  core::id::SequenceMapping query_to_pdbseq = get_qt_mapping(query_pose);
264  tr.Debug << "mapping from " << query_index_ << " to " << template_index_
265  << std::endl;
266  query_to_pdbseq.show( tr.Debug );
267 
268  std::string const template_id(
269  utility::file_basename( template_pose_.pdb_info()->name() )
270  );
271  core::pose::add_score_line_string( query_pose, "template", template_id );
272 
273  core::Size n_copied( 0 );
274 
275  core::id::AtomID_Mask missing( true );
276  core::pose::initialize_atomid_map( missing, query_pose ); // used for repacking atoms
277  for ( Size resi = 1; resi <= query_pose.total_residue(); resi++ ) {
278  Size const t_resi = query_to_pdbseq[ resi ];
279 
280  // skip this residue if we're not aligned
281  if ( t_resi == 0 ) {
282  continue;
283  }
284 
285  if ( t_resi > template_pose_.total_residue() ) {
286  tr.Error << "Error: don't have residue " << t_resi
287  << " in template_pose!" << std::endl;
288 
289  tr.Error << "template_pose.total_residue() == "
290  << template_pose_.total_residue() << std::endl;
291  continue;
292  }
293 
294  tr.Debug << "copying residue in query " << resi << " from template residue "
295  << t_resi << std::endl;
296  for ( Size atomj = 1; atomj <= query_pose.residue(resi).natoms(); ++atomj ) {
297  std::string const atom_name( query_pose.residue(resi).atom_name( atomj ));
298  std::string t_atom_name = atom_name;
299 
300  //determine if we copy this atom: backbone and CB always, sidechain if identical aa
301  // core::id::AtomID cb_id(
302  // core::id::NamedAtomID( "CB", resi ),
303  // query_pose,
304  // false /*don't raise exception we check explicitly*/
305  // );
306  if ( !query_pose.residue(resi).atom_is_backbone(atomj)
307  && query_pose.residue(resi).name1() != template_pose_.residue(t_resi).name1()
308  && query_pose.residue(resi).atom_index("CB") != atomj
309  ) continue;
310 
311  // fix OXT/O ambiguity in template
312  if ( !template_pose_.residue_type(t_resi).has( atom_name ) ) {
313  if ( template_pose_.residue_type(t_resi).has_atom_name("OXT") && atom_name == " O " )
314  t_atom_name = " OXT";
315  else if ( template_pose_.residue_type(t_resi).has_atom_name("O") && atom_name == " OXT" )
316  t_atom_name = " O ";
317  }
318 
319  core::id::NamedAtomID query_id ( atom_name, resi );
320  core::id::NamedAtomID template_id( t_atom_name, t_resi );
321 
322  // check to make sure that both poses have this atom_name
323  if ( !query_pose.residue_type(resi).has( atom_name ) ) {
324  tr.Warning << "skipping atom,position " << atom_name << "," << resi
325  << " because query doesn't have atom " << atom_name << "."
326  << std::endl;
327  continue;
328  }
329  if ( !template_pose_.residue_type(t_resi).has( t_atom_name ) ) {
330  tr.Warning << "skipping atom,position " << atom_name << "," << resi
331  << " because template doesn't have atom " << t_atom_name << "."
332  << std::endl;
333  continue;
334  }
335 
336  missing[ core::id::AtomID( atomj, resi ) ] = false;
337  query_pose.set_xyz( query_id, template_pose_.xyz( template_id ) );
338  } // for atom_i
339 
340  //fpd idealize all H
341  core::conformation::Residue res_to_fix = query_pose.residue(resi);
342  core::conformation::idealize_hydrogens( res_to_fix, query_pose.conformation() );
343  query_pose.replace_residue( resi, res_to_fix, false );
344 
345  ++n_copied;
346  } // for resi
347 
348  tr.Debug << "Built threading model for sequence "
349  << query_pose.sequence() << std::endl;
350  tr.Debug << "Copied " << n_copied << " / "
351  << query_pose.total_residue() << " from "
352  << align_.sequence(template_index_)->id() << std::endl;
353 
354  if ( randomize_loop_coords() ) {
355  for ( core::Size ii = 1; ii <= query_pose.total_residue(); ++ii ) {
356  core::conformation::ResidueOP iires = query_pose.residue( ii ).clone();
358  query_pose.replace_residue( ii, *iires, false );
359  }
360 
361  // randomize missing atoms
362  randomize_selected_atoms(query_pose,missing);
363  } // if randomize_loop_coords()
364 
365  if ( build_loops() ) {
367  tr.Debug << "building query loops." << std::endl;
368  loops::LoopsOP query_loops = loops_from_alignment(
369  query_pose.total_residue(), align_, min_loop_size()
370  );
371  query_loops->choose_cutpoints( query_pose );
372  tr.Debug << query_loops << std::endl;
373 
374  if ( query_loops->size() > 0 ) {
375  // switch to centroid ResidueTypeSet for loop remodeling
376  std::string const orig_rsd_set_name(
377  query_pose.residue_type(1).residue_type_set().name()
378  );
379 
382 
384  option[ cm::loop_mover ](), query_loops
385  );
386  for ( Size ii = 1; ii <= frag_libs().size(); ++ii ) {
387  loop_mover->add_fragments( frag_libs()[ii] );
388  }
389  loop_mover->apply( query_pose );
390 
391  // switch back to original ResidueTypeSet after loop modeling
392  if ( orig_rsd_set_name != core::chemical::CENTROID ) {
394  query_pose,
395  orig_rsd_set_name
396  );
397  }
398  } else {
399  tr.Warning << "No loops found!" << std::endl;
400  }
401  } // build_query_loops
402 
403  // steal side chains
404  //std::cout << "copying sidechains" << std::endl;
405  //StealSideChainsMover sc_mover( template_pose_, query_to_pdbseq );
406  //sc_mover.apply( query_pose );
407  //std::cout << "finished copying sidechains" << std::endl;
408 
409  // repack the structure if specified by the user
410  if ( repack_query() ) {
411  using namespace core::scoring;
412  ScoreFunctionOP scorefxn( getScoreFunction() );
413 
414  // repack missing sidechains
415  core::id::AtomID_Mask missing( true );
416  core::pose::initialize_atomid_map( missing, query_pose );
417  tr.Debug << "repacking residues on pose with ScoreFunction: " << std::endl;
418  scorefxn->show( tr.Debug );
419  tr.Debug << std::endl << std::endl;
420  core::pack::pack_missing_sidechains( query_pose, missing );
421 
422  tr.Debug << "setting up ideal hydrogen geometry on all residues."
423  << std::endl;
424  for ( core::Size ii = 1; ii <= query_pose.total_residue(); ++ii ) {
425  core::conformation::ResidueOP iires = query_pose.residue( ii ).clone();
427  query_pose.replace_residue( ii, *iires, false );
428  }
429 
430  tr.Debug << "optimizing hydrogen placement with the packer."
431  << std::endl;
432  core::pack::optimize_H_and_notify( query_pose, missing );
433 
434  scorefxn->set_weight( core::scoring::peptide_bond, 1.0 );
435  (*scorefxn)(query_pose);
436  scorefxn->show( tr.Debug, query_pose );
437  } // repack_query
438 
439  tr.flush();
440 } // apply
441 
444  return "ThreadingMover";
445 }
446 
447 } // comparative_modeling
448 } // protocols