Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CartesianSampler.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
12 /// @author Yifan Song
13 /// @author Frank DiMaio
14 
19 #include <basic/datacache/BasicDataCache.hh>
20 
22 #include <protocols/moves/Mover.hh>
25 #include <protocols/relax/util.hh>
26 
29 
33 
35 #include <protocols/loops/Loops.hh>
36 
39 #include <core/scoring/rms_util.hh>
41 #include <core/scoring/Energies.hh>
42 #include <core/sequence/util.hh>
46 
47 #include <core/pose/Pose.hh>
48 #include <core/pose/PDBInfo.hh>
49 #include <core/pose/Remarks.hh>
50 #include <core/pose/selection.hh>
52 
53 #include <core/pose/util.hh>
54 
57 
64 
70 
74 #include <core/scoring/Energies.hh>
75 
81 
84 #include <core/fragment/FragSet.hh>
85 #include <core/fragment/Frame.hh>
88 
89 // symmetry
94 
95 
96 #include <utility/excn/Exceptions.hh>
97 #include <utility/file/file_sys_util.hh>
98 
99 #include <numeric/random/random.hh>
100 #include <numeric/xyzVector.hh>
101 #include <numeric/xyz.functions.hh>
102 #include <numeric/model_quality/rms.hh>
103 #include <numeric/random/WeightedSampler.hh>
104 
105 #include <basic/options/option.hh>
106 #include <basic/options/option_macros.hh>
107 #include <basic/options/keys/OptionKeys.hh>
108 #include <basic/options/keys/in.OptionKeys.gen.hh>
109 #include <basic/options/keys/cm.OptionKeys.gen.hh>
110 
111 #include <utility/tag/Tag.hh>
112 #include <utility/string_util.hh>
113 #include <basic/Tracer.hh>
114 
115 #include <boost/unordered/unordered_map.hpp>
116 
117 namespace protocols {
118 //namespace comparative_modeling {
119 namespace hybridization {
120 
121 static basic::Tracer TR("protocols.hybridization.CartesianSampler");
122 static numeric::random::RandomGenerator RG(8403155);
123 
124 /////////////
125 // creator
129 }
130 
133  return new CartesianSampler;
134 }
135 
138  return "CartesianSampler";
139 }
140 
141 ////////////
142 
144  init();
145 }
146 
149  init();
150 
151  fragments_ = fragments_in;
153 }
154 
155 void
157  using namespace basic::options;
158  using namespace basic::options::OptionKeys;
159 
160  overlap_ = 2;
161  ncycles_ = 250;
162 
163  fragment_bias_strategy_ = "uniform";
164 
165  // default scorefunction
167 }
168 
169 void
171  core::Size nfragsets = fragments_.size();
172 
173  // map positions to fragments
174  library_.resize( nfragsets );
175  for (int i=1; i<=(int)nfragsets; ++i) {
176  for (core::fragment::FrameIterator j = fragments_[i]->begin(); j != fragments_[i]->end(); ++j) {
177  core::Size position = (*j)->start();
178  library_[i][position] = **j;
179  }
180  }
181 }
182 
185 
186 void
188  core::Size start = frame.start(),len = frame.length();
189  core::Size end = start + len - 1;
190 
191  int aln_len = overlap_;
192  runtime_assert( overlap_>=1 && overlap_<=len/2);
193 
194  // number of protein residues in the asymmetric unit
195  core::Size nres = pose.total_residue();
199  dynamic_cast<core::conformation::symmetry::SymmetricConformation &> ( pose.conformation()) );
200  symm_info = SymmConf.Symmetry_Info();
201  nres = symm_info->num_independent_residues();
202  }
203  while (!pose.residue(nres).is_protein()) nres--;
204 
205  bool nterm = ( (start == 1) || pose.fold_tree( ).is_cutpoint(start-1) );
206  bool cterm = ( (end == nres) || pose.fold_tree( ).is_cutpoint(end) );
207 
208  // insert frag
209  core::pose::Pose pose_copy = pose;
210 
211  ObjexxFCL::FArray1D< numeric::Real > ww( 2*4*aln_len, 1.0 );
212  ObjexxFCL::FArray2D< numeric::Real > uu( 3, 3, 0.0 );
213  numeric::xyzVector< core::Real > com1(0,0,0), com2(0,0,0);
214 
215  for (int i=0; i<(int)len; ++i) {
217  }
218 
219  int maxtries = frame.nr_frags() / 2;
220  for (int tries = 0; tries<maxtries; ++tries) {
221  ww = 1.0;
222  uu = 0.0;
223  com1 = numeric::xyzVector< core::Real >(0,0,0);
224  com2 = numeric::xyzVector< core::Real >(0,0,0);
225 
226  // grab coords
227  ObjexxFCL::FArray2D< core::Real > init_coords( 3, 2*4*aln_len );
228  for (int ii=-aln_len; ii<aln_len; ++ii) {
229  int i = (ii>=0) ? (nterm?len-ii-1:ii) : (cterm?-ii-1:len+ii);
230  numeric::xyzVector< core::Real > x_1 = pose.residue(start+i).atom(" C ").xyz();
231  numeric::xyzVector< core::Real > x_2 = pose.residue(start+i).atom(" O ").xyz();
232  numeric::xyzVector< core::Real > x_3 = pose.residue(start+i).atom(" CA ").xyz();
233  numeric::xyzVector< core::Real > x_4 = pose.residue(start+i).atom(" N ").xyz();
234  com1 += x_1+x_2+x_3+x_4;
235  for (int j=0; j<3; ++j) {
236  init_coords(j+1,4*(ii+aln_len)+1) = x_1[j];
237  init_coords(j+1,4*(ii+aln_len)+2) = x_2[j];
238  init_coords(j+1,4*(ii+aln_len)+3) = x_3[j];
239  init_coords(j+1,4*(ii+aln_len)+4) = x_4[j];
240  }
241  }
242  com1 /= 2.0*4.0*aln_len;
243  for (int ii=0; ii<2*4*aln_len; ++ii) {
244  for ( int j=0; j<3; ++j ) init_coords(j+1,ii+1) -= com1[j];
245  }
246 
247  core::Size toget = numeric::random::random_range( 1, frame.nr_frags() );
248  frame.apply( toget, pose_copy );
249 
250  // grab new coords
251  ObjexxFCL::FArray2D< core::Real > final_coords( 3, 2*4*aln_len );
252  for (int ii=-aln_len; ii<aln_len; ++ii) {
253  int i = (ii>=0) ? (nterm?len-ii-1:ii) : (cterm?-ii-1:len+ii);
254  numeric::xyzVector< core::Real > x_1 = pose_copy.residue(start+i).atom(" C ").xyz();
255  numeric::xyzVector< core::Real > x_2 = pose_copy.residue(start+i).atom(" O ").xyz();
256  numeric::xyzVector< core::Real > x_3 = pose_copy.residue(start+i).atom(" CA ").xyz();
257  numeric::xyzVector< core::Real > x_4 = pose_copy.residue(start+i).atom(" N ").xyz();
258  com2 += x_1+x_2+x_3+x_4;
259  for (int j=0; j<3; ++j) {
260  final_coords(j+1,4*(ii+aln_len)+1) = x_1[j];
261  final_coords(j+1,4*(ii+aln_len)+2) = x_2[j];
262  final_coords(j+1,4*(ii+aln_len)+3) = x_3[j];
263  final_coords(j+1,4*(ii+aln_len)+4) = x_4[j];
264  }
265  }
266  com2 /= 2.0*4.0*aln_len;
267  for (int ii=0; ii<2*4*aln_len; ++ii) {
268  for ( int j=0; j<3; ++j ) final_coords(j+1,ii+1) -= com2[j];
269  }
270 
271  numeric::Real ctx; float rms;
272  numeric::model_quality::findUU( final_coords, init_coords, ww, 2*4*aln_len, uu, ctx );
273  numeric::model_quality::calc_rms_fast( rms, final_coords, init_coords, ww, 2*4*aln_len, ctx );
274 
275  if (rms < 0.5) break;
276  if (tries >= maxtries/4 && rms < 1) break;
277  if (tries >= maxtries/2 && rms < 1.5) break;
278  }
279 
281  R.xx( uu(1,1) ); R.xy( uu(2,1) ); R.xz( uu(3,1) );
282  R.yx( uu(1,2) ); R.yy( uu(2,2) ); R.yz( uu(3,2) );
283  R.zx( uu(1,3) ); R.zy( uu(2,3) ); R.zz( uu(3,3) );
284 
285  // apply rotation to ALL atoms
286  // x_i' <- = R*x_i + com1;
287  for ( Size i = 0; i < len; ++i ) {
288  for ( Size j = 1; j <= pose.residue_type(start+i).natoms(); ++j ) {
289  core::id::AtomID id( j, start+i );
290  pose.set_xyz( id, R * ( pose_copy.xyz(id) - com2) + com1 );
291  }
292  }
293 }
294 
295 void
297  using namespace core::scoring;
298 
299  utility::vector1< core::Real > fragmentProbs;
300  frag_bias_.resize( fragments_.size() );
301 
302  // get nres, accounting for symmetry/vrt/ligands
303  core::Size nres = pose.total_residue();
307  dynamic_cast<core::conformation::symmetry::SymmetricConformation const &> ( pose.conformation()) );
308  symminfo = SymmConf.Symmetry_Info();
309  nres = symminfo->num_independent_residues();
310  }
311  while (!pose.residue(nres).is_protein()) nres--;
312 
313  if (fragment_bias_strategy_ == "density") {
314  // find segments with worst agreement to the density
316  edm.setScoreWindowContext( true );
317  edm.setWindow( 3 );
318 
319  // score the pose
321  myscore->set_weight( core::scoring::elec_dens_window, 1.0 );
322  if (pose.is_fullatom())
323  myscore->set_weight( core::scoring::fa_rep, 1.0 );
324  else
325  myscore->set_weight( core::scoring::vdw, 1.0 );
326 
328  myscore = new core::scoring::symmetry::SymmetricScoreFunction(*myscore);
329  }
330 
332  per_resCC.resize(nres);
333  fragmentProbs.resize(nres);
334  core::Real CCsum=0, CCsum2=0;
335  (*myscore)(pose);
336 
337  for (int r=1; r<=(int)nres; ++r) {
338  per_resCC[r] = core::scoring::electron_density::getDensityMap().matchRes( r , pose.residue(r), pose, symminfo , false);
339  CCsum += per_resCC[r];
340  CCsum2 += per_resCC[r]*per_resCC[r];
341  }
342  CCsum /= nres;
343  CCsum2 = sqrt( CCsum2/nres-CCsum*CCsum );
344 
345  for (int r=1; r<=(int)nres; ++r) {
346  fragmentProbs[r] = exp( (CCsum-per_resCC[r])/CCsum2 );
347  TR << "Prob_dens_density( " << r << " ) = " << fragmentProbs[r] << " ; CC=" << per_resCC[r] << " (Z=" << (CCsum-per_resCC[r])/CCsum2 << ")" << std::endl;
348  }
349  } else if (fragment_bias_strategy_ == "bfactors") {
350  // find segments with highest bfactors
351  fragmentProbs.resize(nres);
352  core::Real Btemp=25; // no idea what value makes sense here
353  // with Btemp = 25, a B=100 is ~54 times more likely to be sampled than B=0
354 
355  runtime_assert( pose.pdb_info() );
356  for (int r=1; r<=(int)nres; ++r) {
357  core::Real Bsum=0;
359  for (core::Size atm=1; atm<=nbb; ++atm) {
360  Bsum += pose.pdb_info()->temperature( r, atm );
361  }
362  Bsum /= nbb;
363  fragmentProbs[r] = exp( Bsum/Btemp );
364  TR << "Prob_dens_bfact( " << r << " ) = " << fragmentProbs[r] << " ; B=" << Bsum << std::endl;
365  }
366  } else if (fragment_bias_strategy_ == "rama") {
367  // find segments with worst rama score
368  core::Real Rtemp=1; // again, this is a guess
369 
370  // score the pose
372  myscore->set_weight( core::scoring::rama, 1.0 );
374  myscore = new core::scoring::symmetry::SymmetricScoreFunction(*myscore);
375  }
376 
377  Energies & energies( pose.energies() );
378  (*myscore)(pose);
379 
380  for (int r=1; r<=(int)nres; ++r) {
381  EnergyMap & emap( energies.onebody_energies( r ) );
382  // i dont think this will work for symmetric systems where 1st subunit is not the scoring one
383  core::Real ramaScore = emap[ rama ];
384  fragmentProbs[r] = exp( ramaScore / Rtemp );
385  TR << "Prob_dens_rama( " << r << " ) = " << fragmentProbs[r] << " ; rama=" << ramaScore << std::endl;
386  }
387  } else if (fragment_bias_strategy_ == "user") {
388  // user defined segments to rebuild
389  runtime_assert( user_pos_.size()>0 );
390 
391  for (int r=1; r<=(int)nres; ++r) {
392  fragmentProbs[r] = 0.0;
393  if ( user_pos_.find(r) != user_pos_.end() ) fragmentProbs[r] = 1.0;
394  TR << "Prob_dens_user( " << r << " ) = " << fragmentProbs[r] << std::endl;
395  }
396  } else {
397  // default to uniform
398  for (int r=1; r<=(int)nres; ++r) {
399  fragmentProbs[r] = 1.0;
400  TR << "Prob_dens_uniform( " << r << " ) = " << 1.0 << std::endl;
401  }
402  }
403 
404 
405  // for each fragment size, smooth over the fragment window
406  // - handle mapping from frame->seqpos
407  for (Size i_frag_set = 1; i_frag_set<=fragments_.size(); ++i_frag_set) {
408  utility::vector1< core::Real > frame_weights(fragments_[i_frag_set]->nr_frames(), 0.0);
409  for (Size i_frame = 1; i_frame <= fragments_[i_frag_set]->nr_frames(); ++i_frame) {
410  core::fragment::FrameIterator frame_it = fragments_[i_frag_set]->begin(); // first frame of the fragment library
411  advance(frame_it, i_frame-1); // point frame_it to the i_frame of the library
412  core::Size seqpos_start = (*frame_it)->start(); // find starting and ending residue seqpos of the inserted fragment
413  core::Size seqpos_end = (*frame_it)->end();
414 
415  frame_weights[i_frame] = 0;
416  for(int i_pos = (int)seqpos_start; i_pos<=(int)seqpos_end; ++i_pos)
417  frame_weights[i_frame] += fragmentProbs[i_pos];
418  frame_weights[i_frame] /= (seqpos_end-seqpos_start+1);
419  }
420  frag_bias_[i_frag_set].weights(frame_weights);
421  }
422 }
423 
424 void
426  using namespace basic::options;
427  using namespace basic::options::OptionKeys;
428  using namespace core::pose::datacache;
429 
430  // autogenerate fragments if they are not loaded yet
431  if (fragments_.size() == 0) {
432  fragments_.push_back( create_fragment_set(pose, 9, 25) );
434  }
435 
436  // using the current fragment_bias_strategy_, compute bias
437  // do this from fullatom (if the input pose is fullatom)
438  compute_fragment_bias(pose);
439 
440  //
441  bool fullatom_input = pose.is_fullatom();
442  protocols::moves::MoverOP restore_sc;
443  if (fullatom_input) {
444  restore_sc = new protocols::simple_moves::ReturnSidechainMover( pose );
446  tocen->apply( pose );
447 
448  // to do: save b factors
449  }
450 
451  // minimizer
452  core::optimization::MinimizerOptions options_minilbfgs( "lbfgs_armijo_nonmonotone", 0.01, true, false, false );
453  options_minilbfgs.max_iter(5);
454  core::optimization::MinimizerOptions options_lbfgs( "lbfgs_armijo_nonmonotone", 0.01, true, false, false );
455  options_lbfgs.max_iter(200);
456 
457  // to do ... make this parsable
460  mm.set_bb ( true );
461  mm.set_chi ( true );
462  mm.set_jump( true );
463 
466  }
467 
468  Pose pose_in = pose;
469  core::Size nres = pose.total_residue();
470  if (pose.residue(nres).aa() == core::chemical::aa_vrt) nres--;
471  core::Size n_prot_res = pose.total_residue();
472  while (!pose.residue(n_prot_res).is_protein()) n_prot_res--;
473 
474  (*scorefxn_)(pose);
476 
477  for (int n=1; n<=(int)ncycles_; ++n) {
478  // pick fragment set
479  core::Size i_frag_set = numeric::random::random_range(1, fragments_.size());
480 
481  // pick insertion position
482  core::Size insert_pos = frag_bias_[i_frag_set].random_sample(RG);
483 
484  if (library_[i_frag_set].find(insert_pos) != library_[i_frag_set].end())
485  apply_frame (pose, library_[i_frag_set][insert_pos]);
486 
487  // MC
488  (*scorefxn_)(pose);
489  minimizer.run( pose, mm, *scorefxn_, options_minilbfgs );
490  mc->boltzmann( pose );
491  }
492  mc->recover_low(pose);
493 
494  // final minimization
495  (*scorefxn_)(pose); minimizer.run( pose, mm, *scorefxn_, options_lbfgs );
496  (*scorefxn_)(pose);
497 
498  if (fullatom_input) {
500  tofa->apply( pose );
501  restore_sc->apply( pose );
502  }
503 }
504 
505 
506 // parse_my_tag
507 void
509  utility::tag::TagPtr const tag, moves::DataMap & data, filters::Filters_map const & , moves::Movers_map const & , core::pose::Pose const & pose )
510 {
511  using namespace core::scoring;
512 
513  // scorfxns
514  if( tag->hasOption( "scorefxn" ) ) {
515  std::string const scorefxn_name( tag->getOption<std::string>( "scorefxn" ) );
516  set_scorefunction ( data.get< ScoreFunction * >( "scorefxns", scorefxn_name ) );
517  }
518 
519  // options
520  if( tag->hasOption( "overlap" ) ) {
521  overlap_ = tag->getOption<core::Size>( "overlap" );
522  }
523  if( tag->hasOption( "ncycles" ) ) {
524  ncycles_ = tag->getOption<core::Size>( "ncycles" );
525  }
526  if( tag->hasOption( "strategy" ) ) {
527  fragment_bias_strategy_ = tag->getOption<std::string>( "strategy" );
528  }
529 
530  if( tag->hasOption( "residues" ) ) {
531  user_pos_ = core::pose::get_resnum_list( tag->getOption<std::string>( "residues" ), pose );
532  }
533 
534  // fragments
535  utility::vector1< utility::tag::TagPtr > const branch_tags( tag->getTags() );
537  for (tag_it = branch_tags.begin(); tag_it != branch_tags.end(); ++tag_it) {
538  if ( (*tag_it)->getName() == "Fragments" ) {
539  using namespace core::fragment;
540  fragments_.push_back( FragmentIO().read_data( (*tag_it)->getOption<std::string>( "fragfile" ) ) );
541  }
542  }
543 
544  core::Size nfrags = tag->getOption< core::Size >( "nfrags", 25 );
545 
546  // autofragments
547  if( tag->hasOption( "fraglens" ) ) {
548  utility::vector1<std::string> fraglens = utility::string_split( tag->getOption< std::string >( "fraglens" ), ',' );
549  for (core::Size i=1; i<=fraglens.size(); ++i) {
550  fragments_.push_back( create_fragment_set(pose, atoi(fraglens[i].c_str()), nfrags) );
551  }
552  }
554 }
555 
556 }
557 //}
558 }