28 #include "ObjexxFCL/FArray1D.hh"
29 #include "ObjexxFCL/FArray2D.hh"
32 #include <utility/vector1.fwd.hh>
33 #include <utility/exit.hh>
34 #include <basic/Tracer.hh>
44 #include <basic/options/option.hh>
45 #include <basic/options/keys/jumps.OptionKeys.gen.hh>
48 #include <utility/vector1.hh>
49 #include <boost/functional/hash.hpp>
51 static basic::Tracer
tr(
"core.scoring.dssp");
55 using namespace basic;
56 using namespace ObjexxFCL;
90 StrandPairingSet::StrandPairingSet(
pose::Pose const& pose,
Real threshold ) {
91 ObjexxFCL::FArray2D_float hbond_bb_pair_score;
93 compute( hbond_bb_pair_score, threshold, pose );
96 StrandPairingSet::StrandPairingSet( FArray2_float
const &hbonds,
98 compute( hbonds, threshold, pose);
102 for ( core::scoring::dssp::PairingList::const_iterator it = in_pairings.begin(), eit = in_pairings.end();
112 void StrandPairingSet::compute( FArray2_float
const &hbonds,
117 for (
Size i = 2; i <= nres - 1; i++ ) {
118 for (
Size j = i + 1; j <= nres - 1; j++ ) {
120 ( hbonds(i,j) < threshold
121 && hbonds(j,i) < threshold )
122 || ( hbonds(i-1,j+1) < threshold
123 && hbonds(j-1,i+1) < threshold ) ) {
124 Size orientation, pleating;
127 add_pairing(i, j,
true , pleating );
129 ( hbonds(i-1,j) < threshold
130 && hbonds(j,i+1) < threshold )
131 || ( hbonds(j-1,i) < threshold
132 && hbonds(i,j+1) < threshold ) ) {
133 Size orientation, pleating;
137 add_pairing(i,j,
false, pleating );
146 is >> tag >> nstrand;
147 if ( tag !=
"STRAND_TOPOLOGY" ) {
148 tr.Trace <<
"failed reading STRAND_TOPOLOGY --- found instead: " << tag << std::endl;
149 is.setstate( std::ios_base::failbit );
152 for (
Size ct = 1; ct <= nstrand && is.good(); ct++ ) {
163 out <<
"STRAND_TOPOLGY " << sp.
pairings_.size() << std::endl;
166 out << *it << std::endl;
193 void StrandPairingSet::add_pairing(
Size res1,
Size res2,
bool antiparallel,
Size pleating) {
196 for (
iterator it = pairings_.begin();
197 it != pairings_.end();
199 if ( it->extend(res1,res2,antiparallel,pleating) ) {
201 if ( !it->range_check() ) {
202 tr.Error <<
"[ERROR] just inconsistently added " << res1 <<
"-" << res2 <<
" to pairing " << *it << std::endl;
203 runtime_assert(
false );
212 for (
iterator it = pairings_.begin();
213 it != pairings_.end();
217 pairings_.insert(it, add);
221 pairings_.push_back(add);
226 StrandPairings::iterator it = pairings_.
begin();
227 StrandPairings::const_iterator oit = other.
pairings_.begin();
228 while( it != pairings_.end() ) {
230 while( oit != other.
pairings_.end() && it->merge(*oit, domerge) ) {
240 if ( domerge ) selfmerge();
244 void StrandPairingSet::selfmerge() {
246 for(StrandPairings::iterator it = pairings_.begin();
247 it != pairings_.end();
249 for(StrandPairings::iterator oit = pairings_.begin();
252 while(oit != it && it->merge(*oit,
true))
253 oit = pairings_.erase(oit);
256 bool StrandPairingSet::check_pleat()
const {
257 for(StrandPairings::const_iterator it = pairings_.begin();
258 it != pairings_.end();
260 if(!it->check_pleat())
266 bool StrandPairing::check_pleat()
const {
267 for(
Size i = 1; i < (
Size)pleating1.size(); i++) {
268 if(pleating1[i] == pleating1[i-1] && pleating1[i] != 0)
275 if ( antiparallel() ) {
276 return end2_-begin1_;
278 return begin2_-begin1_;
314 Size temp = std::min(res1, res2);
315 res2 = std::max(res1, res2);
318 begin1_ = end1_ = res1;
319 begin2_ = end2_ = res2;
320 antipar = antiparallel;
321 pairing1.push_back( antipar ? end2_ : begin2_);
322 pairing2.push_back( antipar ? end1_ : begin1_ );
323 pleating1.push_back(pleating);
326 const Size SMALL_BULGE_LIMIT( basic::options::option[ basic::options::OptionKeys::jumps::max_strand_gap_allowed] );
327 const Size BIG_BULGE_LIMIT( SMALL_BULGE_LIMIT + 3 );
330 if(res1 >= begin1_ && res1 <= end1_) {
331 tr.Trace <<
"trivial case " << std::endl;
332 cando = (pairing1[res1 - begin1_] == res2);
333 }
else if(res1 > end1_ && res1 <= end1_ + BIG_BULGE_LIMIT) {
334 tr.Trace <<
"case1 " << std::endl;
336 if(res1 > end1_ + SMALL_BULGE_LIMIT)
337 cando = (res2 < begin2_ && res2 + SMALL_BULGE_LIMIT >= begin2_ );
339 cando = (res2 < begin2_ && res2 + BIG_BULGE_LIMIT >= begin2_ );
341 if(res1 > end1_ + SMALL_BULGE_LIMIT)
342 cando = (res2 > end2_ && res2 <= end2_ + SMALL_BULGE_LIMIT);
344 cando = (res2 > end2_ && res2 <= end2_ + BIG_BULGE_LIMIT);
346 }
else if(res1 < begin1_ && res1 + BIG_BULGE_LIMIT >= begin1_ ) {
347 tr.Trace <<
"case2 "<< std::endl;
349 if( res1 + SMALL_BULGE_LIMIT < begin1_ )
350 cando = (res2 > end2_ && res2 <= end2_ + SMALL_BULGE_LIMIT);
352 cando = (res2 > end2_ && res2 <= end2_ + BIG_BULGE_LIMIT);
354 if(res1 + SMALL_BULGE_LIMIT < begin1_)
355 cando = (res2 < begin2_ && res2 + SMALL_BULGE_LIMIT >= begin2_);
357 cando = (res2 < begin2_ && res2 + BIG_BULGE_LIMIT >= begin2_ );
360 runtime_assert( begin1_ <= end1_ );
361 runtime_assert( begin2_ <= end2_ );
365 tr.Trace <<
"extend " << *
this <<
" to residues " << res1 <<
" " << res2 << std::endl;
367 if(res1 + 1 < begin1_) {
368 pairing1.insert(pairing1.begin(),begin1_ - res1 - 1, 0);
369 pleating1.insert(pleating1.begin(),begin1_ - res1 - 1, 0);
371 pairing1.insert(pairing1.begin(), res2);
372 pleating1.insert(pleating1.begin(), pleating);
374 }
else if(res1 > end1_) {
375 if(res1 > end1_ + 1) {
377 pairing1.insert(pairing1.end(), res1 - end1_ - 1, 0);
378 pleating1.insert(pleating1.end(), res1 - end1_ - 1, 0);
380 pairing1.push_back( res2 );
381 pleating1.push_back( pleating );
386 if(res2 + 1 < begin2_ )
387 pairing2.insert(pairing2.begin(),begin2_ - res2 - 1, 0);
388 pairing2.insert(pairing2.begin(), res1);
390 }
else if(res2 > end2_) {
392 pairing2.insert(pairing2.end(), res2 - end2_ - 1, 0);
393 pairing2.insert(pairing2.end(), res1);
397 tr.Trace <<
" cannot extend "<< *
this <<
" to residues " << res1 <<
" " << res2 << std::endl;
400 show_internals(
tr.Trace );
401 if ( !valid_ends() ) {
408 void StrandPairing::extend_to(
Size res) {
409 Size res1, res2, pleat, diff = (antipar ? -1 : 1);
412 res2 = pairing1[0] - diff;
413 pleat = 3 - pleating1[0];
415 extend(res1, res2, antipar, pleat);
420 }
else if(res > end1_) {
422 res2 = pairing1[end1_ - begin1_] + diff;
423 pleat = 3 - pleating1[end1_ - begin1_];
425 extend(res1, res2, antipar, pleat);
433 void StrandPairing::show_internals( std::ostream& out )
const {
435 for (
Size i=0; i < pairing1.size(); i++) {
436 out << pairing1[ i ] <<
" ";
438 out <<
"\npairing2: ";
439 for (
Size i=0; i < pairing2.size(); i++) {
440 out << pairing2[ i ] <<
" ";
442 out <<
"\npairing2: ";
443 for (
Size i=0; i < pleating1.size(); i++) {
444 out << pleating1[ i ] <<
" ";
450 std::ostringstream
str;
451 str << (antipar ?
'A' :
'P') <<
'_';
454 regA=begin1_ + end2_;
455 regE=end1_ + begin2_;
457 regA=begin2_-begin1_;
460 str << regA <<
'_' << regE;
465 tr.Trace <<
"compare " << *
this <<
" to " << other << std::endl;
466 if ( antipar != other.
antipar) {
467 tr.Trace <<
" not the same directionality " << std::endl;
472 const Size MARGIN( basic::options::option[ basic::options::OptionKeys::jumps::max_strand_gap_allowed] - 1 );
473 if ( begin1_ > other.
end1_ + MARGIN || begin2_ > other.
end2_ + MARGIN
474 || other.
begin1_ > end1_ + MARGIN || other.
begin2_ > end2_ + MARGIN ) {
475 tr.Trace <<
" no overlap between strands " << std::endl;
476 tr.Trace <<
"begin1_ end1 begin2 end2 (repeat with other ) " <<
477 begin1_ <<
" " << end1_ <<
" " << begin2_ <<
" " << end2_ <<
" " <<
483 if ( end1_ >= other.
begin2_ || other.
end1_ >= begin2_ ) {
484 tr.Trace <<
"merged strands will overlap " << std::endl;
487 tr.Trace <<
"passed presecreen" << std::endl;
494 tr.Trace <<
"register mismatch " << std::endl;
499 (end1_ + other.
end2_ != other.
end1_ + end2_ )) {
500 tr.Trace <<
"register mismatch " << std::endl;
505 runtime_assert( end1_ - begin1_ < pleating1.size() );
506 runtime_assert( end2_ - begin2_ < pairing2.size() );
509 myex.extend_to(other.
end1_);
515 if (myex.end2_ != otherex.
end2_ || myex.begin2_ != otherex.
begin2_) {
516 tr.Debug <<
"SURPRISE!\n" << myex <<
"\n" << otherex <<
"\n" << *
this <<
"\n" << other <<
"\n" << std::endl;
521 for(
Size i = 0; i <= myex.end1_ - myex.begin1_; i++) {
522 runtime_assert( i < myex.pleating1.size() && i < otherex.
pleating1.size() );
523 if(myex.pleating1[i] != otherex.
pleating1[i] && myex.pleating1[i] > 0 && otherex.
pleating1[i] > 0) {
524 tr.Trace <<
" wrong pleating " << std::endl;
527 runtime_assert( i < myex.pairing1.size() && i < otherex.
pairing1.size() );
528 if(myex.pairing1[i] != otherex.
pairing1[i] && myex.pairing1[i] > 0 && otherex.
pairing1[i] > 0) {
529 tr.Trace <<
"wrong pairing1 " << std::endl;
533 for(
Size i = 0; i <= myex.end2_ - myex.begin2_; i++) {
534 runtime_assert( i < myex.pairing2.size() && i < otherex.
pairing2.size() );
535 if(myex.pairing2[i] != otherex.
pairing2[i] && myex.pairing2[i] > 0 && otherex.
pairing2[i] > 0) {
536 tr.Trace <<
"wrong pairing2 :" << myex.pairing2[i] <<
" " << otherex.
pairing2[i] << std::endl;
540 tr.Trace <<
"EQUAL" << std::endl;
545 bool possible ( mergeable( other ) );
546 if( domerge && possible ) {
560 if((res < begin1_ || res > end1_) && otherex.
pairing1[i] == 0) {
562 std::cout <<
"SERIOUS PROBLEM.\n";
569 std::cout <<
"ANOTHER SERIOUS PROBLEM.\n";
583 if ( res >= begin1_ && res <= end1_ ) {
584 return pleating1[res - begin1_];
585 }
else if ( res >= begin2_ && res <= end2_ ) {
586 if ( pairing2[res - begin2_] != 0 )
587 return pleating1[pairing2[res-begin2_]];
596 char StrandPairingSet::dssp_state(
Size res )
const {
598 for(StrandPairings::const_iterator it = pairings_.begin();
599 it != pairings_.end();
601 if(it->contains(res)) {
604 else if(state ==
' ')
610 char StrandPairingSet::featurizer_state(
Size res)
const {
612 for(StrandPairings::const_iterator it = pairings_.begin();
613 it != pairings_.end();
615 if(it->contains(res)) {
616 if(it->is_bulge(res)) {
619 else if(state ==
'b')
626 else if(state ==
'b')
640 bool found (
false );
641 for ( StrandPairings::const_iterator it = pairings_.begin();
642 it != pairings_.end() && !found; it++) {
652 bool StrandPairing::paired(
Size res1,
Size res2,
bool antipar )
const {
653 return ( antiparallel() == antipar &&
contains( res1 ) && get_pair( res1 ) == res2 );
656 bool StrandPairingSet::paired(
Size res1,
Size res2,
bool antiparallel)
const {
657 for ( StrandPairings::const_iterator it = pairings_.begin();
658 it != pairings_.end(); it++) {
659 if ( it->paired( res1, res2, antiparallel ) ) {
670 for( StrandPairings::const_iterator it = pairings_.begin(),
671 eit = pairings_.end(); it!=eit; it++) {
672 it->get_beta_pairs( beta_pairs );
676 StrandPairingSet::~StrandPairingSet() {
679 StrandPairing::StrandPairing(
Size res1,
Size res2,
bool antiparallel,
Size pleating) :
680 begin1_( std::min( res1, res2 ) ), end1_(begin1_),
681 begin2_( std::max( res1, res2 ) ), end2_(begin2_),
682 antipar(antiparallel)
706 regs.push_back( reg );
707 for (
Size i = 1; (
Size)i < pairing1.size(); i++) {
708 if( pairing1[i] != 0 &&
begin1_ + i + pairing1[i] != reg ) {
709 reg =
begin1_ + i + pairing1[i];
710 regs.push_back( reg );
711 bulges.push_back(
begin1_ + i - 1 );
716 regs.push_back( reg );
720 regs.push_back( reg );
721 bulges.push_back( begin1_ + i - 1 );
735 if ( direction ==
'A' ) {
737 }
else if ( direction ==
'P' ) {
740 tr.Trace <<
"failed reading A/P info --- found instead: " << direction << std::endl;
741 is.setstate( std::ios_base::failbit );
754 if ( minus !=
'-' ) {
755 tr.Trace <<
"failed reading start pairing --- found instead: " << sp.
begin1_ << minus << sp.
end2_ << std::endl;
756 is.setstate( std::ios_base::failbit );
762 if ( regstr !=
"reg:" ) {
763 tr.Trace <<
"failed reading register tag --- found instead: " << regstr << std::endl;
764 is.setstate( std::ios_base::failbit );
768 runtime_assert( !is.fail() );
773 while ( comma ==
"," && is >> reg1 >> comma ) {
774 regs.push_back( reg1 );
777 if ( comma !=
"bulges:" && comma !=
"pleating:" ) {
778 tr.Trace <<
"failed reading bulges tag --- found instead: " << comma << std::endl;
779 is.setstate( std::ios_base::failbit );
783 if (
tr.Trace.visible() ) {
784 tr.Trace <<
" regs: ";
787 tr.Trace << *it <<
" ";
792 if ( comma ==
"bulges:" ) {
795 while ( comma ==
"," && is >> bulge >> comma ) {
796 bulges.push_back( bulge );
800 if (
tr.Trace.visible() ) {
801 tr.Trace <<
" bulges: ";
804 tr.Trace << *it <<
" ";
808 if ( comma !=
"pleating:" ) {
809 tr.Trace <<
"failed reading pleating tag --- found instead: " << comma << std::endl;
810 is.setstate( std::ios_base::failbit );
826 if ( bulgeit != ebulgeit ) bulge = *bulgeit;
828 tr.Trace <<
" pos1 " << pos1 <<
" next bulge " << bulge <<
" pos2 " << pos2 << std::endl;
834 bool bulge2(
false );
837 if ( next_regit != eregit ) ++next_regit;
838 if ( next_regit != eregit ) {
839 Size nex_reg = *next_regit;
840 bulge2 = sp.
antipar ? nex_reg > reg : nex_reg < reg;
843 if ( !bulge2 && !bulge ) {
854 if ( pos1 == bulge ) {
855 if ( regit == eregit ) {
856 tr.Error <<
"read bulge at " << bulge <<
" but no new register in list " << std::endl;
857 is.setstate( std::ios_base::failbit );
862 Size new_pos2 = sp.
antipar ? ( *regit - pos1 - 1 ) : ( *regit + pos1 + 1);
863 tr.Trace <<
"jump to " << new_pos2 <<
" in strand2 due to new register " << *regit <<
" after bulge at " << bulge << std::endl;
864 if ( sp.
antipar && new_pos2 < pos2 ) {
866 }
else if ( !sp.
antipar && new_pos2 > pos2 ) {
875 utility_exit_with_message(
"error reading pairing from stream " );
878 tr.Trace << std::endl;
879 runtime_assert( !is.fail() );
892 for ( StrandPairing::SizeList::const_iterator it = regs.begin(), eit = regs.end(); it != eit; ++it ) {
900 if ( bulges.size() ) {
902 for ( StrandPairing::SizeList::const_iterator it = bulges.begin(), eit = bulges.end(); it != eit; ++it ) {
911 out <<
" pleating: ";
923 if(reg == otherreg) {
926 else if(begin1_ >= other.
end1_)
929 std::cout <<
"DSSP error: strange strand pairing\n";
930 std::cout << begin1_ <<
' ' <<
end1_ <<
' ' <<
begin2_ <<
' ' <<
end2_ <<
' ' << std::endl;
932 return begin1_ < other.
begin1_;
935 return reg < otherreg;
962 if (
get_pair(res) != 0 )
return false;
1001 beta_pairs.push_back( pair );
1010 if ( begin2 > end2 )
return false;
1014 if ( begin2 > end2 )
return false;