Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
util.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
11 /// @brief Align a random jump to template
12 /// @detailed
13 /// @author Yifan Song
14 
16 
17 #include <core/pose/Pose.hh>
18 #include <core/pose/util.hh>
23 #include <core/fragment/FragSet.hh>
24 #include <core/fragment/Frame.hh>
26 
28 #include <core/kinematics/Jump.hh>
29 #include <core/kinematics/Edge.hh>
30 #include <core/types.hh>
31 
32 #include <numeric/model_quality/rms.hh>
33 #include <numeric/model_quality/maxsub.hh>
34 #include <ObjexxFCL/FArray1D.hh>
35 #include <ObjexxFCL/FArray2D.hh>
36 #include <ObjexxFCL/format.hh>
37 
47 #include <core/pose/PDBInfo.hh>
48 
49 // dynamic fragpick
52 
53 
54 // symmetry
60 
61 // evaluation
62 #include <core/scoring/rms_util.hh>
64 #include <core/sequence/util.hh>
66 
67 #include <list>
68 
69 namespace protocols {
70 //namespace comparative_modeling {
71 namespace hybridization {
72 
73 using namespace core;
74 using namespace kinematics;
75 using namespace core::scoring::constraints;
76 
79  core::Size nres_tgt = pose.total_residue();
83  dynamic_cast<core::conformation::symmetry::SymmetricConformation const &> ( pose.conformation()) );
84  symm_info = SymmConf.Symmetry_Info();
85  nres_tgt = symm_info->num_independent_residues();
86  }
87  if (pose.residue(nres_tgt).aa() == core::chemical::aa_vrt) nres_tgt--;
88  while (!pose.residue(nres_tgt).is_protein()) nres_tgt--;
89  return nres_tgt;
90 }
91 
93  core::pose::Pose &pose,
95  utility::vector1 < core::Real > template_weights,
96  std::string cen_cst_file,
97  std::set< core::Size > ignore_res_for_AUTO) {
98  if (cen_cst_file == "AUTO") {
99  // automatic constraints
100  generate_centroid_constraints( pose, templates, template_weights, ignore_res_for_AUTO );
101  } else if (!cen_cst_file.empty() && cen_cst_file != "NONE") {
102  ConstraintSetOP constraint_set = ConstraintIO::get_instance()->read_constraints_new( cen_cst_file, new ConstraintSet, pose );
103  pose.constraint_set( constraint_set ); //reset constraints
104  }
105 }
106 
108  core::pose::Pose &pose,
110  utility::vector1 < core::Real > template_weights,
111  std::string cen_cst_file,
112  std::string fa_cst_file ) {
113 
114  // use fa if specified, otherwise centroid
115  if (fa_cst_file == "AUTO") {
116  // automatic fa constraints
117  generate_fullatom_constraints( pose, templates, template_weights );
118  } else if (fa_cst_file == "SELF") {
120  add_constraints.apply(pose);
121  } else if (!fa_cst_file.empty() && fa_cst_file != "NONE") {
122  ConstraintSetOP constraint_set = ConstraintIO::get_instance()->read_constraints_new( fa_cst_file, new ConstraintSet, pose );
123  pose.constraint_set( constraint_set ); //reset constraints
124  } else if (cen_cst_file == "AUTO") {
125  // automatic constraints
126  generate_centroid_constraints( pose, templates, template_weights );
127  } else if (!cen_cst_file.empty() && cen_cst_file != "NONE") {
128  ConstraintSetOP constraint_set = ConstraintIO::get_instance()->read_constraints_new( cen_cst_file, new ConstraintSet, pose );
129  pose.constraint_set( constraint_set ); //reset constraints
130  }
131 }
132 
134  core::pose::Pose &pose,
136  utility::vector1 < core::Real > /*template_weights*/,
137  std::set< core::Size > ignore_res )
138 {
139 
140  core::Size MINSEQSEP = 8;
141  core::Real MAXDIST = 12.0;
142  core::Size GAPBUFFER = 3;
143  core::Real COORDDEV = 1.0;
144 
145  pose.remove_constraints();
146 
147  // number of residues
148  core::Size nres_tgt = get_num_residues_nonvirt( pose );
149 
151  utility::vector1< utility::vector1< core::Real > > tgt_weights(nres_tgt);
152  for (int i=1; i<=(int)templates.size(); ++i) {
153  utility::vector1< bool > passed_gapcheck(nres_tgt,false);
154  for (int j=1; j<(int)templates[i]->total_residue(); ++j ) {
155  bool includeme=true;
156  for (int k=1; k<=(int)GAPBUFFER && includeme; ++k) {
157  if ( j-k < 1 || j+k > (int)templates[i]->total_residue() ) includeme=false;
158  else if (templates[i]->pdb_info()->number(j+k) - templates[i]->pdb_info()->number(j) != k ) includeme=false;
159  else if (templates[i]->pdb_info()->number(j-k) - templates[i]->pdb_info()->number(j) != -k ) includeme=false;
160  }
161  passed_gapcheck[j] = includeme;
162  }
163 
164  for (core::Size j=1; j<templates[i]->total_residue(); ++j ) {
165  if (!templates[i]->residue_type(j).is_protein()) continue;
166  if (!passed_gapcheck[j]) continue;
167  for (core::Size k=j+1; k<templates[i]->total_residue(); ++k ) {
168  if (!templates[i]->residue_type(k).is_protein()) continue;
169  if (!passed_gapcheck[k]) continue;
170  if (templates[i]->pdb_info()->number(k) - templates[i]->pdb_info()->number(j) < (int)MINSEQSEP) continue;
171  if ( ignore_res.count(templates[i]->pdb_info()->number(j)) ||
172  ignore_res.count(templates[i]->pdb_info()->number(k)) ) continue;
173  core::Real dist = templates[i]->residue(j).xyz(2).distance( templates[i]->residue(k).xyz(2) );
174  if ( dist <= MAXDIST ) {
175  pose.add_constraint(
176  new AtomPairConstraint( core::id::AtomID(2,templates[i]->pdb_info()->number(j)),
177  core::id::AtomID(2,templates[i]->pdb_info()->number(k)),
178  new ScalarWeightedFunc( 1.0, new SOGFunc( dist, COORDDEV ) )
179  //new ScalarWeightedFunc( template_weights[i], new SOGFunc( dist, COORDDEV ) )
180  )
181  );
182  }
183  }
184  }
185  }
186 }
187 
189  core::pose::Pose &pose,
191  utility::vector1 < core::Real > template_weights ) {
192  //fpd ... for now just use centroid variant
193  generate_centroid_constraints( pose, templates, template_weights);
194 }
195 
196 void add_strand_pairs_cst(core::pose::Pose & pose, utility::vector1< std::pair< core::Size, core::Size > > const strand_pairs) {
197  core::Real MAXDIST = 12.0;
198  core::Real COORDDEV = 1.0;
199  for (core::Size i=1; i<=strand_pairs.size(); ++i) {
200  std::pair< core::Size, core::Size > strand_pair = strand_pairs[i];
201  core::Real dist = pose.residue(strand_pair.first).xyz(2).distance( pose.residue(strand_pair.second).xyz(2) );
202  if ( dist <= MAXDIST ) {
203  pose.add_constraint(
204  new AtomPairConstraint( core::id::AtomID(2,strand_pair.first),
205  core::id::AtomID(2,strand_pair.second),
206  new ScalarWeightedFunc( 4.0, new SOGFunc( dist, COORDDEV ) ) // try to lock it down with a high weight
207  )
208  );
209  }
210  }
211 }
212 
213 void add_non_protein_cst(core::pose::Pose & pose, core::Real const cst_weight) {
214  core::Size n_prot_res = pose.total_residue();
215  while (!pose.residue(n_prot_res).is_protein()) n_prot_res--;
216  core::Size n_nonvirt = pose.total_residue();
217  while (!pose.residue(n_prot_res).is_protein()) n_nonvirt--;
218 
219  core::Real MAXDIST = 15.0;
220  core::Real COORDDEV = 3.0;
221  // constraint between protein and substrate
222  for (Size ires=1; ires<=n_prot_res; ++ires) {
223  if ( ! pose.residue_type(ires).has("CA") ) continue;
224  core::Size iatom = pose.residue_type(ires).atom_index("CA");
225 
226  for (Size jres=n_prot_res+1; jres<=n_nonvirt; ++jres) {
227  for (Size jatom=1; jatom<=pose.residue(jres).nheavyatoms(); ++jatom) {
228  core::Real dist = pose.residue(ires).xyz(iatom).distance( pose.residue(jres).xyz(jatom) );
229  if ( dist <= MAXDIST ) {
230  pose.add_constraint(
232  core::id::AtomID(jatom,jres),
234  )
235  );
236  }
237  }
238  }
239  }
240 
241  // constraint within substrate
242  for (Size ires=n_prot_res+1; ires<=n_nonvirt; ++ires) {
243  for (Size iatom=1; iatom<=pose.residue(ires).nheavyatoms(); ++iatom) {
244 
245  for (Size jres=ires; jres<=n_nonvirt; ++jres) {
246  for (Size jatom=1; jatom<=pose.residue(jres).nheavyatoms(); ++jatom) {
247  if ( ires == jres && iatom >= jatom) continue;
248  core::Real dist = pose.residue(ires).xyz(iatom).distance( pose.residue(jres).xyz(jatom) );
249  if ( dist <= MAXDIST ) {
250  pose.add_constraint(
252  core::id::AtomID(jatom,jres),
254  )
255  );
256  }
257  }
258  }
259  }
260  }
261 }
262 
263 bool discontinued_upper(core::pose::Pose const & pose, Size const seqpos) {
264  core::Real N_C_cutoff(2.0);
265 
266  if (seqpos == 1) return true;
267  if (!pose.residue_type(seqpos).is_polymer()) return true;
268  if (!pose.residue_type(seqpos-1).is_polymer()) return true;
269  if (pose.residue_type(seqpos).is_protein() && pose.residue_type(seqpos-1).is_protein()) {
270  if ( pose.residue(seqpos).xyz("N").distance(pose.residue(seqpos-1).xyz("C")) > N_C_cutoff ) {
271  return true;
272  }
273  }
274  return false;
275 }
276 
277 bool discontinued_lower(core::pose::Pose const & pose, Size const seqpos) {
278  core::Real N_C_cutoff(2.0);
279 
280  if (seqpos == pose.total_residue()) return true;
281  if (!pose.residue_type(seqpos).is_polymer()) return true;
282  if (!pose.residue_type(seqpos+1).is_polymer()) return true;
283  if ( pose.residue_type(seqpos).is_protein() && pose.residue_type(seqpos+1).is_protein()) {
284  if ( pose.residue(seqpos).xyz("C").distance(pose.residue(seqpos+1).xyz("N")) > N_C_cutoff ) {
285  return true;
286  }
287  }
288  return false;
289 }
290 
291 std::list < Size >
292 downstream_residues_from_jump(core::pose::Pose const & pose, Size const jump_number) {
293  std::list < Size > residue_list;
294  Size downstream_res = pose.fold_tree().jump_edge(jump_number).stop();
295  utility::vector1< Edge > edges = pose.fold_tree().get_outgoing_edges(downstream_res);
296 
297  // for jumps to singletons
298  residue_list.push_back(downstream_res);
299 
300  for (Size i_edge = 1; i_edge <= edges.size(); ++i_edge) {
301  if ( !edges[i_edge].is_polymer() ) continue;
302  Size start = edges[i_edge].start() <= edges[i_edge].stop() ? edges[i_edge].start() : edges[i_edge].stop();
303  Size stop = edges[i_edge].start() <= edges[i_edge].stop() ? edges[i_edge].stop() : edges[i_edge].start();
304  for ( Size ires = start; ires <= stop; ++ires ) {
305  residue_list.push_back(ires);
306  }
307  }
308  residue_list.sort();
309  residue_list.unique();
310  return residue_list;
311 }
312 
313 void
315  core::pose::Pose & pose,
316  core::pose::Pose const & ref_pose,
317  id::AtomID_Map< id::AtomID > const & atom_map,
318  bool iterate_convergence,
319  utility::vector1<core::Real> distance_thresholds,
320  core::Real min_coverage )
321 {
322  std::list <core::Size> residue_list;
323  for ( Size ires=1; ires<= pose.total_residue(); ++ires ) {
324  if ( !pose.residue(ires).is_protein() ) continue;
325  residue_list.push_back(ires);
326  }
327 
328  partial_align( pose, ref_pose, atom_map, residue_list, iterate_convergence, distance_thresholds, min_coverage );
329 }
330 
331 void
333  core::pose::Pose & pose,
334  core::pose::Pose const & ref_pose,
335  id::AtomID_Map< id::AtomID > const & atom_map,
336  std::list <Size> const & residue_list,
337  bool iterate_convergence,
338  utility::vector1<core::Real> distance_thresholds,
339  core::Real min_coverage )
340 {
344 
345  // default
346  if (distance_thresholds.size() == 0) {
347  distance_thresholds.push_back(6);
348  distance_thresholds.push_back(4);
349  distance_thresholds.push_back(3);
350  distance_thresholds.push_back(2);
351  distance_thresholds.push_back(1.5);
352  distance_thresholds.push_back(1);
353  }
354 
355  get_superposition_transformation( pose, ref_pose, atom_map, R, preT, postT );
356  apply_transformation( pose, residue_list, R, preT, postT );
357 
358  if (iterate_convergence) {
359  core::id::AtomID_Map< core::id::AtomID > updated_atom_map(atom_map);
360  core::Real coverage = 1.0;
361  core::Size natoms_aln = atom_map_valid_size(pose, updated_atom_map);
362 
363  //std::cout << "coverage: " << coverage << " " << natoms_aln << std::endl;
364 
365  for (int i=1; i<=(int)distance_thresholds.size() && coverage>=min_coverage; ++i) {
366  core::Real my_d_sq = distance_thresholds[i]*distance_thresholds[i];
367  bool converged = false;
368  while (!converged) {
369  core::id::AtomID_Map< core::id::AtomID > updated_atom_map_last_round = updated_atom_map;
370  updated_atom_map = update_atom_map(pose, ref_pose, atom_map, my_d_sq);
371  coverage = ((core::Real)(atom_map_valid_size(pose, updated_atom_map)))/natoms_aln;
372  //std::cout << "coverage: " << coverage << " " << natoms_aln << std::endl;
373  if (updated_atom_map == updated_atom_map_last_round || coverage<min_coverage) {
374  converged = true;
375  } else {
376  get_superposition_transformation( pose, ref_pose, updated_atom_map, R, preT, postT );
377  apply_transformation( pose, residue_list, R, preT, postT );
378  }
379  }
380  }
381  }
382 }
383 
385  core::pose::Pose const & pose,
387  )
388 {
389  core::Size n_valid = 0;
390  for ( Size ires=1; ires<= pose.total_residue(); ++ires ) {
391  for ( Size iatom=1; iatom<= pose.residue(ires).natoms(); ++iatom ) {
392  core::id::AtomID const & aid( atom_map[ id::AtomID( iatom,ires ) ] );
393  if (!aid.valid()) continue;
394  ++n_valid;
395  }
396  }
397  return n_valid;
398 }
399 
402  core::pose::Pose & pose,
403  core::pose::Pose const & ref_pose,
404  id::AtomID_Map< id::AtomID > const & atom_map,
405  core::Real distance_squared_threshold )
406 {
408 
410 
411  for ( Size ires=1; ires<= pose.total_residue(); ++ires ) {
412  for ( Size iatom=1; iatom<= pose.residue(ires).natoms(); ++iatom ) {
413  core::id::AtomID const & aid( atom_map[ id::AtomID( iatom,ires ) ] );
414  if (!aid.valid()) continue;
415 
416  if (pose.xyz(id::AtomID( iatom,ires )).distance_squared( ref_pose.xyz(aid) ) < distance_squared_threshold)
417  updated_atom_map[ id::AtomID( iatom,ires ) ] = aid;
418  }
419  }
420  return updated_atom_map;
421 }
422 
423 Size
425  core::pose::Pose & pose,
426  core::pose::Pose const & ref_pose,
427  id::AtomID_Map< id::AtomID > const & atom_map,
428  core::Real distance_squared_threshold
429  )
430 {
431  Size n_align=0;
432  for ( Size ires=1; ires<= pose.total_residue(); ++ires ) {
433  for ( Size iatom=1; iatom<= pose.residue(ires).natoms(); ++iatom ) {
434  core::id::AtomID const & aid( atom_map[ id::AtomID( iatom,ires ) ] );
435  if (!aid.valid()) continue;
436 
437  if (pose.xyz(id::AtomID( iatom,ires )).distance_squared( ref_pose.xyz(aid) ) < distance_squared_threshold) {
438  ++n_align;
439  }
440  }
441  }
442  return n_align;
443 
444 }
445 
446 // atom_map: from mod_pose to ref_pose
447 void
449  pose::Pose const & mod_pose,
450  pose::Pose const & ref_pose,
453 {
454  using namespace core;
455  using namespace core::id;
456  // count number of atoms for the array
457  Size total_mapped_atoms(0);
458  for ( Size ires=1; ires<= mod_pose.total_residue(); ++ires ) {
459  for ( Size iatom=1; iatom<= mod_pose.residue(ires).natoms(); ++iatom ) {
460  AtomID const & aid( atom_map[ id::AtomID( iatom,ires ) ] );
461  if (!aid.valid()) continue;
462 
463  ++total_mapped_atoms;
464  }
465  }
466 
467  preT = postT = numeric::xyzVector< core::Real >(0,0,0);
468  if (total_mapped_atoms <= 2) {
469  R.xx() = R.yy() = R.zz() = 1;
470  R.xy() = R.yx() = R.zx() = R.zy() = R.yz() = R.xz() = 0;
471  return;
472  }
473 
474  ObjexxFCL::FArray2D< core::Real > final_coords( 3, total_mapped_atoms );
475  ObjexxFCL::FArray2D< core::Real > init_coords( 3, total_mapped_atoms );
476  preT = postT = numeric::xyzVector< core::Real >(0,0,0);
477  Size atomno(0);
478  for ( Size ires=1; ires<= mod_pose.total_residue(); ++ires ) {
479  for ( Size iatom=1; iatom<= mod_pose.residue(ires).natoms(); ++iatom ) {
480  AtomID const & aid( atom_map[ id::AtomID( iatom,ires ) ] );
481  if (!aid.valid()) continue;
482  ++atomno;
483 
484  numeric::xyzVector< core::Real > x_i = mod_pose.residue(ires).atom(iatom).xyz();
485  preT += x_i;
486  numeric::xyzVector< core::Real > y_i = ref_pose.xyz( aid );
487  postT += y_i;
488 
489  for (int j=0; j<3; ++j) {
490  init_coords(j+1,atomno) = x_i[j];
491  final_coords(j+1,atomno) = y_i[j];
492  }
493  }
494  }
495 
496  preT /= (float) total_mapped_atoms;
497  postT /= (float) total_mapped_atoms;
498  for (int i=1; i<=(int)total_mapped_atoms; ++i) {
499  for ( int j=0; j<3; ++j ) {
500  init_coords(j+1,i) -= preT[j];
501  final_coords(j+1,i) -= postT[j];
502  }
503  }
504 
505  // get optimal superposition
506  // rotate >init< to >final<
507  ObjexxFCL::FArray1D< numeric::Real > ww( total_mapped_atoms, 1.0 );
508  ObjexxFCL::FArray2D< numeric::Real > uu( 3, 3, 0.0 );
509  numeric::Real ctx;
510 
511  numeric::model_quality::findUU( init_coords, final_coords, ww, total_mapped_atoms, uu, ctx );
512  R.xx( uu(1,1) ); R.xy( uu(2,1) ); R.xz( uu(3,1) );
513  R.yx( uu(1,2) ); R.yy( uu(2,2) ); R.yz( uu(3,2) );
514  R.zx( uu(1,3) ); R.zy( uu(2,3) ); R.zz( uu(3,3) );
515 }
516 
517 void
519  pose::Pose & mod_pose,
520  std::list <Size> const & residue_list,
522 ) {
523  using namespace ObjexxFCL;
524  // translate xx2 by COM and fill in the new ref_pose coordinates
527 
528  for (std::list<Size>::const_iterator it = residue_list.begin();
529  it != residue_list.end();
530  ++it) {
531  Size ires = *it;
532  for ( Size iatom=1; iatom<= mod_pose.residue_type(ires).natoms(); ++iatom ) { // use residue_type to prevent internal coord update
533  ids.push_back(core::id::AtomID(iatom,ires));
534  positions.push_back(postT + (R*( mod_pose.xyz(core::id::AtomID(iatom,ires)) - preT )));
535  }
536  }
537  mod_pose.batch_set_xyz(ids,positions);
538 }
539 
543  core::scoring::dssp::Dssp dssp( pose );
544 
545  // number of residues
546  core::Size nres_tgt = get_num_residues_nonvirt( pose );
547 
548  // sequence
549  std::string tgt_seq = pose.sequence();
550  std::string tgt_ss = dssp.get_dssp_secstruct();
551 
552  // pick from vall based on template SS + target sequence
553  for ( core::Size j=1; j<=nres_tgt-len+1; ++j ) {
554  bool crosses_cut = false;
555  for (core::Size k=j; k<j+len-1; ++k) // it's alright if the last residue is a cutpoint
556  crosses_cut |= pose.fold_tree().is_cutpoint( k );
557 
558  if (!crosses_cut) {
559  core::fragment::FrameOP frame = new core::fragment::Frame( j, len );
560  frame->add_fragment(
562  tgt_ss.substr( j-1, len ), tgt_seq.substr( j-1, len ), nfrag, true, core::fragment::IndependentBBTorsionSRFD()
563  )
564  );
565  fragset->add( frame );
566  }
567  }
568  return fragset;
569 }
570 
572  protocols::loops::Loops & template_chunk,
573  core::pose::PoseCOP template_pose
574 ) {
575  protocols::loops::Loops renumbered_template_chunks(template_chunk);
576  for (core::Size ichunk = 1; ichunk<=template_chunk.num_loop(); ++ichunk) {
577  Size seqpos_start_templ = template_chunk[ichunk].start();
578  Size seqpos_start_target = template_pose->pdb_info()->number(seqpos_start_templ);
579  renumbered_template_chunks[ichunk].set_start( seqpos_start_target );
580 
581  Size seqpos_stop_templ = template_chunk[ichunk].stop();
582  Size seqpos_stop_target = template_pose->pdb_info()->number(seqpos_stop_templ);
583  renumbered_template_chunks[ichunk].set_stop( seqpos_stop_target );
584  }
585  return renumbered_template_chunks;
586 }
587 
589  runtime_assert( native.total_residue() > 0 && pose.total_residue() > 0 );
590  if ( !aln ) {
591  core::sequence::SequenceOP model_seq ( new core::sequence::Sequence( pose.sequence(), "model", 1 ) );
592  core::sequence::SequenceOP native_seq( new core::sequence::Sequence( native.sequence(), "native", 1 ) );
594  *aln = align_naive(model_seq,native_seq);
595  }
596 
597  int n_atoms;
598  ObjexxFCL::FArray2D< core::Real > p1a, p2a;
599  protocols::comparative_modeling::gather_coords( pose, native, *aln, n_atoms, p1a, p2a );
600 
601  core::Real m_1_1, m_2_2, m_3_3, m_4_3, m_7_4;
602  return core::scoring::xyz_gdtmm( p1a, p2a, m_1_1, m_2_2, m_3_3, m_4_3, m_7_4 );
603 }
604 
605 
606 
607 } // hybridize
608 //} // comparative_modeling
609 } // protocols