Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BetaAlphaBetaMotif.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 // This file is part of the Rosetta software suite and is made available under license.
5 // The Rosetta software is developed by the contributing members of the Rosetta Commons consortium.
6 // Copyright in the Rosetta software belongs to the developers and their institutions.
7 // For more information, see www.rosettacommons.org.
8 
9 /// @file ./src/protocols/topology/BetaAlphaBetaMotif.cc
10 /// @brief class for beta alpha beta motifs
11 /// @author Nobuyasu Koga ( nobuyasu@u.washington.edu )
12 
13 // unit headers
18 
19 // project headers
20 #include <core/types.hh>
21 #include <basic/Tracer.hh>
23 
24 // utility headers
25 #include <utility/exit.hh>
26 #include <utility/pointer/ReferenceCount.hh>
27 
28 // C++ headers
29 #include <cassert>
30 
31 // Numeric headers
32 #include <numeric/xyzVector.hh>
33 #include <numeric/conversions.hh>
34 
35 // AUTO-REMOVED #include <ObjexxFCL/format.hh>
36 
37 #include <utility/vector1.hh>
38 
39 
40 static basic::Tracer TR( "protocols.fldsgn.topology.BetaAlphaBetaMotif" );
41 
42 using namespace core;
43 
44 namespace protocols {
45 namespace fldsgn {
46 namespace topology {
47 
48 /// @brief default constructor
49 BetaAlphaBetaMotif::BetaAlphaBetaMotif():
50  strand1_( 0 ),
51  strand2_( 0 ),
52  helix_( 0 ),
53  cross_over_( 0 ),
54  left_handed_( false ),
55  hs_dist_( 0.0 ),
56  hs_angle_( 0.0 ),
57  hs1_dist_( 0.0 ),
58  hs2_dist_( 0.0 ),
59  hsheet_elev_angle_( 0.0 ),
60  geometry_is_initialized_( false )
61 {
62  helix_cycle_.push_back( 0 );
63 }
64 
65 /// @brief value constructor
67  Size const & strand1,
68  Size const & strand2,
69  Size const & helix,
70  Size const & cross_over ) :
71  strand1_( strand1 ),
72  strand2_( strand2 ),
73  helix_( helix ),
74  cross_over_( cross_over ),
75  left_handed_( false ),
76  hs_dist_( 0.0 ),
77  hs_angle_( 0.0 ),
78  hs1_dist_( 0.0 ),
79  hs2_dist_( 0.0 ),
80  hsheet_elev_angle_( 0.0 ),
81  geometry_is_initialized_( false )
82 {
83  helix_cycle_.push_back( 0 );
84 }
85 
86 /// @brief copy constructor
88  ReferenceCount(),
89  strand1_( s.strand1_ ),
90  strand2_( s.strand2_ ),
91  helix_( s.helix_ ),
92  cross_over_( s.cross_over_ ),
93  left_handed_( s.left_handed_ ),
94  sheet_plane_( s.sheet_plane_ ),
95  sheet_pos_( s.sheet_pos_ ),
96  hs_dist_( s.hs_dist_ ),
97  hs_angle_( s.hs_angle_ ),
98  hs1_dist_( s.hs1_dist_ ),
99  hs2_dist_( s.hs2_dist_ ),
100  hsheet_elev_angle_( s.hsheet_elev_angle_ ),
101  helix_cycle_( s.helix_cycle_ ),
102  geometry_is_initialized_( s.geometry_is_initialized_ )
103 {}
104 
105 /// @brief destructor
107 
108 /// @brief IO operator
109 std::ostream & operator<<(std::ostream & out, const BetaAlphaBetaMotif & s ) {
110 
111  if( s.is_lefthanded() ) {
112  out << "# " << s.helix() << "," << s.strand1() << "-" << s.strand2() << "." << s.cross_over() << "." << "Left_handed";
113  } else {
114  out << "# " << s.helix() << "," << s.strand1() << "-" << s.strand2() << "." << s.cross_over();
115  }
116  out << " " << s.hsheet_dist() << " " << s.hs_angle() << " " << s.hsheet_elev_angle() << " " << s.hs1_dist() << " " << s.hs2_dist() << " "
117  << s.helix_cycle_as_string() << std::endl;
118 
119  return out;
120 }
121 
122 /// @brief return name
125 {
126  std::ostringstream name;
127  name << helix() << "," << strand1() << "-" << strand2();
128  return name.str();
129 }
130 
131 /// @brief return helix cycle as string
134 {
135  std::ostringstream name;
136  if( helix_cycle_[ 1 ] == 0 ) {
137  name << "0";
138  } else {
139  if( helix_cycle_.size() == 1 ) {
140  name << helix_cycle_[ 1 ];
141  } else {
142  if( helix_cycle_[ 1 ] < helix_cycle_[ 2 ] ) {
143  name << helix_cycle_[ 1 ] << helix_cycle_[ 2 ];
144  } else {
145  name << helix_cycle_[ 2 ] << helix_cycle_[ 1 ];
146  }
147  }
148  }
149  return name.str();
150 }
151 
152 /// @brief whether the CB->CA vector of the C-term residue of 1st strand is pointing inward or outward
153 /// 1: inward, 2: outward
155 BetaAlphaBetaMotif::calc_inout( SS_Info2_COP const ssinfo, Size const resi ) const
156 {
157  using core::Vector;
159 
160  Real neighbor_dist( 14.0 );
161  Size burial( 4 );
162 
163  BB_Pos bb_pos( ssinfo->bb_pos() );
164 
165  Size start = ssinfo->strand( strand1_ )->end() + 1;
166  Size end = ssinfo->strand( strand2_ )->begin() - 1;
167 
168  Vector cbca = bb_pos.CB( resi ) - bb_pos.CA( resi );
169 
170  Size neighbor( 0 );
171  for( Size ii=start; ii<=end; ii++ ) {
172 
173  Vector bb = bb_pos.CA( resi ) - bb_pos.CA( ii );
174 
175  Real orient = cbca.x()*( bb_pos.CA( ii ).x() - bb_pos.CA( resi ).x() ) +
176  cbca.y()*( bb_pos.CA( ii ).y() - bb_pos.CA( resi ).y() ) +
177  cbca.z()*( bb_pos.CA( ii ).z() - bb_pos.CA( resi ).z() );
178 
179  if( bb.length() <= neighbor_dist && orient > 0 ) {
180  neighbor ++;
181  }
182 
183  if( neighbor > burial ) {
184  return 1;
185  }
186  }
187  return 2;
188 }
189 
190 /// @brief
191 bool compare( std::map< Size, Real >::const_iterator a, std::map< Size, Real >::const_iterator b )
192 {
193  return ( (*a).second < (*b).second );
194 }
195 
196 
197 
198 /// @brief calc helix cycle against sheet. Helix cycle is classified as 0, 1, 2, 3, 4,
199 /// which denote the position on helix, where the residue pointing to sheet plane.
200 /// 0 means helix cycle is not calculated, or it's impossible to determine the helix cycle.
201 void
203 {
206 
207  if( ! geometry_is_initialized_ ) {
208  TR << "Geometry have to be initialized before calculating helix cycle. ";
209  runtime_assert( false );
210  }
211 
212  // get helix
213  Helix const hx ( *ssinfo->helix( helix_ ) );
214  Strand const s1 ( *ssinfo->strand( strand1_ ) );
215  Strand const s2 ( *ssinfo->strand( strand2_ ) );
216  BB_Pos bb_pos( ssinfo->bb_pos() );
217 
218  Size h_end( 8 );
219  if( hx.length() < 8 ) {
220  h_end = hx.length();
221  }
222 
223 
224  bool use_ca( false );
225  for( Size ii=1; ii<=h_end; ++ii ) {
226  Size pos( hx.begin() + ii - 1 );
227  if( bb_pos.CB( pos ).is_zero() ) use_ca = true;
228  }
229 
230  std::map< Size, Real > pos_dist;
231  for( Size ii=1; ii<=h_end; ++ii ) {
232 
233  Size pos( hx.begin() + ii - 1 );
234 
235  Vector hpos;
236  if( use_ca ) {
237  hpos = bb_pos.CA( pos );
238  } else {
239  hpos = bb_pos.CB( pos );
240  }
241 
242  // get orient vector from the center of helical wheel to ca
243  Vector const helix_center = hx.Nend_pos() + hx.Nend_orient().dot( hpos - hx.Nend_pos() )*hx.Nend_orient();
244  Vector const center2hpos = ( hpos - helix_center ).normalized();
245 
246  // distance between ca and sheet
247  Real const dist_hpos_sheet = sheet_plane_.dot( hpos - sheet_pos_ );
248 
249  if( dist_hpos_sheet < 0 ) {
250  TR << " Distance between CA and sheet is negative value. Conformation is something funny. ";
251  TR << " Cannot determine helix cycle. " << std::endl;
252  TR << "Pos " << pos << ", " << dist_hpos_sheet << std::endl;
253  return;
254  }
255 
256  // angle between center2ca and sheet_plane
257  Real cos = cos_of( center2hpos, -sheet_plane_ );
258  if( cos < 0 ) continue;
259 
260  // distance from ca along the vector of center2ca
261  Real dist = dist_hpos_sheet/cos;
262 
263  //std::cout << ii << " " << dist << std::endl;
264  pos_dist.insert( std::pair< Size, Real >( ii, dist ) );
265 
266  }
267 
269  std::map< Size, Real >::iterator it = pos_dist.begin();
270  while( it != pos_dist.end() ) {
271  vec_ite.push_back( it );
272  it++;
273  }
274 
275  helix_cycle_.clear();
276  std::sort( vec_ite.begin(), vec_ite.end(), compare );
277 
278  if( hx.length() > 8 ) {
279  helix_cycle_.push_back( ( **vec_ite.begin() ).first );
280  helix_cycle_.push_back( ( **( vec_ite.begin() + 1 ) ).first );
281  } else {
282  helix_cycle_.push_back( ( **vec_ite.begin() ).first );
283  }
284 
285 }
286 
287 
288 /// @brief
289 void
291 {
298 
299  if( ! ssinfo->bbpos_is_set() ) return;
300  runtime_assert( ssinfo->bbpos_is_set() );
301 
302  Helix const hx ( *ssinfo->helix( helix_ ) );
303  Strand const s1 ( *ssinfo->strand( strand1_ ) );
304  Strand const s2 ( *ssinfo->strand( strand2_ ) );
305  BB_Pos bb_pos( ssinfo->bb_pos() );
306 
307  if( ! s1.is_geometry_initialized() ) return;
308  if( ! s2.is_geometry_initialized() ) return;
309  if( ! hx.is_geometry_initialized() ) return;
310 
312  hss3.calc_geometry( ssinfo );
313 
314  // get mid point of helix
315  Vector const hmid = hx.mid_pos();
316 
317  //hs_dist_ = hss3.hsheet_dist();
318  //hs_angle_ = hss3.hs_angle();
319  left_handed_ = hss3.left_handed();
320 
321  // check strand1_ and strand2_ are in same sheet
322  Size isheet = sheet_set->which_sheet( strand1_ );
323  runtime_assert( isheet == sheet_set->which_sheet( strand1_ ) );
324  SheetOP sheet( sheet_set->sheet( isheet ) );
325 
326  // get strand order of strand1 and strand2 in sheet
327  Size s1_order = sheet->strand_order( strand1_ );
328  Size s2_order = sheet->strand_order( strand2_ );
329  runtime_assert( s1_order > 0 && s2_order > 0 );
330  int sign( 1 );
331  if( s1_order > s2_order ) sign = -1;
332 
333  // determine 1st reference strand for calculating geometry,
334  // reference strands are center strands of sheets
335  int ref1 = sign * ( cross_over_/2 + 1 ) + s1_order + sign*-1;
336 
337  runtime_assert( ref1 > 0 );
338 
339  int s1_orient = sheet->orient_strand( s1_order );
340 
341  // calc v1, v2, v3 to define sheet plane
342  // v1 and v2 are orient vectors to define sheet plane,
343  // v3 is a positional vector, which locates on sheet plane.
344  Vector v1, v2, v3;
345 
346  int ref2 = ref1 + sign;
347  runtime_assert( ref2 > 0 );
348 
349  Size ref1_stid = sheet->order_strand( ref1 );
350  Size ref2_stid = sheet->order_strand( ref2 );
351 
352  // Strand const & ref_s1 = *ssinfo->strand( ref1_stid ); // Unused variable causes warning.
353  // Strand const & ref_s2 = *ssinfo->strand( ref2_stid ); // Unused variable causes warning.
354 
355  int refs1_orient = sheet->orient_strand( ref1 );
356  int refs2_orient = sheet->orient_strand( ref2 );
357 
358  Real ss_sign1( 1.0 ), ss_sign2( 1.0 );
359  if( s1_orient != refs1_orient ) ss_sign1 = -1.0;
360  if( s1_orient != refs2_orient ) ss_sign2 = -1.0;
361 
362  // get StrandPairingSet
363  StrandPairingSet spairset = sheet_set->spairset();
364 
365  StrandPairingOP spair1 = spairset.strand_pairing( ref1_stid, ref2_stid );
366  runtime_assert( " spair1->orient() == 'P' || spair1->orient() == 'A' " );
367  runtime_assert( " spair1->size1() != 1 || spair1->size2() != 1 " );
368 
369  // get vectors to define sheet plane
370  Size begin1, end1, begin2, end2;
371  if( ref1_stid < ref2_stid ) {
372  begin1 = spair1->begin1();
373  end1 = spair1->end1();
374  if( spair1->orient() == 'P' ) {
375  begin2 = spair1->begin2();
376  end2 = spair1->end2();
377  } else {
378  begin2 = spair1->end2();
379  end2 = spair1->begin2();
380  }
381 
382  } else {
383  if( spair1->orient() == 'P' ) {
384  begin1 = spair1->begin2();
385  end1 = spair1->end2();
386  } else {
387  begin1 = spair1->end2();
388  end1 = spair1->begin2();
389  }
390  begin2 = spair1->begin1();
391  end2 = spair1->end1();
392  }
393 
394  Vector const s1p = ( bb_pos.C( end1 ) - bb_pos.N( begin1 ) ).normalized();
395  Vector const s2p = ( bb_pos.C( end2 ) - bb_pos.N( begin2 ) ).normalized();
396  Vector const s1p_mid = ( bb_pos.N( begin1 ) + bb_pos.C( end1 ) )/2.0;
397  Vector const s2p_mid = ( bb_pos.N( begin2 ) + bb_pos.C( end2 ) )/2.0;
398 
399  if( cross_over_%2 == 0 ) {
400 
401  v1 = ( s2p_mid - s1p_mid ).normalized();
402  v2 = ( ss_sign1*s1p + ss_sign2*s2p ).normalized();
403  v3 = s1p_mid;
404 
405  hs1_dist_ = ( hmid - s1p_mid ).length();
406  hs2_dist_ = ( hmid - s2p_mid ).length();
407 
408  //TR << begin1 << "-" << end1 << "," << begin2 << "-" << end2 << std::endl;
409  //TR << "Ref " << ref1 << " " << ref2 << ", "
410  // << ref1_stid << " " << ref2_stid << ", "
411  // << refs1_orient << " " << refs2_orient << std::endl;
412 
413  } else {
414 
415  int ref3 = ref2 + sign;
416  runtime_assert( ref3 > 0 );
417 
418  Size ref3_stid = sheet->order_strand( ref3 );
419  // Strand const & ref_s3 = *ssinfo->strand( ref3_stid ); // Unused variable causes warning.
420  int refs3_orient = sheet->orient_strand( ref3 );
421 
422  Real ss_sign3( 1.0 );
423  if( s1_orient != refs3_orient ) ss_sign3 = -1.0;
424 
425  StrandPairingOP spair2 = spairset.strand_pairing( ref2_stid, ref3_stid );
426  runtime_assert( " spair2->orient() == 'P' || spair2->orient() == 'A' " );
427  runtime_assert( " spair2->size1() != 1 || spair2->size2() != 1 " );
428 
429  // get vectors to define sheet plane
430  Size begin3, end3;
431  if( ref2_stid < ref3_stid ) {
432  if( spair2->orient() == 'P' ) {
433  begin3 = spair2->begin2();
434  end3 = spair2->end2();
435  } else {
436  begin3 = spair2->end2();
437  end3 = spair2->begin2();
438  }
439  } else {
440  begin3 = spair2->begin1();
441  end3 = spair2->end1();
442  }
443 
444  Vector const s3p = ( bb_pos.C( end3 ) - bb_pos.N( begin3 ) ).normalized();
445  Vector const s3p_mid = ( bb_pos.N( begin3 ) + bb_pos.C( end3 ) )/2.0;
446 
447  hs1_dist_ = ( hmid - s1p_mid ).length();
448  hs2_dist_ = ( hmid - s3p_mid ).length();
449 
450  v1 = ( s3p_mid - s1p_mid ).normalized();
451  v2 = ( ss_sign1*s1p + ss_sign2*s2p + ss_sign3*s3p ).normalized();
452  v3 = s1p_mid;
453 
454  //TR << begin1 << "-" << end1 << "," << begin2 << "-" << end2 << "," << begin3 << "-" << end3 << std::endl;
455  //TR << "Ref " << ref1 << " " << ref2 << " " << ref3 << ", "
456  // << ref1_stid << " " << ref2_stid << " " << ref3_stid << ", "
457  // << s1_orient << " " << refs1_orient << " " << refs2_orient << " " << refs3_orient << std::endl;
458 
459  }
460 
461  sheet_plane_ = ( v1.cross( v2 ) ).normalized();
462  sheet_pos_ = v3;
463  // distance between helix and sheet
464  hs_dist_ = sheet_plane_.dot( hmid - v3 );
465 
466  // angle between helix and strands
467  Real dot2( -hx.orient().dot( sheet_plane_ ) );
468  Real angle( numeric::conversions::degrees( angle_of( -hx.orient(), v2 ) ));
469  if( dot2 > 0.0 ) {
470  hsheet_elev_angle_ = angle;
471  } else {
472  hsheet_elev_angle_ = -angle;
473  }
474 
475  // calc angle between strands and helix projected on sheet
476  Vector const h1 = hx.Nend_pos() - sheet_plane_.dot( hx.Nend_pos() - v3 )*sheet_plane_;
477  Vector const h2 = hx.Cend_pos() - sheet_plane_.dot( hx.Cend_pos() - v3 )*sheet_plane_;
478  Vector const hx_on_sheet = ( h1 - h2 ).normalized();
479  Real ori = cross( hx_on_sheet, v2 ).dot( sheet_plane_ );
480  hs_angle_ = numeric::conversions::degrees( angle_of( v2, hx_on_sheet ) );
481  if( ori < 0 ) hs_angle_ = -1*hs_angle_;
482 
484 
485  calc_helix_cycle( ssinfo );
486 
487  // std::cout << *this;
488 
489 }
490 
491 
492 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
493 /// @brief default constructor
495 
496 /// @brief value constructor
498  bab_motifs_( bab_motifs )
499 {}
500 
501 
502 /// @brief value constructor
504 {
505  set_babmotifs( ssinfo, sheet_set );
506  calc_geometry( ssinfo, sheet_set );
507 }
508 
509 
510 /// @brief copy constructor
512  ReferenceCount(),
513  bab_motifs_( s.bab_motifs_ )
514 {}
515 
516 /// @brief destructor
518 
519 /// @brief add BetaAlphaBetaMotif
520 void
522 {
523  bab_motifs_.push_back( bop );
524 }
525 
526 /// @brief
527 void
529  bab_motifs_.clear();
530 }
531 
532 /// @brief
533 BetaAlphaBetaMotifs const &
535 {
536  return bab_motifs_;
537 }
538 
539 /// @brief
542 {
543  runtime_assert( i <= bab_motifs_.size() );
544  return bab_motifs_[ i ];
545 }
546 
547 /// @brief
548 std::ostream & operator<<( std::ostream & out, const BetaAlphaBetaMotifSet & s )
549 {
550  out << "### BetaAlphaBetaMotif Info " << std::endl;
551  out << "# helix,strand1-strand2.num_crossover hsheet_dist hs_angl hsheet_elev_angl hs1_dist hs2_dist helix_cycle " << std::endl;
552  for( BetaAlphaBetaMotifs::const_iterator iter = s.bab_motifs().begin(),
553  iter_end = s.bab_motifs().end(); iter != iter_end; ++iter ) {
554  BetaAlphaBetaMotif const & bab( **iter );
555  out << bab;
556  }
557  return out;
558 }
559 
560 /// @brief set bab motif
561 void
563 {
568 
569  Helices helices = ssinfo->helices();
570  Strands strands = ssinfo->strands();
571 
572  if( strands.size() < 2 ) {
573  return;
574  }
575 
576  for( Size ist1=1; ist1<=strands.size()-1 ; ist1++ ) {
577 
578  Size ist2 = ist1+1;
579  Strand const & s1 ( *strands[ ist1 ] );
580  Strand const & s2 ( *strands[ ist2 ] );
581 
582  Size const sheet_num1 ( sheet_set->which_sheet( ist1 ) );
583  Size const sheet_num2 ( sheet_set->which_sheet( ist2 ) );
584  if( sheet_num1 == 0 || sheet_num2 == 0 ) continue; // in the case, ist1 or ist2 does not belong to sheet
585  if( sheet_num1 != sheet_num2 ) continue;
586 
587  Size const ord1 = sheet_set->sheet( sheet_num1 )->strand_order( ist1 );
588  Size const ord2 = sheet_set->sheet( sheet_num2 )->strand_order( ist2 );
589 
590  utility::vector1< Real > orients( sheet_set->sheet( sheet_num1 )->orient_strands() );
591  if( orients[ ord1 ] != orients[ ord2 ] ) continue;
592 
593  Size ih( 0 ), ihelix( 0 );
594  Size helix_num( 0 );
595  for( Helices::const_iterator jt=helices.begin(), jte=helices.end(); jt!=jte; ++jt ) {
596  ih++;
597  Helix const & hx( **jt );
598  if( hx.begin() < s1.begin() ) continue;
599  if( hx.begin() > s2.end() ) continue;
600  if( hx.begin() > s1.end() && hx.end() < s2.begin() ) {
601  ihelix = ih;
602  helix_num++;
603  }
604  }//helices
605 
606  if( helix_num == 1 ) {
607  runtime_assert( ihelix != 0 );
608  Size cross_over = Size ( std::abs( Real(ord1) - Real(ord2) ) ) - 1;
609  bab_motifs_.push_back( new BetaAlphaBetaMotif( ist1, ist2, ihelix, cross_over ) );
610  TR.Debug << ist1 << " " << ist2 << " " << ihelix << " " << cross_over << std::endl;
611  }
612 
613  }//strands
614 
615 
616 } // SheetTopology::set_bab_motifs
617 
618 
619 /// @brief
620 void
622 {
623  if( ! ssinfo->bbpos_is_set() ) return;
624  runtime_assert( ssinfo->bbpos_is_set() );
625  for( BetaAlphaBetaMotifs::iterator it=bab_motifs_.begin(), ite=bab_motifs_.end(); it!=ite; ++it ) {
626  BetaAlphaBetaMotifOP const babm( *it );
627  babm->calc_geometry( ssinfo, sheet_set );
628  }
629 }
630 
631 
632 } // namespace topology
633 } // namespace fldsgn
634 } // namespace protocols
635