Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FragsToAtomDist.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 // :noTabs=false:tabSize=4:indentSize=4:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file core/fragments/FragstoAtomDist.fwd.hh
12 /// @brief simulate fragments and recored atom distances
13 /// @author Zaiyong Zhang (zaiyong.zhang@tum.de)
14 /// @date Thr NOV 22 13:22:31 2012
15 ///
16 
17 // Unit Headers
19 
20 // Package Headers
23 
24 
25 // Project Headers
27 
30 #include <core/fragment/Frame.hh>
31 
32 #include <core/id/AtomID.hh>
33 #include <core/id/NamedAtomID.hh>
34 
38 
39 #include <core/pose/Pose.hh>
40 
43 
46 
47 #include <core/pose/util.hh>
48 #include <core/types.hh>
49 
50 // Utility headers
51 #include <basic/Tracer.hh>
52 
53 #include <numeric/random/random.hh>
54 #include <numeric/xyzVector.io.hh>
55 
56 #include <utility/vector1.hh>
57 #include <utility/io/ozstream.hh>
58 #include <utility/io/izstream.hh>
59 #include <utility/string_util.hh>
60 
61 #include <ObjexxFCL/string.functions.hh>
62 
63 // C++ headers
64 #include <string>
65 
67  return floor(in+0.5);
68 }
69 
70 static numeric::random::RandomGenerator RG(482136);
71 static basic::Tracer tr("protocols.noesy_assign.FragsToAtomDist");
72 
73 using namespace std;
74 using namespace core;
75 using namespace core::pose;
76 using namespace core::id;
77 using namespace fragment;
78 using namespace core::chemical;
79 
80 namespace protocols {
81 namespace noesy_assign {
82 
86 typedef std::map< core::id::AtomID, FragsToAtomDist::DistanceRecord > InnerMap;
87 typedef std::map< core::id::AtomID, InnerMap > DistanceMap;
88 
89 
90 
91 core::Real FragsToAtomDist::DistanceRecord::popular_bin() const {
92  core::Size max_bin(0);
93  core::Real pop_dist(-1.0);
94  std::map< core::Real, core::Size >::const_iterator it;
95  tr.Info << "size of hist_dist_ "<< hist_dist_.size() <<std::endl;
96  for ( it=hist_dist_.begin(); it !=hist_dist_.end(); it++ ) {
97  tr.Info << " it->second "<< it->second<<std::endl;
98  tr.Info << " max_bin "<< max_bin<<std::endl;
99  if ( it->second > max_bin ) {
100  tr.Info << " it->first "<< it->first<<std::endl;
101  max_bin=it->second;
102  pop_dist=it->first;
103  }
104  }
105  tr.Info << " pop_dist "<< pop_dist<<std::endl;
106  return pop_dist;
107 }
108 FragsToAtomDist::DistanceRecord FragsToAtomDist::NO_CONTACT( 100.0, 100.0, 100.0, 1 );
109 std::ostream& operator<< ( std::ostream& os, FragsToAtomDist::DistanceRecord const& dr ) {
110  return os << " " << setw(10) << setprecision(4) << dr.average_dist6()
111  << " " << setw(10) << setprecision(4) << dr.average_dist()
112  << " " << setw(10) << setprecision(4) << dr.min_dist()
113  << " " << setw(10) << setprecision(4) << dr.popular_bin();
114 }
115 std::istream& operator>> ( std::istream& is, FragsToAtomDist::DistanceRecord& dr ) {
116  core::Real t1, t2, t3;
117  is >> t1 >> t2 >> t3;
118  dr = FragsToAtomDist::DistanceRecord( pow( t1, -6.0 ), t2, t3, 1 );
119  return is;
120 }
121 
122 void FragsToAtomDist::DistanceRecord::record_inv6( core::Real inv6 ) {
123  core::Real const dist( std::pow( inv6, -1.0/6.0 ) );
124  cum_dist6_ += inv6;
125  cum_dist_ += dist;
126  min_dist_ = std::min( min_dist_, dist );
127  ++count_;
128  //tr.Info << " dist " << dist << " half adjust " << half_adjust( dist ) <<std::endl;
129  hist_dist_[ half_adjust( dist ) ]=hist_dist_[ half_adjust( dist ) ]+1;
130  //tr.Info << " hist_dist_ " << hist_dist_[ half_adjust( dist ) ] <<std::endl;
131  hist_dist6_[ half_adjust( inv6 ) ]=hist_dist6_[ half_adjust( inv6 ) ]+1;
132 }
133 
134 void FragsToAtomDist::DistanceRecord::record( core::Real dist ) {
135  core::Real const inv6( std::pow( dist, -6.0 ) );
136  cum_dist6_ += inv6;
137  cum_dist_ += dist;
138  min_dist_ = std::min( min_dist_, dist );
139  ++count_;
140 }
141 
142 
143 
144 
146  GroupList& grp_list,
147  core::pose::Pose const& pose )
148 {
149  MethylNameLibrary const& methyl_lib( *MethylNameLibrary::get_instance() );
150  for ( core::Size pos =1; pos<=pose.total_residue(); pos++) {
151  core::chemical::ResidueType const& rsd(pose.residue_type( pos ));
152  // std::string name( utility::trim( pose.residue_type( pos ).atom_name( iatom1 ) ) );
153  MethylNames const& methyls( methyl_lib[ rsd.aa() ] );
154  AtomGrps new_grps;
155  for ( MethylNames::const_iterator it = methyls.begin(); it != methyls.end(); ++it ) {
156  SizeList indices;
157  tr.Info << "pos " << pos << " " << it->first << " ";
158  for ( MethylNames::AtomList::const_iterator ait = it->second.begin(); ait != it->second.end(); ++ait ) {
159  std::string atom( *ait );
160  if ( pos == 1 && atom == "H" ) {
161  atom="1H";
162  }
163  indices.push_back( rsd.atom_index( atom ) );
164  tr.Info << atom << " ";
165  }
166  new_grps.push_back( std::make_pair<std::string, SizeList >( it->first, indices ) );
167  // tr.Info << "CONTROL: " << it->first << " " << new_grps.back().first << std::endl;
168  tr.Info << std::endl;
169  }
170  tr.Info << "generated " << new_grps.size() << " proton-groups for position " << pos << std::endl;
171  grp_list.push_back( new_grps );
172  }
173 }
174 
175 bool FragsToAtomDist::check_sequence(std::string const& other_sequence) const {
176  if (sequence_.compare(other_sequence)==0) {
177  return true;
178  } else {
179  return false;
180  }
181 }
182 
183 FragsToAtomDist::DistanceRecord const& FragsToAtomDist::distance_record( core::id::NamedAtomID atom1, core::id::NamedAtomID atom2 ) const {
184  swap_atoms( atom1, atom2 );
185  NamedDistanceMap::const_iterator it1 = named_distmap_.find( atom1 );
186  if ( it1 != named_distmap_.end() ) {
187  NamedInnerMap::const_iterator it2 = it1->second.find( atom2 );
188  if ( it2 != it1->second.end() ) {
189  return it2->second;
190  }
191  }
192  return NO_CONTACT;
193 }
194 
195 void FragsToAtomDist::write_to_stream(std::ostream& output) const {
196  Size count =1;
197  for (std::string::const_iterator i = sequence_.begin();i != sequence_.end();++i) {
198  if ( count%50 == 1 ) {
199  output << "DATA SEQUENCE ";
200  }
201  output << *i;
202  if ( count%50 == 0 ) {
203  output << endl;
204  }
205  if ( count%10 == 0 && count%50 != 0 ) {
206  output << " ";
207  }
208  count++;
209  }
210  output << endl << endl;
211  // if ( FragsToAtomDist::r6_averaged_ ) {
212  // output << "DATA R6_AVERAGED YES" << endl;
213  // }
214  // else {
215  // output << "DATA R6_AVERAGED NO" << endl;
216  // }
217  output << "VARS RESID1 ATOMNAME1 RESID2 ATOMNAME2 DIST_R6_AVERAGED DIST_AVERAGED DIST_MIN DIST_POP" << endl << endl;
218  NamedDistanceMap::const_iterator iter1;
219  NamedInnerMap::const_iterator iter2;
220  for ( iter1 = named_distmap_.begin(); iter1 != named_distmap_.end(); iter1++ ) {
221  for (iter2 = iter1->second.begin(); iter2 != iter1->second.end(); iter2++ ) {
222  if ( iter2->second.is_valid() ) {
223  output << setw(5)<<iter1->first.rsd()
224  << setw(5)<<iter1->first.atom()
225  << setw(5)<<iter2->first.rsd()
226  << setw(8)<<iter2->first.atom()
227  << setw(8)<< setprecision(14)<< iter2->second <<endl;
228  }
229  }
230  }
231 }
232 
233 void FragsToAtomDist::write_to_file(std::string const& filename) const {
234  utility::io::ozstream output( filename );
235  write_to_stream(output);
236 }
237 
238 void FragsToAtomDist::read_from_stream(std::istream& input) {
239  std::string line;
240  while ( getline( input, line ) ) {
241  if ( line.size() == 0 ) continue;
242  std::istringstream tag_stream( line );
243  if (line.substr(0,4)=="DATA") {
244  if (line.substr(0,13)=="DATA SEQUENCE") {
245  line.erase(0,14);
246  for (std::string::iterator i = line.begin();i != line.end();++i) {
247  if ( *i !=' ' ) {
248  sequence_+=*i;
249  }
250  }
251  }
252  // if (line.substr(0,20)=="DATA R6_AVERAGED YES") {
253  //r6_averaged_=true;
254  //}
255  //else if (line.substr(0,19)=="DATA R6_AVERAGED NO") {
256  // r6_averaged_=false;
257  //}
258  }
259  else if ( line.substr(0,4) !="VARS" && line.length()>10 ) {
260  int residue1,residue2;
261  std::string name1,name2;
262  DistanceRecord dist;
263  tag_stream >> residue1 >> name1 >> residue2 >> name2 >> dist;
264  NamedAtomID atom1( name1,residue1);
265  NamedAtomID atom2( name2,residue2);
266  named_distmap_[atom1][atom2]=dist;
267  }
268  }
269 }
270 
271 void FragsToAtomDist::read_from_file(std::string const& filename) {
272  utility::io::izstream input( filename );
273  read_from_stream( input );
274 }
275 
276 
277 
278 void FragsToAtomDist::generate_from_fragments( FragSetOP fragments, std::string const& sequence, core::Size cycles, core::Size cycle_mod ) {
279  frags_=fragments;
280  set_sequence(sequence);
281  //set_r6_averaged(r6_averaging);
282  compute_average_distances( cycles, cycle_mod );
283 }
284 
285 void FragsToAtomDist::generate_from_frag_file( std::string const& filename, std::string const& sequence, core::Size cycles, core::Size cycle_mod ) {
286  generate_from_fragments( FragmentIO().read_data( filename ), sequence, cycles, cycle_mod);
287 }
288 
289 //re-order atom-ids so that always smaller residue number and/or smaller atom number comes first
290 void FragsToAtomDist::swap_atoms( NamedAtomID& atom1, NamedAtomID& atom2 ) const {
291  bool swap( false );
292  if ( atom1.rsd() > atom2.rsd() ) {
293  swap = true;
294  } else if ( atom1.rsd() == atom2.rsd() ) {
295  AA aa( aa_from_oneletter_code( sequence_[ atom1.rsd()-1 ] ) );
296  MethylNameLibrary const& methyl_lib( *MethylNameLibrary::get_instance() );
297  try {
298  if ( methyl_lib[aa].proton_index( atom1.atom() ) > methyl_lib[ aa ].proton_index( atom2.atom() ) ) {
299  swap = true;
300  }
301  } catch( EXCN_UnknownAtomname& excn ) {
302  excn.add_msg( "cannot find proton/methyl name at position "+ObjexxFCL::string_of( atom1.rsd() ) );
303  }
304  }
305  if ( swap ) {
306  NamedAtomID atom3( atom1 );
307  atom1=atom2;
308  atom2=atom3;
309  }
310 }
311 
312 //translate from AtomID into NamedAtomID --- store in named_distmap_
314  FragsToAtomDist::NamedDistanceMap &named_distmap,
315  DistanceMap const& distmap,
316  GroupList const& proton_groups
317 ) {
318  DistanceMap::const_iterator iter1;
319  InnerMap::const_iterator iter2;
320  for ( iter1 = distmap.begin(); iter1 != distmap.end(); iter1++) {
321  for (iter2=iter1->second.begin(); iter2 != iter1->second.end();iter2++) {
322  core::id::AtomID const& grp_1(iter1->first);
323  core::id::AtomID const& grp_2(iter2->first);
324  std::string const& grp_name1( proton_groups[ grp_1.rsd() ][ grp_1.atomno() ].first );
325  std::string const& grp_name2( proton_groups[ grp_2.rsd() ][ grp_2.atomno() ].first );
326  core::id::NamedAtomID named_atom_1( grp_name1, grp_1.rsd() );
327  core::id::NamedAtomID named_atom_2( grp_name2, grp_2.rsd() );
328  named_distmap[named_atom_1][named_atom_2]=iter2->second;
329  }
330  }
331 }
332 
334  DistanceMap& distmap,
335  // DistanceMap& countmap,
336  core::pose::Pose const& short_pose,
337  Size start,
338  Size short_size,
339  GroupList const& grps
340  // bool r6_averaging
341 ) {
342  for ( core::Size rsd1 =1; rsd1<=short_size; rsd1++) {
343  AtomGrps const& group1( grps[ rsd1+start-1 ] );
344  for ( core::Size igrp1 =1; igrp1<=group1.size(); igrp1++ ) {
345  for ( core::Size rsd2 =rsd1; rsd2<=short_size; rsd2++) {
346  AtomGrps const& group2( grps[ rsd2+start-1 ] );
347  for ( core::Size igrp2 = ( rsd2==rsd1 ? igrp1+1 : 1 ); igrp2<=group2.size(); igrp2++ ) {
348  Real cumdist( 0 );
349  for ( SizeList::const_iterator atom1 = group1[igrp1].second.begin(); atom1 != group1[igrp1].second.end(); ++atom1 ) {
350  PointPosition const & xyz_1 = short_pose.xyz( id::AtomID( *atom1, rsd1 ) );
351  for ( SizeList::const_iterator atom2 = group2[igrp2].second.begin(); atom2 != group2[igrp2].second.end(); ++atom2 ) {
352  PointPosition const & xyz_2 = short_pose.xyz( id::AtomID( *atom2, rsd2 ) );
353  Real const inv_dist2( 1.0/xyz_1.distance_squared( xyz_2 ) );
354  Real const inv_dist6( inv_dist2 * inv_dist2 * inv_dist2 );
355  cumdist += inv_dist6;
356  }
357  }
358  id::AtomID grpid1( igrp1, rsd1+start-1 );
359  id::AtomID grpid2( igrp2, rsd2+start-1 );
360  distmap[ grpid1 ][ grpid2 ].record_inv6( cumdist );
361  }
362  }
363  }
364  }
365 }
366 
367 void FragsToAtomDist::compute_average_distances(core::Size cycles,core::Size dump_freq ) {
368  using namespace protocols::simple_moves;
369 
372  scorefxn->set_weight( core::scoring::fa_dun, 0 ); //since we use the JumpRotamer Mover the dunbrack energy is already in the sampling bias
373  core::pose::Pose pose;
374 
375  core::pose::make_pose_from_sequence( pose, sequence_, "fa_standard", true );
376 
377  //SizeList natoms( pose.total_residue(), 0);
378  // initialize_natoms( natoms, pose );
379 
380  GroupList proton_groups;
381  initialize_group_list( proton_groups, pose );
382 
383  DistanceMap countmap;
384  DistanceMap distmap;
385  //initialize_maps( distmap, countmap, proton_groups );
386 
387  for ( FrameIterator frame = frags_->begin(), eframe=frags_->end();
388  frame != eframe; ++frame ) {
389  core::pose::Pose short_pose;
391  short_pose,
392  sequence_.substr( frame->start()-1, frame->length() ),
393  "fa_standard",
394  true
395  );
396 
397  Size const short_size( frame->length() );
398  std::string short_sequence = short_pose.sequence();
399  Size const short_start( frame->start() );
400  tr.Info << "frame position: " << frame->start() << std::endl;
401 
402  frame->shift_to(1);
403 
406  for ( Size ifrag=1; ifrag<=frame->nr_frags(); ifrag++ ) {
407  if ( ifrag % 10 == 0 ) tr.Info << "fragment (" << ifrag << "," << frame->nr_frags() << ")" << std::endl;
408  frame->apply( ifrag, short_pose );
409  core::Real score_old(scorefxn->score(short_pose));
410 
411  //start monte-carlo simulation
412  for ( core::Size cycle = 1; cycle<=cycles; cycle++ ) {
413  //better select rsd randomly
414  //for ( Size irsd = 1; irsd<=short_size; irsd++) {
415  Size const irsd( RG.random_range(1, short_size) );
416  core::conformation::Residue const& rsd( short_pose.residue( irsd ));
417  core::Size const n_chi_angles(rsd.nchi());
418  old_chi=rsd.chi();
419 
420  //make chi-move
421  if ( n_chi_angles != 0 ) {
422  jrmover.make_chi_move(rsd,old_chi,new_chi);
423  }
424 
425  //set new chi-angles in pose
426  for (core::Size ichi = 1; ichi<=n_chi_angles; ichi++) {
427  short_pose.set_chi(ichi,irsd,new_chi[ ichi ]);
428  }
429 
430  //evaluate energy and accept/reject
431  core::Real score_new(scorefxn->score(short_pose));
432  if ( score_new > score_old ) {
433  core::Real Delta_score(score_new - score_old);
434  core::Real p( exp( -1*Delta_score ) );
435  if ( RG.uniform() > p) {
436  for (core::Size ichi = 1; ichi<=n_chi_angles; ichi++) {
437  short_pose.set_chi(ichi,irsd,old_chi[ ichi ]);
438  }
439  } else {
440  score_old = score_new;
441  old_chi = new_chi;
442  }
443  } else {
444  score_old = score_new;
445  old_chi = new_chi;
446  }
447 
448  if (cycle%dump_freq == 0 ) {
449  store_distance_snapshot( distmap, short_pose, short_start, short_size, proton_groups );
450  }
451  }
452  }
453  }
454  //average_distmap( distmap,countmap, r6_averaged_ );
455  store_distmap_with_namedatoms(named_distmap_,distmap,proton_groups);
456 }
457 
458 
459 } //noesy_assign
460 } //protocols